diff --git a/.dorpsgek.yml b/.dorpsgek.yml index a8b976f5c7..363d8b0b42 100644 --- a/.dorpsgek.yml +++ b/.dorpsgek.yml @@ -1,13 +1,15 @@ notifications: + global: + irc: + - openttd + - openttd.notice + push: - irc: - - openttd - - openttd.notice + only: + - master + only-by: + - DorpsGek + commit-comment: pull-request: - irc: - - openttd - - openttd.notice issue: - irc: - - openttd - - openttd.notice + tag-created: diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml new file mode 100644 index 0000000000..231b93314c --- /dev/null +++ b/.github/FUNDING.yml @@ -0,0 +1 @@ +custom: https://www.openttd.org/donate.html diff --git a/.github/workflows/commit-checker.yml b/.github/workflows/commit-checker.yml new file mode 100644 index 0000000000..d2546ab30b --- /dev/null +++ b/.github/workflows/commit-checker.yml @@ -0,0 +1,45 @@ +name: Commit checker + +on: + pull_request: + +jobs: + commit-checker: + name: Commit checker + runs-on: ubuntu-latest + + steps: + - name: Checkout + uses: actions/checkout@v2 + with: + fetch-depth: 4 + + - name: Get pull-request commits + run: | + set -x + # actions/checkout did a merge checkout of the pull-request. As such, the first + # commit is the merge commit. This means that on HEAD^ is the base branch, and + # on HEAD^2 are the commits from the pull-request. We now check if those trees + # have a common parent. If not, we fetch a few more commits till we do. In result, + # the log between HEAD^ and HEAD^2 will be the commits in the pull-request. + DEPTH=4 + while [ -z "$(git merge-base HEAD^ HEAD^2)" ]; do + git -c protocol.version=2 fetch --no-tags --prune --progress --no-recurse-submodules --deepen=${DEPTH} origin HEAD + DEPTH=$(( ${DEPTH} * 4 )) + done + + # Just to show which commits we are going to evaluate. + git log --oneline HEAD^..HEAD^2 + + - name: Checkout commit-checker + uses: actions/checkout@v2 + with: + repository: OpenTTD/OpenTTD-git-hooks + path: git-hooks + ref: master + + - name: Check commits + run: | + set -x + HOOKS_DIR=./git-hooks/hooks GIT_DIR=.git ./git-hooks/hooks/check-commits.sh HEAD^..HEAD^2 + echo "Commit checks passed" diff --git a/.gitignore b/.gitignore index e30aabe37c..3e74133dfe 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,9 @@ bin/baseset/* !bin/baseset/no_sound.obs !bin/baseset/no_music.obm !bin/baseset/orig_*.obm +!bin/game +bin/game/* +!bin/game/compat*.nut !bin/scripts bin/scripts/* !bin/scripts/*.example diff --git a/COMPILING.md b/COMPILING.md new file mode 100644 index 0000000000..46de5e09e2 --- /dev/null +++ b/COMPILING.md @@ -0,0 +1,141 @@ +# Compiling OpenTTD + +## Required/optional libraries + +The following libraries are used by OpenTTD for: + +- zlib: (de)compressing of old (0.3.0-1.0.5) savegames, content downloads, + heightmaps +- liblzo2: (de)compressing of old (pre 0.3.0) savegames +- liblzma: (de)compressing of savegames (1.1.0 and later) +- libpng: making screenshots and loading heightmaps +- 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 (Linux only) +- libSDL2: hardware access (video, sound, mouse) (not required for Windows or macOS) + +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. +Without libSDL/liballegro on non-Windows and non-macOS machines you have +no graphical user interface; you would be building a dedicated server. + +## Windows: + +You need Microsoft Visual Studio 2015 Update 3 or newer. + +You can download the free Visual Studio Community Edition from Microsoft at +https://visualstudio.microsoft.com/vs/community/. + +OpenTTD needs the Platform SDK, if it isn't installed already. This can be +done during installing Visual Studio, by selecting +`Visual C++ MFC for x86 and x64` (and possibly +`Visual C++ ATL for x86 and x64` depending on your version). If not, you +can get download it as [MS Windows Platform SDK](https://developer.microsoft.com/en-US/windows/downloads/windows-10-sdk). + +Install the SDK by following the instructions as given. + +Dependencies for OpenTTD on Windows are handled via +[vcpkg](https://github.com/Microsoft/vcpkg/). First you need to install vcpkg +by following the `Quick Start` instructions of their +[README](https://github.com/Microsoft/vcpkg/blob/master/README.md). + +After this, you can install the dependencies OpenTTD needs. We advise to use +the `static` versions, and OpenTTD currently needs the following dependencies: + +- liblzma +- libpng +- lzo +- zlib + +To install both the x64 (64bit) and x86 (32bit) variants (though only one is necessary), you can use: + +```ps +.\vcpkg install liblzma:x64-windows-static libpng:x64-windows-static lzo:x64-windows-static zlib:x64-windows-static +.\vcpkg install liblzma:x86-windows-static libpng:x86-windows-static lzo:x86-windows-static zlib:x86-windows-static +``` + +Open the relevant project file and it should build automatically. +- VS 2015: projects/openttd_vs140.sln +- VS 2017: projects/openttd_vs141.sln +- VS 2019: projects/openttd_vs142.sln + +Set the build mode to `Release` in +`Build > Configuration manager > Active solution configuration`. +You can now compile. + +If everything works well the binary should be in `objs\Win[32|64]\Release\openttd.exe` +and in `bin\openttd.exe` + +The OpenTTD wiki may provide additional help with [compiling for Windows](https://wiki.openttd.org/Compiling_on_Windows_using_Microsoft_Visual_C%2B%2B_2015). + +You can also build OpenTTD with MSYS2/MinGW-w64 or Cygwin/MinGW using the Makefile. The OpenTTD wiki may provide additional help with [MSYS2](https://wiki.openttd.org/Compiling_on_Windows_using_MSYS2) + +## Linux, Unix, Solaris: + +OpenTTD can be built with GNU '`make`'. On non-GNU systems it is called '`gmake`'. +However, for the first build one has to do a '`./configure`' first. + +The OpenTTD wiki may provide additional help with: + +- [compiling for Linux and *BSD](https://wiki.openttd.org/Compiling_on_%28GNU/%29Linux_and_*BSD) +- [compiling for Solaris](https://wiki.openttd.org/Compiling_on_Solaris) + + +## macOS: + +Use '`make`' or Xcode (which will then call make for you) +This will give you a binary for your CPU type (PPC/Intel) +However, for the first build one has to do a '`./configure`' first. +To make a universal binary type '`./configure --enable-universal`' +instead of '`./configure`'. + +The OpenTTD wiki may provide additional help with [compiling for macOS](https://wiki.openttd.org/Compiling_on_Mac_OS_X). + +## Haiku: + +Use '`make`', but do a '`./configure`' before the first build. + +The OpenTTD wiki may provide additional help with [compiling for Haiku](https://wiki.openttd.org/Compiling_on_Haiku). + +## OS/2: + +A comprehensive GNU build environment is required to build the OS/2 version. + +The OpenTTD wiki may provide additional help with [compiling for OS/2](https://wiki.openttd.org/Compiling_on_OS/2). + +## Supported compilers + +The following compilers are tested with and known to compile OpenTTD: + +- Microsoft Visual C++ (MSVC) 2015, 2017 and 2019. +- GNU Compiler Collection (GCC) 4.8 - 9. +- Clang/LLVM 3.9 - 8 + +The following compilers are known not to compile OpenTTD: + +In general, this is because these old versions do not (fully) support modern +C++11 language features. + +- Microsoft Visual C++ (MSVC) 2013 and earlier. +- GNU Compiler Collection (GCC) 4.7 and earlier. +- Clang/LLVM 3.8 and earlier. + +If any of these, or any other, compilers can compile OpenTTD, let us know. +Pull requests to support more compilers are welcome. + +## Compilation of base sets + +To recompile the extra graphics needed to play with the original Transport +Tycoon Deluxe graphics you need GRFCodec (which includes NFORenum) as well. +GRFCodec can be found at https://www.openttd.org/download-grfcodec. +The compilation of these extra graphics does generally not happen, unless +you remove the graphics file using '`make maintainer-clean`'. + +Re-compilation of the base sets, thus also use of '`--maintainer-clean`' can +leave the repository in a modified state as different grfcodec versions can +cause binary differences in the resulting grf. Also translations might have +been added for the base sets which are not yet included in the base set +information files. Use the configure option '`--without-grfcodec`' to avoid +modification of the base set files by the build process. diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 2c7ce528c9..40aad630c8 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -5,21 +5,26 @@ Looking to contribute something to OpenTTD? **Here's how you can help.** Please take a moment to review this document in order to make the contribution process easy and effective for everyone involved. -Following these guidelines helps to communicate that you respect the time of the developers managing and developing this open source project. In return, they should reciprocate that respect in addressing your issue or assessing patches and features. +Following these guidelines helps to communicate that you respect the time of the developers managing and developing this open source project. +In return, they should reciprocate that respect in addressing your issue or assessing patches and features. ## Using the issue tracker The [issue tracker](https://github.com/OpenTTD/OpenTTD/issues) is the preferred channel for [bug reports](#bug-reports), but please respect the following restrictions: -* Please **do not** use the issue tracker for help playing or using OpenTTD. Please try [irc](https://wiki.openttd.org/IRC_channel), or the [forums](https://www.tt-forums.net/) +* Please **do not** use the issue tracker for help playing or using OpenTTD. +Please try [irc](https://wiki.openttd.org/IRC_channel), or the [forums](https://www.tt-forums.net/) * Please **do not** derail or troll issues. Keep the discussion on topic and respect the opinions of others. * Please **do not** post comments consisting solely of "+1" or ":thumbsup:". -Use [GitHub's "reactions" feature](https://github.com/blog/2119-add-reactions-to-pull-requests-issues-and-comments) instead. We reserve the right to delete comments which violate this rule. +Use [GitHub's "reactions" feature](https://github.com/blog/2119-add-reactions-to-pull-requests-issues-and-comments) instead. +We reserve the right to delete comments which violate this rule. + +* Please **do not** open issues or pull requests regarding add-on content in NewGRF, GameScripts, AIs, etc. +These are created by third-parties. Please try [irc](https://wiki.openttd.org/IRC_channel) or the [forums](https://www.tt-forums.net/) to discuss these. -* Please **do not** open issues or pull requests regarding add-on content in NewGRF, GameScripts, AIs, etc. These are created by third-parties. Please try [irc](https://wiki.openttd.org/IRC_channel) or the [forums](https://www.tt-forums.net/) to discuss these. ## Bug reports @@ -69,13 +74,15 @@ Example: > causing the bug, and potential solutions (and your opinions on their > merits). + ## Feature requests -Before opening a feature request, please take a moment to find out whether your idea fits with the scope and aims of the project. +Before opening a feature request, please take a moment to find out whether your idea fits with the [scope and goals](./CONTRIBUTING.md#project-goals) of the project. It's up to *you* to make a strong case to convince the project's developers of the merits of this feature. -Please provide as much detail and context as possible. This means don't request for a solution, but describe the problem you see and how/why you think it should be fixed. +Please provide as much detail and context as possible. +This means don't request for a solution, but describe the problem you see and how/why you think it should be fixed. For feature request we have a strict policy. @@ -88,14 +95,18 @@ Many of those ideas etc do have a place on the [forums](https://www.tt-forums.ne It's usually best discuss in [irc](https://wiki.openttd.org/IRC_channel) 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 :) + ## Pull requests Good pull requests—patches, improvements, new features—are a fantastic help. -They should remain focused in scope and avoid containing unrelated commits. -**Please ask first** before embarking on any significant pull request (e.g. implementing features, refactoring code, porting to a different language), otherwise you risk spending a lot of time working on something that the project's developers might not want to merge into the project. +Pull requests should fit with the [goals of the project](./CONTRIBUTING.md#project-goals). -Please adhere to the [coding guidelines](#code-guidelines) used throughout the project (indentation, accurate comments, etc.) and any other requirements (such as test coverage). +**Please do ask first** before embarking on any significant pull request (e.g. implementing features, refactoring code, porting to a different language), otherwise you risk spending a lot of time working on something that the project's developers might not want to merge into the project. + +Every pull request should have a clear scope, with no unrelated commits. + +[Code style](https://wiki.openttd.org/Coding_style) must be complied with for pull requests to be accepted; this also includes [commit message format](https://wiki.openttd.org/Coding_style#Commit_message). Adhering to the following process is the best way to get your work included in the project: @@ -147,17 +158,8 @@ git push 7. [Open a Pull Request](https://help.github.com/articles/using-pull-requests/) with a clear title and description against the `master` branch. -**IMPORTANT**: By submitting a patch, you agree to the [License](#license). +**IMPORTANT**: By submitting a pull request or patch, you agree to the [License](#license) and the [Privacy Notice](CONTRIBUTING.md#privacy-notice). -### Privacy Notice - -We would like to make you aware that contributing to OpenTTD via git will permanently store the name and email address you provide as well as the actual changes and the time and date you made it inside git's version history. - -This is inevitable, because it is a main feature of git. If you are concerned about your privacy, we strongly recommend to use "Anonymous <anonymous@openttd.org>" as the git commit author. We might refuse anonymous contributions if malicious intent is suspected. - -Please note that the contributor identity, once given, is used for copyright verification and to provide proof should a malicious commit be made. As such, the [EU GDPR](https://www.eugdpr.org/key-changes.html) "right to be forgotten" does not apply, as this is an overriding legitimate interest. - -Please also note that your commit is public and as such will potentially be processed by many third-parties. Git's distributed nature makes it impossible to track where exactly your commit, and thus your personal data, will be stored and be processed. If you would not like to accept this risk, please do either commit anonymously or refrain from contributing to the OpenTTD project. ### Pull request validation @@ -165,15 +167,99 @@ Continuous integration (CI) tools monitor pull requests, and help us identify bu The results of the CI tests will show on your pull request. -By clicking on Details you can further zoom in; in case of a failure it will show you why it failed. In case of success it will report how awesome you were. +By clicking on Details you can further zoom in; in case of a failure it will show you why it failed. +In case of success it will report how awesome you were. -## Code guidelines +Tip: [commit message format](https://wiki.openttd.org/Coding_style#Commit_message) is a common reason for pull requests to fail validation. -[Code style](https://wiki.openttd.org/Coding_style) must be adhered to for pull requests to be accepted -## License +### Are there any development docs? + +There is no single source for OpenTTD development docs. It's a complex project with a long history, and multiple APIs. + +A good entry point is [Development](https://wiki.openttd.org/Development) on the OpenTTD wiki; this provides links to wiki documentation and other sources. + +The GitHub repo also includes some non-comprehensive documentation in [/docs](./docs). + +You may also want the guide to [compiling OpenTTD](./COMPILING.md). + + +## Project goals + +### What are the goals of the official branch? + +The main goals of the official branch are: + +- Stay faithful to the original gameplay from Transport Tycoon Deluxe +- Improve the user interface +- Allow extending the gameplay with add-ons / mods via supported content APIs +- Provide a (relatively) stable core for both players of the official branch, and for authors of add-ons and maintainers of patchpacks + +In contrast, extending or altering the gameplay of the base game is not encouraged. + +The rationale behind these goals is that people have different opinions about what OpenTTD is and what it should be. +When it comes to gameplay, there are at least these groups of people: + +- *Model railway (mostly singleplayer)*: build "realistic" landscapes, roleplay a world, or even replicate historical scenarios +- *Economical challenge (mostly singleplayer)*: run a business with economical challenges +- *Transport challenge (singleplayer or cooperative multiplayer)*: build efficient track layouts with high cargo throughput and tons of vehicles +- *Competitive speed run (competitive multiplayer)*: maximize some goal in some limited amount of time + +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. + +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". + +The preferred method to introduce new gameplay features is to extend the content APIs, supporting ever more add-on content / mods. + +This moves conflict-solving away from the codebase to content authors / players. +It is more accepted for add-ons not working together than the base game not working with certain setting combinations. + +In general the game should allow anything that doesn't violate basic rules, but it should warn players if they take potentially dangerous or "stupid" actions. + +For example, players are not prevented from starting vehicles without orders, but will receive a warning about vehicles having too few orders. +This lack of limitation has led to players challenging themselves to create networks where all vehicles have no orders, increasing gameplay possibilities. + +### I do not agree with the goals of the official branch, what can I do instead? + +Fork! There is a rich history of experimental patches for OpenTTD. + +Many of these will never be accepted for core, but are creative and interesting ways to modify OpenTTD. + +Sometimes patches are combined into long-running patchpacks, modified OpenTTD versions which can be downloaded by anyone, or modified OpenTTD clients for dedicated multiplayer servers. + +One of the reasons to keep core relatively stable is to make life easier for patch authors and patchpack maintainers where possible. + +Patchpack discussions and related topics may be found in community sites such as [TT-Forums development section](https://www.tt-forums.net/viewforum.php?f=33). + + +## Legal stuff + +### License + +By contributing your code, you agree to license your contribution under the [GPL v2](https://github.com/OpenTTD/OpenTTD/blob/master/COPYING.md). + + +### Privacy Notice + +We would like to make you aware that contributing to OpenTTD via git will permanently store the name and email address you provide as well as the actual changes and the time and date you made it inside git's version history. + +This is inevitable, because it is a main feature of git. +If you are concerned about your privacy, we strongly recommend to use "Anonymous <anonymous@openttd.org>" as the git commit author. We might refuse anonymous contributions if malicious intent is suspected. + +Please note that the contributor identity, once given, is used for copyright verification and to provide proof should a malicious commit be made. +As such, the [EU GDPR](https://www.eugdpr.org/key-changes.html) "right to be forgotten" does not apply, as this is an overriding legitimate interest. + +Please also note that your commit is public and as such will potentially be processed by many third-parties. +Git's distributed nature makes it impossible to track where exactly your commit, and thus your personal data, will be stored and be processed. +If you would not like to accept this risk, please do either commit anonymously or refrain from contributing to the OpenTTD project. -By contributing your code, you agree to license your contribution under the [GPL v2](https://github.com/OpenTTD/OpenTTD/blob/master/COPYING). ### Attribution of this Contributing Guide diff --git a/COPYING b/COPYING.md similarity index 74% rename from COPYING rename to COPYING.md index b790734971..2c2818d14c 100644 --- a/COPYING +++ b/COPYING.md @@ -1,18 +1,19 @@ This is the license which applies to OpenTTD with the exception of some -3rd party modules. See README.md for details +3rd party modules. See [./README.md](./README.md) for details +GNU General Public License +========================== - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 +_Version 2, June 1991_ +_Copyright © 1989, 1991 Free Software Foundation, Inc.,_ +_51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA_ - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. +Everyone is permitted to copy and distribute verbatim copies +of this license document, but changing it is not allowed. - Preamble +### Preamble - The licenses for most software are designed to take away your +The licenses for most software are designed to take away your freedom to share and change it. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change free software--to make sure the software is free for all its users. This @@ -22,48 +23,47 @@ using it. (Some other Free Software Foundation software is covered by the GNU Lesser General Public License instead.) You can apply it to your programs, too. - When we speak of free software, we are referring to freedom, not +When we speak of free software, we are referring to freedom, not price. Our General Public Licenses are designed to make sure that you have the freedom to distribute copies of free software (and charge for this service if you wish), that you receive source code or can get it if you want it, that you can change the software or use pieces of it in new free programs; and that you know you can do these things. - To protect your rights, we need to make restrictions that forbid +To protect your rights, we need to make restrictions that forbid anyone to deny you these rights or to ask you to surrender the rights. These restrictions translate to certain responsibilities for you if you distribute copies of the software, or if you modify it. - For example, if you distribute copies of such a program, whether +For example, if you distribute copies of such a program, whether gratis or for a fee, you must give the recipients all the rights that you have. You must make sure that they, too, receive or can get the source code. And you must show them these terms so they know their rights. - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, +We protect your rights with two steps: **(1)** copyright the software, and +**(2)** offer you this license which gives you legal permission to copy, distribute and/or modify the software. - Also, for each author's protection and ours, we want to make certain +Also, for each author's protection and ours, we want to make certain that everyone understands that there is no warranty for this free software. If the software is modified by someone else and passed on, we want its recipients to know that what they have is not the original, so that any problems introduced by others will not reflect on the original authors' reputations. - Finally, any free program is threatened constantly by software +Finally, any free program is threatened constantly by software patents. We wish to avoid the danger that redistributors of a free program will individually obtain patent licenses, in effect making the program proprietary. To prevent this, we have made it clear that any patent must be licensed for everyone's free use or not licensed at all. - The precise terms and conditions for copying, distribution and +The precise terms and conditions for copying, distribution and modification follow. - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION +### TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - 0. This License applies to any program or other work which contains +**0.** This License applies to any program or other work which contains a notice placed by the copyright holder saying it may be distributed under the terms of this General Public License. The "Program", below, refers to any such program or work, and a "work based on the Program" @@ -80,7 +80,7 @@ is covered only if its contents constitute a work based on the Program (independent of having been made by running the Program). Whether that is true depends on what the Program does. - 1. You may copy and distribute verbatim copies of the Program's +**1.** You may copy and distribute verbatim copies of the Program's source code as you receive it, in any medium, provided that you conspicuously and appropriately publish on each copy an appropriate copyright notice and disclaimer of warranty; keep intact all the @@ -91,29 +91,27 @@ along with the Program. You may charge a fee for the physical act of transferring a copy, and you may at your option offer warranty protection in exchange for a fee. - 2. You may modify your copy or copies of the Program or any portion +**2.** You may modify your copy or copies of the Program or any portion of it, thus forming a work based on the Program, and copy and distribute such modifications or work under the terms of Section 1 above, provided that you also meet all of these conditions: - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) +* **a)** You must cause the modified files to carry prominent notices +stating that you changed the files and the date of any change. +* **b)** You must cause any work that you distribute or publish, that in +whole or in part contains or is derived from the Program or any +part thereof, to be licensed as a whole at no charge to all third +parties under the terms of this License. +* **c)** If the modified program normally reads commands interactively +when run, you must cause it, when started running for such +interactive use in the most ordinary way, to print or display an +announcement including an appropriate copyright notice and a +notice that there is no warranty (or else, saying that you provide +a warranty) and that users may redistribute the program under +these conditions, and telling the user how to view a copy of this +License. (Exception: if the Program itself is interactive but +does not normally print such an announcement, your work based on +the Program is not required to print an announcement.) These requirements apply to the modified work as a whole. If identifiable sections of that work are not derived from the Program, @@ -135,26 +133,24 @@ with the Program (or with a work based on the Program) on a volume of a storage or distribution medium does not bring the other work under the scope of this License. - 3. You may copy and distribute the Program (or a work based on it, +**3.** You may copy and distribute the Program (or a work based on it, under Section 2) in object code or executable form under the terms of Sections 1 and 2 above provided that you also do one of the following: - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) +* **a)** Accompany it with the complete corresponding machine-readable +source code, which must be distributed under the terms of Sections +1 and 2 above on a medium customarily used for software interchange; or, +* **b)** Accompany it with a written offer, valid for at least three +years, to give any third party, for a charge no more than your +cost of physically performing source distribution, a complete +machine-readable copy of the corresponding source code, to be +distributed under the terms of Sections 1 and 2 above on a medium +customarily used for software interchange; or, +* **c)** Accompany it with the information you received as to the offer +to distribute corresponding source code. (This alternative is +allowed only for noncommercial distribution and only if you +received the program in object code or executable form with such +an offer, in accord with Subsection b above.) The source code for a work means the preferred form of the work for making modifications to it. For an executable work, complete source @@ -173,7 +169,7 @@ access to copy the source code from the same place counts as distribution of the source code, even though third parties are not compelled to copy the source along with the object code. - 4. You may not copy, modify, sublicense, or distribute the Program +**4.** You may not copy, modify, sublicense, or distribute the Program except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense or distribute the Program is void, and will automatically terminate your rights under this License. @@ -181,7 +177,7 @@ However, parties who have received copies, or rights, from you under this License will not have their licenses terminated so long as such parties remain in full compliance. - 5. You are not required to accept this License, since you have not +**5.** You are not required to accept this License, since you have not signed it. However, nothing else grants you permission to modify or distribute the Program or its derivative works. These actions are prohibited by law if you do not accept this License. Therefore, by @@ -190,7 +186,7 @@ Program), you indicate your acceptance of this License to do so, and all its terms and conditions for copying, distributing or modifying the Program or works based on it. - 6. Each time you redistribute the Program (or any work based on the +**6.** Each time you redistribute the Program (or any work based on the Program), the recipient automatically receives a license from the original licensor to copy, distribute or modify the Program subject to these terms and conditions. You may not impose any further @@ -198,7 +194,7 @@ restrictions on the recipients' exercise of the rights granted herein. You are not responsible for enforcing compliance by third parties to this License. - 7. If, as a consequence of a court judgment or allegation of patent +**7.** If, as a consequence of a court judgment or allegation of patent infringement or for any other reason (not limited to patent issues), conditions are imposed on you (whether by court order, agreement or otherwise) that contradict the conditions of this License, they do not @@ -230,7 +226,7 @@ impose that choice. This section is intended to make thoroughly clear what is believed to be a consequence of the rest of this License. - 8. If the distribution and/or use of the Program is restricted in +**8.** If the distribution and/or use of the Program is restricted in certain countries either by patents or by copyrighted interfaces, the original copyright holder who places the Program under this License may add an explicit geographical distribution limitation excluding @@ -238,7 +234,7 @@ those countries, so that distribution is permitted only in or among countries not thus excluded. In such case, this License incorporates the limitation as if written in the body of this License. - 9. The Free Software Foundation may publish revised and/or new versions +**9.** The Free Software Foundation may publish revised and/or new versions of the General Public License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. @@ -251,7 +247,7 @@ Software Foundation. If the Program does not specify a version number of this License, you may choose any version ever published by the Free Software Foundation. - 10. If you wish to incorporate parts of the Program into other free +**10.** If you wish to incorporate parts of the Program into other free programs whose distribution conditions are different, write to the author to ask for permission. For software which is copyrighted by the Free Software Foundation, write to the Free Software Foundation; we sometimes @@ -259,9 +255,9 @@ make exceptions for this. Our decision will be guided by the two goals of preserving the free status of all derivatives of our free software and of promoting the sharing and reuse of software generally. - NO WARRANTY +### NO WARRANTY - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY +**11.** BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED @@ -271,7 +267,7 @@ TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING +**12.** IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING @@ -281,15 +277,15 @@ YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES. - END OF TERMS AND CONDITIONS +END OF TERMS AND CONDITIONS - How to Apply These Terms to Your New Programs +### How to Apply These Terms to Your New Programs - If you develop a new program, and you want it to be of the greatest +If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it free software which everyone can redistribute and change under these terms. - To do so, attach the following notices to the program. It is safest +To do so, attach the following notices to the program. It is safest to attach them to the start of each source file to most effectively convey the exclusion of warranty; and each file should have at least the "copyright" line and a pointer to where the full notice is found. @@ -321,20 +317,20 @@ when it starts in an interactive mode: This is free software, and you are welcome to redistribute it under certain conditions; type `show c' for details. -The hypothetical commands `show w' and `show c' should show the appropriate +The hypothetical commands `show w` and `show c` should show the appropriate parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be +be called something other than `show w` and `show c`; they could even be mouse-clicks or menu items--whatever suits your program. You should also get your employer (if you work as a programmer) or your school, if any, to sign a "copyright disclaimer" for the program, if necessary. Here is a sample; alter the names: - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. + Yoyodyne, Inc., hereby disclaims all copyright interest in the program + `Gnomovision' (which makes passes at compilers) written by James Hacker. - , 1 April 1989 - Ty Coon, President of Vice + , 1 April 1989 + Ty Coon, President of Vice This General Public License does not permit incorporating your program into proprietary programs. If your program is a subroutine library, you may diff --git a/CREDITS.md b/CREDITS.md new file mode 100644 index 0000000000..8c20a4ac18 --- /dev/null +++ b/CREDITS.md @@ -0,0 +1,60 @@ +### 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) +- Charles Pigott (LordAro) - General / Correctness police (since 1.9) +- Michael Lutz (michi_cc) - 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) +- Leif Linse (Zuu) - AI/Game Script (since 1.2) + +### Inactive Developers: + +- 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) +- 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) +- Zdeněk Sojka (SmatZ) - Bug finder and fixer (0.6 - 1.3) +- 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) + +### Retired Developers: + +- 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) +- 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) +- Benedikt Brüggemeier (skidd13) - Bug fixer and code reworker (0.6 - 0.7) +- Serge Paquet (vurlix) - 2nd contributor after ludde (0.1 - 0.3) + +### Thanks to: + +- Josef Drexler - For his great work on TTDPatch. +- Marcin Grzegorczyk - For his TTDPatch work and documentation of Transport Tycoon Deluxe internals and track foundations +- Stefan Meißner (sign_de) - For his work on the console +- Mike Ragsdale - OpenTTD installer +- Christian Rosentreter (tokai) - MorphOS / AmigaOS port +- Richard Kempton (RichK67) - Additional airports, initial TGP implementation +- Alberto Demichelis - Squirrel scripting language +- L. Peter Deutsch - MD5 implementation +- Michael Blunck - For revolutionizing TTD with awesome graphics +- George - Canal graphics +- Andrew Parkhouse (andythenorth) - River graphics +- David Dallaston (Pikka) - Tram tracks +- All Translators - For their support to make OpenTTD a truly international game +- Bug Reporters - Thanks for all bug reports +- Chris Sawyer - For an amazing game! diff --git a/Doxyfile b/Doxyfile index 251b36be15..e288ffbd87 100644 --- a/Doxyfile +++ b/Doxyfile @@ -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. # 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. @@ -9,8 +7,8 @@ # Project related configuration options #--------------------------------------------------------------------------- DOXYFILE_ENCODING = UTF-8 -PROJECT_NAME = OpenTTD -PROJECT_NUMBER = +PROJECT_NAME = "OpenTTD Source" +PROJECT_NUMBER = $(VERSION) PROJECT_BRIEF = PROJECT_LOGO = OUTPUT_DIRECTORY = docs/source/ @@ -289,16 +287,15 @@ EXPAND_ONLY_PREDEF = YES SEARCH_INCLUDES = YES INCLUDE_PATH = INCLUDE_FILE_PATTERNS = -PREDEFINED = ENABLE_NETWORK \ - WITH_ZLIB \ +PREDEFINED = WITH_ZLIB \ WITH_LZO \ - WITH_LZMA \ + WITH_LIBLZMA \ WITH_SDL \ WITH_PNG \ WITH_FONTCONFIG \ WITH_FREETYPE \ - WITH_ICU_SORT \ - WITH_ICU_LAYOUT \ + WITH_ICU_I18N \ + WITH_ICU_LX \ UNICODE \ _UNICODE \ _GNU_SOURCE \ diff --git a/Makefile.bundle.in b/Makefile.bundle.in index eaf7134dde..276307c33e 100644 --- a/Makefile.bundle.in +++ b/Makefile.bundle.in @@ -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. # 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. @@ -69,10 +67,10 @@ endif $(Q)cp "$(BIN_DIR)/baseset/opntitle.dat" "$(BASESET_DIR)/" $(Q)cp "$(BIN_DIR)/baseset/"*.obm "$(BASESET_DIR)/" $(Q)cp "$(BIN_DIR)/lang/"*.lng "$(LANG_DIR)/" - $(Q)cp "$(ROOT_DIR)/README.md" "$(BUNDLE_DIR)/" - $(Q)cp "$(ROOT_DIR)/COPYING" "$(BUNDLE_DIR)/" + $(Q)cp "$(ROOT_DIR)/README.md" "$(BUNDLE_DIR)/" + $(Q)cp "$(ROOT_DIR)/COPYING.md" "$(BUNDLE_DIR)/" $(Q)cp "$(ROOT_DIR)/known-bugs.txt" "$(BUNDLE_DIR)/" - $(Q)cp "$(ROOT_DIR)/docs/multiplayer.txt" "$(BUNDLE_DIR)/docs/" + $(Q)cp "$(ROOT_DIR)/docs/multiplayer.md" "$(BUNDLE_DIR)/docs/" $(Q)cp "$(ROOT_DIR)/changelog.txt" "$(BUNDLE_DIR)/" ifdef MAN_DIR $(Q)mkdir -p "$(BUNDLE_DIR)/man/" @@ -88,13 +86,7 @@ ifdef MENU_DIR $(Q)sed s/=openttd/=$(BINARY_NAME)/g "$(BUNDLE_DIR)/media/openttd.desktop" > "$(ROOT_DIR)/media/openttd.desktop.install" endif ifeq ($(TTD), openttd.exe) - $(Q)unix2dos "$(BUNDLE_DIR)/docs/"* "$(BUNDLE_DIR)/README.md" "$(BUNDLE_DIR)/COPYING" "$(BUNDLE_DIR)/changelog.txt" "$(BUNDLE_DIR)/known-bugs.txt" -ifeq ($(OS), DOS) - $(Q)cp "$(ROOT_DIR)/os/dos/cwsdpmi/cwsdpmi.txt" "$(BUNDLE_DIR)/docs/" -ifndef STRIP - $(Q)cp "$(ROOT_DIR)/os/dos/cwsdpmi/cwsdpmi.exe" "$(TTD_DIR)/" -endif -endif + $(Q)unix2dos "$(BUNDLE_DIR)/docs/"* "$(BUNDLE_DIR)/README.md" "$(BUNDLE_DIR)/COPYING.md" "$(BUNDLE_DIR)/changelog.txt" "$(BUNDLE_DIR)/known-bugs.txt" endif ### Packing the current bundle into several compressed file formats ### @@ -159,7 +151,7 @@ bundle_dmg: bundle bundle_exe: all @echo '[BUNDLE] Creating $(BUNDLE_NAME).exe' $(Q)mkdir -p "$(BUNDLES_DIR)" - $(Q)unix2dos "$(ROOT_DIR)/docs/"*.txt "$(ROOT_DIR)/README.md" "$(ROOT_DIR)/COPYING" "$(ROOT_DIR)/changelog.txt" "$(ROOT_DIR)/known-bugs.txt" + $(Q)unix2dos "$(ROOT_DIR)/docs/"* "$(ROOT_DIR)/README.md" "$(ROOT_DIR)/COPYING.md" "$(ROOT_DIR)/changelog.txt" "$(ROOT_DIR)/known-bugs.txt" $(Q)cd $(ROOT_DIR)/os/windows/installer && makensis.exe //DVERSION_INCLUDE=version_$(PLATFORM).txt install.nsi $(Q)mv $(ROOT_DIR)/os/windows/installer/*$(PLATFORM).exe "$(BUNDLES_DIR)/$(BUNDLE_NAME).exe" @@ -196,7 +188,7 @@ ifndef DO_NOT_INSTALL_CHANGELOG endif ifndef DO_NOT_INSTALL_LICENSE $(Q)install -d "$(INSTALL_DOC_DIR)" - $(Q)install -m 644 "$(BUNDLE_DIR)/COPYING" "$(INSTALL_DOC_DIR)" + $(Q)install -m 644 "$(BUNDLE_DIR)/COPYING.md" "$(INSTALL_DOC_DIR)" endif $(Q)install -m 644 "$(BUNDLE_DIR)/media/openttd.32.xpm" "$(INSTALL_ICON_DIR)/${BINARY_NAME}.32.xpm" ifdef ICON_THEME_DIR diff --git a/Makefile.grf.in b/Makefile.grf.in index 8e8113a033..be382d708d 100644 --- a/Makefile.grf.in +++ b/Makefile.grf.in @@ -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. # 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. diff --git a/Makefile.in b/Makefile.in index d33d8a0d2a..38d7f53294 100644 --- a/Makefile.in +++ b/Makefile.in @@ -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. # 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. @@ -50,7 +48,7 @@ RES := $(shell if [ ! -f $(CONFIG_CACHE_SOURCE_LIST) ] || [ -n "`cmp $(CONFIG_CA all: config.pwd config.cache ifdef DISTCC - @if [ -z "`echo '$(MFLAGS)' | grep '\-j'`" ]; then echo; echo "WARNING: you enabled distcc support, but you don't seem to be using the -jN paramter"; echo; fi + @if [ -z "`echo '$(MFLAGS)' | grep '\-j'`" ]; then echo; echo "WARNING: you enabled distcc support, but you don't seem to be using the -jN parameter"; echo; fi endif @for dir in $(DIRS); do \ $(MAKE) -C $$dir all || exit 1; \ diff --git a/Makefile.lang.in b/Makefile.lang.in index 2853ae3898..bce43b8466 100644 --- a/Makefile.lang.in +++ b/Makefile.lang.in @@ -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. # 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. diff --git a/Makefile.msvc b/Makefile.msvc index 0a02c8cf95..8070062acf 100644 --- a/Makefile.msvc +++ b/Makefile.msvc @@ -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. # 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. diff --git a/Makefile.setting.in b/Makefile.setting.in index 1e2dc992f8..987a882db1 100644 --- a/Makefile.setting.in +++ b/Makefile.setting.in @@ -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. # 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. diff --git a/Makefile.src.in b/Makefile.src.in index 6b235be9d3..ef2d2bb503 100644 --- a/Makefile.src.in +++ b/Makefile.src.in @@ -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. # 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. @@ -139,7 +137,7 @@ $(OBJS_CPP:%.o=%.d): %.d: $(SRC_DIR)/%.cpp $(FILE_DEP) $(OBJS_MM:%.o=%.d): %.d: $(SRC_DIR)/%.mm $(FILE_DEP) $(E) '$(STAGE) DEP $(<:$(SRC_DIR)/%.mm=%.mm)' - $(Q)$(CC_HOST) $(CFLAGS) -MM $< | sed 's@^$(@F:%.d=%.o):@$@ $(@:%.d=%.o):@' > $@ + $(Q)$(CXX_HOST) $(CFLAGS) $(CXXFLAGS) -MM $< | sed 's@^$(@F:%.d=%.o):@$@ $(@:%.d=%.o):@' > $@ $(OBJS_RC:%.o=%.d): %.d: $(SRC_DIR)/%.rc $(FILE_DEP) $(E) '$(STAGE) DEP $(<:$(SRC_DIR)/%.rc=%.rc)' @@ -249,7 +247,7 @@ $(filter %sse4.o, $(OBJS_CPP)): %.o: $(SRC_DIR)/%.cpp $(DEP_MASK) $(FILE_DEP) $(OBJS_MM): %.o: $(SRC_DIR)/%.mm $(DEP_MASK) $(FILE_DEP) $(E) '$(STAGE) Compiling $(<:$(SRC_DIR)/%.mm=%.mm)' - $(Q)$(CC_HOST) $(CFLAGS) -c -o $@ $< + $(Q)$(CXX_HOST) $(CFLAGS) $(CXXFLAGS) -c -o $@ $< $(OBJS_RC): %.o: $(SRC_DIR)/%.rc $(FILE_DEP) $(E) '$(STAGE) Compiling resource $(<:$(SRC_DIR)/%.rc=%.rc)' @@ -270,10 +268,6 @@ $(TTD): $(OBJS) $(CONFIG_CACHE_LINKER) ifdef STRIP $(Q)$(STRIP) $@ endif -ifeq ($(OS), DOS) - $(E) '$(STAGE) Adding CWSDPMI stub to $@' - $(Q)$(ROOT_DIR)/os/dos/make_dos_binary_selfcontained.sh $(SRC_OBJS_DIR)/$@ -endif # Revision files diff --git a/README.md b/README.md index e621dc0215..230bbf3b6e 100644 --- a/README.md +++ b/README.md @@ -3,211 +3,78 @@ ## Table of contents - 1.0) [About](#10-about) -- 2.0) [Contacting](#20-contacting) - - 2.1) [Reporting bugs](#21-reporting-bugs) - - 2.2) [Reporting desyncs](#22-reporting-desyncs) -- 3.0) [Supported platforms](#30-supported-platforms) -- 4.0) [Installing and running OpenTTD](#40-installing-and-running-openttd) - - 4.1) [(Required) 3rd party files](#41-required-3rd-party-files) - - 4.2) [OpenTTD directories](#42-openttd-directories) - - 4.3) [Portable installations (portable media)](#43-portable-installations-portable-media) - - 4.4) [Files in tar (archives)](#44-files-in-tar-archives) -- 5.0) [OpenTTD features](#50-openttd-features) - - 5.1) [Logging of potentially dangerous actions](#51-logging-of-potentially-dangerous-actions) - - 5.2) [Frame rate and performance metrics](#52-frame-rate-and-performance-metrics) -- 6.0) [Configuration file](#60-configuration-file) -- 7.0) [Compiling](#70-compiling) - - 7.1) [Required/optional libraries](#71-requiredoptional-libraries) - - 7.2) [Supported compilers](#72-supported-compilers) - - 7.3) [Compilation of base sets](#73-compilation-of-base-sets) -- 8.0) [Translating](#80-translating) - - 8.1) [Translation](#81-translation) - - 8.2) [Previewing](#82-previewing) -- 9.0) [Troubleshooting](#90-troubleshooting) -- 10.0) [Licensing](#100-licensing) -- X.X) [Credits](#xx-credits) + - 1.1) [Downloading OpenTTD](#11-downloading-openttd) + - 1.2) [OpenTTD gameplay manual](#12-openttd-gameplay-manual) + - 1.3) [Supported platforms](#13-supported-platforms) + - 1.4) [Installing and running OpenTTD](#14-installing-and-running-openttd) + - 1.5) [Add-on content / mods](#15-add-on-content--mods) + - 1.6) [OpenTTD directories](#16-openttd-directories) + - 1.7) [Compiling OpenTTD](#17-compiling-openttd) +- 2.0) [Contact and community](#20-contact-and-community) + - 2.1) [Contributing to OpenTTD](#21-contributing-to-openttd) + - 2.2) [Reporting bugs](#22-reporting-bugs) + - 2.3) [Translating](#23-translating) +- 3.0) [Licensing](#30-licensing) +- 4.0) [Credits](#40-credits) ## 1.0) About -OpenTTD is a transport simulation game based upon the popular game Transport -Tycoon Deluxe, written by Chris Sawyer. It attempts to mimic the original -game as closely as possible while extending it with new features. +OpenTTD is a transport simulation game based upon the popular game Transport Tycoon Deluxe, written by Chris Sawyer. +It attempts to mimic the original game as closely as possible while extending it with new features. -OpenTTD is licensed under the GNU General Public License version 2.0, -but includes some 3rd party software under different licenses. See the -section "Licensing" below for details. +OpenTTD is licensed under the GNU General Public License version 2.0, but includes some 3rd party software under different licenses. +See the section ["Licensing"](#30-licensing) below for details. -## 2.0) Contacting +## 1.1) Downloading OpenTTD -The easiest way to contact the OpenTTD team is by submitting bug reports or -posting comments in our forums. You can also chat with us on IRC (#openttd -on irc.oftc.net). +OpenTTD can be downloaded from the [official OpenTTD website](https://www.openttd.org/). -The OpenTTD homepage is https://www.openttd.org. +Both 'stable' and 'nightly' versions are available for download: -You can also find the OpenTTD forums at -[https://www.tt-forums.net](https://www.tt-forums.net/viewforum.php?f=55). +- most people should choose the 'stable' version, as this has been more extensively tested +- the 'nightly' version includes the latest changes and features, but may sometimes be less reliable -### 2.1) Reporting bugs +On some platforms OpenTTD will also be available via your OS package manager or a similar service. -First of all, check whether the bug is not already known. Do this by looking -through the file called 'known-bugs.txt' which is distributed with OpenTTD -like this readme. -For tracking our bugs we are using GitHub's issue tracker. You can find -the tracker at https://github.com/OpenTTD/OpenTTD/issues. Before actually -reporting take a look through the already reported bugs there to see if -the bug is already known. The 'known-bugs.txt' file might be a bit outdated -at the moment you are reading it as only bugs known before the release -are documented there. Also look through the recently closed bugs. +## 1.2) OpenTTD gameplay manual -When you are sure it is not already reported you should: +OpenTTD has a [community-maintained wiki](https://wiki.openttd.org/), including a gameplay manual and tips. -- Make sure you are running a recent version, i.e. run the latest stable or - nightly based on where you found the bug. -- Make sure you are not running a non-official binary, like a patch pack. - When you are playing with a patch pack you should report any bugs to the - forum thread related to that patch pack. -- Make it reproducible for the developers. In other words, create a savegame - in which you can reproduce the issue once loaded. It is very useful to give - us the crash.dmp, crash.sav, crash.log and crash screenshot which are - created on crashes. -- Check whether the bug is already reported on our bug tracker. This includes - searching for recently closed bug reports as the bug might already be fixed. -After you have done all that you can report the bug. Please include the -following information in your bug report: +## 1.3) Supported platforms -- OpenTTD version (PLEASE test the latest Git revision/nightly build) -- Bug details, including instructions how to reproduce it -- Platform (Windows, Linux, FreeBSD, …) and compiler (including version) if - you compiled OpenTTD yourself. -- The processor architecture of your OS (32-bit Windows, 64-bit Windows, - Linux on an ARM, Mac OS X on a PowerPC, etc.) -- Attach a saved game **and** a screenshot if possible -- If this bug only occurred recently please note the last version without - the bug and the first version including the bug. That way we can fix it - quicker by looking at the changes made. -- Attach crash.dmp, crash.log and crash.sav. These files are usually created - next to your openttd.cfg. The crash handler will tell you the location. +OpenTTD has been ported to several platforms and operating systems. -### 2.2) Reporting desyncs +The currently working platforms are: -As desyncs are hard to make reproducible OpenTTD has the ability to log all -actions done by clients so we can replay the whole game in an effort to make -desyncs better reproducible. You need to turn this ability on. When turned -on an automatic savegame will be made once the map has been constructed in -the 'save/autosave' directory, see OpenTTD directories to know where to find -this directory. Furthermore the log file 'commands-out.log' will be created -and all actions will be written to there. - -To enable the desync debugging you need to set the debug level for 'desync' -to at least 1. You do this by starting OpenTTD with '`-d desync=`' as -parameter or by typing '`debug_level desync=`' in OpenTTD's internal -console. -The desync debug levels are: - -- 0: nothing. -- 1: dumping of commands to 'commands-out.log'. -- 2: same as 1 plus checking vehicle caches and dumping that too. -- 3: same as 2 plus monthly saves in autosave. -- 4 and higher: same as 3 - -Restarting OpenTTD will overwrite 'commands-out.log'. OpenTTD will not remove -the savegames (dmp_cmds_*.sav) made by the desync debugging system, so you -have to occasionally remove them yourself! - -The naming format of the desync savegames is as follows: -dmp_cmds_XXXXXXXX_YYYYYYYY.sav. The XXXXXXXX is the hexadecimal representation -of the generation seed of the game and YYYYYYYY is the hexadecimal -representation of the date of the game. This sorts the savegames by game and -then by date making it easier to find the right savegames. - -When a desync has occurred with the desync debugging turned on you should file -a bug report with the following files attached: - -- commands-out.log as it contains all the commands that were done -- the last saved savegame (search for the last line beginning with - 'save: dmp_cmds_' in commands-out.log). We use this savegame to check - whether we can quickly reproduce the desync. Otherwise we will need … -- the first saved savegame (search for the first line beginning with 'save' - where the first part, up to the last underscore '_', is the same). We need - this savegame to be able to reproduce the bug when the last savegame is not - old enough. If you loaded a scenario or savegame you need to attach that. -- optionally you can attach the savegames from around 50%, 75%, 85%, 90% and - 95% of the game's progression. We can use these savegames to speed up the - reproduction of the desync, but we should be able to reproduce these - savegames based on the first savegame and commands-out.log. -- in case you use any NewGRFs you should attach the ones you used unless - we can easily find them ourselves via bananas or when they are in the - #openttdcoop pack. - -Do NOT remove the dmp_cmds savegames of a desync you have reported until the -desync has been fixed; if you, by accident, send us the wrong savegames we -will not be able to reproduce the desync and thus will be unable to fix it. - -## 3.0) Supported platforms - -OpenTTD has been ported to several platforms and operating systems. It should -not be very difficult to port it to a new platform. The currently working -platforms are: - -- BeOS (SDL or Allegro) -- DOS (Allegro) - FreeBSD (SDL) -- Linux (SDL or Allegro) +- Haiku (SDL) +- Linux (SDL) - macOS (universal) (Cocoa video and sound drivers) -- MorphOS (SDL) - OpenBSD (SDL) - OS/2 (SDL) -- Windows (Win32 GDI (faster) or SDL or Allegro) +- Windows (Win32 GDI (faster) or SDL) -## 4.0) Installing and running OpenTTD +### 1.3.1) Legacy support +Platforms, languages and compilers change. +We'll keep support going on old platforms as long as someone is interested in supporting them, except where it means the project can't move forward to keep up with language and compiler features. -Installing OpenTTD is fairly straightforward. Either you have downloaded an -archive which you have to extract to a directory where you want OpenTTD to -be installed, or you have downloaded an installer, which will automatically -extract OpenTTD in the given directory. +We guarantee that every revision of OpenTTD will be able to load savegames from every older revision (excepting where the savegame is corrupt). +Please report a bug if you find a save that doesn't load. -OpenTTD looks in multiple locations to find the required data files (described -in section 4.2). Installing any 3rd party files into a 'shared' location has -the advantage that you only need to do this step once, rather than copying the -data files into all OpenTTD versions you have. +## 1.4) Installing and running OpenTTD -Savegames, screenshots, etc are saved relative to the config file (openttd.cfg) -currently being used. This means that if you use a config file in one of the -shared directories, savegames will reside in the save/ directory next to the -openttd.cfg file there. +OpenTTD is usually straightforward to install, but for more help the wiki [includes an installation guide](https://wiki.openttd.org/Installation). -If you want savegames and screenshots in the directory where the OpenTTD binary -resides, simply have your config file in that location. But if you remove this -config file, savegames will still be in this directory (see notes in -section 4.2 'OpenTTD directories') +OpenTTD needs some additional graphics and sound files to run. -OpenTTD comes without AIs, 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. -Another way is manually downloading the AIs from the forum although then you -need to make sure that you install all the required AI libraries too; they get -automatically selected (and downloaded) if you get the AIs via the 'Check -Online Content'. If you do not have an AI but have configured OpenTTD to start -an AI a message will be shown that the 'dummy' AI has been started. +For some platforms these will be downloaded during the installation process if required. -### 4.1) (Required) 3rd party files +For some platforms, you will need to refer to [the installation guide](https://wiki.openttd.org/Installation). -Before you run OpenTTD, you need to put the game's data files into a baseset/ -directory which can be located in various places addressed in the following -section. -For OpenTTD you need to acquire some third party data files. For this you have -the choice of using the original Transport Tycoon Deluxe data files or a set -of free data files. - -Do NOT copy files included with OpenTTD into 'shared' directories (explained in -the following sections) as sooner or later you will run into graphical glitches -when using other versions of the game. - -#### 4.1.1) Free graphics and sound files +### 1.4.1) Free graphics and sound files The free data files, split into OpenGFX for graphics, OpenSFX for sounds and OpenMSX for music can be found at: @@ -219,12 +86,13 @@ OpenMSX for music can be found at: Please follow the readme of these packages about the installation procedure. The Windows installer can optionally download and install these packages. -#### 4.1.2) Original Transport Tycoon Deluxe graphics and sound files -If you want to play with the original Transport Tycoon Deluxe data files you -have to copy the data files from the CD-ROM into the baseset/ directory. It -does not matter whether you copy them from the DOS or Windows version of -Transport Tycoon Deluxe. The Windows install can optionally copy these files. +### 1.4.2) Original Transport Tycoon Deluxe graphics and sound files + +If you want to play with the original Transport Tycoon Deluxe data files you have to copy the data files from the CD-ROM into the baseset/ directory. +It does not matter whether you copy them from the DOS or Windows version of Transport Tycoon Deluxe. +The Windows install can optionally copy these files. + You need to copy the following files: - sample.cat - trg1r.grf or TRG1.GRF @@ -233,607 +101,113 @@ You need to copy the following files: - trgir.grf or TRGI.GRF - trgtr.grf or TRGT.GRF -#### 4.1.3) Original Transport Tycoon Deluxe music -If you want the Transport Tycoon Deluxe music, copy the appropriate files from -the original game into the baseset folder. +### 1.4.3) Original Transport Tycoon Deluxe music + +If you want the Transport Tycoon Deluxe music, copy the appropriate files from the original game into the baseset folder. - TTD for Windows: All files in the gm/ folder (gm_tt00.gm up to gm_tt21.gm) - TTD for DOS: The GM.CAT file - Transport Tycoon Original: The GM.CAT file, but rename it to GM-TTO.CAT -#### 4.1.4) AIs - -If you want AIs use the in-game content downloader. If for some reason that is -not possible or you want to use an AI that has not been uploaded to the content -download system download the tar file and place it in the ai/ directory. If the -AI needs libraries you will have to download those too and put them in the -ai/library/ directory. All AIs and AI Libraries that have been uploaded to -the content download system can be found at https://noai.openttd.org/downloads. -The AIs and libraries can be found their in the form of .tar.gz packages. -OpenTTD can read inside tar files but it does not extract .tar.gz files by itself. - -To figure out which libraries you need for an AI you have to start the AI and -wait for an error message to pop up. The error message will tell you -'could not find library "lib-name"'. Download that library and try again. - -#### 4.1.5) Game scripts - -If you want an extra challenge in OpenTTD you can download so-called game -scripts via the in-game content downloader. These game scripts have varying -functionality, though they can generally influence town growth, subsidies, add -goals to reach or provide a different ranking system. - -If you download a game script manually you have to follow the same rules as for -AIs, except that game scripts are placed in the game/ directory instead of the -ai/ directory. - -### 4.2) OpenTTD directories - -OpenTTD uses its own directory to store its required 3rd party base set files -(see section 4.1 'Required 3rd party files') and non-compulsory extension and -configuration files. See below for their proper place within this OpenTTD main -data directory. - -The main OpenTTD directories can be found in various locations, depending on -your operating system: - -1. The current working directory (from where you started OpenTTD) - - For non-Windows operating systems OpenTTD will not scan for files in this - directory if it is your personal directory, i.e. '~/', or when it is the - root directory, i.e. '/'. - -2. Your personal directory - - Windows: - - `C:\My Documents\OpenTTD` (95, 98, ME) - - `C:\Documents and Settings\\My Documents\OpenTTD` (2000, XP) - - `C:\Users\\Documents\OpenTTD` (Vista, 7, 8.1, 10) - - macOS: `~/Documents/OpenTTD` - - Linux: `$XDG_DATA_HOME/openttd` which is usually `~/.local/share/openttd` - when built with XDG base directory support, otherwise `~/.openttd` -3. The shared directory - - Windows: - - `C:\Documents and Settings\All Users\Shared Documents\OpenTTD` (2000, XP) - - `C:\Users\Public\Documents\OpenTTD` (Vista, 7, 8.1, 10) - - macOS: `/Library/Application Support/OpenTTD` - - Linux: not available -4. The binary directory (where the OpenTTD executable is) - - Windows: `C:\Program Files\OpenTTD` - - Linux: `/usr/games` -5. The installation directory (Linux only) - - Linux: `/usr/share/games/openttd` -6. The application bundle (macOS only) - - It includes the OpenTTD files (grf+lng) and it will work as long as they - are not touched - -Different types of data or extensions go into different subdirectories of the -chosen main OpenTTD directory: - -| data type | directory | additional info | -| ------------------- | ----------------- | --------------------------- | -| Config File | (no subdirectory) | | -| Screenshots | screenshot | | -| Base Graphics | baseset | (or a subdirectory thereof) | -| Sound Sets | baseset | (or a subdirectory thereof) | -| NewGRFs | newgrf | (or a subdirectory thereof) | -| 32bpp Sets | newgrf | (or a subdirectory thereof) | -| Music Sets | baseset | (or a subdirectory thereof) | -| AIs | ai | (or a subdirectory thereof) | -| AI Libraries | ai/library | (or a subdirectory thereof) | -| Game Scripts (GS) | game | (or a subdirectory thereof) | -| GS Libraries | game/library | (or a subdirectory thereof) | -| Savegames | save | | -| Automatic Savegames | save/autosave | | -| Scenarios | scenario | | - -The (automatically created) directory content_download is for OpenTTD's internal -use and no files should be added to it or its subdirectories manually. - -#### Notes: - -- Linux in the previous list means .deb, but most paths should be similar for - others. -- The previous search order is also used for NewGRFs and openttd.cfg. -- If openttd.cfg is not found, then it will be created using the 2, 4, 1, 3, - 5 order. When built with XDG base directory support, openttd.cfg will be - created in $XDG_CONFIG_HOME/openttd which is usually ~/.config/openttd. -- Savegames will be relative to the config file only if there is no save/ - directory in paths with higher priority than the config file path, but - autosaves and screenshots will always be relative to the config file. - Unless the configuration file is in $XDG_CONFIG_HOME/openttd, then all - other files will be saved under $XDG_DATA_HOME/openttd. - -#### The preferred setup: - -Place 3rd party files in shared directory (or in personal directory if you do -not have write access on shared directory) and have your openttd.cfg config -file in personal directory (where the game will then also place savegames and -screenshots). - -### 4.3) Portable installations (portable media) - -You can install OpenTTD on external media so you can take it with you, i.e. -using a USB key, or a USB HDD, etc. -Create a directory where you shall store the game in (i.e. OpenTTD/). -Copy the binary (OpenTTD.exe, OpenTTD.app, openttd, etc), baseset/ and your -openttd.cfg to this directory. -You can copy binaries for any operating system into this directory, which will -allow you to play the game on nearly any computer you can attach the external -media to. -As always - additional grf files are stored in the newgrf/ dir (for details, -again, see section 4.1). - -### 4.4) Files in tar (archives) - -OpenTTD can read files that are in an uncompressed tar (archive), which -makes it easy to bundle files belonging to the same script, NewGRF or base -set. Music sets are the only exception as they cannot be stored in a tar -file due to being played by external applications. - -OpenTTD sees each tar archive as the 'root' of its search path. This means that -having a file with the same path in two different tar files means that one -cannot be opened, after all only one file will be found first. As such it is -advisable to put an uniquely named folder in the root of the tar and put all the -content in that folder. For example, all downloaded content has a path that -concatenates the name of the content and the version, which makes the path -unique. For custom tar files it is advised to do this as well. - -The normal files are also referred to by their relative path from the search -directory, this means that also normal files could hide files in a tar as -long as the relative path from the search path of the normal file is the -same as the path in the tar file. Again it is advised to have an unique path -to the normal file so they do not collide with the files from other tar -files. - -## 5.0) OpenTTD features - -OpenTTD has a lot of features going beyond the original Transport Tycoon Deluxe -emulation. Unfortunately, there is currently no comprehensive list of features, -but there is a basic features list on the web, and some optional features can be -controlled through the Advanced Settings dialog. We also implement some -features known from [TTDPatch](https://www.ttdpatch.net). - -Several important non-standard controls: - -- Ctrl modifies many commands and makes them more powerful. For example Ctrl - clicking on signals with the build signal tool changes their behaviour, - holding Ctrl while the track build tool is activated changes it to the track - removal tool, and so on. See https://wiki.openttd.org/Hidden_features - for a non-comprehensive list or look at the tooltips. -- Ingame console. More information at https://wiki.openttd.org/Console -- Hovering over a GUI element shows tooltips. This can be changed to right click - via the advanced settings. - -### 5.1) Logging of potentially dangerous actions - -OpenTTD is a complex program, and together with NewGRF, it may show a buggy -behaviour. But not only bugs in code can cause problems. There are several -ways to affect game state possibly resulting in program crash or multiplayer -desyncs. - -Easier way would be to forbid all these unsafe actions, but that would affect -game usability for many players. We certainly do not want that. -However, we receive bug reports because of this. To reduce time spent with -solving these problems, these potentially unsafe actions are logged in -the savegame (including crash.sav). Log is stored in crash logs, too. - -Information logged: - -- Adding / removing / changing order of NewGRFs -- Changing NewGRF parameters, loading compatible NewGRF -- Changing game mode (scenario editor <-> normal game) -- Loading game saved in a different OpenTTD / TTDPatch / Transport Tycoon Deluxe / - original Transport Tycoon version -- Running a modified OpenTTD build -- Changing settings affecting NewGRF behaviour (non-network-safe settings) -- Triggering NewGRF bugs - -No personal information is stored. - -You can show the game log by typing 'gamelog' in the console or by running -OpenTTD in debug mode. - -### 5.2) Frame rate and performance metrics - -The Help menu in-game has a function to open the Frame rate window. This -window shows various real-time performance statistics, measuring what parts -of the game require the most processing power currently. - -A summary of the statistics can also be retrieved from the console with the -`fps` command. This is especially useful on dedicated servers, where the -administrator might want to determine what's limiting performance in a slow -game. - -The frame rate is given as two figures, the simulation rate and the graphics -frame rate. Usually these are identical, as the screen is rendered exactly -once per simulated tick, but in the future there might be support for graphics -and simulation running at different rates. When the game is paused, the -simulation rate drops to zero. - -In addition to the simulation rate, a game speed factor is also calculated. -This is based on the target simulation speed, which is 30 milliseconds per -game tick. At that speed, the expected frame rate is 33.33 frames/second, and -the game speed factor is how close to that target the actual rate is. When -the game is in fast forward mode, the game speed factor shows how much -speed up is achieved. - -The lower part of the window shows timing statistics for individual parts of -the game. The times shown are short-term and long-term averages of how long -it takes to process one tick of game time, all figures are in milliseconds. - -Clicking a line in the lower part of the window opens a graph window, giving -detailed readings on each tick simulated by the game. - -The following is an explanation of the different statistics: - -- *Game loop* - Total processing time used per simulated "tick" in the game. - This includes all pathfinding, world updates, and economy handling. -- *Cargo handling* - Time spent loading/unloading cargo at stations, and - industries and towns sending/retrieving cargo from stations. -- *Train ticks*, *Road vehicle ticks*, *Ship ticks*, *Aircraft ticks* - - Time spent on pathfinding and other processing for each player vehicle type. -- *World ticks* - Time spent on other world/landscape processing. This - includes towns growing, building animations, updates of farmland and trees, - and station rating updates. -- *GS/AI total*, *Game script*, and *AI players* - Time spent running logic - for game scripts and AI players. The total may show as less than the current - sum of the individual scripts, this is because AI players at lower - difficulty settings do not run every game tick, and hence contribute less - to the average across all ticks. Keep in mind that the "Current" figure is - also an average, just only over short term. -- *Link graph delay* - Time overruns of the cargo distribution link graph - update thread. Usually the link graph is updated in a background thread, - but these updates need to synchronise with the main game loop occasionally, - if the time spent on link graph updates is longer than the time taken to - otherwise simulate the game while it was updating, these delays are counted - in this figure. -- *Graphics rendering* - Total time spent rendering all graphics, including - both GUI and world viewports. This typically spikes when panning the view - around, and when more things are happening on screen at once. -- *World viewport rendering* - Isolated time spent rendering just world - viewports. If this figure is significantly lower than the total graphics - rendering time, most time is spent rendering GUI than rendering world. -- *Video output* - Speed of copying the rendered graphics to the display - adapter. Usually this should be very fast (in the range of 0-3 ms), large - values for this can indicate a graphics driver problem. -- *Sound mixing* - Speed of mixing active audio samples together. Usually - this should be very fast (in the range of 0-3 ms), if it is slow, consider - switching to the NoSound set. - -If the frame rate window is shaded, the title bar will instead show just the -current simulation rate and the game speed factor. - -## 6.0) Configuration file - -The configuration file for OpenTTD (openttd.cfg) is in a simple Windows-like -.INI format. It is mostly undocumented. Almost all settings can be changed -ingame by using the 'Advanced Settings' window. -When you cannot find openttd.cfg you should look in the directories as -described in section 4.2. If you do not have an openttd.cfg OpenTTD will -create one after closing. - -## 7.0) Compiling - -### Windows: - -You need Microsoft Visual Studio 2015 Update 3 or more recent. Open the project file -and it should build automatically. In case you want to build with SDL support -you need to add WITH_SDL to the project settings. - -PNG (WITH_PNG), ZLIB (WITH_ZLIB), LZO (WITH_LZO), Freetype (WITH_FREETYPE) and -LZMA (WITH_LZMA) support is enabled by default. For these to work you need their -development files. To get them just use vcpkg from https://github.com/Microsoft/vcpkg -using x86-windows-static and x64-windows-static triplets. -For more help with VS see docs/Readme_Windows_MSVC.md. - -You can also build it using the Makefile with MSYS/MinGW or Cygwin/MinGW. -Please read the Makefile for more information. - -### Solaris, FreeBSD, OpenBSD: - -Use '`gmake`', but do a '`./configure`' before the first build. - -### Linux/Unix: - -OpenTTD can be built with GNU '`make`'. On non-GNU systems it is called '`gmake`'. -However, for the first build one has to do a '`./configure`' first. - -### macOS: - -Use '`make`' or Xcode (which will then call make for you) -This will give you a binary for your CPU type (PPC/Intel) -However, for the first build one has to do a '`./configure`' first. -To make a universal binary type '`./configure --enabled-universal`' -instead of '`./configure`'. - -### BeOS: - -Use '`make`', but do a '`./configure`' before the first build. - -### MorphOS: - -Use '`make`'. However, for the first build one has to do a '`./configure`' -first. Note that you need the MorphOS SDK, latest libnix updates (else C++ -parts of OpenTTD will not build) and the powersdl.library SDK. Optionally libz, -libpng and freetype2 developer files. - -### OS/2: - -A comprehensive GNU build environment is required to build the OS/2 version. -See the docs/Readme_OS2.txt file for more information. - -### DOS: - -A build environment with DJGPP is needed as well as libraries such as -Allegro, zlib and libpng, which all can be downloaded from the DJGPP -website. Compilation is straight forward: use '`make`', but do a '`./configure`' -before the first build. The build binary will need cwsdpmi.exe to be in -the same directory as the openttd executable. cwsdpmi.exe can be found in -the os/dos/cwsdpmi subdirectory. If you compile with stripping turned on a -binary will be generated that does not need cwsdpmi.exe by adding the -cswdstub.exe to the created OpenTTD binary. - -### 7.1) Required/optional libraries - -The following libraries are used by OpenTTD for: - -- libSDL/liballegro: hardware access (video, sound, mouse) -- zlib: (de)compressing of old (0.3.0-1.0.5) savegames, content downloads, - heightmaps -- liblzo2: (de)compressing of old (pre 0.3.0) savegames -- liblzma: (de)compressing of savegames (1.1.0 and later) -- libpng: making screenshots and loading heightmaps -- 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. -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. -Without libSDL/liballegro on non-Windows and non-macOS machines you have -no graphical user interface; you would be building a dedicated server. +## 1.5) Add-on content / mods -### 7.2) Supported compilers +OpenTTD features multiple types of add-on content, which modify gameplay in different ways. -The following compilers are known to compile OpenTTD: +Most types of add-on content can be downloaded within OpenTTD via the 'Check Online Content' button in the main menu. -- Microsoft Visual C++ (MSVC) 2015, 2017 and 2019. -- GNU Compiler Collection (GCC) 3.3 - 4.4, 4.6 - 4.8. - - Versions 4.1 and earlier give bogus warnings about uninitialised variables. - - Versions 4.4, 4.6 give bogus warnings about freeing non-heap objects. - - Versions 4.6 and later give invalid warnings when lto is enabled. -- Intel C++ Compiler (ICC) 12.0. -- Clang/LLVM 2.9 - 3.0 - Version 2.9 gives bogus warnings about code nonconformity. +Add-on content can also be installed manually, but that's more complicated; the [OpenTTD wiki](https://wiki.openttd.org/OpenTTD) may offer help with that, or the [OpenTTD directory structure guide](./docs/directory_structure.md). -The following compilers are known not to compile OpenTTD: +### 1.5.1) AI opponents -- Microsoft Visual C++ (MSVC) 2013 and earlier. - These old versions do not support modern C++ language features. -- GNU Compiler Collection (GCC) 3.2 and earlier. - These old versions fail due to OpenTTD's template usage. -- GNU Compiler Collection (GCC) 4.5. It optimizes enums too aggressively. - See https://github.com/OpenTTD/OpenTTD/issues/5513 and references therein. -- Intel C++ Compiler (ICC) 11.1 and earlier. - - Version 10.0 and earlier fail a configure check and fail with recent - system headers. - - Version 10.1 fails to compile station_gui.cpp. - - Version 11.1 fails with an internal error when compiling network.cpp. -- Clang/LLVM 2.8 and earlier. -- (Open) Watcom. +OpenTTD comes without AI opponents, so if you want to play with AIs you have to download them. -If any of these compilers can compile OpenTTD again, please let us know. -Patches to support more compilers are welcome. +The easiest way is via the 'Check Online Content' button in the main menu. -### 7.3) Compilation of base sets +You can select some AIs that you think are compatible with your playing style. -To recompile the extra graphics needed to play with the original Transport -Tycoon Deluxe graphics you need GRFCodec (which includes NFORenum) as well. -GRFCodec can be found at https://www.openttd.org/download-grfcodec. -The compilation of these extra graphics does generally not happen, unless -you remove the graphics file using '`make maintainer-clean`'. +AI help and discussions may also be found in the [AI section of the forum](https://www.tt-forums.net/viewforum.php?f=65). -Re-compilation of the base sets, thus also use of '`--maintainer-clean`' can -leave the repository in a modified state as different grfcodec versions can -cause binary differences in the resulting grf. Also translations might have -been added for the base sets which are not yet included in the base set -information files. Use the configure option '`--without-grfcodec`' to avoid -modification of the base set files by the build process. +### 1.5.2) Scenarios and height maps -## 8.0) Translating +Scenarios and heightmaps can be added via the 'Check Online Content' button in the main menu. -See https://www.openttd.org/development for up-to-date information. +### 1.5.3) NewGRFs -The use of the online Translator service, located at -https://translator.openttd.org, is highly encouraged. For getting an account -simply follow the guidelines in the FAQ of the translator website. +A wide range of add-content is available as NewGRFs, including vehicles, industries, stations, landscape objects, town names and more. -If for some reason the website is down for a longer period of time, the -information below might be of help. +NewGRFs can be added via the 'Check Online Content' button in the main menu. -Please contact the translations manager (https://www.openttd.org/contact) -before beginning the translation process! This avoids double work, as -someone else may have already started translating to the same language. +See also the wiki [guide to NewGRFs](https://wiki.openttd.org/NewGRF) and [the forum graphics development section](https://www.tt-forums.net/viewforum.php?f=66). -### 8.1) Translation +### 1.5.4) Game scripts -So, now that you have notified the development team about your intention to -translate (You did, right? Of course you did.) you can pick up english.txt -(found in the Git repository under /src/lang) and translate. +Game scripts can provide additional challenges or changes to the standard OpenTTD gameplay, for example setting transport goals, or changing town growth behaviour. -You must change the first two lines of the file appropriately: +Game scripts can be added via the 'Check Online Content' button in the main menu. - ##name English-Name-Of-Language - ##ownname Native-Name-Of-Language - -Note: Do not alter the following parts of the file: +See also the wiki [guide to game scripts](https://wiki.openttd.org/Game_script) and [the forum graphics game script section](https://www.tt-forums.net/viewforum.php?f=65). -- String identifiers (the first word on each line) -- Parts of the strings which are in curly braces (such as {STRING}) -- Lines beginning with ## (such as ##id), other than the first two lines - of the file - -### 8.2) Previewing - -In order to view the translation in the game, you need to compile your language -file with the strgen utility. As this utility is tailored to a specific OpenTTD -version, you need to compile it yourself. Just take the normal OpenTTD sources -and build that. During the build process the strgen utility will be made. +### 1.6) OpenTTD directories -strgen is a command-line utility. It takes the language filename as parameter. +OpenTTD uses its own directory structure to store game data, add-on content etc. -Example: +For more information, see the [directory structure guide](./docs/directory_structure.md). - strgen lang/german.txt +### 1.7) Compiling OpenTTD -This results in compiling german.txt and produces another file named german.lng. -Any missing strings are replaced with the English strings. Note that it looks -for english.txt in the lang subdirectory, which is where your language file -should also be. - -That is all! You should now be able to select the language in the game options. +If you want to compile OpenTTD from source, instructions can be found in [COMPILING.md](./COMPILING.md). -## 9.0) Troubleshooting -To see all startup options available to you, start OpenTTD with the -'`./openttd -h`' option. This might help you tweak some of the settings. - -If the game is acting strange and you feel adventurous you can try the -'`-d [[=]]`' flag, where the higher levels will give you more -debugging output. The 'name' variable can help you to display only some type of -debugging messages. This is mostly undocumented so best is to look in the -source code file debug.c for the various debugging types. For more information -look at https://wiki.openttd.org/Command_line. - -The most frequent problem is missing data files. Please install OpenGFX and -possibly OpenSFX and OpenMSX. See section 4.1.1 for more information. - -Under certain circumstance, especially on Ubuntu OpenTTD can be extremely slow -and/or freeze. See known-bugs.txt for more information and how to solve this -problem on your computer. - -Under Windows 98 and lower it is impossible to use a dedicated server; it will -fail to start. Perhaps this is for the better because those OSes are not known -for their stability. - -With the added support for font-based text selecting a non-latin language can -result in lots of question marks ('?') being shown on screen. Please open your -configuration file (openttd.cfg - see Section 4.2 for where to find it) -and add a suitable font for the small, medium and / or large font, e.g.: +## 2.0) Contact and Community - small_font = "Tahoma" - medium_font = "Tahoma" - large_font = "Tahoma" - -You should use a font name like 'Tahoma' or a path to the desired font. - -Any NewGRF file used in a game is stored inside the savegame and will refuse to -load if you do not have that NewGRF file available. A list of missing files can -be viewed in the NewGRF window accessible from the file load dialogue window. - -You can try to obtain the missing files from that NewGRF dialogue or – if they -are not available online – you can search manually through our -[forum's graphics development section](https://www.tt-forums.net/viewforum.php?f=66) -or [GRFCrawler](https://grfcrawler.tt-forums.net). Put the NewGRF files in -OpenTTD's newgrf folder (see section 4.2 'OpenTTD directories') and rescan the -list of available NewGRFs. Once you have all missing files, you are set to go. - -## 10.0) Licensing - -OpenTTD is licensed under the GNU General Public License version 2.0. For -the complete license text, see the file 'COPYING'. This license applies -to all files in this distribution, except as noted below. - -The squirrel implementation in src/3rdparty/squirrel is licensed under -the Zlib license. See src/3rdparty/squirrel/COPYRIGHT for the complete -license text. - -The md5 implementation in src/3rdparty/md5 is licensed under the Zlib -license. See the comments in the source files in src/3rdparty/md5 for -the complete license text. - -The implementations of Posix getaddrinfo and getnameinfo for OS/2 in -src/3rdparty/os2 are distributed partly under the GNU Lesser General Public -License 2.1, and partly under the (3-clause) BSD license. The exact licensing -terms can be found in src/3rdparty/os2/getaddrinfo.c resp. -src/3rdparty/os2/getnameinfo.c. - -The exe2coff implementation in os/dos/exe2coff is available under the -GPL, with a number of additional terms. See os/dos/exe2coff/copying and -os/dos/exe2coff/copying.dj for the exact licensing terms. - -The CWSDPMI implementation in os/dos/cwsdpmi is distributed under a -custom binary-only license that prohibits modification. The exact -licensing terms can be found in os/dos/cwsdpmi/cwsdpmi.txt. The sources -for these files can be downloaded at its author site, at -http://homer.rice.edu/~sandmann/cwsdpmi/csdpmi5s.zip. - -CONTRIBUTING.md is adapted from -[Bootstrap](https://github.com/twbs/bootstrap/blob/master/CONTRIBUTING.md) -under the [Creative Commons Attribution 3.0 Unported -License](https://github.com/twbs/bootstrap/blob/master/docs/LICENSE) -terms for Bootstrap documentation. - -## X.X) Credits - -### 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) -- Michael Lutz (michi_cc) - 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) -- Leif Linse (Zuu) - AI/Game Script (since 1.2) - -### Inactive Developers: - -- 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) -- 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) -- Zdeněk Sojka (SmatZ) - Bug finder and fixer (0.6 - 1.3) -- 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) - -### Retired Developers: - -- 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) -- 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) -- Benedikt Brüggemeier (skidd13) - Bug fixer and code reworker (0.6 - 0.7) -- Serge Paquet (vurlix) - 2nd contributor after ludde (0.1 - 0.3) - -### Thanks to: - -- Josef Drexler - For his great work on TTDPatch. -- Marcin Grzegorczyk - For his TTDPatch work and documentation of Transport Tycoon Deluxe internals and track foundations -- Stefan Meißner (sign_de) - For his work on the console -- Mike Ragsdale - OpenTTD installer -- Christian Rosentreter (tokai) - MorphOS / AmigaOS port -- Richard Kempton (RichK67) - Additional airports, initial TGP implementation -- Alberto Demichelis - Squirrel scripting language -- L. Peter Deutsch - MD5 implementation -- Michael Blunck - For revolutionizing TTD with awesome graphics -- George - Canal graphics -- Andrew Parkhouse (andythenorth) - River graphics -- David Dallaston (Pikka) - Tram tracks -- All Translators - For their support to make OpenTTD a truly international game -- Bug Reporters - Thanks for all bug reports -- Chris Sawyer - For an amazing game! +'Official' channels + +- [OpenTTD website](https://www.openttd.org) +- IRC chat using #openttd on irc.oftc.net [more info about our irc channel](https://wiki.openttd.org/Irc) +- [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 +- [OpenTTD wiki](https://wiki.openttd.org/) community-maintained wiki, including topics like gameplay guide, detailed explanation of some game mechanics, how to use add-on content (mods) and much more + +'Unofficial' channels + +- the OpenTTD wiki has a [page listing OpenTTD communities](https://wiki.openttd.org/Community) including some in languages other than English + + +### 2.1) Contributing to OpenTTD + +We welcome contributors to OpenTTD. More information for contributors can be found in [CONTRIBUTING.md](./CONTRIBUTING.md) + + +### 2.2) Reporting bugs + +Good bug reports are very helpful. We have a [guide to reporting bugs](./CONTRIBUTING.md#bug-reports) to help with this. + +Desyncs in multiplayer are complex to debug and report (some software development skils are required). +Instructions can be found in [debugging and reporting desyncs](./docs/debugging_desyncs.md). + + +### 2.3) Translating + +OpenTTD is translated into many languages. Translations are added and updated via the [online translation tool](https://translator.openttd.org). + + +## 3.0) Licensing + +OpenTTD is licensed under the GNU General Public License version 2.0. +For the complete license text, see the file '[COPYING.md](./COPYING.md)'. +This license applies to all files in this distribution, except as noted below. + +The squirrel implementation in `src/3rdparty/squirrel` is licensed under the Zlib license. +See `src/3rdparty/squirrel/COPYRIGHT` for the complete license text. + +The md5 implementation in `src/3rdparty/md5` is licensed under the Zlib license. +See the comments in the source files in `src/3rdparty/md5` for the complete license text. + +The implementations of Posix `getaddrinfo` and `getnameinfo` for OS/2 in `src/3rdparty/os2` are distributed partly under the GNU Lesser General Public License 2.1, and partly under the (3-clause) BSD license. +The exact licensing terms can be found in `src/3rdparty/os2/getaddrinfo.c` resp. `src/3rdparty/os2/getnameinfo.c`. + + +## 4.0 Credits + +See [CREDITS.md](./CREDITS.md) diff --git a/azure-pipelines-ci.yml b/azure-pipelines-ci.yml index 789f8f6a32..c58a856d93 100644 --- a/azure-pipelines-ci.yml +++ b/azure-pipelines-ci.yml @@ -25,6 +25,7 @@ jobs: - template: azure-pipelines/templates/windows-build.yml parameters: BuildPlatform: $(BuildPlatform) + BuildConfiguration: Debug - script: | call "C:\Program Files (x86)\Microsoft Visual Studio\2017\Enterprise\VC\Auxiliary\Build\vcvarsall.bat" x86 cd projects @@ -38,10 +39,12 @@ jobs: strategy: matrix: - commit-checker: {} - linux-amd64-clang-3.8: {} - linux-amd64-gcc-6: {} - linux-i386-gcc-6: {} + linux-amd64-clang-3.9: + Tag: 'linux-amd64-clang-3.9' + linux-amd64-gcc-6: + Tag: 'linux-amd64-gcc-6' + linux-i386-gcc-6: + Tag: 'linux-i386-gcc-6' steps: - template: azure-pipelines/templates/ci-git-rebase.yml @@ -50,7 +53,7 @@ jobs: - template: azure-pipelines/templates/linux-build.yml parameters: Image: compile-farm-ci - Tag: $(Agent.JobName) + Tag: $(Tag) - job: macos displayName: 'MacOS' diff --git a/azure-pipelines/changelog.sh b/azure-pipelines/changelog.sh index 33eb8a78d4..ea0da948c1 100755 --- a/azure-pipelines/changelog.sh +++ b/azure-pipelines/changelog.sh @@ -1,16 +1,16 @@ #!/bin/sh -tag=$(git describe --tags 2>/dev/null) +tag=$(git name-rev --name-only --tags --no-undefined HEAD 2>/dev/null | sed 's@\^0$@@') # If we are a tag, show the part of the changelog till (but excluding) the last stable if [ -n "$tag" ]; then - grep='^[0-9]\.[0-9]\.[0-9][^-]' + grep='^[0-9]\+\.[0-9]\+\.[0-9]\+[^-]' next=$(cat changelog.txt | grep '^[0-9]' | awk 'BEGIN { show="false" } // { if (show=="true") print $0; if ($1=="'$tag'") show="true"} ' | grep "$grep" | head -n1 | sed 's/ .*//') - cat changelog.txt | awk 'BEGIN { show="false" } /^[0-9].[0-9].[0-9]/ { if ($1=="'$next'") show="false"; if ($1=="'$tag'") show="true";} // { if (show=="true") print $0 }' + cat changelog.txt | awk 'BEGIN { show="false" } /^[0-9]+.[0-9]+.[0-9]+/ { if ($1=="'$next'") show="false"; if ($1=="'$tag'") show="true";} // { if (show=="true") print $0 }' exit 0 fi # In all other cases, show the git log of the last 7 days revdate=$(git log -1 --pretty=format:"%ci") -last_week=$(date -u -d "$revdate -7days" +"%Y-%m-%d %H:%M") +last_week=$(date -d "$revdate -7days" +"%Y-%m-%d %H:%M") git log --after="${last_week}" --pretty=fuller diff --git a/azure-pipelines/manifest.sh b/azure-pipelines/manifest.sh index d8f4f9aac9..730a09283f 100755 --- a/azure-pipelines/manifest.sh +++ b/azure-pipelines/manifest.sh @@ -31,29 +31,55 @@ DATE=$(cat .release_date | tr ' ' T | sed 's/TUTC/:00-00:00/') VERSION=$(cat .version) BASE="openttd-${VERSION}" -echo "name: ${NAME}" >> manifest.yaml +echo "name: ${NAME}" > manifest.yaml echo "date: ${DATE}" >> manifest.yaml echo "base: ${BASE}-" >> manifest.yaml -echo "files:" >> manifest.yaml error="" -for i in $(ls ${FOLDER} | grep -v ".txt$\|.md$\|sum$" | sort); do - if [ -n "$(echo $i | grep pdb.xz)" ]; then continue; fi - if [ -n "$(echo $i | grep dbg.deb)" ]; then continue; fi - if [ ! -e ${FOLDER}/$i.md5sum ] || [ ! -e ${FOLDER}/$i.sha1sum ] || [ ! -e ${FOLDER}/$i.sha256sum ]; then - echo "ERROR: missing checksum file for ${i}" 1>&2 - error="y" - continue - fi +FILES= +DEV_FILES= +for filename in $(ls ${FOLDER} | grep -v ".txt$\|.md$\|sum$" | sort); do + case ${filename} in + *docs* |\ + *source* |\ + *dbg.deb |\ + *pdb.xz ) + DEV_FILES="${DEV_FILES} ${filename}" + ;; - echo "- id: $i" >> manifest.yaml - echo " size: $(stat -c"%s" ${FOLDER}/$i)" >> manifest.yaml - echo " md5sum: $(cat ${FOLDER}/$i.md5sum | cut -d\ -f1)" >> manifest.yaml - echo " sha1sum: $(cat ${FOLDER}/$i.sha1sum | cut -d\ -f1)" >> manifest.yaml - echo " sha256sum: $(cat ${FOLDER}/$i.sha256sum | cut -d\ -f1)" >> manifest.yaml + *) + FILES="${FILES} ${filename}" + ;; + esac done +# output_files key filename... +output_files() { + if [ "$#" -lt 2 ]; then return; fi + key=$1 + echo "${key}:" >> manifest.yaml + shift + while [ "$#" -gt 0 ]; do + filename=$1 + if [ ! -e ${FOLDER}/${filename}.md5sum ] || [ ! -e ${FOLDER}/${filename}.sha1sum ] || [ ! -e ${FOLDER}/${filename}.sha256sum ]; then + echo "ERROR: missing checksum file for ${filename}" 1>&2 + error="y" + continue + fi + + echo "- id: ${filename}" >> manifest.yaml + echo " size: $(stat -c"%s" ${FOLDER}/${filename})" >> manifest.yaml + echo " md5sum: $(cat ${FOLDER}/${filename}.md5sum | cut -d\ -f1)" >> manifest.yaml + echo " sha1sum: $(cat ${FOLDER}/${filename}.sha1sum | cut -d\ -f1)" >> manifest.yaml + echo " sha256sum: $(cat ${FOLDER}/${filename}.sha256sum | cut -d\ -f1)" >> manifest.yaml + shift + done +} + +output_files files ${FILES} +output_files dev_files ${DEV_FILES} + if [ -n "${error}" ]; then echo "ERROR: exiting due to earlier errors" 1>&2 exit 1 diff --git a/azure-pipelines/templates/linux-build.yml b/azure-pipelines/templates/linux-build.yml index 7f442904c4..a173f3364d 100644 --- a/azure-pipelines/templates/linux-build.yml +++ b/azure-pipelines/templates/linux-build.yml @@ -24,7 +24,7 @@ steps: ${{ if eq(parameters.Image, 'compile-farm-ci') }}: displayName: 'Build and test' # Run the commit-checker only if it is a Pull Request - condition: and(succeeded(), or(ne(variables['Agent.JobName'], 'commit-checker'), eq(variables['Build.Reason'], 'PullRequest'))) + condition: and(succeeded(), or(not(contains(variables['Agent.JobName'], 'commit-checker')), eq(variables['Build.Reason'], 'PullRequest'))) inputs: command: 'Run an image' imageName: openttd/${{ parameters.Image }}:${{ parameters.Tag }} diff --git a/azure-pipelines/templates/release.yml b/azure-pipelines/templates/release.yml index 7628d3c91e..00e5b1040a 100644 --- a/azure-pipelines/templates/release.yml +++ b/azure-pipelines/templates/release.yml @@ -88,6 +88,7 @@ jobs: - template: windows-build.yml parameters: BuildPlatform: $(BuildPlatform) + BuildConfiguration: Release - bash: | set -ex make -f Makefile.msvc bundle_pdb bundle_zip PLATFORM=$(BundlePlatform) BUNDLE_NAME=openttd-$(Build.BuildNumber)-windows-$(BundlePlatform) @@ -110,14 +111,22 @@ jobs: strategy: matrix: - linux-ubuntu-xenial-i386-gcc: {} - linux-ubuntu-xenial-amd64-gcc: {} - linux-ubuntu-bionic-i386-gcc: {} - linux-ubuntu-bionic-amd64-gcc: {} - linux-debian-jessie-i386-gcc: {} - linux-debian-jessie-amd64-gcc: {} - linux-debian-stretch-i386-gcc: {} - linux-debian-stretch-amd64-gcc: {} + linux-ubuntu-xenial-i386-gcc: + Tag: 'linux-ubuntu-xenial-i386-gcc' + linux-ubuntu-xenial-amd64-gcc: + Tag: 'linux-ubuntu-xenial-amd64-gcc' + linux-ubuntu-bionic-i386-gcc: + Tag: 'linux-ubuntu-bionic-i386-gcc' + linux-ubuntu-bionic-amd64-gcc: + Tag: 'linux-ubuntu-bionic-amd64-gcc' + linux-debian-stretch-i386-gcc: + Tag: 'linux-debian-stretch-i386-gcc' + linux-debian-stretch-amd64-gcc: + Tag: 'linux-debian-stretch-amd64-gcc' + linux-debian-buster-i386-gcc: + Tag: 'linux-debian-buster-i386-gcc' + linux-debian-buster-amd64-gcc: + Tag: 'linux-debian-buster-amd64-gcc' steps: - template: release-fetch-source.yml @@ -125,7 +134,7 @@ jobs: parameters: Image: compile-farm ContainerCommand: '$(Build.BuildNumber)' - Tag: $(Agent.JobName) + Tag: $(Tag) - template: linux-claim-bundles.yml - template: release-bundles.yml diff --git a/azure-pipelines/templates/windows-build.yml b/azure-pipelines/templates/windows-build.yml index 5e12f2243f..117dd062c1 100644 --- a/azure-pipelines/templates/windows-build.yml +++ b/azure-pipelines/templates/windows-build.yml @@ -7,5 +7,5 @@ steps: inputs: solution: 'projects/openttd_vs141.sln' platform: ${{ parameters.BuildPlatform }} - configuration: Release + configuration: ${{ parameters.BuildConfiguration }} maximumCpuCount: true diff --git a/bin/ai/compat_0.7.nut b/bin/ai/compat_0.7.nut index 86ab06bba5..c40308592c 100644 --- a/bin/ai/compat_0.7.nut +++ b/bin/ai/compat_0.7.nut @@ -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/bin/ai/compat_1.0.nut b/bin/ai/compat_1.0.nut index 6aa0e1a973..b8da71a194 100644 --- a/bin/ai/compat_1.0.nut +++ b/bin/ai/compat_1.0.nut @@ -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/bin/ai/compat_1.1.nut b/bin/ai/compat_1.1.nut index 3d7b7553ee..f1bda9c7fe 100644 --- a/bin/ai/compat_1.1.nut +++ b/bin/ai/compat_1.1.nut @@ -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/bin/ai/compat_1.10.nut b/bin/ai/compat_1.10.nut new file mode 100644 index 0000000000..3081fb58e8 --- /dev/null +++ b/bin/ai/compat_1.10.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/ai/compat_1.2.nut b/bin/ai/compat_1.2.nut index 594ba98352..550f79969c 100644 --- a/bin/ai/compat_1.2.nut +++ b/bin/ai/compat_1.2.nut @@ -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/bin/ai/compat_1.3.nut b/bin/ai/compat_1.3.nut index fb0f41d308..6b2c7e8a71 100644 --- a/bin/ai/compat_1.3.nut +++ b/bin/ai/compat_1.3.nut @@ -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/bin/ai/compat_1.4.nut b/bin/ai/compat_1.4.nut index 4bbb971604..a9ab5a4757 100644 --- a/bin/ai/compat_1.4.nut +++ b/bin/ai/compat_1.4.nut @@ -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/bin/ai/compat_1.5.nut b/bin/ai/compat_1.5.nut index b006f1733e..23944149f6 100644 --- a/bin/ai/compat_1.5.nut +++ b/bin/ai/compat_1.5.nut @@ -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/bin/ai/compat_1.6.nut b/bin/ai/compat_1.6.nut index e57a3cb980..bcbe91455c 100644 --- a/bin/ai/compat_1.6.nut +++ b/bin/ai/compat_1.6.nut @@ -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/bin/ai/compat_1.7.nut b/bin/ai/compat_1.7.nut index ae403d104b..7c2fd9b825 100644 --- a/bin/ai/compat_1.7.nut +++ b/bin/ai/compat_1.7.nut @@ -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/bin/ai/compat_1.8.nut b/bin/ai/compat_1.8.nut index ecf4accdde..a118a63b57 100644 --- a/bin/ai/compat_1.8.nut +++ b/bin/ai/compat_1.8.nut @@ -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/bin/ai/compat_1.9.nut b/bin/ai/compat_1.9.nut index fe985b90d0..a3d0941327 100644 --- a/bin/ai/compat_1.9.nut +++ b/bin/ai/compat_1.9.nut @@ -1,8 +1,8 @@ -/* $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. * 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("1.9 API compatibility in effect."); diff --git a/bin/ai/regression/completeness.sh b/bin/ai/regression/completeness.sh index 9f5e96eb0b..46cee4ed3e 100755 --- a/bin/ai/regression/completeness.sh +++ b/bin/ai/regression/completeness.sh @@ -1,7 +1,5 @@ #!/bin/sh -# $Id$ - if ! [ -f ai/regression/completeness.sh ]; then echo "Make sure you are in the root of OpenTTD before starting this script." exit 1 @@ -46,9 +44,9 @@ cat ai/regression/tst_*/main.nut | tr ';' '\n' | awk ' } } } - # We want to remove everything before the FIRST occurence of AI. - # If we do not remove any other occurences of AI from the string - # we will remove everything before the LAST occurence of AI, so + # We want to remove everything before the FIRST occurrence of AI. + # If we do not remove any other occurrences of AI from the string + # we will remove everything before the LAST occurrence of AI, so # do some little magic to make it work the way we want. sub("AI", "AXXXXY") gsub("AI", "AXXXXX") diff --git a/bin/ai/regression/regression_info.nut b/bin/ai/regression/regression_info.nut index 341d13a085..020b186faf 100644 --- a/bin/ai/regression/regression_info.nut +++ b/bin/ai/regression/regression_info.nut @@ -1,12 +1,10 @@ -/* $Id$ */ - class Regression extends AIInfo { function GetAuthor() { return "OpenTTD NoAI Developers Team"; } function GetName() { return "Regression"; } 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 "1.9"; } + function GetAPIVersion() { return "1.10"; } function GetDate() { return "2007-03-18"; } function CreateInstance() { return "Regression"; } } diff --git a/bin/ai/regression/run.sh b/bin/ai/regression/run.sh index c9197c4d56..7574b0b388 100755 --- a/bin/ai/regression/run.sh +++ b/bin/ai/regression/run.sh @@ -1,7 +1,5 @@ #!/bin/sh -# $Id$ - if ! [ -f ai/regression/run.sh ]; then echo "Make sure you are in the root of OpenTTD before starting this script." exit 1 diff --git a/bin/ai/regression/run.vbs b/bin/ai/regression/run.vbs index 930562ec68..b4bdef4c17 100644 --- a/bin/ai/regression/run.vbs +++ b/bin/ai/regression/run.vbs @@ -1,7 +1,5 @@ Option Explicit -' $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. ' 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. diff --git a/bin/ai/regression/tst_regression/main.nut b/bin/ai/regression/tst_regression/main.nut index 7315f33f82..5ace44eec7 100644 --- a/bin/ai/regression/tst_regression/main.nut +++ b/bin/ai/regression/tst_regression/main.nut @@ -1,5 +1,3 @@ -/* $Id$ */ - class Regression extends AIController { function Start(); }; @@ -1704,6 +1702,19 @@ function Regression::Vehicle() print(" GetWagonEngineType(): " + AIVehicle.GetWagonEngineType(17 3)); print(" GetWagonAge(): " + AIVehicle.GetWagonAge(17, 3)); + print(" --Refit--"); + print(" GetBuildWithRefitCapacity(): " + AIVehicle.GetBuildWithRefitCapacity(28479, 211, 255)); + print(" GetBuildWithRefitCapacity(): " + AIVehicle.GetBuildWithRefitCapacity(28479, 211, 0)); + print(" GetBuildWithRefitCapacity(): " + AIVehicle.GetBuildWithRefitCapacity(28479, 211, 9)); + print(" BuildVehicleWithRefit(): " + AIVehicle.BuildVehicleWithRefit(28479, 211, 9)); + print(" GetCapacity(): " + AIVehicle.GetCapacity(20, 9)); + print(" GetCapacity(): " + AIVehicle.GetCapacity(20, 5)); + print(" GetRefitCapacity(): " + AIVehicle.GetRefitCapacity(20, 5)); + print(" RefitVehicle(): " + AIVehicle.RefitVehicle(20, 5)); + print(" GetCapacity(): " + AIVehicle.GetCapacity(20, 9)); + print(" GetCapacity(): " + AIVehicle.GetCapacity(20, 5)); + print(" SellVehicle(): " + AIVehicle.SellVehicle(20)); + print(" --Errors--"); print(" RefitVehicle(): " + AIVehicle.RefitVehicle(12, 0)); print(" GetLastErrorString(): " + AIError.GetLastErrorString()); diff --git a/bin/ai/regression/tst_regression/require.nut b/bin/ai/regression/tst_regression/require.nut index 360e1c23b0..d8dc4baa7d 100644 --- a/bin/ai/regression/tst_regression/require.nut +++ b/bin/ai/regression/tst_regression/require.nut @@ -1,4 +1,2 @@ -/* $Id$ */ - print(" Required this file"); diff --git a/bin/ai/regression/tst_regression/result.txt b/bin/ai/regression/tst_regression/result.txt index e93b2e2343..18ae14cb7a 100644 --- a/bin/ai/regression/tst_regression/result.txt +++ b/bin/ai/regression/tst_regression/result.txt @@ -8534,9 +8534,8 @@ ERROR: IsEnd() is invalid as Begin() is never called 19693 => 8 --TileList_IndustryProducing-- - Count(): 92 + Count(): 90 Location ListDump: - 46920 => 1 46919 => 1 46918 => 1 46917 => 1 @@ -8545,7 +8544,6 @@ ERROR: IsEnd() is invalid as Begin() is never called 46914 => 1 46913 => 1 46912 => 1 - 46911 => 1 46664 => 1 46663 => 1 46662 => 1 @@ -9128,6 +9126,18 @@ ERROR: IsEnd() is invalid as Begin() is never called GetWagonAge(): 0 GetWagonEngineType(): 65535 GetWagonAge(): -1 + --Refit-- + GetBuildWithRefitCapacity(): -1 + GetBuildWithRefitCapacity(): 0 + GetBuildWithRefitCapacity(): 160 + BuildVehicleWithRefit(): 20 + GetCapacity(): 160 + GetCapacity(): 0 + GetRefitCapacity(): 160 + RefitVehicle(): true + GetCapacity(): 0 + GetCapacity(): 160 + SellVehicle(): true --Errors-- RefitVehicle(): false GetLastErrorString(): ERR_VEHICLE_NOT_IN_DEPOT @@ -9175,7 +9185,7 @@ ERROR: IsEnd() is invalid as Begin() is never called 13 => 5489 12 => 5489 CurrentSpeed ListDump: - 12 => 21 + 12 => 27 17 => 0 16 => 0 14 => 0 diff --git a/bin/ai/regression/tst_stationlist/main.nut b/bin/ai/regression/tst_stationlist/main.nut index 60f3e4a4a7..2f00ea1d6f 100644 --- a/bin/ai/regression/tst_stationlist/main.nut +++ b/bin/ai/regression/tst_stationlist/main.nut @@ -1,5 +1,3 @@ -/* $Id$ */ - class Regression extends AIController { function Start(); }; diff --git a/bin/baseset/openttd.grf b/bin/baseset/openttd.grf index ea5f55ce1d..111004c175 100644 Binary files a/bin/baseset/openttd.grf and b/bin/baseset/openttd.grf differ diff --git a/bin/game/compat_1.10.nut b/bin/game/compat_1.10.nut new file mode 100644 index 0000000000..3081fb58e8 --- /dev/null +++ b/bin/game/compat_1.10.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/compat_1.2.nut b/bin/game/compat_1.2.nut index 7822a44d01..c042e988b5 100644 --- a/bin/game/compat_1.2.nut +++ b/bin/game/compat_1.2.nut @@ -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/bin/game/compat_1.3.nut b/bin/game/compat_1.3.nut index 0d7a2afb60..161f4fd0a0 100644 --- a/bin/game/compat_1.3.nut +++ b/bin/game/compat_1.3.nut @@ -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/bin/game/compat_1.4.nut b/bin/game/compat_1.4.nut index 3ff887727e..0ebb850675 100644 --- a/bin/game/compat_1.4.nut +++ b/bin/game/compat_1.4.nut @@ -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/bin/game/compat_1.5.nut b/bin/game/compat_1.5.nut index b29a8ed2f3..86283cc0dd 100644 --- a/bin/game/compat_1.5.nut +++ b/bin/game/compat_1.5.nut @@ -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/bin/game/compat_1.6.nut b/bin/game/compat_1.6.nut index a3f5975287..4a091b81ea 100644 --- a/bin/game/compat_1.6.nut +++ b/bin/game/compat_1.6.nut @@ -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/bin/game/compat_1.7.nut b/bin/game/compat_1.7.nut index b4c4d1bb35..febd335c36 100644 --- a/bin/game/compat_1.7.nut +++ b/bin/game/compat_1.7.nut @@ -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/bin/game/compat_1.8.nut b/bin/game/compat_1.8.nut index 5aac3f8c1d..bd33b79f09 100644 --- a/bin/game/compat_1.8.nut +++ b/bin/game/compat_1.8.nut @@ -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/bin/game/compat_1.9.nut b/bin/game/compat_1.9.nut index fe985b90d0..ab9ffbccaf 100644 --- a/bin/game/compat_1.9.nut +++ b/bin/game/compat_1.9.nut @@ -1,8 +1,8 @@ -/* $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. * 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("1.9 API compatibility in effect."); diff --git a/changelog.txt b/changelog.txt index b181431ff6..143513dbe3 100644 --- a/changelog.txt +++ b/changelog.txt @@ -1,3 +1,134 @@ +1.10.0-beta2 (2019-12-25) +------------------------------------------------------------------------ +- Feature: [Script] More error mappings (#7857) +- Feature: Ctrl+Click on a vehicle in the vehicle group window selects and scrolls to the vehicle's group (#7800) +- Feature: Ctrl+Click on the vehicle details button in the vehicle view window opens the vehicle group window focused on the vehicle (#7800) +- Feature: Add a button to the vehicle advisory news window to open the vehicle's group window (#7800) +- Feature: Ctrl+Click on a vehicle in the vehicle list window opens the vehicle group window focused on the vehicle's group (#7800) +- Fix: Custom sea level default value is now equal to minimum value (#7866) +- Fix: [NewGRF] Various tracktype fixes (#7863) +- Fix: Infrastructure total update when removing tram road stop (#7856) +- Fix #7847: Use ViewportSign coordinates for sign Kdtree coordinates (#7849) +- Fix #7836: Check coherency of NewGRF parameter min/max (#7840) +- Fix #7673: [Script] Allow removal of custom town text (#7834) +- Fix: Crash when displaying an error message at map edges (#7833) +- Fix #7783, #7816: [SDL2] Fix input handling in edit context (#7825) +- Fix #7697: Tile query on HQs did not display cargo correctly (#7824) +- Fix #7820: Possible game crash when removing oil rig (#7821) +- Fix #7606: Rare crash when trying to clean up a crashed script (#7819) +- Fix #7784: [SDL2] up/down/home/end key behaviour (#7815) +- Fix #7631: 16 out cargo support for industry directory (#7809) +- Fix #7646: Crash on random map generation failure (#7805) +- Fix #7430: Only reset time since pickup when train visits station if it has room to load (#7595) +- Fix #5405: Aircraft could route to depots outside their range (#7104) + + +1.10.0-beta1 (2019-10-29) +------------------------------------------------------------------------ +- Feature: Configurable minimum age for companies before allowing share trading (#7780) +- Feature: Filter on town list window (#7621) +- Feature: Ability to show Newspaper and Ticker messages in parallel (#7612) +- Feature: Show coverage area for stations and towns (#7446) +- Feature: Collapsible vehicle groups (#7417) +- Feature: More flexible docks - can now have multiple per station, ships can use any part of dock (#7380) +- Feature: [NewGRF] Railtype flags to allow/disallow 90 degree curves (#7352) +- Feature/Change: Non-rectangular catchment area for sparse stations (#7235) +- Feature: Improved performance for road vehicle pathfinding (#7261) +- Feature: Option to show local authority boundary of towns (#7025) +- Feature: Experimental method of town cargo generation that scales linearly with population (#6965) +- Feature: [NewGRF] RoadTypes (NRT) (#6811) +- Add: [Win32] Select MIDI device by port name (#7666) +- Add: 'getsysdate' console command (#7658) +- Add: Currencies NTD, CNY, HKD (#7596) +- Add: Icons to vehicle construction drop down lists (#7358, #7485) +- Add: Security warning to players that company passwords are not truly secure (#7351) +- Add: [Script] Various API functions for managing vehicle groups (#7225, #7336, #7716) +- Add: SDL2 video driver (#7086) +- Change: Inactive industries do not make sound effects (#7752) +- Change: [Win32] Use native GDI engine for rendering fonts (#7572) +- Change: Scale oil refinery edge distance limit by map size (#7514) +- Change: Do not display a news message about old vehicles when a replacement for it is activated (#7401) +- Change: When filtering purchase list by cargo type, buy button now performs a refit if required (#7301) +- Change: Don't apply forbid 90 deg turn settings to ships, and make penalties for turns configurable (#7289, #7372) +- Change: Make the chance of an aeroplane crashing at an airport with a short runway independent of plane crash setting (#7302) +- Change: Keep town growth rate in sync with house count (#6777) +- Fix #6219: Improve helicopter's ability to takeoff from commuter and international airports (#7710) +- Fix #6407: Show snowy ground sprites for train depots (#7671) +- Fix: Power/running cost sorting algorithm was not correct when power was higher than running cost (#7561) +- Fix: Tweaks to small-map colours to make dark blue company more visible (#7436, #7450) +- Fix: [SDL] Do not offer video smaller than 640x480 (#7442) +- Fix: Incorrect display of industry production around tiles (#7426) +- Fix: Show industry name in Land Area Information window for industries with neutral stations instead of just 'Oil Rig' (#7349) +- Fix: Remove redundant and broken file lookups when loading base sets (#7348) +- Fix: Always report error when ordering a road vehicle to wrong type of road stop (#7316) +- Fix #7043, #7274: Improve performance when creating towns during world creation (#7284) +- Fix #7062: Remove ship max order distance (#7279) +- Fix #7189: Fluidsynth volume gain too high (#7253) +- Fix: Add setting for whether industries with neutral stations (e.g. Oil rigs) accept and supply cargo to/from surrounding stations to fix exploit as old as TTO (#7234) +- Fix: Properly reset dropdown menu windows after changing AI/GS settings (#7092) +- Remove: DOS, MorphOS, AmigaOS & BeOS support (#7326, #7388) +- Remove: Original Path Finder (#7245) + + +1.9.3 (2019-09-16) +------------------------------------------------------------------------ +- Change: Use natural sort when sorting the file list (#7727) +- Fix #7479: Don't close construction windows when changing client name (#7728) +- Fix #7731: Files sorting by modification time on Windows XP (#7731) +- Fix #7644: [OSX] Better solution for colourspace/performance issues (#7741) + + +1.9.3-RC1 (2019-09-07) +------------------------------------------------------------------------ +- Add: Can now click industries to make orders to their neutral station (e.g. oil rig) (#7709) +- Fix #7644: [OSX] Poor framerate on certain systems (#7721) +- Fix #7702: Highscore screen UI scaling (#7714) +- Fix #7704: [OSX] Handle malformed UTF8 strings, leading to crashes in server browser (#7705) +- Fix #7188: [AI] Possible crash when reloading an AI in multiplayer games (#7701, #7725) +- Fix: RemoveAirport function now returns 'Aircraft in the way' error message when occupied (#7690) +- Fix: Spelling in running costs setting help text (#7686) +- Fix #7655: 'Decrease' buttons in cheat window not working properly with UI scaling (#7669) +- Fix: [GS] Could not create elements on Storybook pages with ID > 255 (#7657) +- Fix #7626: Allow building road stops over town-owned one-way roads, instead of crashing (#7627) + + +1.9.2 (2019-07-07) +------------------------------------------------------------------------ +- Change: Set default setting in server browser of "Advertised" to "Yes" (#7568) +- Change: Allow building road stops over self-owned one-way/blocked road (#7547) +- Fix #7463: Promote scroll mode setting to basic category (#7586) +- Fix: Inconsistent GUI scaling (#7539) +- Fix #7491: Send company update admin message when bankruptcy counter changes (#7492) +- Fix #7553: Check bounds when loading strings (#7554) +- Fix: Really increase the maximum number of GameScript texts to 64k (#7555) +- Fix: Crash when attempting to load old save game with GRFs set (#7546) +- Fix #6507: Don't try to load invalid depots from older savegames (#7546) +- Fix: Railtype bits were moved too late, leading to rails under bridges losing their type (#7546) +- Fix: Bounds check access to railtype_map (#7529) +- Fix: Spurious errors when using more than 32 railtypes (#7533) +- Fix #7633: Allow zero-cost track conversion to succeed (#7634) +- Fix #7577: Check if linkgraph station index is valid before dereferencing (#7583) +- Fix #7224: Drag and drop vehicle group creation does not work correctly (#7581) +- Fix #7570: Show Github URL in the crashlog window (#7571) +- Fix: Clicking on scrollbar 'thumb' moved position up instantly (#7549) +- Fix #7255: Prevent crashlog corruption by only printing the 32 most recent news messages (#7542) +- Fix #5685: Check for free wagons in ScriptVehicleList (#7617) +- Fix: Make GSGoal.QuestionClient work correctly at least for clients with ID < 2**16 (#7560) +- Fix #6666: Mismatched parentheses in RTL languages (#7480) +- Fix: [Windows] Various reliability and correctness improvements to MIDI on Windows (#7620) + + +1.9.1 (2019-04-08) +------------------------------------------------------------------------ +- Fix #6564: Enforce types of arguments for station name strings (#7419) +- Fix #7433: Don't use AirportSpec substitute if it's not enabled (#7435) +- Fix #7447, #7466, #7476: Missing NewGRF strings due to Action 4 feature check skipping pseudo-feature 48 (#7449) +- Fix #6222: Advanced sprite layout sometimes showed incorrect railtype ground tile. (#7460) +- Fix #7439: CompanyRemoveReason overwritten by ClientID (#7465) +- Fix: [Windows] Incorrect error handling could lead to cascading error windows (#7482) +- Fix #7478: Don't remove NewGRF objects on company take-over. (#7483) + + 1.9.0 (2019-04-01) ------------------------------------------------------------------------ - Fix #7411: Use industry production callback (if used) on initial industry cargo generation (#7412) @@ -186,7 +317,7 @@ Note: OpenTTD was migrated to GitHub for 1.9, so SVN revision and FlySpray numbe - Fix: [Win32] Right mouse scrolling didn't work properly with the Windows 10 Fall Creators Update [FS#6629] (r27935) - Fix: Forest, candyfloss forest and battery farm skipped the first animation frame [FS#6639] (r27932) - Fix: Glyphs in range U+0020 to U+00FF may only be defined in orig_extra.grf, not in openttd.grf [FS#6620] (r27915) -- Fix: 'unban' console command was not handling IPv6 adresses properly (r27914, r27913) +- Fix: 'unban' console command was not handling IPv6 addresses properly (r27914, r27913) - Fix: Keep the 'link' between industry chain and smallmap windows whenever possible [FS#6585] (r27905) - Fix: When the last vehicle is removed from a shared orders group, hide the 'Stop sharing' button in the vehicle orders window [FS#6593] (r27904) - Fix: Tooltip of 'increase service interval' said 'decrease' [FS#6606] (r27895) @@ -292,7 +423,7 @@ Note: OpenTTD was migrated to GitHub for 1.9, so SVN revision and FlySpray numbe - Fix: [Build] Force sorting to be locale independent, so files are always ordered the same and by that token better diff-able (r27562, r27558) - Fix: Typos in comments and string (r27561, r27560) - Fix: [Build] bashism that caused different CFLAGS with bash vs dash (r27557) -- Fix: Use a more appropiate sound effect for convert-rail (r27547) +- Fix: Use a more appropriate sound effect for convert-rail (r27547) - Fix: Remove SetFill from vehicle GUI buttons, so that the viewport is resized instead of them in case of long window titles (r27546) - Fix: [Script] Generation of API wrappers (r27545, r27544, r27543) - Fix: [Windows] ICU got disabled for Windows builds, breaking RTL support [FS#6427] (r27542) @@ -3183,7 +3314,7 @@ Note: OpenTTD was migrated to GitHub for 1.9, so SVN revision and FlySpray numbe - Fix: Improve corner case order handling: mark order as done only when actually done, obey non-stop orders, do only stop/refit at the depot in the order (r16240, r16228, r16199, r16198, r16187) - Fix: [NoAI] Use the stop/non-stop intermediate orderflags AIs can give for goto-depot orders (r16239) - Fix: [NewGRF] ActionB should use the online parameters from GRFFile instead of the initial user-specified values from GRFConfig. Also use the values as they were set when the ActionB was executed, not as they are set when the message is shown (r16223) -- Fix: Possible crashes when quiting OpenTTD or forcing resizes/redraws of the screen during map generation [FS#2862] (r16220) +- Fix: Possible crashes when quitting OpenTTD or forcing resizes/redraws of the screen during map generation [FS#2862] (r16220) - Fix: Shared orders without orders were not properly converted causing corrupt/invalid orders when loading pre 0.7 savegames [FS#2878] (r16214) - Fix: Hardcoded (old sized) MAX_COMPANIES constant (r16182) - Fix: [Squirrel] The traps variable was not restored, causing try/catch blocks to be 'forgotten' during a suspend (r16181) @@ -3191,7 +3322,7 @@ Note: OpenTTD was migrated to GitHub for 1.9, so SVN revision and FlySpray numbe - Fix: Forbid joining AI companies via the 'move' and 'join' console commands/multiplayer lobby (r16176, r16175) - Fix: [NoAI] AIOrder::GetOrderDestination and AIOrder::GetOrderFlags did not work on ORDER_CURRENT when the vehicle was loading/leaving in a station (r16165) - Fix: [NoAI] Change WAYPOINT_INVALID to 0xFFFF from -1 as that is the value the AIs got (due to casting) (r16150) -- Fix: The overflowsafe type did not like dividing by int64 larger than MAX_INT32 causing division by negative numbers and small anomolies when drawing graphs [FS#2855] (r16130) +- Fix: The overflowsafe type did not like dividing by int64 larger than MAX_INT32 causing division by negative numbers and small anomalies when drawing graphs [FS#2855] (r16130) - Fix: Road was removed when both the Remove button was active and Ctrl was pressed [FS#2582] (r16119) - Fix: [NoAI] Make sure AIOrder::GetDestination always returns a tile belonging to the station (16109) - Fix: [NoAI] When giving an aircraft a goto-hangar order do not let it be a normal goto-station order (r16108) @@ -3647,7 +3778,7 @@ Note: OpenTTD was migrated to GitHub for 1.9, so SVN revision and FlySpray numbe - Fix: Inconsistent use of 8/15-bitness of NewGRF callback results with respect to TTDP's implementation of the specification (r12819, r12818, r12759) - Fix: Possible out of bounds array access (r12809) - Fix: Enforce autorenew values range in command (r12808) -- Fix: Vehicles could break down during loading and keep loading. The intention of the break down code is not to break down when having zero speed, therefor break downs now do not happen when loading [FS#1938] (r12795) +- Fix: Vehicles could break down during loading and keep loading. The intention of the break down code is not to break down when having zero speed, therefore break downs now do not happen when loading [FS#1938] (r12795) - Fix: [OSX] In some rare cases when using an uncalibrated monitor the system colour space could not be retrieved. Show an error when this happens instead of just trying an assertion (r12776) - Fix: Slope checking for NewGRFs failed (r12759) - Fix: Check the TILE_NOT_SLOPED flag of the _north_ tile of multi-tile houses to decide if autoslope is allowed (r12717) @@ -3755,7 +3886,7 @@ Note: OpenTTD was migrated to GitHub for 1.9, so SVN revision and FlySpray numbe - Feature: Separate catenary transparency settings from building transparency settings (r12103) - Feature: Allow locking individual transparency settings so they will not be changed by pressing 'x' (r12102) - Feature: Add some missing VarAction2 variables (r12124) -- Feature: Make snow appear on rail tiles dependant on track height, not on height of the lowest part of the tile (r12098) +- Feature: Make snow appear on rail tiles dependent on track height, not on height of the lowest part of the tile (r12098) - Feature: [NewGRF] Specify the purchase, rail and road description of a bridge (r12069) - Feature: [NewGRF] Add support for var 12, Variational Action 2 (r12045) - Feature: Allow trees on shore (r12029) @@ -4036,7 +4167,7 @@ Note: OpenTTD was migrated to GitHub for 1.9, so SVN revision and FlySpray numbe - Feature: Add support for variable snow lines in the arctic climate, supplied by NewGRF files (r9371) - Feature: [NewGRF] Add support for newhouses (r9315) - Feature: [NewGRF] Add support for Action 13, which allows you to translate GRF-specific texts. The translations will only be shown if you are using a language with a GRF language id and if a string has not already been set specifically for the language you are using (r9037) -- Feature: Translation dependant formatting of dates (r8906) +- Feature: Translation dependent formatting of dates (r8906) - Feature: If an action 7/9 leads to skipping the rest of the file, disable the NewGRF if an action 8 has not been encountered yet (r8831) - Feature: Stop loading and disable the current NewGRF if a fatal error message in Action B is encountered. Also be more strict on the values accepted (r8830) - Feature: Build aircraft windows will no longer show aircraft that cannot use the airport in question (r8771) @@ -4157,7 +4288,7 @@ Note: OpenTTD was migrated to GitHub for 1.9, so SVN revision and FlySpray numbe - Fix: Do not display income/expenses when they do not belong to a 'valid' tile, like the money cheat and giving money [FS#1175] (r11021) - Fix: One could not give money when (s)he had too much money [FS#1174] (r11020) - Fix: Disallow buying/selling shares in your own company or a bankrupt company [FS#1169] (r11018) -- Fix: Crash when quiting the game in one of the end score windows [FS#1218] (r11071) +- Fix: Crash when quitting the game in one of the end score windows [FS#1218] (r11071) 0.5.3-RC3 (2007-08-30) @@ -4289,7 +4420,7 @@ Note: OpenTTD was migrated to GitHub for 1.9, so SVN revision and FlySpray numbe 0.5.1-RC1 (2007-03-20) ------------------------------------------------------------------------ -- Feature: Translation dependant formatting of dates (r8906) +- Feature: Translation dependent formatting of dates (r8906) - Feature: Kick inactive initial network connections after some time [FS#115] (r9038, r9061) - Feature: Add an extra news group for opening and closing of industries (r9097) - Codechange: Disable shares by default and increase the default maximum distance from edge for oil refineries (r9339) @@ -5252,7 +5383,7 @@ Note: OpenTTD was migrated to GitHub for 1.9, so SVN revision and FlySpray numbe - Fix: Wrong pathfinding when northern station tile is missing - Fix: You cannot take ownership of an oilrig by building right next to it - Fix: [Makefile] Fixed issue where sdl-config was needed even on systems without SDL -- Fix: [SDL] Performance fix fo palette animation and mouse jumping +- Fix: [SDL] Performance fix for palette animation and mouse jumping - Fix: [SDL] Same resolution was displayed more than once in game options - Fix: [SDL] Smoother mouse and performance fix, like in the Windows video driver - Fix: Wrong trains you can buy with scenarios [SF#963056] diff --git a/config.lib b/config.lib index de1285e0eb..7ce3fe6288 100644 --- a/config.lib +++ b/config.lib @@ -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. # 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. @@ -52,7 +50,6 @@ set_default() { enable_profiling="0" enable_lto="0" enable_dedicated="0" - enable_network="1" enable_static="1" enable_translator="0" enable_unicode="1" @@ -82,7 +79,6 @@ set_default() { with_iconv="1" with_midi="" with_midi_arg="" - with_libtimidity="1" with_fluidsynth="1" with_freetype="1" with_fontconfig="1" @@ -131,7 +127,6 @@ set_default() { enable_profiling enable_lto enable_dedicated - enable_network enable_static enable_translator enable_unicode @@ -160,7 +155,6 @@ set_default() { with_iconv with_midi with_midi_arg - with_libtimidity with_fluidsynth with_freetype with_fontconfig @@ -291,9 +285,6 @@ detect_params() { --enable-ipo=*) enable_lto="$optarg";; --enable-dedicated) enable_dedicated="1";; --enable-dedicated=*) enable_dedicated="$optarg";; - --enable-network) enable_network="2";; - --enable-network=*) enable_network="$optarg";; - --disable-network) enable_network="0";; --disable-static) enable_static="0";; --enable-static) enable_static="2";; --enable-static=*) enable_static="$optarg";; @@ -370,10 +361,6 @@ detect_params() { --without-libpng) with_png="0";; --with-libpng=*) with_png="$optarg";; - --with-libtimidity) with_libtimidity="2";; - --without-libtimidity) with_libtimidity="0";; - --with-libtimidity=*) with_libtimidity="$optarg";; - --with-fluidsynth) with_fluidsynth="2";; --without-fluidsynth) with_fluidsynth="0";; --with-fluidsynth=*) with_fluidsynth="$optarg";; @@ -549,8 +536,8 @@ check_params() { # Export some variables to be used by pkg-config # - # PKG_CONFIG_LIBDIR variable musn't be set if we are not willing to - # override the default pkg-config search path, it musn't be an empty + # PKG_CONFIG_LIBDIR variable mustn't be set if we are not willing to + # override the default pkg-config search path, it mustn't be an empty # string. If the variable is empty (e.g. when an empty string comes # from config.cache) then unset it. This way the "don't override" state # will be properly preserved when (re)configuring. @@ -559,10 +546,10 @@ check_params() { # Check if all params have valid values - # OS only allows DETECT, UNIX, OSX, FREEBSD, DRAGONFLY, OPENBSD, NETBSD, MORPHOS, BEOS, HAIKU, SUNOS, CYGWIN, MINGW, OS2, and DOS - if [ -z "`echo $os | egrep '^(DETECT|UNIX|OSX|FREEBSD|DRAGONFLY|OPENBSD|NETBSD|HPUX|MORPHOS|BEOS|HAIKU|SUNOS|CYGWIN|MINGW|OS2|DOS|ANDROID)$'`" ]; then + # OS only allows DETECT, UNIX, OSX, FREEBSD, DRAGONFLY, OPENBSD, NETBSD, HAIKU, SUNOS, CYGWIN, MINGW, and OS2 + if [ -z "`echo $os | egrep '^(DETECT|UNIX|OSX|FREEBSD|DRAGONFLY|OPENBSD|NETBSD|HPUX|HAIKU|SUNOS|CYGWIN|MINGW|OS2|ANDROID)$'`" ]; then log 1 "configure: error: invalid option --os=$os" - log 1 " Available options are: --os=[DETECT|UNIX|OSX|FREEBSD|DRAGONFLY|OPENBSD|NETBSD|HPUX|MORPHOS|BEOS|HAIKU|SUNOS|CYGWIN|MINGW|OS2|DOS|ANDROID]" + log 1 " Available options are: --os=[DETECT|UNIX|OSX|FREEBSD|DRAGONFLY|OPENBSD|NETBSD|HPUX|HAIKU|SUNOS|CYGWIN|MINGW|OS2|ANDROID]" exit 1 fi # cpu_type can be either 32 or 64 @@ -629,7 +616,7 @@ check_params() { detect_sse_capable_architecture if [ "$enable_static" = "1" ]; then - if [ "$os" = "MINGW" ] || [ "$os" = "CYGWIN" ] || [ "$os" = "MORPHOS" ] || [ "$os" = "DOS" ]; then + if [ "$os" = "MINGW" ] || [ "$os" = "CYGWIN" ]; then enable_static="2" else enable_static="0" @@ -639,8 +626,8 @@ check_params() { if [ "$enable_static" != "0" ]; then log 1 "checking static... yes" - if [ "$os" != "MINGW" ] && [ "$os" != "CYGWIN" ] && [ "$os" != "OSX" ] && [ "$os" != "MORPHOS" ] && [ "$os" != "DOS" ]; then - log 1 "WARNING: static is only known to work on Windows, DOS, MacOSX and MorphOS" + if [ "$os" != "MINGW" ] && [ "$os" != "CYGWIN" ] && [ "$os" != "OSX" ]; then + log 1 "WARNING: static is only known to work on Windows, and MacOSX" log 1 "WARNING: use static at your own risk on this platform" sleep 5 @@ -650,7 +637,7 @@ check_params() { fi if [ "$enable_unicode" = "1" ]; then - if [ "$os" = "MINGW" ] || [ "$os" = "CYGWIN" ] || [ "$os" = "DOS" ]; then + if [ "$os" = "MINGW" ] || [ "$os" = "CYGWIN" ]; then enable_unicode="2" else enable_unicode="0" @@ -755,11 +742,6 @@ check_params() { if [ "$enable_dedicated" != "0" ]; then log 1 "checking GDI video driver... dedicated server, skipping" log 1 "checking dedicated... found" - - if [ "$enable_network" = "0" ]; then - log 1 "configure: error: building a dedicated server without network support is pointless" - exit 1 - fi else if [ "$os" = "MINGW" ] || [ "$os" = "CYGWIN" ]; then log 1 "checking GDI video driver... found" @@ -767,7 +749,7 @@ check_params() { log 1 "checking GDI video driver... not Windows, skipping" fi - if [ -z "$allegro_config" ] && [ -z "$sdl_config" ] && [ "$with_cocoa" = 0 ] && [ "$os" != "MINGW" ] && [ "$os" != "CYGWIN" ]; then + if [ -z "$allegro_config" ] && [ -z "$sdl2_config" ] && [ -z "$sdl_config" ] && [ "$with_cocoa" = 0 ] && [ "$os" != "MINGW" ] && [ "$os" != "CYGWIN" ]; then log 1 "configure: error: no video driver development files found" log 1 " If you want a dedicated server use --enable-dedicated as parameter" exit 1 @@ -790,15 +772,6 @@ check_params() { log 1 "checking console application... enabled" fi - if [ "$enable_network" = "1" ] && [ "$os" = "DOS" ]; then - log 1 "checking network... DOS, skipping" - enable_network=0 - elif [ "$enable_network" != "0" ]; then - log 1 "checking network... found" - else - log 1 "checking network... disabled" - fi - log 1 "checking squirrel... found" SCRIPT_SRC_DIR="$ROOT_DIR/src/3rdparty/squirrel/include" @@ -895,7 +868,6 @@ check_params() { detect_fontconfig detect_icu_layout detect_icu_sort - detect_libtimidity detect_fluidsynth if [ "$with_direct_music" != "0" ]; then @@ -939,9 +911,7 @@ check_params() { fi if [ "$enable_debug" = "0" ] && [ "$enable_profiling" = "0" ] && [ "$enable_strip" != "0" ]; then - if [ "$os" = "MORPHOS" ]; then - strip_arg="--strip-all --strip-unneeded --remove-section .comment" - elif [ "$os" = "OSX" ]; then + if [ "$os" = "OSX" ]; then strip_arg="" elif [ "$os" = "OS2" ]; then strip_arg="" @@ -1032,10 +1002,6 @@ check_params() { grfcodec="" fi - if [ "$os" = "DOS" ]; then - with_threads="0" - fi - if [ "$os" != "OSX" ] && [ "$with_application_bundle" != "0" ]; then if [ "$with_application_bundle" = "1" ]; then with_application_bundle="0" @@ -1091,18 +1057,8 @@ check_params() { fi fi - if [ -d "$ROOT_DIR/.svn" ] && [ -n "`svn help 2>/dev/null`" ]; then - log 1 "checking revision... svn detection" - elif [ -d "$ROOT_DIR/../.svn" ] && [ -n "`svn help 2>/dev/null`" ] && [ -n "`LC_ALL=C svn info $ROOT_DIR/.. | grep '^URL:.*tags$'`" ]; then - # subversion changed its behaviour; now not all folders have a .svn folder, - # but only the root folder. Since making tags requires a (sparse) checkout - # of the tags folder, the folder of the tag does not have a .svn folder - # anymore and this fails to detect the subversion repository checkout. - log 1 "checking revision... svn detection (tag)" - elif [ -e "$ROOT_DIR/.git" ] && [ -n "`git help 2>/dev/null`" ]; then + if { [ -d "$ROOT_DIR/.git" ] || [ -f "$ROOT_DIR/.git" ]; } && [ -n "`git help 2>/dev/null`" ]; then log 1 "checking revision... git detection" - elif [ -d "$ROOT_DIR/.hg" ] && [ -n "`HGPLAIN= hg help 2>/dev/null`" ]; then - log 1 "checking revision... hg detection" elif [ -f "$ROOT_DIR/.ottdrev" ]; then log 1 "checking revision... source tarball" else @@ -1138,7 +1094,7 @@ check_params() { fi if [ "$personal_dir" = "1" ]; then - if [ "$os" = "MINGW" ] || [ "$os" = "CYGWIN" ] || [ "$os" = "DOS" ] || [ "$os" = "HAIKU" ]; then + if [ "$os" = "MINGW" ] || [ "$os" = "CYGWIN" ] || [ "$os" = "HAIKU" ]; then personal_dir="OpenTTD" elif [ "$os" = "OSX" ]; then personal_dir="Documents/OpenTTD" @@ -1353,6 +1309,9 @@ make_compiler_cflags() { # it happens when using the FOR_ALL_WINDOWS_FROM_BACK_FROM macro flags="$flags -Wno-self-assign" + # warning: is a C++11 extension + flags="$flags -Wno-c++11-extensions" + if [ "$cc_version" -lt "30" ]; then # warning: equality comparison with extraneous parentheses flags="$flags -Wno-parentheses" @@ -1428,7 +1387,7 @@ make_compiler_cflags() { if [ $cc_version -ge 402 ]; then # GCC 4.2+ automatically assumes that signed overflows do - # not occur in signed arithmetics, whereas we are not + # not occur in signed arithmetic, whereas we are not # sure that they will not happen. It furthermore complains # about its own optimized code in some places. flags="$flags -fno-strict-overflow" @@ -1527,10 +1486,6 @@ make_cflags_and_ldflags() { if [ "$enable_debug" = "0" ]; then # No debug, add default stuff OBJS_SUBDIR="release" - if [ "$os" = "MORPHOS" ]; then - CFLAGS="-I/gg/os-include -noixemul -fstrict-aliasing -fexpensive-optimizations -mcpu=604 -fno-inline -mstring -mmultiple $CFLAGS" - LDFLAGS="$LDFLAGS -noixemul" - fi if [ "$enable_profiling" = "0" ]; then # -fomit-frame-pointer and -pg do not go well together (gcc errors they are incompatible) @@ -1561,12 +1516,20 @@ make_cflags_and_ldflags() { # extensions in a way that breaks build with at least ICC. # This requires -O1 or more, so debug level 3 (-O0) is excluded. CFLAGS="$CFLAGS -D_FORTIFY_SOURCE=2" + if [ "$os" = "MINGW" ]; then + # Prevent undefined references when _FORTIFY_SOURCE > 0 + LDFLAGS="$LDFLAGS -fstack-protector" + fi fi cc_build_is_gcc=`basename "$cc_build" | grep "gcc" 2>/dev/null` if [ -n "$cc_build_is_gcc" ]; then # Just add -O1 to the tools needed for building. CFLAGS_BUILD="$CFLAGS_BUILD -D_FORTIFY_SOURCE=2 -O1" + if [ "$os" = "MINGW" ]; then + # Prevent undefined references when _FORTIFY_SOURCE > 0 + LDFLAGS_BUILD="$LDFLAGS_BUILD -fstack-protector" + fi fi fi @@ -1605,7 +1568,7 @@ make_cflags_and_ldflags() { LDFLAGS="$LDFLAGS -Wl,--subsystem,windows" fi - LIBS="$LIBS -lws2_32 -lwinmm -lgdi32 -ldxguid -lole32 -limm32" + LIBS="$LIBS -lws2_32 -lwinmm -lusp10 -lgdi32 -ldxguid -lole32 -limm32" if [ $cc_version -ge 404 ]; then LDFLAGS_BUILD="$LDFLAGS_BUILD -static-libgcc -static-libstdc++" @@ -1616,19 +1579,14 @@ make_cflags_and_ldflags() { fi fi - if [ "$os" != "CYGWIN" ] && [ "$os" != "HAIKU" ] && [ "$os" != "OPENBSD" ] && [ "$os" != "MINGW" ] && [ "$os" != "MORPHOS" ] && [ "$os" != "OSX" ] && [ "$os" != "DOS" ] && [ "$os" != "OS2" ] && [ "$os" != "ANDROID" ]; then + if [ "$os" != "CYGWIN" ] && [ "$os" != "HAIKU" ] && [ "$os" != "OPENBSD" ] && [ "$os" != "MINGW" ] && [ "$os" != "OSX" ] && [ "$os" != "OS2" ] && [ "$os" != "ANDROID" ]; then LIBS="$LIBS -lpthread" fi - if [ "$os" != "CYGWIN" ] && [ "$os" != "HAIKU" ] && [ "$os" != "MINGW" ] && [ "$os" != "DOS" ]; then + if [ "$os" != "CYGWIN" ] && [ "$os" != "HAIKU" ] && [ "$os" != "MINGW" ]; then LIBS="$LIBS -lc" fi - if [ "$os" = "MORPHOS" ]; then - # -Wstrict-prototypes generates much noise because of system headers - CFLAGS="$CFLAGS -Wno-strict-prototypes" - fi - if [ "$os" = "OPENBSD" ]; then LIBS="$LIBS -pthread" fi @@ -1652,12 +1610,12 @@ make_cflags_and_ldflags() { fi fi - if [ "$os" = "BEOS" ] || [ "$os" = "HAIKU" ]; then + if [ "$os" = "HAIKU" ]; then LIBS="$LIBS -lmidi -lbe" fi # Most targets act like UNIX, just with some additions - if [ "$os" = "BEOS" ] || [ "$os" = "HAIKU" ] || [ "$os" = "OSX" ] || [ "$os" = "MORPHOS" ] || [ "$os" = "FREEBSD" ] || [ "$os" = "DRAGONFLY" ] || [ "$os" = "OPENBSD" ] || [ "$os" = "NETBSD" ] || [ "$os" = "HPUX" ] || [ "$os" = "SUNOS" ] || [ "$os" = "OS2" ] || [ "$os" = "ANDROID" ]; then + if [ "$os" = "HAIKU" ] || [ "$os" = "OSX" ] || [ "$os" = "FREEBSD" ] || [ "$os" = "DRAGONFLY" ] || [ "$os" = "OPENBSD" ] || [ "$os" = "NETBSD" ] || [ "$os" = "HPUX" ] || [ "$os" = "SUNOS" ] || [ "$os" = "OS2" ] || [ "$os" = "ANDROID" ]; then CFLAGS="$CFLAGS -DUNIX" fi # And others like Windows @@ -1677,7 +1635,16 @@ make_cflags_and_ldflags() { fi fi - if [ -n "$sdl_config" ]; then + if [ -n "$sdl2_config" ]; then + CFLAGS="$CFLAGS -DWITH_SDL2" + # SDL must not add _GNU_SOURCE as it breaks many platforms + CFLAGS="$CFLAGS `$sdl2_config --cflags | sed 's@-D_GNU_SOURCE[^ ]*@@'`" + if [ "$enable_static" != "0" ]; then + LIBS="$LIBS `$sdl2_config --static --libs`" + else + LIBS="$LIBS `$sdl2_config --libs`" + fi + elif [ -n "$sdl_config" ]; then CFLAGS="$CFLAGS -DWITH_SDL" # SDL must not add _GNU_SOURCE as it breaks many platforms CFLAGS="$CFLAGS `$sdl_config --cflags | sed 's@-D_GNU_SOURCE[^ ]*@@'`" @@ -1712,7 +1679,7 @@ make_cflags_and_ldflags() { fi if [ -n "$lzma_config" ]; then - CFLAGS="$CFLAGS -DWITH_LZMA" + CFLAGS="$CFLAGS -DWITH_LIBLZMA" CFLAGS="$CFLAGS `$lzma_config --cflags | tr '\n\r' ' '`" if [ "$enable_static" != "0" ]; then @@ -1783,7 +1750,7 @@ make_cflags_and_ldflags() { fi if [ -n "$icu_layout_config" ]; then - CFLAGS="$CFLAGS -DWITH_ICU_LAYOUT" + CFLAGS="$CFLAGS -DWITH_ICU_LX" CFLAGS="$CFLAGS `$icu_layout_config --cflags | tr '\n\r' ' '`" if [ "$static_icu" != "0" ]; then @@ -1794,7 +1761,7 @@ make_cflags_and_ldflags() { fi if [ -n "$icu_sort_config" ]; then - CFLAGS="$CFLAGS -DWITH_ICU_SORT" + CFLAGS="$CFLAGS -DWITH_ICU_I18N" CFLAGS="$CFLAGS `$icu_sort_config --cflags | tr '\n\r' ' '`" if [ "$static_icu" != "0" ]; then @@ -1823,17 +1790,6 @@ make_cflags_and_ldflags() { CFLAGS="$CFLAGS -DWITH_XAUDIO2" fi - if [ -n "$libtimidity_config" ]; then - CFLAGS="$CFLAGS -DLIBTIMIDITY" - CFLAGS="$CFLAGS `$libtimidity_config --cflags | tr '\n\r' ' '`" - - if [ "$enable_static" != "0" ]; then - LIBS="$LIBS `$libtimidity_config --libs --static | tr '\n\r' ' '`" - else - LIBS="$LIBS `$libtimidity_config --libs | tr '\n\r' ' '`" - fi - fi - if [ -n "$fluidsynth" ]; then LIBS="$LIBS -lfluidsynth" CFLAGS="$CFLAGS -DFLUIDSYNTH" @@ -1869,20 +1825,12 @@ make_cflags_and_ldflags() { CFLAGS="$CFLAGS -DUNICODE -D_UNICODE" fi - if [ "$enable_network" != "0" ]; then - CFLAGS="$CFLAGS -DENABLE_NETWORK" + if [ "$os" = "HAIKU" ]; then + LDFLAGS="$LDFLAGS -lnetwork" + fi - if [ "$os" = "BEOS" ]; then - LDFLAGS="$LDFLAGS -lbind -lsocket" - fi - - if [ "$os" = "HAIKU" ]; then - LDFLAGS="$LDFLAGS -lnetwork" - fi - - if [ "$os" = "SUNOS" ]; then - LDFLAGS="$LDFLAGS -lnsl -lsocket" - fi + if [ "$os" = "SUNOS" ]; then + LDFLAGS="$LDFLAGS -lnsl -lsocket" fi if [ "$enable_static" != "0" ]; then @@ -2361,7 +2309,7 @@ detect_awk() { detect_os() { if [ "$os" = "DETECT" ]; then - # Detect UNIX, OSX, FREEBSD, DRAGONFLY, OPENBSD, NETBSD, HPUX, MORPHOS, BEOS, SUNOS, CYGWIN, MINGW, OS2, and DOS + # Detect UNIX, OSX, FREEBSD, DRAGONFLY, OPENBSD, NETBSD, HPUX, SUNOS, CYGWIN, MINGW, and OS2 # Try first via dumpmachine, then via uname os=`echo "$host" | tr '[A-Z]' '[a-z]' | $awk ' @@ -2372,15 +2320,12 @@ detect_os() { /openbsd/ { print "OPENBSD"; exit} /netbsd/ { print "NETBSD"; exit} /hp-ux/ { print "HPUX"; exit} - /morphos/ { print "MORPHOS"; exit} - /beos/ { print "BEOS"; exit} /haiku/ { print "HAIKU"; exit} /sunos/ { print "SUNOS"; exit} /solaris/ { print "SUNOS"; exit} /cygwin/ { print "CYGWIN"; exit} /mingw/ { print "MINGW"; exit} /os2/ { print "OS2"; exit} - /dos/ { print "DOS"; exit} '` if [ -z "$os" ]; then @@ -2392,8 +2337,6 @@ detect_os() { /openbsd/ { print "OPENBSD"; exit} /netbsd/ { print "NETBSD"; exit} /hp-ux/ { print "HPUX"; exit} - /morphos/ { print "MORPHOS"; exit} - /beos/ { print "BEOS"; exit} /haiku/ { print "HAIKU"; exit} /sunos/ { print "SUNOS"; exit} /cygwin/ { print "CYGWIN"; exit} @@ -2406,7 +2349,7 @@ detect_os() { if [ -z "$os" ]; then log 1 "detecting OS... none detected" log 1 "I couldn't detect your OS. Please use --os=OS to force one" - log 1 "Allowed values are: UNIX, OSX, FREEBSD, DRAGONFLY, OPENBSD, NETBSD, MORPHOS, HPUX, BEOS, HAIKU, SUNOS, CYGWIN, MINGW, OS2, and DOS" + log 1 "Allowed values are: UNIX, OSX, FREEBSD, DRAGONFLY, OPENBSD, NETBSD, HPUX, HAIKU, SUNOS, CYGWIN, MINGW, and OS2" exit 1 fi @@ -2498,7 +2441,13 @@ detect_sdl() { sleep 5 fi - detect_pkg_config "$with_sdl" "sdl" "sdl_config" "1.2" + if [ $with_sdl = "sdl1" ]; then + detect_pkg_config "2" "sdl" "sdl_config" "1.2" + elif [ $with_sdl = "sdl2" ] || [ -x `which sdl2-config` ]; then + detect_pkg_config "2" "sdl2" "sdl2_config" "2.0" + else + detect_pkg_config "$with_sdl" "sdl" "sdl_config" "1.2" + fi } detect_osx_sdk() { @@ -2771,10 +2720,6 @@ detect_lzo2() { detect_library "$with_lzo2" "lzo2" "liblzo2.a" "lzo/" "lzo1x.h" } -detect_libtimidity() { - detect_pkg_config "$with_libtimidity" "libtimidity" "libtimidity_config" "0.1" "1" -} - detect_fluidsynth() { detect_library "$with_fluidsynth" "fluidsynth" "" "" "fluidsynth.h" } @@ -2852,6 +2797,12 @@ detect_png() { } detect_freetype() { + if [ "$with_freetype" = "1" ] && ([ "$os" = "MINGW" ] || [ "$os" = "CYGWIN" ]); then + log 1 "checking freetype2... WIN32, skipping" + freetype_config="" + return 0 + fi + detect_pkg_config "$with_freetype" "freetype2" "freetype_config" "2.2" "1" } @@ -3191,7 +3142,7 @@ detect_sse_capable_architecture() { else # It was forced, so it should be found. if [ "$with_sse" != "1" ]; then - log 1 "configure: error: SSE couln't be found" + log 1 "configure: error: SSE couldn't be found" log 1 "configure: error: you force enabled SSE, but it seems unavailable" exit 1 fi @@ -3493,8 +3444,8 @@ showhelp() { echo " --lipo=LIPO the lipo to use (OSX ONLY) [HOST-lipo]" echo " --os=OS the OS we are compiling for [DETECT]" echo " DETECT/UNIX/OSX/FREEBSD/DRAGONFLY/OPENBSD/" - echo " NETBSD/MORPHOS/HPUX/BEOS/SUNOS/CYGWIN/" - echo " MINGW/OS2/DOS/HAIKU/ANDROID" + echo " NETBSD/HPUX/SUNOS/CYGWIN/" + echo " MINGW/OS2/HAIKU/ANDROID" echo "" echo "Paths:" echo " --prefix-dir=dir specifies the prefix for all installed" @@ -3548,7 +3499,6 @@ showhelp() { echo " --enable-console compile as a console application instead of as a GUI application." echo " If this setting is active, debug output will appear in the same" echo " console instead of opening a new window. (Win32 ONLY)" - echo " --disable-network disable network support" echo " --disable-assert disable asserts (continue on errors)" echo " --enable-strip enable any possible stripping" echo " --without-osx-sysroot disable the automatic adding of sysroot " @@ -3563,13 +3513,11 @@ showhelp() { echo " --with-midi=midi define which midi-player to use" echo " --with-midi-arg=arg define which args to use for the" echo " midi-player" - echo " --with-libtimidity[=\"pkg-config libtimidity\"]" - echo " enables libtimidity support" echo " --with-fluidsynth enables fluidsynth support" echo " --with-allegro[=\"pkg-config allegro\"]" echo " enables Allegro video driver support" echo " --with-cocoa enables COCOA video driver (OSX ONLY)" - echo " --with-sdl[=\"pkg-config sdl\"] enables SDL video driver support" + echo " --with-sdl[=\"sdl1|sdl2\"] enables SDL video driver support" echo " --with-zlib[=\"pkg-config zlib\"]" echo " enables zlib support" echo " --with-liblzma[=\"pkg-config liblzma\"]" diff --git a/configure b/configure index 3644fa5174..0cbfd4d2e9 100755 --- a/configure +++ b/configure @@ -1,7 +1,5 @@ #!/bin/sh -# $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. # 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. @@ -75,7 +73,7 @@ save_params make_cflags_and_ldflags EXE="" -if [ "$os" = "MINGW" ] || [ "$os" = "CYGWIN" ] || [ "$os" = "OS2" ] || [ "$os" = "DOS" ]; then +if [ "$os" = "MINGW" ] || [ "$os" = "CYGWIN" ] || [ "$os" = "OS2" ]; then EXE=".exe" fi @@ -110,24 +108,23 @@ AWKCOMMAND=' if ($0 == "ALLEGRO" && "'$allegro_config'" == "") { next; } if ($0 == "SDL" && "'$sdl_config'" == "") { next; } + if ($0 == "SDL2" && "'$sdl2_config'" == "") { next; } if ($0 == "PNG" && "'$png_config'" == "") { next; } if ($0 == "OSX" && "'$os'" != "OSX") { next; } if ($0 == "OS2" && "'$os'" != "OS2") { next; } if ($0 == "DEDICATED" && "'$enable_dedicated'" != "1") { next; } if ($0 == "AI" && "'$enable_ai'" == "0") { next; } if ($0 == "COCOA" && "'$with_cocoa'" == "0") { next; } - if ($0 == "DOS" && "'$os'" != "DOS") { next; } - if ($0 == "BEOS" && "'$os'" != "BEOS" && - "'$os'" != "HAIKU") { next; } + if ($0 == "HAIKU" && "'$os'" != "HAIKU") { next; } if ($0 == "WIN32" && "'$os'" != "MINGW" && "'$os'" != "CYGWIN" && "'$os'" != "MSVC") { next; } - if ($0 == "MORPHOS" && "'$os'" != "MORPHOS") { next; } if ($0 == "MSVC" && "'$os'" != "MSVC") { next; } if ($0 == "DIRECTMUSIC" && "'$with_direct_music'" == "0") { next; } if ($0 == "LIBTIMIDITY" && "'$libtimidity_config'" == "" ) { next; } if ($0 == "FLUIDSYNTH" && "'$fluidsynth'" == "" ) { next; } - if ($0 == "HAVE_THREAD" && "'$with_threads'" == "0") { next; } - if ($0 == "SSE" && "'$with_sse'" != "1") { next; } + if ($0 == "USE_XAUDIO2" && "'$with_xaudio2'" == "0") { next; } + if ($0 == "USE_THREADS" && "'$with_threads'" == "0") { next; } + if ($0 == "USE_SSE" && "'$with_sse'" != "1") { next; } skip += 1; diff --git a/docs/HOWTO_compile_lang_files.txt b/docs/HOWTO_compile_lang_files.txt deleted file mode 100644 index 547854e508..0000000000 --- a/docs/HOWTO_compile_lang_files.txt +++ /dev/null @@ -1,72 +0,0 @@ -OpenTTD and strgen -Last updated: 2009-06-30 ------------------------------------------------------------------------- - - -Table of contents ------------------ -1.0) strgen usage - * 1.1) Examples - * 1.2) strgen command switches - - -1.0) strgen usage ----- ------------ -This guide is only interesting for people who want to alter something -themselves without access to translator.openttd.org. Please note that -your compiled language file will only be compatible with the OpenTTD version -you have downloaded english.txt, the master language file, for. While this is -not always true, namely when changes in the code have not touched language -files, your safest bet is to assume this 'limitation'. -As a first step you need to compile strgen. This is as easy as typing -'make strgen'. You can download the precompile strgen from: -http://www.openttd.org/download-strgen - -strgen takes as argument a txt file and translates it to a lng file, allowing -it to be used inside OpenTTD. strgen needs the master language file -english.txt to work. Below are some examples of strgen usage. - -1.1) Examples ----- -------- -Example 1: -if you are in the root of your working copy (git repository), you should type -strgen/strgen -s lang lang/english.txt -to compile englist.txt into english.lng. It will be placed in the lang dir - -Example 2: -you only have the strgen executable (no working copy) and you want to compile -a txt file in the same directory. You should type -./strgen english.txt -and you will get and english.lng in the same dir - -Example 3: -you have strgen somewhere, english.txt in /usr/openttd/lang and you want the -resulting language file to go to /tmp. Use -./strgen -s /usr/openttd/lang -d /tmp english.txt - -You can interchange english.txt to whichever language you want to generate a -.lng file for. - -1.2) strgen command switches ----- ----------------------- --v | --version -strgen will tell what git revision it was last modified - --t | --todo -strgen will add to any untranslated/missing strings and use the english -strings while compiling the language file - --w | --warning -strgen will print any missing strings or wrongly translated (bad format) -to standard error output(stderr) - --h | --help | -? -Print out a summarized help message explaining these switches - --s | --source_dir -strgen will search for the master file english.txt in the directory specified -by this switch instead of the current directory - --d | --dest_dir -strgen will put .lng in the directory specified by this switch; if -no dest_dir is given, output is the same as source_dir diff --git a/docs/Readme_OS2.txt b/docs/Readme_OS2.txt deleted file mode 100644 index 84fa6ec7e1..0000000000 --- a/docs/Readme_OS2.txt +++ /dev/null @@ -1,139 +0,0 @@ -OpenTTD: OS/2 version -===================== - -OpenTTD has been ported to work on OS/2 4.x or later (including -eComStation). The game should work as well as it does on Windows -or other platforms: the main issues you may encounter are graphics -card problems, but that is really the fault of SDL. - -========================= -USING OPENTTD FOR OS/2 -========================= - -LIBRARIES REQUIRED FOR END USERS --------------------------------- - -SDL.DLL (SDL 1.2.7) and FSLib.dll are required to use this program: -these can be downloaded from the Files section at -http://sourceforge.net/projects/openttd/ - see "os2-useful-v1.1.zip". -Version 20051222 of SDL or later is required. This can be found at -http://sdl.netlabs.org/. - -Please note that earlier SDL releases will probably NOT work with -OpenTTD. If you experience problems with OpenTTD, please check -your SDL and FSLib.dll versions (both must match). - -Note that to actually play the game, I have found in my own -experience that a version of the Scitech Display Drivers or its later -incarnation (see www.scitech.com) are necessary for it to work. If -you have trouble with your native drivers, try the Scitech drivers -and see if they help the problem. - -KNOWN ISSUES ------------- - -- If an error occurs during loading, the OS/2 error message window - is not always displayed. - -A NOTE ABOUT MUSIC ------------------- - -OpenTTD includes a music driver which uses the MCI MIDI system. Unfortunately, -due to the lack of proper MIDI hardware myself, I have been unable to test it, -but during testing, I found that when MIDI was enabled, I got no sound -effects. I therefore decided to DISABLE music by default. - -To enable music, start OpenTTD with the command line: - - openttd -m os2 - -If I hear enough responses that both music and sound work together (it might -just be my system), I'll have the defaults changed. - -Please note also that the GCC version does not currently support the MCI MIDI -system. - - -A NOTE ABOUT DEDICATED MULTIPLAYER SERVERS ------------------------------------------- - -To start a dedicated multiplayer server, you should run the dedicated.cmd -file. This enables OpenTTD to open up a VIO console window to display -its output and gather any necessary input. Running "openttd -D" -directly will result in the console not being displayed. You may -still pass any other parameters ('-D' is already passed) to -dedicated.cmd. - -You can find the dedicated.cmd file in the os/os2 directory. - -========================= -BUILDING THE OS/2 VERSION -========================= - -Compiler --------- - -Innotek GCC, an OS/2 port of the popular GCC compiler, was used to build OpenTTD. -See www.innotek.de for more information. You WILL need a reasonably UNIX-like -build environment in order to build OpenTTD successfully - the following link -may help to set one up (although some of the links from that page are broken): - - http://www.mozilla.org/ports/os2/gccsetup.html - -Alternatively, Paul Smedley's ready-to-go GCC build environment has been known to -successfully build the game: - - http://www.smedley.info/os2ports/index.php?page=build-environment - -To build, you should, if your environment is set up well enough, be able to just -type `./configure' (or `sh configure' if you're using the OS/2 shell) and `make'. - -You may have to manually specify `--os OS2' on the configure command line, as -configure cannot always detect OS/2 correctly. - -A note on Open Watcom ---------------------- - -Open Watcom C/C++ was previously used to build OpenTTD (version 0.4.x and earlier). -However, due to advanced C++ features used in the YAPF portion of OpenTTD 0.5 -in particular, the compiler is no longer able to build the game at the moment. -Hopefully one day Open Watcom will be able to catch up and we will be able to build -the game once again (it's easier than getting an OS/2 UNIX-like environment set up -in my opinion!), but until then, OpenTTD 0.5 and later can only be built with GCC. - -Libraries Required ------------------- - -The following libraries are required. To build zlib and libpng, I -simply added the required files (watch out for sample programs, etc) -to an IDE project file and built a library. Do not use the makefiles -provided, they are not designed for Watcom (apart from SDL): - -- zlib - http://www.zlib.org/ - -- libpng - http://www.libpng.org/ - -- SDL for OS/2 - ftp://ftp.netlabs.org/pub/sdl/sdl-1.2.7-src-20051222.zip used for - 0.4.7 - -- Freetype - http://freetype.sourceforge.net/ - -Currently, there are no pre-built libraries available for GCC. If you manage to get -OpenTTD working on Watcom though (do let us know if this is the case!), pre-built -versions can be downloaded from the Files section at -http://sourceforge.net/projects/openttd/ - see "os2-useful-v1.1.zip". - -Contact Information -------------------- - -If you have any questions regarding OS/2 issues, please contact me -(owen@owenrudge.net) and I'll try to help you out. For general OpenTTD -issues, see the Contacting section of readme.txt. - -Thanks to Paul Smedley for his help with getting OpenTTD to compile under GCC on OS/2. - -- Owen Rudge, 24th June 2007 diff --git a/docs/Readme_Windows_MSVC.md b/docs/Readme_Windows_MSVC.md deleted file mode 100644 index 90ab2af657..0000000000 --- a/docs/Readme_Windows_MSVC.md +++ /dev/null @@ -1,71 +0,0 @@ -# Compiling OpenTTD using Microsoft Visual C++ - -Last updated: 2018-12-27 - -## Supported MSVC compilers - -OpenTTD includes projects for Visual Studio 2015 Update 3 or more recent. -You can download the free Visual Studio Community Edition from Microsoft at -https://visualstudio.microsoft.com/vs/community/. - -## Required files - -### Microsoft platform files - -OpenTTD needs the Platform SDK, if it isn't installed already. This can be -done during installing Visual Studio, by selecting -`Visual C++ MFC for x86 and x64` (and possibly -`Visual C++ ATL for x86 and x64` depending on your version). If not, you -can get it at this location: - -- [MS Windows Platform SDK](https://developer.microsoft.com/en-US/windows/downloads/windows-10-sdk) - -Install the SDK by following the instructions as given. - -### OpenTTD dependencies - -Dependencies for OpenTTD on Windows are handled via -[vcpkg](https://github.com/Microsoft/vcpkg/). First you need to install vcpkg -by following the `Quick Start` intructions of their -[README](https://github.com/Microsoft/vcpkg/blob/master/README.md). - -After this, you can install the dependencies OpenTTD needs. We advise to use -the `static` versions, and OpenTTD currently needs the following dependencies: - -- freetype -- liblzma -- libpng -- lzo -- zlib - -To install both the x64 (64bit) and x86 (32bit) variants, you can use: - -```ps -.\vcpkg install freetype:x64-windows-static liblzma:x64-windows-static libpng:x64-windows-static lzo:x64-windows-static zlib:x64-windows-static -.\vcpkg install freetype:x86-windows-static liblzma:x86-windows-static libpng:x86-windows-static lzo:x86-windows-static zlib:x86-windows-static -``` - -## TTD Graphics files - -See section 4.1 of README.md for the required 3rdparty files and how to install them. - -## Compiling - -Open the appropriate `sln` (Solution) file for your version of Visual Studio: - -- VS 2015: projects/openttd_vs140.sln -- VS 2017: projects/openttd_vs141.sln -- VS 2019: projects/openttd_vs142.sln - -Set the build mode to `Release` in -`Build > Configuration manager > Active solution configuration`. -You can now compile. - -If everything works well the binary should be in `objs\Win[32|64]\Release\openttd.exe` -and in `bin\openttd.exe` - -## Problems - -If compilation fails, double-check that you are using the latest github -source. If it still doesn't work, check in on IRC (irc://irc.oftc.net/openttd), -to ask for help. diff --git a/docs/admin_network.txt b/docs/admin_network.md similarity index 53% rename from docs/admin_network.txt rename to docs/admin_network.md index 904f3ca204..ff5ea7c27a 100644 --- a/docs/admin_network.txt +++ b/docs/admin_network.md @@ -1,23 +1,23 @@ -OpenTTD's admin network +# OpenTTD's admin network + Last updated: 2011-01-20 ------------------------------------------------------------------------- -Table of contents ------------------ -1.0) Preface -2.0) Joining the network -3.0) Asking for updates - * 3.1) Polling manually -4.0) Sending rcon commands -5.0) Sending chat - * 5.1) Receiving chat -6.0) Disconnecting -7.0) Certain packet information +## Table of contents + +- 1.0) [Preface](#10-preface) +- 2.0) [Joining the network](#20-joining-the-network) +- 3.0) [Asking for updates](#30-asking-for-updates) + - 3.1) [Polling manually](#31-polling-manually) +- 4.0) [Sending rcon commands](#40-sending-rcon-commands) +- 5.0) [Sending chat](#50-sending-chat) + - 5.1) [Receiving chat](#51-receiving-chat) +- 6.0) [Disconnecting](#60-disconnecting) +- 7.0) [Certain packet information](#70-certain-packet-information) -1.0) Preface ----- ------- +## 1.0) Preface + The admin network provides a dedicated network protocol designed for other applications to communicate with OpenTTD. Connected applications can execute console commands remotely (rcon commands) with no further authentication. @@ -28,7 +28,7 @@ Table of contents This document describes the admin network and its protocol. - Please refer to the mentioned enums in src/network/core/tcp_admin.h + Please refer to the mentioned enums in `src/network/core/tcp_admin.h` Please also note that further improvements to the admin protocol can mean that more packet types will be sent by the server. For forward compatibility it is @@ -36,94 +36,106 @@ Table of contents additional data to packets. This data should be ignored. Data will never be removed from packets in later versions, except the possibility that complete packets are dropped in favour of a new packet. + This though will be reflected in the protocol version as announced in the - ADMIN_PACKET_SERVER_PROTOCOL in section 2.0). + `ADMIN_PACKET_SERVER_PROTOCOL` in section 2.0). A reference implementation in Java for a client connecting to the admin interface - can be found at: http://dev.openttdcoop.org/projects/joan + can be found at: [http://dev.openttdcoop.org/projects/joan](http://dev.openttdcoop.org/projects/joan) -2.0) Joining the network ----- ------------------- +## 2.0) Joining the network + Create a TCP connection to the server on port 3977. The application is expected to authenticate within 10 seconds. - To authenticate send a ADMIN_PACKET_ADMIN_JOIN packet. + To authenticate send a `ADMIN_PACKET_ADMIN_JOIN` packet. - The server will reply with ADMIN_PACKET_SERVER_PROTOCOL followed directly by - ADMIN_PACKET_SERVER_WELCOME. + The server will reply with `ADMIN_PACKET_SERVER_PROTOCOL` followed directly by + `ADMIN_PACKET_SERVER_WELCOME`. - ADMIN_PACKET_SERVER_PROTOCOL contains details about the protocol version. + `ADMIN_PACKET_SERVER_PROTOCOL` contains details about the protocol version. It is the job of your application to check this number and decide whether it will remain connected or not. - Furthermore, this packet holds details on every AdminUpdateType and the - supported AdminFrequencyTypes (bitwise representation). + Furthermore, this packet holds details on every `AdminUpdateType` and the + supported `AdminFrequencyTypes` (bitwise representation). - ADMIN_PACKET_SERVER_WELCOME contains details on the server and the map, + `ADMIN_PACKET_SERVER_WELCOME` contains details on the server and the map, e.g. if the server is dedicated, its NetworkLanguage, size of the Map, etc. - Once you have received ADMIN_PACKET_SERVER_WELCOME you are connected and + Once you have received `ADMIN_PACKET_SERVER_WELCOME` you are connected and authorized to do your thing. + The server will not provide any game related updates unless you ask for them. There are four packets the server will none the less send, if applicable: + - ADMIN_PACKET_SERVER_ERROR - ADMIN_PACKET_SERVER_WELCOME - ADMIN_PACKET_SERVER_NEWGAME - ADMIN_PACKET_SERVER_SHUTDOWN - However, ADMIN_PACKET_SERVER_WELCOME only after a ADMIN_PACKET_SERVER_NEWGAME + However, `ADMIN_PACKET_SERVER_WELCOME` only after a `ADMIN_PACKET_SERVER_NEWGAME` -3.0) Asking for updates ----- ------------------ - Asking for updates is done with ADMIN_PACKET_ADMIN_UPDATE_FREQUENCY. +## 3.0) Asking for updates + + Asking for updates is done with `ADMIN_PACKET_ADMIN_UPDATE_FREQUENCY`. With this packet you define which update you wish to receive at which frequency. Note: not every update type supports every frequency. If in doubt, you can - verify against the data received in ADMIN_PACKET_SERVER_PROTOCOL. + verify against the data received in `ADMIN_PACKET_SERVER_PROTOCOL`. The server will not confirm your registered update. However, asking for an - invalid AdminUpdateType or a not supported AdminUpdateFrequency you will be - disconnected from the server with NETWORK_ERROR_ILLEGAL_PACKET. + invalid `AdminUpdateType` or a not supported `AdminUpdateFrequency` you will be + disconnected from the server with `NETWORK_ERROR_ILLEGAL_PACKET`. - Additional debug information can be found with a debug level of net=3. + Additional debug information can be found with a debug level of `net=3`. + + `ADMIN_UPDATE_DATE` results in the server sending: - ADMIN_UPDATE_DATE results in the server sending: - ADMIN_PACKET_SERVER_DATE - ADMIN_UPDATE_CLIENT_INFO results in the server sending: + `ADMIN_UPDATE_CLIENT_INFO` results in the server sending: + - ADMIN_PACKET_SERVER_CLIENT_JOIN - ADMIN_PACKET_SERVER_CLIENT_INFO - ADMIN_PACKET_SERVER_CLIENT_UPDATE - ADMIN_PACKET_SERVER_CLIENT_QUIT - ADMIN_PACKET_SERVER_CLIENT_ERROR - ADMIN_UPDATE_COMPANY_INFO results in the server sending: + `ADMIN_UPDATE_COMPANY_INFO` results in the server sending: + - ADMIN_PACKET_SERVER_COMPANY_NEW - ADMIN_PACKET_SERVER_COMPANY_INFO - ADMIN_PACKET_SERVER_COMPANY_UPDATE - ADMIN_PACKET_SERVER_COMPANY_REMOVE - ADMIN_UPDATE_COMPANY_ECONOMY results in the server sending: + `ADMIN_UPDATE_COMPANY_ECONOMY` results in the server sending: + - ADMIN_PACKET_SERVER_COMPANY_ECONOMY - ADMIN_UPDATE_COMPANY_STATS results in the server sending: + `ADMIN_UPDATE_COMPANY_STATS` results in the server sending: + - ADMIN_PACKET_SERVER_COMPANY_STATS - ADMIN_UPDATE_CHAT results in the server sending: + `ADMIN_UPDATE_CHAT` results in the server sending: + - ADMIN_PACKET_SERVER_CHAT - ADMIN_UPDATE_CONSOLE results in the server sending: + `ADMIN_UPDATE_CONSOLE` results in the server sending: + - ADMIN_PACKET_SERVER_CONSOLE - ADMIN_UPDATE_CMD_LOGGING results in the server sending: + `ADMIN_UPDATE_CMD_LOGGING` results in the server sending: + - ADMIN_PACKET_SERVER_CMD_LOGGING -3.1) Polling manually ----- ---------------- - Certain AdminUpdateTypes can also be polled: +## 3.1) Polling manually + + Certain `AdminUpdateTypes` can also be polled: + - ADMIN_UPDATE_DATE - ADMIN_UPDATE_CLIENT_INFO - ADMIN_UPDATE_COMPANY_INFO @@ -131,88 +143,92 @@ Table of contents - ADMIN_UPDATE_COMPANY_STATS - ADMIN_UPDATE_CMD_NAMES - ADMIN_UPDATE_CLIENT_INFO and ADMIN_UPDATE_COMPANY_INFO accept an additional + `ADMIN_UPDATE_CLIENT_INFO` and `ADMIN_UPDATE_COMPANY_INFO` accept an additional parameter. This parameter is used to specify a certain client or company. - Setting this parameter to UINT32_MAX (0xFFFFFFFF) will tell the server you + Setting this parameter to `UINT32_MAX (0xFFFFFFFF)` will tell the server you want to receive updates for all clients or companies. - Not supported AdminUpdateType in the poll will result in the server - disconnecting the application with NETWORK_ERROR_ILLEGAL_PACKET. + Not supported `AdminUpdateType` in the poll will result in the server + disconnecting the application with `NETWORK_ERROR_ILLEGAL_PACKET`. - Additional debug information can be found with a debug level of net=3. + Additional debug information can be found with a debug level of `net=3`. -4.0) Sending rcon commands ----- --------------------- - Rcon runs separate from the ADMIN_UPDATE_CONSOLE AdminUpdateType. Requesting +## 4.0) Sending rcon commands + + Rcon runs separate from the `ADMIN_UPDATE_CONSOLE` `AdminUpdateType`. Requesting the execution of a remote console command is done with the packet - ADMIN_PACKET_ADMIN_RCON. + `ADMIN_PACKET_ADMIN_RCON`. Note: No additional authentication is required for rcon commands. - The server will reply with one or more ADMIN_PACKET_SERVER_RCON packets. - Finally an ADMIN_PACKET_ADMIN_RCON_END packet will be sent. Applications - will not receive the answer twice if they have asked for the AdminUpdateType - ADMIN_UPDATE_CONSOLE, as the result is not printed on the servers console + The server will reply with one or more `ADMIN_PACKET_SERVER_RCON` packets. + Finally an `ADMIN_PACKET_ADMIN_RCON_END` packet will be sent. Applications + will not receive the answer twice if they have asked for the `AdminUpdateType` + `ADMIN_UPDATE_CONSOLE`, as the result is not printed on the servers console (just like clients rcon commands). - Furthermore, sending a 'say' command (or any similar command) will not + Furthermore, sending a `say` command (or any similar command) will not be sent back into the admin network. Chat from the server itself will only be sent to the admin network when it was not sent from the admin network. Note that when content is queried or updated via rcon, the processing - happens asynchronously. But the ADMIN_PACKET_ADMIN_RCON_END packet is sent + happens asynchronously. But the `ADMIN_PACKET_ADMIN_RCON_END` packet is sent already right after the content is requested as there's no immediate output. Thus other packages and the output of content rcon command may be sent at an arbitrary later time, mixing into the output of other console activity, e.g. also of possible subsequent other rcon commands sent. -5.0) Sending chat ----- ------------ - Sending a ADMIN_PACKET_ADMIN_CHAT results in chat originating from the server. +## 5.0) Sending chat + + Sending a `ADMIN_PACKET_ADMIN_CHAT` results in chat originating from the server. Currently four types of chat are supported: + - NETWORK_ACTION_CHAT - NETWORK_ACTION_CHAT_CLIENT - NETWORK_ACTION_CHAT_COMPANY - NETWORK_ACTION_SERVER_MESSAGE - NETWORK_ACTION_SERVER_MESSAGE can be sent to a single client or company - using the respective DestType and ID. - This is a message prefixed with the 3 stars, e.g. *** foo has joined the game + `NETWORK_ACTION_SERVER_MESSAGE` can be sent to a single client or company + using the respective `DestType` and ID. + This is a message prefixed with the 3 stars, e.g. `*** foo has joined the game` -5.1) Receiving chat ----- ------------- - Register ADMIN_UPDATE_CHAT at ADMIN_FREQUENCY_AUTOMATIC to receive chat. +## 5.1) Receiving chat + + Register `ADMIN_UPDATE_CHAT` at `ADMIN_FREQUENCY_AUTOMATIC` to receive chat. The application will be able to receive all chat the server can see. - The configuration option network.server_admin_chat specifies whether + The configuration option `network.server_admin_chat` specifies whether private chat for to the server is distributed into the admin network. -6.0) Disconnecting ----- ------------- +## 6.0) Disconnecting + It is a kind thing to say good bye before leaving. Do this by sending the - ADMIN_PACKET_ADMIN_QUIT packet. + `ADMIN_PACKET_ADMIN_QUIT` packet. -7.0) Certain packet information ----- -------------------------- - All ADMIN_PACKET_SERVER_* packets have an enum value greater 100. +## 7.0) Certain packet information - ADMIN_PACKET_SERVER_WELCOME - Either directly follows ADMIN_PACKET_SERVER_PROTOCOL or is sent + All `ADMIN_PACKET_SERVER_*` packets have an enum value greater 100. + + `ADMIN_PACKET_SERVER_WELCOME` + + Either directly follows `ADMIN_PACKET_SERVER_PROTOCOL` or is sent after a new game has been started or a map loaded, i.e. also after ADMIN_PACKET_SERVER_NEWGAME. - ADMIN_PACKET_SERVER_CLIENT_JOIN and ADMIN_PACKET_SERVER_COMPANY_NEW + `ADMIN_PACKET_SERVER_CLIENT_JOIN` and `ADMIN_PACKET_SERVER_COMPANY_NEW` + These packets directly follow their respective INFO packets. If you receive a CLIENT_JOIN / COMPANY_NEW packet without having received the INFO packet it may be a good idea to POLL for the specific ID. - ADMIN_PACKET_SERVER_CMD_NAMES and ADMIN_PACKET_SERVER_CMD_LOGGING + `ADMIN_PACKET_SERVER_CMD_NAMES` and `ADMIN_PACKET_SERVER_CMD_LOGGING` + Data provided with these packets is not stable and will not be treated as such. Do not rely on IDs or names to be constant across different versions / revisions of OpenTTD. diff --git a/docs/compiling_lang_files.md b/docs/compiling_lang_files.md new file mode 100644 index 0000000000..234fcf2a65 --- /dev/null +++ b/docs/compiling_lang_files.md @@ -0,0 +1,69 @@ +# How to compile lang files (OpenTTD and strgen) + +Last updated: 2009-06-30 + +## strgen usage + +This guide is only interesting for people who want to alter something +themselves without access to [translator.openttd.org](https://translator.openttd.org/). + +Please note that your compiled language file will only be compatible with the OpenTTD version +you have downloaded `english.txt`, the master language file, for. While this is +not always true, namely when changes in the code have not touched language +files, your safest bet is to assume this 'limitation'. + +As a first step you need to compile strgen. This is as easy as typing +`'make strgen'`. You can download the precompile strgen from: +[http://www.openttd.org/download-strgen](http://www.openttd.org/download-strgen) + +strgen takes as argument a txt file and translates it to a lng file, allowing +it to be used inside OpenTTD. strgen needs the master language file +`english.txt` to work. Below are some examples of strgen usage. + +## Examples + +### Example 1 + +If you are in the root of your working copy (git repository), you should type +`./strgen/strgen -s lang lang/english.txt` +to compile `english.txt` into `english.lng`. It will be placed in the lang dir. + +### Example 2 + +You only have the strgen executable (no working copy) and you want to compile +a txt file in the same directory. You should type +`./strgen english.txt` +and you will get and `english.lng` in the same dir. + +### Example 3 + +You have strgen somewhere, `english.txt` in `/usr/openttd/lang` and you want the +resulting language file to go to /tmp. Use +`./strgen -s /usr/openttd/lang -d /tmp english.txt` + +You can interchange `english.txt` to whichever language you want to generate a +.lng file for. + +## strgen command switches + +`-v | --version` +strgen will tell what git revision it was last modified + +`-t | --todo` +strgen will add to any untranslated/missing strings and use the english +strings while compiling the language file + +`-w | --warning` +strgen will print any missing strings or wrongly translated (bad format) +to standard error output(stderr) + +`-h | --help | -?` +Print out a summarized help message explaining these switches + +`-s | --source_dir` +strgen will search for the master file english.txt in the directory specified +by this switch instead of the current directory + +`-d | --dest_dir` +strgen will put .lng in the directory specified by this switch; if +no dest_dir is given, output is the same as source_dir diff --git a/docs/debugging_desyncs.md b/docs/debugging_desyncs.md new file mode 100644 index 0000000000..f5ea06e082 --- /dev/null +++ b/docs/debugging_desyncs.md @@ -0,0 +1,56 @@ +# Debugging / reporting desyncs + +As desyncs are hard to make reproducible OpenTTD has the ability to log all +actions done by clients so we can replay the whole game in an effort to make +desyncs better reproducible. You need to turn this ability on. When turned +on an automatic savegame will be made once the map has been constructed in +the 'save/autosave' directory, see OpenTTD directories to know where to find +this directory. Furthermore the log file 'commands-out.log' will be created +and all actions will be written to there. + +To enable the desync debugging you need to set the debug level for 'desync' +to at least 1. You do this by starting OpenTTD with '`-d desync=`' as +parameter or by typing '`debug_level desync=`' in OpenTTD's internal +console. +The desync debug levels are: + +- 0: nothing. +- 1: dumping of commands to 'commands-out.log'. +- 2: same as 1 plus checking vehicle caches and dumping that too. +- 3: same as 2 plus monthly saves in autosave. +- 4 and higher: same as 3 + +Restarting OpenTTD will overwrite 'commands-out.log'. OpenTTD will not remove +the savegames (dmp_cmds_*.sav) made by the desync debugging system, so you +have to occasionally remove them yourself! + +The naming format of the desync savegames is as follows: +dmp_cmds_XXXXXXXX_YYYYYYYY.sav. The XXXXXXXX is the hexadecimal representation +of the generation seed of the game and YYYYYYYY is the hexadecimal +representation of the date of the game. This sorts the savegames by game and +then by date making it easier to find the right savegames. + +When a desync has occurred with the desync debugging turned on you should file +a bug report with the following files attached: + +- commands-out.log as it contains all the commands that were done +- the last saved savegame (search for the last line beginning with + 'save: dmp_cmds_' in commands-out.log). We use this savegame to check + whether we can quickly reproduce the desync. Otherwise we will need … +- the first saved savegame (search for the first line beginning with 'save' + where the first part, up to the last underscore '_', is the same). We need + this savegame to be able to reproduce the bug when the last savegame is not + old enough. If you loaded a scenario or savegame you need to attach that. +- optionally you can attach the savegames from around 50%, 75%, 85%, 90% and + 95% of the game's progression. We can use these savegames to speed up the + reproduction of the desync, but we should be able to reproduce these + savegames based on the first savegame and commands-out.log. +- in case you use any NewGRFs you should attach the ones you used unless + we can easily find them ourselves via bananas or when they are in the + #openttdcoop pack. + +Do NOT remove the dmp_cmds savegames of a desync you have reported until the +desync has been fixed; if you, by accident, send us the wrong savegames we +will not be able to reproduce the desync and thus will be unable to fix it. + + diff --git a/docs/desync.txt b/docs/desync.md similarity index 90% rename from docs/desync.txt rename to docs/desync.md index b0b6bd7d47..20003c9810 100644 --- a/docs/desync.txt +++ b/docs/desync.md @@ -1,25 +1,24 @@ -Some explanations about Desyncs +# Some explanations about Desyncs + Last updated: 2014-02-23 ------------------------------------------------------------------------- + +## Table of contents + +- 1.0) Desync theory + - 1.1) [OpenTTD multiplayer architecture](#11-openttd-multiplayer-architecture) + - 1.2) [What is a Desync and how is it detected](#12-what-is-a-desync-and-how-is-it-detected) + - 1.3) [Typical causes of Desyncs](#13-typical-causes-of-desyncs) +- 2.0) What to do in case of a Desync + - 2.1) [Cache debugging](#21-cache-debugging) + - 2.2) [Desync recording](#22-desync-recording) +- 3.0) Evaluating the Desync records + - 3.1) [Replaying](#31-replaying) + - 3.2) [Evaluation of the replay](#32-evaluation-of-the-replay) + - 3.3) [Comparing savegames](#33-comparing-savegames) -Table of contents ------------------ -1.0) Desync theory - * 1.1) OpenTTD multiplayer architecture - * 1.2) What is a Desync and how is it detected - * 1.3) Typical causes of Desyncs -2.0) What to do in case of a Desync - * 2.1) Cache debugging - * 2.2) Desync recording -3.0) Evaluating the Desync records - * 3.1) Replaying - * 3.2) Evaluation the replay - * 3.3) Comparing savegames +## 1.1) OpenTTD multiplayer architecture - -1.1) OpenTTD multiplayer architecture ----- -------------------------------- OpenTTD has a huge gamestate, which changes all of the time. The savegame contains the complete gamestate at a specific point in time. But this state changes completely each tick: Vehicles move @@ -30,7 +29,7 @@ Table of contents in the same way, and trees always grow the same. In OpenTTD multiplayer synchronisation works by creating a savegame - when clients join, and then transfering that savegame to the client, + when clients join, and then transferring that savegame to the client, so it has the complete gamestate at a fixed point in time. Afterwards clients only receive 'commands', that is: Stuff which is @@ -69,8 +68,8 @@ Table of contents clients, which execute the command simultaneously in the same network frame in the same order. -1.2) What is a Desync and how is it detected ----- --------------------------------------- +## 1.2) What is a Desync and how is it detected + In the ideal case all clients have the same gamestate as the server and run in sync. That is, vehicle movement is the same on all clients, and commands are executed the same everywhere and @@ -81,7 +80,7 @@ Table of contents that a vehicle picks the left line instead of the right line at a junction on one client. - The important thing here is, that noone notices when a Desync + The important thing here is, that no one notices when a Desync occurs. The desync client will continue to simulate the gamestate and execute commands from the server. Once the gamestate differs it will increasingly spiral out of control: If a vehicle picks a @@ -108,12 +107,12 @@ Table of contents indication on when the Desync happened. The Desync may after all have occurred long ago, and just did not affect the checksum up to now. The checksum may have matched 10 times or more - since the Desync happend, and only now the Desync has spiraled + since the Desync happened, and only now the Desync has spiraled enough to finally affect the checksum. (There was once a desync which was only noticed by the checksum after 20 game years.) -1.3) Typical causes of Desyncs ----- ------------------------- +## 1.3) Typical causes of Desyncs + Desyncs can be caused by the following scenarios: - The savegame does not describe the complete gamestate. - Some information which affects the progression of the @@ -138,9 +137,9 @@ Table of contents using commands. -2.1) Cache debugging ----- --------------- - Desyncs which are caused by inproper cache validation can +## 2.1) Cache debugging + + Desyncs which are caused by improper cache validation can often be found by enabling cache validation: - Start OpenTTD with '-d desync=2'. - This will enable validation of caches every tick. @@ -151,8 +150,8 @@ Table of contents Mind that this type of debugging can also be done in singleplayer. -2.2) Desync recording ----- ---------------- +## 2.2) Desync recording + If you have a server, which happens to encounter Desyncs often, you can enable recording of the gamestate alterations. This will later allow the replay the gamestate and locate the Desync @@ -180,8 +179,8 @@ Table of contents However, they also take a lot of disk space. -3.1) Replaying ----- --------- +## 3.1) Replaying + To replay a Desync recording, you need these files: - The savegame from when the server was started, resp. the automatically created savegame from when the map @@ -201,8 +200,8 @@ Table of contents This replays the server log and creates new 'commands-out.log' and 'dmp_cmds_*.sav' in your autosave folder. -3.2) Evaluation the replay ----- --------------------- +## 3.2) Evaluation of the replay + The replaying will also compare the checksums which are part of the 'commands-out.log' with the replayed gamestate. If they differ, it will trigger a 'NOT_REACHED'. @@ -242,8 +241,8 @@ Table of contents dates, and the original log will contain the chat, but otherwise they should match. -3.2) Comparing savegames ----- ------------------- +## 3.3) Comparing savegames + The binary form of the savegames from the original server and from your replay will always differ: - The savegame contains paths to used NewGRF files. diff --git a/docs/directory_structure.md b/docs/directory_structure.md new file mode 100644 index 0000000000..51ad1c5a3e --- /dev/null +++ b/docs/directory_structure.md @@ -0,0 +1,130 @@ +# OpenTTD directory structure + +OpenTTD uses its own directory to store its required 3rd party base set files +(see section 4.1 'Required 3rd party files') and non-compulsory extension and +configuration files. + +See below for their proper place within this OpenTTD main data directory. + +The main OpenTTD directories can be found in various locations, depending on +your operating system: + +1. The current working directory (from where you started OpenTTD) + + For non-Windows operating systems OpenTTD will not scan for files in this + directory if it is your personal directory, i.e. '~/', or when it is the + root directory, i.e. '/'. + +2. Your personal directory + - Windows: + - `C:\My Documents\OpenTTD` (95, 98, ME) + - `C:\Documents and Settings\\My Documents\OpenTTD` (2000, XP) + - `C:\Users\\Documents\OpenTTD` (Vista, 7, 8.1, 10) + - macOS: `~/Documents/OpenTTD` + - Linux: `$XDG_DATA_HOME/openttd` which is usually `~/.local/share/openttd` + when built with XDG base directory support, otherwise `~/.openttd` +3. The shared directory + - Windows: + - `C:\Documents and Settings\All Users\Shared Documents\OpenTTD` (2000, XP) + - `C:\Users\Public\Documents\OpenTTD` (Vista, 7, 8.1, 10) + - macOS: `/Library/Application Support/OpenTTD` + - Linux: not available +4. The binary directory (where the OpenTTD executable is) + - Windows: `C:\Program Files\OpenTTD` + - Linux: `/usr/games` +5. The installation directory (Linux only) + - Linux: `/usr/share/games/openttd` +6. The application bundle (macOS only) + + It includes the OpenTTD files (grf+lng) and it will work as long as they + are not touched + +Different types of data or extensions go into different subdirectories of the +chosen main OpenTTD directory: + +| data type | directory | additional info | +| ------------------- | ----------------- | --------------------------- | +| Config File | (no subdirectory) | | +| Screenshots | screenshot | | +| Base Graphics | baseset | (or a subdirectory thereof) | +| Sound Sets | baseset | (or a subdirectory thereof) | +| NewGRFs | newgrf | (or a subdirectory thereof) | +| 32bpp Sets | newgrf | (or a subdirectory thereof) | +| Music Sets | baseset | (or a subdirectory thereof) | +| AIs | ai | (or a subdirectory thereof) | +| AI Libraries | ai/library | (or a subdirectory thereof) | +| Game Scripts (GS) | game | (or a subdirectory thereof) | +| GS Libraries | game/library | (or a subdirectory thereof) | +| Savegames | save | | +| Automatic Savegames | save/autosave | | +| Scenarios | scenario | | + +The (automatically created) directory content_download is for OpenTTD's internal +use and no files should be added to it or its subdirectories manually. + +## Notes: + +- Linux in the previous list means .deb, but most paths should be similar for + others. +- The previous search order is also used for NewGRFs and openttd.cfg. +- If openttd.cfg is not found, then it will be created using the 2, 4, 1, 3, + 5 order. When built with XDG base directory support, openttd.cfg will be + created in $XDG_CONFIG_HOME/openttd which is usually ~/.config/openttd. +- Savegames will be relative to the config file only if there is no save/ + directory in paths with higher priority than the config file path, but + autosaves and screenshots will always be relative to the config file. + Unless the configuration file is in $XDG_CONFIG_HOME/openttd, then all + other files will be saved under $XDG_DATA_HOME/openttd. + +## The preferred setup: + +Place 3rd party files in shared directory (or in personal directory if you do +not have write access on shared directory) and have your openttd.cfg config +file in personal directory (where the game will then also place savegames and +screenshots). + +## Portable installations (portable media) + +You can install OpenTTD on external media so you can take it with you, i.e. +using a USB key, or a USB HDD, etc. +Create a directory where you shall store the game in (i.e. OpenTTD/). +Copy the binary (OpenTTD.exe, OpenTTD.app, openttd, etc), baseset/ and your +openttd.cfg to this directory. +You can copy binaries for any operating system into this directory, which will +allow you to play the game on nearly any computer you can attach the external +media to. +As always - additional grf files are stored in the newgrf/ dir (for details, +again, see section 4.1). + +## Files in tar (archives) + +OpenTTD can read files that are in an uncompressed tar (archive), which +makes it easy to bundle files belonging to the same script, NewGRF or base +set. Music sets are the only exception as they cannot be stored in a tar +file due to being played by external applications. + +OpenTTD sees each tar archive as the 'root' of its search path. This means that +having a file with the same path in two different tar files means that one +cannot be opened, after all only one file will be found first. As such it is +advisable to put an uniquely named folder in the root of the tar and put all the +content in that folder. For example, all downloaded content has a path that +concatenates the name of the content and the version, which makes the path +unique. For custom tar files it is advised to do this as well. + +The normal files are also referred to by their relative path from the search +directory, this means that also normal files could hide files in a tar as +long as the relative path from the search path of the normal file is the +same as the path in the tar file. Again it is advised to have an unique path +to the normal file so they do not collide with the files from other tar +files. + +## Configuration file + +The configuration file for OpenTTD (openttd.cfg) is in a simple Windows-like +.INI format. It is mostly undocumented. Almost all settings can be changed +ingame by using the 'Advanced Settings' window. + +When you cannot find openttd.cfg you should look in the directories as +described in this document. If you do not have an openttd.cfg OpenTTD will +create one after closing. + diff --git a/docs/landscape.html b/docs/landscape.html index d4d8f7efeb..4eac0926e7 100644 --- a/docs/landscape.html +++ b/docs/landscape.html @@ -16,7 +16,7 @@ Landscape grid page.

Nine attributes (counting "type" and - "height") hold the informations about a tile.
+ "height") hold the information about a tile.
These attributes are referred to as "type", "height", @@ -61,7 +61,7 @@ Bits 1..0: - + @@ -98,6 +98,32 @@ +
  • m4:
    + + Road roadtype. Used for all tiles with road (road, station, tunnelbridge). +
      +
    • + Bits 5..0: Road roadtype, 0x3F for no road. +
    • +
    +
  • +
  • m8:
    + + Tram roadtype. Used for all tiles with road (road, station, tunnelbridge). +
      +
    • + Bits 11..6: Tram roadtype, 0x3F for no tram. +
    • +
    +
  • +
  • m8:
    +
      +
    • + + Bits 5..0: Railtype. Used for all tiles with rail (road, rail, station, tunnelbridge). +
    • +
    +
  • m7:
    Animation frame/state. Used for houses, industries, objects and stations.
  • @@ -108,7 +134,7 @@
    Only meaningfull in tropic climate. It contains the definition of the available zones
    Only meaningful in tropic climate. It contains the definition of the available zones
    00normal
    01desert
    02rain forest
    - + @@ -223,6 +249,7 @@
    ClassMeaning & details of encodingMeaning & details of encoding
    0  
      +
    • m1 bit 7: Ship docking tile status (for half-tile with water)
    • m1 bits 4..0: owner of the tile
    • m2: see signals
    • m3 bits 7..4: see signals
    • @@ -535,21 +562,10 @@
    • m2: Index into the array of towns (owning town for town roads; closest town otherwise, INVALID_TOWN if there is no town or we are creating a town)
    • -
    • m7 bit 5 set = on snow or desert
    • -
    • m7 bits 7..6: present road types - - - - - - - - - - -
      bit 0  normal road
      bit 1  tram
      -
    • m3 bits 7..4: owner of road type 1 (tram); OWNER_NONE (10) is stored as OWNER_TOWN (0F) +
    • m4 bits 5..0: Roadtype
    • +
    • m7 bit 5 set = on snow or desert
    • +
    • m8 bits 11..6: Tramtype
    • m5 bits 7 clear: road or level-crossing
      • m6 bits 5..3: @@ -744,7 +760,7 @@
    - Newhouses is the name englobing a newGRF feature developped by TTDPatch devs (mainly Csaboka).
    + Newhouses is the name englobing a newGRF feature developed by TTDPatch devs (mainly Csaboka).
    It allows the replacement of the properties as well as the graphics of houses in the game.
    To distinguish between the standard behaviour and the newGRF one, HouseID (m4 + m3[6]) is tested for anything above 110.
    110 is the count of standard houses. So above 110 means there is a new definition of at least one house
    @@ -856,12 +872,14 @@
     
      +
    • m1 bit 7: Ship docking tile status (for buoys)
    • m1 bits 6..5: water class for buoys, water part of docks and for airport tiles
    • m1 bits 4..0: owner of the station
    • m2: index into the array of stations
    • m3 bits 7..4: persistent random data for railway stations/waypoints and airports)
    • m3 bits 7..4: owner of tram tracks (road stop)
    • m4: custom station id; 0 means standard graphics
    • +
    • m4: Roadtype for road stops
    • m5: graphics index (range from 0..255 for each station type): @@ -977,8 +995,8 @@
    • m6 bit 2: pbs reservation state for railway stations/waypoints
    • m7 bits 4..0: owner of road (road stops)
    • -
    • m7 bits 7..6: present road types (road stops)
    • m7: animation frame (railway stations/waypoints, airports)
    • +
    • m8 bits 11..6: Tramtype
    • m8 bits 5..0: track type for railway stations/waypoints
    • @@ -992,6 +1010,7 @@ diff --git a/docs/landscape_grid.html b/docs/landscape_grid.html index 4948366e65..d4a88d0bb5 100644 --- a/docs/landscape_grid.html +++ b/docs/landscape_grid.html @@ -100,7 +100,7 @@ the array so you can quickly see what is used and what is not. - + @@ -143,11 +143,11 @@ the array so you can quickly see what is used and what is not. - + - - + + @@ -159,8 +159,8 @@ the array so you can quickly see what is used and what is not. - - + + @@ -169,11 +169,11 @@ the array so you can quickly see what is used and what is not. - + - - + + @@ -208,7 +208,7 @@ the array so you can quickly see what is used and what is not. - + @@ -237,11 +237,11 @@ the array so you can quickly see what is used and what is not. - + - - + + @@ -300,7 +300,7 @@ the array so you can quickly see what is used and what is not. - + @@ -354,14 +354,14 @@ the array so you can quickly see what is used and what is not. - + - + - - + + @@ -370,7 +370,7 @@ the array so you can quickly see what is used and what is not. - + diff --git a/docs/linkgraph.txt b/docs/linkgraph.md similarity index 87% rename from docs/linkgraph.txt rename to docs/linkgraph.md index 2515185a4a..1480bd9145 100644 --- a/docs/linkgraph.txt +++ b/docs/linkgraph.md @@ -1,13 +1,13 @@ -Some clarifications about the link graph ----------------------------------------- +# Some clarifications about the link graph -InitializeLinkGraphs joins all threads, so if the game is abandoned +`InitializeLinkGraphs` joins all threads, so if the game is abandoned with some threads still running, they're joined as soon as the next game -(possibly the title game) is started. See also InitializeGame. +(possibly the title game) is started. See also `InitializeGame`. The MCF (multi-commodity flow) algorithm can be quite CPU-hungry as it's NP-hard and takes exponential time (though with a very small constant factor) in the number of nodes. + This is why it is run in a separate thread where possible. However after some time the thread is joined and if it hasn't finished by then the game will hang. This problem gets worse if we are running on a platform without diff --git a/docs/logging_and_performance_metrics.md b/docs/logging_and_performance_metrics.md new file mode 100644 index 0000000000..1f5866aba0 --- /dev/null +++ b/docs/logging_and_performance_metrics.md @@ -0,0 +1,141 @@ +# Logging, frame rate and performance metrics + +## 1.0) Logging of potentially dangerous actions + +OpenTTD is a complex program, and together with NewGRF, it may show a buggy +behaviour. But not only bugs in code can cause problems. There are several +ways to affect game state possibly resulting in program crash or multiplayer +desyncs. + +Easier way would be to forbid all these unsafe actions, but that would affect +game usability for many players. We certainly do not want that. +However, we receive bug reports because of this. To reduce time spent with +solving these problems, these potentially unsafe actions are logged in +the savegame (including crash.sav). Log is stored in crash logs, too. + +Information logged: + +- Adding / removing / changing order of NewGRFs +- Changing NewGRF parameters, loading compatible NewGRF +- Changing game mode (scenario editor <-> normal game) +- Loading game saved in a different OpenTTD / TTDPatch / Transport Tycoon Deluxe / + original Transport Tycoon version +- Running a modified OpenTTD build +- Changing settings affecting NewGRF behaviour (non-network-safe settings) +- Triggering NewGRF bugs + +No personal information is stored. + +You can show the game log by typing 'gamelog' in the console or by running +OpenTTD in debug mode. + +## 2.0) Frame rate and performance metrics + +The Help menu in-game has a function to open the Frame rate window. This +window shows various real-time performance statistics, measuring what parts +of the game require the most processing power currently. + +A summary of the statistics can also be retrieved from the console with the +`fps` command. This is especially useful on dedicated servers, where the +administrator might want to determine what's limiting performance in a slow +game. + +The frame rate is given as two figures, the simulation rate and the graphics +frame rate. Usually these are identical, as the screen is rendered exactly +once per simulated tick, but in the future there might be support for graphics +and simulation running at different rates. When the game is paused, the +simulation rate drops to zero. + +In addition to the simulation rate, a game speed factor is also calculated. +This is based on the target simulation speed, which is 30 milliseconds per +game tick. At that speed, the expected frame rate is 33.33 frames/second, and +the game speed factor is how close to that target the actual rate is. When +the game is in fast forward mode, the game speed factor shows how much +speed up is achieved. + +The lower part of the window shows timing statistics for individual parts of +the game. The times shown are short-term and long-term averages of how long +it takes to process one tick of game time, all figures are in milliseconds. + +Clicking a line in the lower part of the window opens a graph window, giving +detailed readings on each tick simulated by the game. + +The following is an explanation of the different statistics: + +- *Game loop* - Total processing time used per simulated "tick" in the game. + This includes all pathfinding, world updates, and economy handling. +- *Cargo handling* - Time spent loading/unloading cargo at stations, and + industries and towns sending/retrieving cargo from stations. +- *Train ticks*, *Road vehicle ticks*, *Ship ticks*, *Aircraft ticks* - + Time spent on pathfinding and other processing for each player vehicle type. +- *World ticks* - Time spent on other world/landscape processing. This + includes towns growing, building animations, updates of farmland and trees, + and station rating updates. +- *GS/AI total*, *Game script*, and *AI players* - Time spent running logic + for game scripts and AI players. The total may show as less than the current + sum of the individual scripts, this is because AI players at lower + difficulty settings do not run every game tick, and hence contribute less + to the average across all ticks. Keep in mind that the "Current" figure is + also an average, just only over short term. +- *Link graph delay* - Time overruns of the cargo distribution link graph + update thread. Usually the link graph is updated in a background thread, + but these updates need to synchronise with the main game loop occasionally, + if the time spent on link graph updates is longer than the time taken to + otherwise simulate the game while it was updating, these delays are counted + in this figure. +- *Graphics rendering* - Total time spent rendering all graphics, including + both GUI and world viewports. This typically spikes when panning the view + around, and when more things are happening on screen at once. +- *World viewport rendering* - Isolated time spent rendering just world + viewports. If this figure is significantly lower than the total graphics + rendering time, most time is spent rendering GUI than rendering world. +- *Video output* - Speed of copying the rendered graphics to the display + adapter. Usually this should be very fast (in the range of 0-3 ms), large + values for this can indicate a graphics driver problem. +- *Sound mixing* - Speed of mixing active audio samples together. Usually + this should be very fast (in the range of 0-3 ms), if it is slow, consider + switching to the NoSound set. + +If the frame rate window is shaded, the title bar will instead show just the +current simulation rate and the game speed factor. + +## 3.0) NewGRF callback profiling + +NewGRF developers can profile callback chains via the `newgrf_profile` +console command. The command controls a profiling mode where every sprite +request is measured and logged, and written to a CSV file in the end. + +The NewGRF developer tools need to be enabled for the command to function. + +View the syntax for the command in-game with the console command +`help newgrf_profile`. + +Profiling only works during game or in the editor, it's not possible to +profile across the main menu, world generation, or loading savegames. + +The CSV files contain one line per sprite request during the profiling. +They can get very large, especially on large games with many objects from +the GRF. Start profiling short periods such as 3 or 7 days, and watch the +file sizes. + +The produced CSV file contains the following fields: + +- *Tick* - Game tick counter, this may wrap to zero during recording. + Mainly useful to distinguish events from separate ticks. +- *Sprite* - Index of the root Action 2 sprite in the GRF file. This is + the sprite group being resolved. +- *Feature* - NewGRF feature number the sprite group is being resolved for. + This will be 0xFF for AI purchase selection and ambient sound callbacks. +- *Item* - The id of the item within the GRF. For cargotypes, railtypes, + roadtypes, and tramtypes, this is the integer representation of the label. +- *CallbackID* - The type of callback being resolved. ID 0 is regular graphics + lookup. See the `newgrf_callbacks.h` file in the OpenTTD source code for the + full list of callback IDs. +- *Microseconds* - Total time spent to resolve the Action 2, in microseconds. +- *Depth* - Number of recursive Action 2 lookups were made during resolution. + Value zero means the sprite group resolved directly. +- *Result* - Result of the callback resolution. For lookups that result in + a sprite, this is the index of the base action 2 in the GRF file. For + callbacks that give a numeric result, this is the callback result value. + For lookups that result in an industry production or tilelayout, this + is the sprite index of the action 2 defining the production/tilelayout. diff --git a/docs/multiplayer.txt b/docs/multiplayer.md similarity index 85% rename from docs/multiplayer.txt rename to docs/multiplayer.md index 62314d7b4c..89a490602e 100644 --- a/docs/multiplayer.txt +++ b/docs/multiplayer.md @@ -1,28 +1,28 @@ -Multiplayer manual for OpenTTD +# Multiplayer manual for OpenTTD + Last updated: 2011-02-16 ------------------------------------------------------------------------- -Table of contents ------------------ -1.0) Starting a server -2.0) Connecting to a server - * 2.1) Connecting to a server over the console -3.0) Playing internet games -4.0) Tips for servers - * 4.1) Imposing landscaping limits -5.0) Some useful things -6.0) Troubleshooting +## Table of contents + +- 1.0) [Starting a server](#10-starting-a-server) +- 2.0) [Connecting to a server](#20-connecting-to-a-server) + - 2.1) [Connecting to a server over the console](#21-connecting-to-a-server-over-the-console) +- 3.0) [Playing internet games](#30-playing-internet-games) +- 4.0) [Tips for servers](#40-tips-for-servers) + - 4.1)[Imposing landscaping limits](#41-imposing-landscaping-limits) +- 5.0) [Some useful things](#50-some-useful-things) +- 6.0) [Troubleshooting](#60-troubleshooting) -1.0) Starting a server ----- ----------------- +## 1.0) Starting a server + - Make sure that you have your firewall of the computer as well as possible routers or modems of the server configured such that: - * port 3979 is free for both UDP and TCP connections in- and outgoing - * port 3978 is free outbound for UDP in order to advertise with the master + - port 3979 is free for both UDP and TCP connections in- and outgoing + - port 3978 is free outbound for UDP in order to advertise with the master server (if desired). Otherwise you'll have to tell players your IP. - * port 3977 if use of the admin interface is desired (see admin_network.txt) + - port 3977 if use of the admin interface is desired (see admin_network.txt) - Click "multiplayer" on the startup screen - Click "start server" - Type in a game name @@ -33,42 +33,36 @@ Table of contents - Start playing -2.0) Connecting to a server ----- ---------------------- - - Click "multiplayer" on the startup screen +## 2.0) Connecting to a server + - Click "multiplayer" on the startup screen - If you want to connect to any network game in your LAN click on 'LAN', then on 'Find Server' - If you want to see which servers all online on the Internet, click on 'Internet' and 'Find Server' - - If there were more than one server - - select one in the list below the buttons - - click on 'join game' - + - select one in the list below the buttons + - click on 'join game' - If you want to play and you have the ip or hostname of the game server you want connect to. - - click add server - - type in the ip address or hostname - - if you want to add a port use : - + - click add server + - type in the ip address or hostname + - if you want to add a port use : - Now you can select a company and press: "Join company", to help that company - - Or you can press "Spectate game", to spectate the game - - Or you can press "New company", and start your own company (if there are + - Or you can press "Spectate game", to spectate the game + - Or you can press "New company", and start your own company (if there are slots free) - - You see a progressbar how far you are with joining the server. - - Happy playing -2.1) Connecting to a server over the console ----- --------------------------------------- +## 2.1) Connecting to a server over the console + - Open the console and type in the following command: - connect :# + connect `:#` -3.0) Playing internet games ----- ---------------------- +## 3.0) Playing internet games + - Servers with a red dot behind it have a different version then you have. You will not be able to join those servers. @@ -98,8 +92,8 @@ Table of contents NB: changing frame_freq has more effect on the bandwidth then sync_freq. -4.0) Tips for servers ----- ---------------- +## 4.0) Tips for servers + - You can launch a dedicated server by adding -D as parameter. - In UNIX like systems, you can fork your dedicated server by adding -f as parameter. @@ -155,8 +149,8 @@ Table of contents maximum memory usage for packets is: #max_clients * #max_clients * bytes_per_frame * 10 KiB. -4.1) Imposing landscaping limits ----- --------------------------- +### 4.1) Imposing landscaping limits + - You can impose limits on companies by the following 4 settings: - terraform_per_64k_frames - terraform_frame_burst @@ -196,8 +190,8 @@ Table of contents affected by the above settings. -5.0) Some useful things ----- ------------------ +## 5.0) Some useful things + - You can protect your company so nobody else can join uninvited. To do this, set a password in your Company Screen @@ -209,8 +203,8 @@ Table of contents - Servers can now kick players, so don't make them use it! -6.0) Troubleshooting ----- --------------- +## 6.0) Troubleshooting + - My advertising server does not show up in list at servers.openttd.org Run openttd with the '-d net=2' parameter. That will show which incoming communication is received, whether the replies from the master server or diff --git a/findversion.sh b/findversion.sh index a744c6fba8..cd61040088 100755 --- a/findversion.sh +++ b/findversion.sh @@ -1,7 +1,5 @@ #!/bin/sh -# $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. # 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. @@ -63,7 +61,7 @@ if [ -f "$ROOT_DIR/.ottdrev" ]; then # We are an exported source bundle cat $ROOT_DIR/.ottdrev exit -elif [ -d "$ROOT_DIR/.git" ]; then +elif [ -d "$ROOT_DIR/.git" ] || [ -f "$ROOT_DIR/.git" ]; then # We are a git checkout # Refresh the index to make sure file stat info is in sync, then look for modifications git update-index --refresh >/dev/null diff --git a/known-bugs.txt b/known-bugs.txt index 760f3f6465..440a4709ff 100644 --- a/known-bugs.txt +++ b/known-bugs.txt @@ -1,6 +1,6 @@ OpenTTD's known bugs -Last updated: 2019-04-01 -Release version: 1.9.0 +Last updated: 2019-12-25 +Release version: 1.10.0-beta2 ------------------------------------------------------------------------ @@ -220,7 +220,7 @@ Entry- and exit signals are not dragged [#4378]: Station build date is incorrect [#4415]: The tile query tool will show the date of the last (re)construction at the station and not the date of the first construction. This is - due to compatability reasons with NewGRFs and the fact that it is + due to compatibility reasons with NewGRFs and the fact that it is wrong to say that the station is built in a particular year when it was completely destroyed/rebuilt later on. The tile query tool can be fixed by changing the "Build date" text @@ -404,7 +404,7 @@ Some houses and industries are not affected by transparency [#5817]: Involuntary cargo exchange with cargodist via neutral station [#6114]: When two players serve a neutral station at an industry, a cross-company chain for cargo flow can and will be established which can only be - interrupted if one of the players stops competing for the ressources of + interrupted if one of the players stops competing for the resources of that industry. There is an easy fix for this: If you are loading at the shared station make the order "no unload" and if you're unloading make it "no load". Cargodist will then figure out that it should not create diff --git a/media/baseset/no_music.obm b/media/baseset/no_music.obm index fd75cfef32..e395ba0b0e 100644 --- a/media/baseset/no_music.obm +++ b/media/baseset/no_music.obm @@ -1,5 +1,3 @@ -; $Id$ -; ; This represents more or less nothingness ; [metadata] diff --git a/media/baseset/no_sound.obs b/media/baseset/no_sound.obs index e9d5741a0c..fd2430de54 100644 --- a/media/baseset/no_sound.obs +++ b/media/baseset/no_sound.obs @@ -1,5 +1,3 @@ -; $Id$ -; ; This represents more or less nothingness ; [metadata] diff --git a/media/baseset/orig_dos.obg b/media/baseset/orig_dos.obg index f9db843af1..d56a63712f 100644 --- a/media/baseset/orig_dos.obg +++ b/media/baseset/orig_dos.obg @@ -1,5 +1,3 @@ -; $Id$ -; ; This represents the original graphics as on the non-German Transport ; Tycoon Deluxe DOS CD. ; diff --git a/media/baseset/orig_dos.obm b/media/baseset/orig_dos.obm index 9920bfdbe1..0b51c2db84 100644 --- a/media/baseset/orig_dos.obm +++ b/media/baseset/orig_dos.obm @@ -1,5 +1,3 @@ -; $Id$ -; ; This represents the original music as on the Transport ; Tycoon Deluxe for DOS CD. ; diff --git a/media/baseset/orig_dos.obs b/media/baseset/orig_dos.obs index e095b62210..60afc854f0 100644 --- a/media/baseset/orig_dos.obs +++ b/media/baseset/orig_dos.obs @@ -1,5 +1,3 @@ -; $Id$ -; ; This represents the original sounds as on the Transport ; Tycoon Deluxe DOS CD. ; diff --git a/media/baseset/orig_dos_de.obg b/media/baseset/orig_dos_de.obg index 4e12582727..388d685025 100644 --- a/media/baseset/orig_dos_de.obg +++ b/media/baseset/orig_dos_de.obg @@ -1,5 +1,3 @@ -; $Id$ -; ; This represents the original graphics as on the German Transport ; Tycoon Deluxe DOS CD. It contains one broken sprite. ; diff --git a/media/baseset/orig_tto.obm b/media/baseset/orig_tto.obm index ff600d00f6..c572bcf34b 100644 --- a/media/baseset/orig_tto.obm +++ b/media/baseset/orig_tto.obm @@ -1,5 +1,3 @@ -; $Id$ -; ; This represents the original music as on the Transport ; Tycoon (with World Editor) for DOS CD. ; diff --git a/media/baseset/orig_win.obg b/media/baseset/orig_win.obg index 393b5d3013..f01624a25d 100644 --- a/media/baseset/orig_win.obg +++ b/media/baseset/orig_win.obg @@ -1,5 +1,3 @@ -; $Id$ -; ; This represents the original graphics as on the Transport ; Tycoon Deluxe for Windows CD. ; diff --git a/media/baseset/orig_win.obm b/media/baseset/orig_win.obm index b5d4b024ed..11e363fabd 100644 --- a/media/baseset/orig_win.obm +++ b/media/baseset/orig_win.obm @@ -1,5 +1,3 @@ -; $Id$ -; ; This represents the original music as on the Transport ; Tycoon Deluxe for Windows CD. ; @@ -90,7 +88,7 @@ GM_TT19.GM = Funk Central GM_TT20.GM = Jammit GM_TT21.GM = Movin' On -; MIDI timecodes where the playback should attemp to start and stop short. +; MIDI timecodes where the playback should attempt to start and stop short. ; This is to allow fixing undesired silences in original MIDI files. ; However not all music drivers may support this. [timingtrim] diff --git a/media/baseset/orig_win.obs b/media/baseset/orig_win.obs index e1c2c4e11d..7b02372207 100644 --- a/media/baseset/orig_win.obs +++ b/media/baseset/orig_win.obs @@ -1,5 +1,3 @@ -; $Id$ -; ; This represents the original sounds as on the Transport ; Tycoon Deluxe for Windows CD. ; diff --git a/media/baseset/translations.awk b/media/baseset/translations.awk index f15cb43ffe..af5f2b4a8d 100644 --- a/media/baseset/translations.awk +++ b/media/baseset/translations.awk @@ -1,5 +1,3 @@ -# $Id: openttd.desktop.translation.awk 24100 2012-04-08 14:29:31Z rubidium $ - # 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. diff --git a/media/extra_grf/2ccmap.nfo b/media/extra_grf/2ccmap.nfo index 0e99ff8850..39f3fe4947 100644 --- a/media/extra_grf/2ccmap.nfo +++ b/media/extra_grf/2ccmap.nfo @@ -1,6 +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. // 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. diff --git a/media/extra_grf/airport_preview.nfo b/media/extra_grf/airport_preview.nfo index a98fe67000..6efac6e910 100644 --- a/media/extra_grf/airport_preview.nfo +++ b/media/extra_grf/airport_preview.nfo @@ -1,6 +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. // 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. diff --git a/media/extra_grf/airports.nfo b/media/extra_grf/airports.nfo index 45cd25de04..fc03f1d7f3 100644 --- a/media/extra_grf/airports.nfo +++ b/media/extra_grf/airports.nfo @@ -1,6 +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. // 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. diff --git a/media/extra_grf/airports_orig_extra.nfo b/media/extra_grf/airports_orig_extra.nfo index f2a8dc8327..2d649fbd10 100644 --- a/media/extra_grf/airports_orig_extra.nfo +++ b/media/extra_grf/airports_orig_extra.nfo @@ -1,6 +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. // 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. diff --git a/media/extra_grf/aqueduct.nfo b/media/extra_grf/aqueduct.nfo index d9ba739f53..3f9bb97f3d 100644 --- a/media/extra_grf/aqueduct.nfo +++ b/media/extra_grf/aqueduct.nfo @@ -1,6 +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. // 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. diff --git a/media/extra_grf/assemble_nfo.awk b/media/extra_grf/assemble_nfo.awk index cf6b425c1d..f39e6b6b43 100644 --- a/media/extra_grf/assemble_nfo.awk +++ b/media/extra_grf/assemble_nfo.awk @@ -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. # 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. diff --git a/media/extra_grf/autorail.nfo b/media/extra_grf/autorail.nfo index 08aa5ef9fc..9633064c8a 100644 --- a/media/extra_grf/autorail.nfo +++ b/media/extra_grf/autorail.nfo @@ -1,6 +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. // 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. diff --git a/media/extra_grf/canals.nfo b/media/extra_grf/canals.nfo index e464762ee6..7bf8e5ae49 100644 --- a/media/extra_grf/canals.nfo +++ b/media/extra_grf/canals.nfo @@ -1,6 +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. // 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. diff --git a/media/extra_grf/canals_extra.nfo b/media/extra_grf/canals_extra.nfo index 3103886233..e412e2da47 100644 --- a/media/extra_grf/canals_extra.nfo +++ b/media/extra_grf/canals_extra.nfo @@ -1,6 +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. // 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. diff --git a/media/extra_grf/chars.nfo b/media/extra_grf/chars.nfo index 32462f8c1c..8d1acb814f 100644 --- a/media/extra_grf/chars.nfo +++ b/media/extra_grf/chars.nfo @@ -1,6 +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. // 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. diff --git a/media/extra_grf/chars_orig_extra.nfo b/media/extra_grf/chars_orig_extra.nfo index 7979e79450..c5e3efe269 100644 --- a/media/extra_grf/chars_orig_extra.nfo +++ b/media/extra_grf/chars_orig_extra.nfo @@ -1,6 +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. // 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. diff --git a/media/extra_grf/elrails.nfo b/media/extra_grf/elrails.nfo index 7b8e9dace4..93456ecb30 100644 --- a/media/extra_grf/elrails.nfo +++ b/media/extra_grf/elrails.nfo @@ -1,6 +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. // 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. diff --git a/media/extra_grf/fix_graphics.nfo b/media/extra_grf/fix_graphics.nfo index 1144742230..aaad79c0a9 100644 --- a/media/extra_grf/fix_graphics.nfo +++ b/media/extra_grf/fix_graphics.nfo @@ -1,6 +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. // 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. diff --git a/media/extra_grf/flags.nfo b/media/extra_grf/flags.nfo index ab792ef525..3c125ec79a 100644 --- a/media/extra_grf/flags.nfo +++ b/media/extra_grf/flags.nfo @@ -1,6 +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. // 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. diff --git a/media/extra_grf/foundations.nfo b/media/extra_grf/foundations.nfo index 437fcd99eb..7cb4e5e400 100644 --- a/media/extra_grf/foundations.nfo +++ b/media/extra_grf/foundations.nfo @@ -1,6 +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. // 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. diff --git a/media/extra_grf/mono.nfo b/media/extra_grf/mono.nfo index a5f0fe5eaa..f855e8f0ec 100644 --- a/media/extra_grf/mono.nfo +++ b/media/extra_grf/mono.nfo @@ -1,6 +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. // 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. diff --git a/media/extra_grf/oneway.nfo b/media/extra_grf/oneway.nfo index 74264219ec..46f3b8f947 100644 --- a/media/extra_grf/oneway.nfo +++ b/media/extra_grf/oneway.nfo @@ -1,6 +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. // 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. diff --git a/media/extra_grf/openttd.nfo b/media/extra_grf/openttd.nfo index 460007d68e..b0d80824e8 100644 --- a/media/extra_grf/openttd.nfo +++ b/media/extra_grf/openttd.nfo @@ -2,8 +2,6 @@ // (Info version 32) // Format: spritenum imagefile depth xpos ypos xsize ysize xrel yrel zoom flags // -// $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. // 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. diff --git a/media/extra_grf/openttdgui.nfo b/media/extra_grf/openttdgui.nfo index d0fbba0e70..b458073bef 100644 --- a/media/extra_grf/openttdgui.nfo +++ b/media/extra_grf/openttdgui.nfo @@ -1,13 +1,10 @@ -// -// $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. // 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 "OpenTTD GUI graphics" - -1 * 3 05 15 \b 179 // OPENTTD_SPRITE_COUNT + -1 * 3 05 15 \b 184 // OPENTTD_SPRITE_COUNT -1 sprites/openttdgui.png 8bpp 66 8 64 31 -31 7 normal -1 sprites/openttdgui.png 8bpp 146 8 64 31 -31 7 normal -1 sprites/openttdgui.png 8bpp 226 8 64 31 -31 7 normal @@ -187,3 +184,8 @@ -1 sprites/openttdgui_group_livery.png 8bpp 21 0 20 20 0 0 normal -1 sprites/openttdgui_group_livery.png 8bpp 42 0 20 20 0 0 normal -1 sprites/openttdgui_group_livery.png 8bpp 63 0 20 20 0 0 normal + -1 sprites/openttdgui_build_tram.png 8bpp 0 0 20 20 0 0 normal + -1 sprites/openttdgui_convert_road.png 8bpp 0 0 20 20 0 0 normal + -1 sprites/openttdgui_convert_road.png 8bpp 24 0 32 32 0 0 normal + -1 sprites/openttdgui_convert_tram.png 8bpp 0 0 20 20 0 0 normal + -1 sprites/openttdgui_convert_tram.png 8bpp 24 0 32 32 0 0 normal diff --git a/media/extra_grf/openttdgui_build_tram.png b/media/extra_grf/openttdgui_build_tram.png new file mode 100644 index 0000000000..d9af8effe2 Binary files /dev/null and b/media/extra_grf/openttdgui_build_tram.png differ diff --git a/media/extra_grf/openttdgui_convert_road.png b/media/extra_grf/openttdgui_convert_road.png new file mode 100644 index 0000000000..9218e77054 Binary files /dev/null and b/media/extra_grf/openttdgui_convert_road.png differ diff --git a/media/extra_grf/openttdgui_convert_tram.png b/media/extra_grf/openttdgui_convert_tram.png new file mode 100644 index 0000000000..d4a43e7cb7 Binary files /dev/null and b/media/extra_grf/openttdgui_convert_tram.png differ diff --git a/media/extra_grf/orig_extra.nfo b/media/extra_grf/orig_extra.nfo index a1173a58c1..903d96a572 100644 --- a/media/extra_grf/orig_extra.nfo +++ b/media/extra_grf/orig_extra.nfo @@ -2,8 +2,6 @@ // (Info version 32) // Format: spritenum imagefile depth xpos ypos xsize ysize xrel yrel zoom flags // -// $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. // 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. diff --git a/media/extra_grf/palette.nfo b/media/extra_grf/palette.nfo index 4a6ae69505..2a5b8400fc 100644 --- a/media/extra_grf/palette.nfo +++ b/media/extra_grf/palette.nfo @@ -1,6 +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. // 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. diff --git a/media/extra_grf/rivers/arctic.nfo b/media/extra_grf/rivers/arctic.nfo index 646c9ed139..375946fa5f 100644 --- a/media/extra_grf/rivers/arctic.nfo +++ b/media/extra_grf/rivers/arctic.nfo @@ -1,6 +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. // 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. diff --git a/media/extra_grf/rivers/rapids.nfo b/media/extra_grf/rivers/rapids.nfo index f66f3dc445..e03d96ca17 100644 --- a/media/extra_grf/rivers/rapids.nfo +++ b/media/extra_grf/rivers/rapids.nfo @@ -1,6 +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. // 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. diff --git a/media/extra_grf/rivers/temperate.nfo b/media/extra_grf/rivers/temperate.nfo index a5af841b25..261f727be8 100644 --- a/media/extra_grf/rivers/temperate.nfo +++ b/media/extra_grf/rivers/temperate.nfo @@ -1,6 +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. // 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. diff --git a/media/extra_grf/rivers/toyland.nfo b/media/extra_grf/rivers/toyland.nfo index ca65ce1e3b..8b6dedd386 100644 --- a/media/extra_grf/rivers/toyland.nfo +++ b/media/extra_grf/rivers/toyland.nfo @@ -1,6 +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. // 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. diff --git a/media/extra_grf/rivers/tropic.nfo b/media/extra_grf/rivers/tropic.nfo index b1fa4cf3cf..1041bff54c 100644 --- a/media/extra_grf/rivers/tropic.nfo +++ b/media/extra_grf/rivers/tropic.nfo @@ -1,6 +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. // 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. diff --git a/media/extra_grf/roadstops.nfo b/media/extra_grf/roadstops.nfo index dbb70211da..15ede7027a 100644 --- a/media/extra_grf/roadstops.nfo +++ b/media/extra_grf/roadstops.nfo @@ -1,6 +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. // 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. diff --git a/media/extra_grf/shore.nfo b/media/extra_grf/shore.nfo index 7b7c12ad3b..6dccb8487e 100644 --- a/media/extra_grf/shore.nfo +++ b/media/extra_grf/shore.nfo @@ -1,6 +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. // 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. diff --git a/media/extra_grf/signals.nfo b/media/extra_grf/signals.nfo index a2d2591470..8e612ae66c 100644 --- a/media/extra_grf/signals.nfo +++ b/media/extra_grf/signals.nfo @@ -1,6 +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. // 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. diff --git a/media/extra_grf/sloped_tracks.nfo b/media/extra_grf/sloped_tracks.nfo index ed17bc8445..42c257d316 100644 --- a/media/extra_grf/sloped_tracks.nfo +++ b/media/extra_grf/sloped_tracks.nfo @@ -1,6 +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. // 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. diff --git a/media/extra_grf/tramtracks.nfo b/media/extra_grf/tramtracks.nfo index 5a078194b9..f9a190bd75 100644 --- a/media/extra_grf/tramtracks.nfo +++ b/media/extra_grf/tramtracks.nfo @@ -1,13 +1,10 @@ -// -// $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. // 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 "Tram track graphics by PikkaBird" - -1 * 3 05 0B 71 + -1 * 3 05 0B 77 -1 sprites/tramtracks.png 8bpp 18 8 20 13 0 4 normal -1 sprites/tramtracks.png 8bpp 50 8 20 13 0 4 normal -1 sprites/tramtracks.png 8bpp 82 8 64 36 -18 -8 normal @@ -121,3 +118,9 @@ -1 sprites/tramtracks.png 8bpp 722 696 64 23 -31 0 normal -1 sprites/tramtracks.png 8bpp 2 776 64 23 -31 0 normal -1 sprites/tramtracks.png 8bpp 82 776 64 39 -31 -8 normal + -1 sprites/tramtracks_bare_depot.png 8bpp 0 0 64 31 -31 0 normal + -1 sprites/tramtracks_bare_depot.png 8bpp 80 0 62 64 2 -49 normal + -1 sprites/tramtracks_bare_depot.png 8bpp 158 0 64 31 -31 0 normal + -1 sprites/tramtracks_bare_depot.png 8bpp 238 0 62 64 -62 -49 normal + -1 sprites/tramtracks_bare_depot.png 8bpp 318 0 62 64 -62 -49 normal + -1 sprites/tramtracks_bare_depot.png 8bpp 398 0 62 64 2 -49 normal diff --git a/media/extra_grf/tramtracks_bare_depot.png b/media/extra_grf/tramtracks_bare_depot.png new file mode 100644 index 0000000000..d45bcff41e Binary files /dev/null and b/media/extra_grf/tramtracks_bare_depot.png differ diff --git a/media/extra_grf/tunnel_portals.nfo b/media/extra_grf/tunnel_portals.nfo index 711229aab5..ce09308ef6 100644 --- a/media/extra_grf/tunnel_portals.nfo +++ b/media/extra_grf/tunnel_portals.nfo @@ -1,6 +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. // 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. diff --git a/media/openttd.desktop.filter.awk b/media/openttd.desktop.filter.awk index 06cf1106da..125e21b0d7 100644 --- a/media/openttd.desktop.filter.awk +++ b/media/openttd.desktop.filter.awk @@ -1,5 +1,3 @@ -# $Id: openttd.desktop.translation.awk 19884 2010-05-22 19:59:37Z rubidium $ - # 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. diff --git a/media/openttd.desktop.in b/media/openttd.desktop.in index 513ff712df..4a251114c4 100644 --- a/media/openttd.desktop.in +++ b/media/openttd.desktop.in @@ -1,4 +1,3 @@ -# $Id$ # http://standards.freedesktop.org/desktop-entry-spec/desktop-entry-spec-1.0.html [Desktop Entry] Type=Application diff --git a/media/openttd.desktop.translation.awk b/media/openttd.desktop.translation.awk index ee8fdd9700..3187f9ddf1 100644 --- a/media/openttd.desktop.translation.awk +++ b/media/openttd.desktop.translation.awk @@ -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. # 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. diff --git a/os/debian/changelog b/os/debian/changelog index 8c3b0cbf90..6b24aaa7d5 100644 --- a/os/debian/changelog +++ b/os/debian/changelog @@ -1,3 +1,38 @@ +openttd (1.10.0~beta2-0) unstable; urgency=low + + * New upstream release 1.10.0-beta2 + + -- OpenTTD Wed, 25 Dec 2019 00:00:00 +0000 + +openttd (1.10.0~beta1-0) unstable; urgency=low + + * New upstream release 1.10.0-beta1 + + -- OpenTTD Tue, 29 Oct 2019 00:00:00 +0000 + +openttd (1.9.3-0) unstable; urgency=low + + * New upstream release 1.9.3 + + -- OpenTTD Mon, 16 Sep 2019 21:00:00 +0200 + +openttd (1.9.3~RC1-0) unstable; urgency=low + + * New upstream release 1.9.3-RC1 + -- OpenTTD Sat, 07 Sep 2019 23:30:00 +0200 + +openttd (1.9.2-0) unstable; urgency=low + + * New upstream release 1.9.2 + + -- OpenTTD Sun, 07 Jul 2019 23:00:00 +0200 + +openttd (1.9.1-0) unstable; urgency=low + + * New upstream release 1.9.1 + + -- OpenTTD Mon, 08 Apr 2019 20:00:00 +0100 + openttd (1.9.0-0) unstable; urgency=low * New upstream release 1.9.0 @@ -1033,7 +1068,7 @@ openttd (0.4.0-1) unstable; urgency=low openttd (0.3.6-1) unstable; urgency=low * New upstream release - * Modifed Makefile to install xpm icon and scenarios in /usr/share/games/openttd/ + * Modified Makefile to install xpm icon and scenarios in /usr/share/games/openttd/ * Added openttd.32.xpm, openttd.64.xpm was too big -- Matthijs Kooijman Tue, 25 Jan 2005 19:21:08 +0100 diff --git a/os/debian/control b/os/debian/control index 54e14ce5d4..01b66cc494 100644 --- a/os/debian/control +++ b/os/debian/control @@ -3,7 +3,7 @@ Section: games Priority: optional Maintainer: Matthijs Kooijman Uploaders: Jordi Mallach -Build-Depends: debhelper (>= 7.0.50), libsdl-dev, zlib1g-dev, libpng-dev, libfreetype6-dev, libfontconfig-dev, libicu-dev, liblzma-dev, liblzo2-dev +Build-Depends: debhelper (>= 7.0.50), libsdl2-dev, zlib1g-dev, libpng-dev, libfreetype6-dev, libfontconfig-dev, libicu-dev, liblzma-dev, liblzo2-dev Standards-Version: 3.8.4 Vcs-Browser: http://anonscm.debian.org/gitweb/?p=collab-maint/openttd.git Vcs-Git: git://anonscm.debian.org/collab-maint/openttd.git diff --git a/os/debian/rules b/os/debian/rules index dfd39253ef..b5d67670bd 100755 --- a/os/debian/rules +++ b/os/debian/rules @@ -29,7 +29,7 @@ include /usr/share/dpkg/buildflags.mk # to be explicit about the dependencies, in case we're not running in a # clean build root. override_dh_auto_configure: - ./configure $(CROSS) --prefix-dir=/usr --install-dir=debian/openttd --without-allegro --with-zlib --with-sdl --with-png --with-freetype --with-fontconfig --with-icu --with-liblzo2 --with-lzma --without-xdg-basedir --without-iconv --disable-strip CFLAGS="$(CFLAGS) $(CPPFLAGS)" CXXFLAGS="$(CXXFLAGS) $(CPPFLAGS)" LDFLAGS="$(LDFLAGS)" CFLAGS_BUILD="$(CFLAGS) $(CPPFLAGS)" CXXFLAGS_BUILD="$(CXXFLAGS) $(CPPFLAGS)" LDFLAGS_BUILD="$(LDFLAGS)" + ./configure $(CROSS) --prefix-dir=/usr --install-dir=debian/openttd --without-allegro --with-zlib --with-sdl --with-png --with-freetype --with-fontconfig --with-icu-sort --with-liblzo2 --with-lzma --without-xdg-basedir --without-iconv --disable-strip CFLAGS="$(CFLAGS) $(CPPFLAGS)" CXXFLAGS="$(CXXFLAGS) $(CPPFLAGS)" LDFLAGS="$(LDFLAGS)" CFLAGS_BUILD="$(CFLAGS) $(CPPFLAGS)" CXXFLAGS_BUILD="$(CXXFLAGS) $(CPPFLAGS)" LDFLAGS_BUILD="$(LDFLAGS)" # Do some extra installation override_dh_auto_install: diff --git a/os/dos/cwsdpmi/README.licensing b/os/dos/cwsdpmi/README.licensing deleted file mode 100644 index 112b02a087..0000000000 --- a/os/dos/cwsdpmi/README.licensing +++ /dev/null @@ -1,3 +0,0 @@ -The files in this directory are not licensed under the same terms as the -rest of OpenTTD. Licensing details can be found in OpenTTD's readme.txt -and in this directory or subdirectories as well. diff --git a/os/dos/cwsdpmi/cwsdpmi.exe b/os/dos/cwsdpmi/cwsdpmi.exe deleted file mode 100644 index 17e3220023..0000000000 Binary files a/os/dos/cwsdpmi/cwsdpmi.exe and /dev/null differ diff --git a/os/dos/cwsdpmi/cwsdpmi.txt b/os/dos/cwsdpmi/cwsdpmi.txt deleted file mode 100644 index 14b09c4d76..0000000000 --- a/os/dos/cwsdpmi/cwsdpmi.txt +++ /dev/null @@ -1,173 +0,0 @@ -CWSDPMI is Copyright (C) 1995-2000 Charles W Sandmann (sandmann@clio.rice.edu) - 1206 Braelinn, Sugar Land, TX 77479 - -This is release 5. The files in this binary distribution may be redistributed -under the GPL (with source) or without the source code provided: - -* CWSDPMI.EXE or CWSDPR0.EXE are not modified in any way except via CWSPARAM. - -* CWSDSTUB.EXE internal contents are not modified in any way except via - CWSPARAM or STUBEDIT. It may have a COFF image plus data appended to it. - -* Notice to users that they have the right to receive the source code and/or - binary updates for CWSDPMI. Distributors should indicate a site for the - source in their documentation. - -------------------------------------------------------------------------------- - -CWSDPMI was written to provide DPMI services for V2 of DJGPP. It currently -does not support 16-bit DPMI applications, or DPMI applications requiring a -built in extender. It does support virtual memory and hardware interrupt -reflection from real mode to protected mode. DJGPP V1.1x and RSX applications -will also run using this server, which can be used to provide enhanced control -over hardware interrupts. Some DPMI 1.0 extensions (0x506, 0x507, 0x508) have -been implemented. - -CWSDPR0.EXE is an alternate version which runs at ring 0 with virtual memory -disabled. It may be used if access to ring-0 features are desired. It -currently does not switch stacks on HW interrupts, so some DJGPP features -such as SIGINT and SIGFPE are not supported and will generate a double fault -or stack fault error (to be fixed someday). - -CWSDSTUB.EXE is a stub loader image for DJGPP which includes CWSDPMI. This -allows single executable image distributions. You can use the EXE2COFF -program and COPY /B CWSDSTUB.EXE+yourimage yourimage.exe to create a -standalone executable image. - -Some of the internal tuning and configuration parameters may be modified -in the image using CWSPARAM.EXE (see CWSPARAM.DOC). - -If you want to use CWSDPMI with DJGPP, you expand the distribution into the -DJGPP directory tree. CWSDPMI.EXE will be put in the BIN directory with your -DJGPP images and it will automatically be loaded when they run. - -Directions for use (server can be used in either of two different ways): - -1) "cwsdpmi" alone with no parameters will terminate and stay resident - FOR A SINGLE DPMI PROCESS. This means it unloads itself when your - DPMI application exits. This mode is useful in software which needs - DPMI services, since CWSDPMI can be exec'ed and then will unload on exit. - -2) "cwsdpmi -p" will terminate and stay resident until you remove it. - It can be loaded into UMBs with LH. "cwsdpmi -u" will unload the TSR. - -3) The file used for virtual memory swapping, if desired, is controlled - by the "-sc:\cwsdpmi.swp" syntax on the command line. You must specify - either a file with full disk/directory syntax, or "-s-" which disables - virtual memory. - -4) The default swap file name is c:\cwsdpmi.swp, but this can be changed - with the CWSPARAM image, as can some other parameters. - -5) You can disable the DPMI 1.0 extensions by starting the image with the - "cwsdpmi -x" syntax. This feature allows you to run programs developed - under other DPMI providers which do not behave properly with these - extensions enabled (typically use of NULL pointers). - -I would like to give special thanks to DJ Delorie who wrote the original -GO32 code on which CWSDPMI is based. Morten Welinder also provided and -improved much of the code in this program. - -------------------------------------------------------------------------------- - -This section contains a list of the error messages you might see out of -CWSDPMI and some details on what they mean. - -Exceptions are only handled by CWSDPMI if the application does not establish -an exception handler, exceptions nest 5 deep, or the error is particularly bad: - -"Page fault" - - 1) an illegal page fault happens in a RMCB or HW interrupt, (lock all pages!) - 2) all available pages have been locked, - 3) the application is using non-committed pages for null pointer protection. -"Double Fault" - multiple exceptions occurred -"Invalid TSS" - typically due to RMCB or HW interrupt being called after the - selectors/memory have been deallocated (remember to reset the mouse) -"General Protection Fault" - bad parameter sent to a DPMI call - -"80386 required." - -Since 80286 and lesser processors don't have the hardware necessary to -run CWSDPMI. No workaround, upgrade. - -"DOS 3 required." - -A few interrupts are used which need DOS 3.0 or higher. I don't expect to -ever see this message, since 80386 machines were introduced after DOS 3.0 -and that check is made first. - -"CWSDPMI V0.90+ (r5) Copyright (C) 2000 CW Sandmann ABSOLUTELY NO WARRANTY" - -An informational message displayed if the program is not run in one-pass mode. - -"Protected mode not accessible." - -This message should only be displayed if running CWSDPMI in a protected -environment with no access to protected mode. In this case, DPMI should -already be available and CWSDPMI would not be needed. This might happen if -a 16-bit DPMI client is loaded and a DJGPP image attempts to load CWSDPMI -to provide 32-bit DPMI services under Windows. - -"Warning: cannot open swap file c:\cwsdpmi.swp" - -Maybe you are out of file handles, or the swap file name is incorrectly -specified in the image (change the name with cwsparam). - -"No swap space!" - -This message means you tried to use more paging file than CWSDPMI was -configured to handle. Since this is protected against in the memory -allocation code, you should never see this message. - -"Swap disk full!" - -This means the paging file could not be expanded when trying to page -memory out to disk. This would normally not be seen, unless you are -writing output to the same disk which holds the paging file. Decrease -the amount of memory your DPMI application is using or free up disk space. - -"Interrupt 0x??" - -Your application tried to call an interrupt from protected mode which -normally shouldn't be called (something like a data pointer). If the -request was allowed to continue it would likely hang your machine. If you -see this message and think the interrupt should be allowed to continue, let -me know. - -"Error: Using XMS switched CPU into V86 mode." - -This message might be seen if you have your memory manager in AUTO mode. The -only workaround in this case is to stop using AUTO mode. - -"Error: could not allocate page table memory" - -The page table memory (a minimum of 16Kb) is allocated from conventional -memory (either in the 640Kb region or UMBs). If CWSDPMI cannot allocate the -minimum necessary memory, you would see this message. Free up some -conventional memory. You may also see this message if a page directory needs -to be faulted in, and there are no available pages. This means too many pages -have been locked for the allocated page tables available. While CWSDPMI -tries to dynamically allocate these if needed, this effort failed. You need -to increase the number of page tables with CWSPARAM, or increase the amount -of free conventional memory if it is low. If the application which calls -CWSDPMI internally manages all the DOS memory, the page tables may need to -be pre-allocated at DPMI startup time (if this is needed, try using the -run option flag 2 in cwsparam). - -"16-bit DPMI unsupported." - -CWSDPMI is a 32-bit only DPMI server. Ideally, on the request to enter DPMI's -PM with a 16-bit request, we would just fail the call setting the carry bit -like the DPMI specification describes. Some buggy 16-bit compiler tools don't -check the return status and will hang the machine in this case. So, I issue -an error message and exit the image instead. - -"Descriptors exhausted." - -An attempt to nest a DPMI client failed in the setup phase due to insufficient -free selectors in the LDT. - -"CWSDPMI not removed" - -When the -u parameter is specified, if DPMI is not detected this message is -printed. Informational. diff --git a/os/dos/cwsdpmi/cwsdstub.exe b/os/dos/cwsdpmi/cwsdstub.exe deleted file mode 100644 index fabaf3bf4f..0000000000 Binary files a/os/dos/cwsdpmi/cwsdstub.exe and /dev/null differ diff --git a/os/dos/exe2coff/README.licensing b/os/dos/exe2coff/README.licensing deleted file mode 100644 index 112b02a087..0000000000 --- a/os/dos/exe2coff/README.licensing +++ /dev/null @@ -1,3 +0,0 @@ -The files in this directory are not licensed under the same terms as the -rest of OpenTTD. Licensing details can be found in OpenTTD's readme.txt -and in this directory or subdirectories as well. diff --git a/os/dos/exe2coff/copying b/os/dos/exe2coff/copying deleted file mode 100644 index a43ea2126f..0000000000 --- a/os/dos/exe2coff/copying +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 675 Mass Ave, Cambridge, MA 02139, USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - Appendix: How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) 19yy - - This program 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; either version 2 of the License, or - (at your option) any later version. - - This program 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 this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) 19yy name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. diff --git a/os/dos/exe2coff/copying.dj b/os/dos/exe2coff/copying.dj deleted file mode 100644 index 8a55047845..0000000000 --- a/os/dos/exe2coff/copying.dj +++ /dev/null @@ -1,48 +0,0 @@ -This is the file "copying.dj". It does NOT apply to any sources or -binaries copyrighted by UCB Berkeley, the Free Software Foundation, or -any other agency besides DJ Delorie and others who have agreed to -allow their sources to be distributed under these terms. - - Copyright Information for sources and executables that are marked - Copyright (C) DJ Delorie - 7 Kim Lane - Rochester NH 03867-2954 - -This document is Copyright (C) DJ Delorie and may be distributed -verbatim, but changing it is not allowed. - -Source code copyright DJ Delorie is distributed under the terms of the -GNU General Public Licence, with the following exceptions: - -* Sources used to build crt0.o, gcrt0.o, libc.a, libdbg.a, and - libemu.a are distributed under the terms of the GNU Library General - Public License, rather than the GNU GPL. - -* Any existing copyright or authorship information in any given source - file must remain intact. If you modify a source file, a notice to that - effect must be added to the authorship information in the source file. - -* Runtime binaries, as provided by DJ in DJGPP, may be distributed - without sources ONLY if the recipient is given sufficient information - to obtain a copy of djgpp themselves. This primarily applies to - go32-v2.exe, emu387.dxe, and stubedit.exe. - -* Runtime objects and libraries, as provided by DJ in DJGPP, when - linked into an application, may be distributed without sources ONLY - if the recipient is given sufficient information to obtain a copy of - djgpp themselves. This primarily applies to crt0.o and libc.a. - ------ - -Changes to source code copyright BSD, FSF, or others, by DJ Delorie -fall under the terms of the original copyright. Such files usually -have multiple copyright notices in them. - -A copy of the files "COPYING" and "COPYING.LIB" are included with this -document. If you did not receive a copy of these files, you may -obtain one from whence this document was obtained, or by writing: - - Free Software Foundation - 59 Temple Place - Suite 330 - Boston, MA 02111-1307 - USA diff --git a/os/dos/exe2coff/copying.lib b/os/dos/exe2coff/copying.lib deleted file mode 100644 index bbe3fe1987..0000000000 --- a/os/dos/exe2coff/copying.lib +++ /dev/null @@ -1,481 +0,0 @@ - GNU LIBRARY GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1991 Free Software Foundation, Inc. - 675 Mass Ave, Cambridge, MA 02139, USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the library GPL. It is - numbered 2 because it goes with version 2 of the ordinary GPL.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Library General Public License, applies to some -specially designated Free Software Foundation software, and to any -other libraries whose authors decide to use it. You can use it for -your libraries, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if -you distribute copies of the library, or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link a program with the library, you must provide -complete object files to the recipients so that they can relink them -with the library, after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - Our method of protecting your rights has two steps: (1) copyright -the library, and (2) offer you this license which gives you legal -permission to copy, distribute and/or modify the library. - - Also, for each distributor's protection, we want to make certain -that everyone understands that there is no warranty for this free -library. If the library is modified by someone else and passed on, we -want its recipients to know that what they have is not the original -version, so that any problems introduced by others will not reflect on -the original authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that companies distributing free -software will individually obtain patent licenses, thus in effect -transforming the program into proprietary software. To prevent this, -we have made it clear that any patent must be licensed for everyone's -free use or not licensed at all. - - Most GNU software, including some libraries, is covered by the ordinary -GNU General Public License, which was designed for utility programs. This -license, the GNU Library General Public License, applies to certain -designated libraries. This license is quite different from the ordinary -one; be sure to read it in full, and don't assume that anything in it is -the same as in the ordinary license. - - The reason we have a separate public license for some libraries is that -they blur the distinction we usually make between modifying or adding to a -program and simply using it. Linking a program with a library, without -changing the library, is in some sense simply using the library, and is -analogous to running a utility program or application program. However, in -a textual and legal sense, the linked executable is a combined work, a -derivative of the original library, and the ordinary General Public License -treats it as such. - - Because of this blurred distinction, using the ordinary General -Public License for libraries did not effectively promote software -sharing, because most developers did not use the libraries. We -concluded that weaker conditions might promote sharing better. - - However, unrestricted linking of non-free programs would deprive the -users of those programs of all benefit from the free status of the -libraries themselves. This Library General Public License is intended to -permit developers of non-free programs to use free libraries, while -preserving your freedom as a user of such programs to change the free -libraries that are incorporated in them. (We have not seen how to achieve -this as regards changes in header files, but we have achieved it as regards -changes in the actual functions of the Library.) The hope is that this -will lead to faster development of free libraries. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, while the latter only -works together with the library. - - Note that it is possible for a library to be covered by the ordinary -General Public License rather than by this special one. - - GNU LIBRARY GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library which -contains a notice placed by the copyright holder or other authorized -party saying it may be distributed under the terms of this Library -General Public License (also called "this License"). Each licensee is -addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also compile or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - c) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - d) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the source code distributed need not include anything that is normally -distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Library General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - Appendix: How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library 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 - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/os/dos/exe2coff/exe2coff.c b/os/dos/exe2coff/exe2coff.c deleted file mode 100644 index aa072e8e41..0000000000 --- a/os/dos/exe2coff/exe2coff.c +++ /dev/null @@ -1,94 +0,0 @@ -/* Copyright (C) 1998 DJ Delorie, see COPYING.DJ for details */ -/* Copyright (C) 1995 DJ Delorie, see COPYING.DJ for details */ -/* Updated 2008 to use fread/fopen and friends instead of read/open so it compiles with GCC on Unix (Rubidium) */ -#include -#include -#include -#include -#include -#include -#include - - -static void -exe2aout(char *fname) -{ - unsigned short header[3]; - FILE *ifile; - FILE *ofile; - char buf[4096]; - int rbytes; - char *dot = strrchr(fname, '.'); - if (!dot || strlen(dot) != 4 - || tolower(dot[1]) != 'e' - || tolower(dot[2]) != 'x' - || tolower(dot[3]) != 'e') - { - fprintf(stderr, "%s: Arguments MUST end with a .exe extension\n", fname); - return; - } - - ifile = fopen(fname, "rb"); - if (!ifile) - { - perror(fname); - return; - } - fread(header, sizeof(header), 1, ifile); - if (header[0] == 0x5a4d) - { - long header_offset = (long)header[2]*512L; - if (header[1]) - header_offset += (long)header[1] - 512L; - fseek(ifile, header_offset, SEEK_SET); - header[0] = 0; - fread(header, sizeof(header), 1, ifile); - if ((header[0] != 0x010b) && (header[0] != 0x014c)) - { - fprintf(stderr, "`%s' does not have a COFF/AOUT program appended to it\n", fname); - return; - } - fseek(ifile, header_offset, SEEK_SET); - } - else - { - fprintf(stderr, "`%s' is not an .EXE file\n", fname); - return; - } - - *dot = 0; - ofile = fopen(fname, "w+b"); - if (!ofile) - { - perror(fname); - return; - } - - while ((rbytes=fread(buf, 1, 4096, ifile)) > 0) - { - int wb = fwrite(buf, 1, rbytes, ofile); - if (wb < 0) - { - perror(fname); - break; - } - if (wb < rbytes) - { - fprintf(stderr, "`%s': disk full\n", fname); - exit(1); - } - } - fclose(ifile); - fclose(ofile); -} - -int -main(int argc, char **argv) -{ - int i; - if (argc == 1) printf("Usage: %s ", argv[0]); - for (i=1; i binary.exe || exit -mv binary.exe $1 -rm binary exe2coff/exe2coff diff --git a/os/macosx/plistgen.sh b/os/macosx/plistgen.sh index b6116d9102..f492bcdcf9 100755 --- a/os/macosx/plistgen.sh +++ b/os/macosx/plistgen.sh @@ -1,7 +1,5 @@ #!/bin/sh -# $Id$ - # sets VERSION to the value if RELEASE if there are any, # otherwise it sets VERSION to revision number if [ "$3" ]; then diff --git a/os/os2/installer/make_installer.cmd b/os/os2/installer/make_installer.cmd index a15198b5f1..3addeca1ae 100644 --- a/os/os2/installer/make_installer.cmd +++ b/os/os2/installer/make_installer.cmd @@ -1,6 +1,6 @@ @echo off -set OPENTTD_VERSION=1.9.0 +set OPENTTD_VERSION=1.10.0 set OPENSFX_VERSION=0.8.0 set NOSOUND_VERSION=0.8.0 set OPENGFX_VERSION=1.2.0 diff --git a/os/os2/installer/openttd.wis b/os/os2/installer/openttd.wis index e580e565cf..4b761ed83c 100644 --- a/os/os2/installer/openttd.wis +++ b/os/os2/installer/openttd.wis @@ -71,7 +71,7 @@ ~Next -README.TXT +README.md Welcome to the OpenTTD installer. This program will install OpenTTD 1.0 on your system. Before we begin the installation process, please take a moment to read the following document. Select "Next" to continue, or "Cancel" to abort installation. @@ -80,7 +80,7 @@ Select "Next" to continue, or "Cancel" to abort installation. ~Next -COPYING +COPYING.md OpenTTD is licenced under the GNU General Public License. The text of the licence is below. Select "Next" if you agree to this licence. diff --git a/os/rpm/openttd.changes b/os/rpm/openttd.changes index b0a64dfe18..351f260799 100644 --- a/os/rpm/openttd.changes +++ b/os/rpm/openttd.changes @@ -46,7 +46,7 @@ Sat May 1 15:59:32 UTC 2010 - Marcel Gmür Thu Apr 1 08:53:54 UTC 2010 - Marcel Gmür - upstream update 1.0.0 (finally!) - * completely independend game but still working also + * completely independent game but still working also with ttd original gaphics, sounds and music - Add: Recommends openmsx - requires lzo2 @@ -54,7 +54,7 @@ Thu Apr 1 08:53:54 UTC 2010 - Marcel Gmür ------------------------------------------------------------------- Fri Dec 18 2009 Marcel Gmür - 0.7.4 -- support for differen branches +- support for different branches - easy support for dedicated branch - let openttd build system make the dektop file - split the package to data and gui diff --git a/os/rpm/openttd.spec b/os/rpm/openttd.spec index f19907a56c..340a9886b9 100644 --- a/os/rpm/openttd.spec +++ b/os/rpm/openttd.spec @@ -17,9 +17,9 @@ # Name: openttd -Version: 1.9 +Version: 1.10.beta2 Release: 0 -%define srcver 1.9.0 +%define srcver 1.10.0-beta2 Summary: An open source reimplementation of Chris Sawyer's Transport Tycoon Deluxe License: GPL-2.0 Group: Amusements/Games/Strategy/Other @@ -61,7 +61,7 @@ BuildRequires: kernel BuildRequires: pkg-config %endif -# bulding openttd.grf is not required as it is a) part of source and +# building openttd.grf is not required as it is a) part of source and # b) required only, if you want to use the original set %if 0%{?with_grfcodec} BuildRequires: grfcodec @@ -81,7 +81,7 @@ the original data from the game or install the recommend subackages OpenGFX for free graphics, OpenSFX for free sounds and OpenMSX for free music. OpenTTD is licensed under the GNU General Public License version 2.0. For more -information, see the file 'COPYING' included with every release and source +information, see the file 'COPYING.md' included with every release and source download of the game. %package gui @@ -91,7 +91,7 @@ Group: Amusements/Games/Strategy/Other Requires: %{name} Conflicts: %{name}-dedicated -BuildRequires: SDL-devel +BuildRequires: SDL2-devel BuildRequires: fontconfig-devel %if 0%{?rhel_version} != 600 diff --git a/os/windows/installer/install.nsi b/os/windows/installer/install.nsi index 86a07e562c..2561b76d55 100644 --- a/os/windows/installer/install.nsi +++ b/os/windows/installer/install.nsi @@ -1,9 +1,9 @@ # Version numbers to update !define APPV_MAJOR 1 -!define APPV_MINOR 9 +!define APPV_MINOR 10 !define APPV_MAINT 0 -!define APPV_BUILD 5 -!define APPV_EXTRA "" +!define APPV_BUILD 1 +!define APPV_EXTRA "-beta2" !define APPNAME "OpenTTD" ; Define application name !define APPVERSION "${APPV_MAJOR}.${APPV_MINOR}.${APPV_MAINT}${APPV_EXTRA}" ; Define application version @@ -63,7 +63,7 @@ Var CDDRIVE !define MUI_ABORTWARNING !define MUI_WELCOMEPAGE_TITLE_3LINES !insertmacro MUI_PAGE_WELCOME -!insertmacro MUI_PAGE_LICENSE "..\..\..\COPYING" +!insertmacro MUI_PAGE_LICENSE "..\..\..\COPYING.md" !define MUI_COMPONENTSPAGE_SMALLDESC !insertmacro MUI_PAGE_COMPONENTS @@ -143,10 +143,10 @@ Section "!OpenTTD" Section1 Push "$INSTDIR\scripts\README.md" Call unix2dos - ; Copy some documention files + ; Copy some documentation files SetOutPath "$INSTDIR\docs\" - File ${PATH_ROOT}docs\multiplayer.txt - Push "$INSTDIR\docs\multiplayer.txt" + File ${PATH_ROOT}docs\multiplayer.md + Push "$INSTDIR\docs\multiplayer.md" Call unix2dos ; Copy the rest of the stuff @@ -156,8 +156,8 @@ Section "!OpenTTD" Section1 File ${PATH_ROOT}changelog.txt Push "$INSTDIR\changelog.txt" Call unix2dos - File ${PATH_ROOT}COPYING - Push "$INSTDIR\COPYING" + File ${PATH_ROOT}COPYING.md + Push "$INSTDIR\COPYING.md" Call unix2dos File ${PATH_ROOT}README.md Push "$INSTDIR\README.md" @@ -218,7 +218,7 @@ Section "!OpenTTD" Section1 CreateShortCut "$SMPROGRAMS\$SHORTCUTS\Changelog.lnk" "$INSTDIR\Changelog.txt" CreateShortCut "$SMPROGRAMS\$SHORTCUTS\Known-bugs.lnk" "$INSTDIR\known-bugs.txt" CreateDirectory "$SMPROGRAMS\$SHORTCUTS\Docs" - CreateShortCut "$SMPROGRAMS\$SHORTCUTS\Docs\Multiplayer.lnk" "$INSTDIR\docs\multiplayer.txt" + CreateShortCut "$SMPROGRAMS\$SHORTCUTS\Docs\Multiplayer.lnk" "$INSTDIR\docs\multiplayer.md" CreateDirectory "$SMPROGRAMS\$SHORTCUTS\Scripts" CreateShortCut "$SMPROGRAMS\$SHORTCUTS\Scripts\Readme.lnk" "$INSTDIR\scripts\README.md" !insertmacro MUI_STARTMENU_WRITE_END @@ -392,7 +392,7 @@ Section "Uninstall" Delete "$INSTDIR\README.md" Delete "$INSTDIR\known-bugs.txt" Delete "$INSTDIR\openttd.exe" - Delete "$INSTDIR\COPYING" + Delete "$INSTDIR\COPYING.md" Delete "$INSTDIR\INSTALL.LOG" Delete "$INSTDIR\crash.log" Delete "$INSTDIR\crash.dmp" diff --git a/projects/determineversion.vbs b/projects/determineversion.vbs index 10b38d35a1..a85a085f29 100755 --- a/projects/determineversion.vbs +++ b/projects/determineversion.vbs @@ -1,7 +1,5 @@ Option Explicit -' $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. ' 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. diff --git a/projects/gen-kdev4.sh b/projects/gen-kdev4.sh index 4ea5dbc2a8..2062d9686a 100755 --- a/projects/gen-kdev4.sh +++ b/projects/gen-kdev4.sh @@ -1,7 +1,5 @@ #!/bin/sh -# $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. # 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. diff --git a/projects/generate b/projects/generate index cfedc8b32d..2078809c88 100755 --- a/projects/generate +++ b/projects/generate @@ -1,7 +1,5 @@ #!/bin/bash -# $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. # 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. @@ -132,14 +130,14 @@ load_main_data() { if ($0 == "DEDICATED" && "'$enable_dedicated'" != "1") { next; } if ($0 == "AI" && "'$enable_ai'" == "0") { next; } if ($0 == "COCOA" && "'$with_cocoa'" == "0") { next; } - if ($0 == "BEOS" && "'$os'" != "BEOS") { next; } + if ($0 == "HAIKU" && "'$os'" != "HAIKU") { next; } if ($0 == "WIN32" && "'$os'" != "MINGW" && "'$os'" != "CYGWIN" && "'$os'" != "MSVC" ) { next; } if ($0 == "MSVC" && "'$os'" != "MSVC") { next; } if ($0 == "DIRECTMUSIC" && "'$enable_directmusic'" != "1") { next; } if ($0 == "FLUIDSYNTH" && "'$enable_fluidsynth'" != "1") { next; } - if ($0 == "LIBTIMIDITY" && "'$libtimidity'" == "" ) { next; } - if ($0 == "HAVE_THREAD" && "'$with_threads'" == "0") { next; } + if ($0 == "USE_XAUDIO2" && "'$with_xaudio2'" == "0") { next; } + if ($0 == "USE_THREADS" && "'$with_threads'" == "0") { next; } skip += 1; diff --git a/projects/generate.vbs b/projects/generate.vbs index aa91bd3164..169f8b6890 100644 --- a/projects/generate.vbs +++ b/projects/generate.vbs @@ -1,7 +1,5 @@ Option Explicit -' $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. ' 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. @@ -179,8 +177,9 @@ Sub load_main_data(filename, ByRef vcxproj, ByRef filters, ByRef files) line = "MSVC" Or _ line = "DIRECTMUSIC" Or _ line = "AI" Or _ - line = "SSE" Or _ - line = "HAVE_THREAD" _ + line = "USE_SSE" Or _ + line = "USE_XAUDIO2" Or _ + line = "USE_THREADS" _ ) Then skip = skip + 1 deep = deep + 1 Case "#" diff --git a/projects/generate_vs142.vcxproj b/projects/generate_vs142.vcxproj index 3e55d7a1d4..7230676cb5 100644 --- a/projects/generate_vs142.vcxproj +++ b/projects/generate_vs142.vcxproj @@ -10,7 +10,6 @@ generate {2F31FD79-D1AC-43C4-89F3-B0D5E4E53E34} generate - 8.1 diff --git a/projects/openttd_vs140.vcxproj b/projects/openttd_vs140.vcxproj index 9a741f28df..6453d62b86 100644 --- a/projects/openttd_vs140.vcxproj +++ b/projects/openttd_vs140.vcxproj @@ -107,7 +107,7 @@ Size true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions) + NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";WITH_ASSERT;%(PreprocessorDefinitions) true Sync MultiThreaded @@ -172,7 +172,7 @@ Disabled true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - _DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions) + _DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebug @@ -230,7 +230,7 @@ Size true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions) + NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;WITH_ASSERT;%(PreprocessorDefinitions) true Sync MultiThreaded @@ -293,7 +293,7 @@ Disabled true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - _DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions) + _DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebug @@ -409,6 +409,7 @@ + @@ -448,6 +449,7 @@ + @@ -581,8 +583,10 @@ + + @@ -613,6 +617,7 @@ + @@ -622,8 +627,10 @@ + + @@ -645,6 +652,7 @@ + @@ -679,6 +687,7 @@ + @@ -695,6 +704,7 @@ + @@ -723,6 +733,7 @@ + @@ -737,7 +748,6 @@ - @@ -839,6 +849,7 @@ + @@ -947,6 +958,7 @@ + @@ -1085,6 +1097,7 @@ + @@ -1151,6 +1164,7 @@ + @@ -1223,7 +1237,9 @@ + + @@ -1286,8 +1302,6 @@ - - @@ -1318,6 +1332,7 @@ + @@ -1325,14 +1340,14 @@ + - - + diff --git a/projects/openttd_vs140.vcxproj.filters b/projects/openttd_vs140.vcxproj.filters index 751e54887c..0405740d4c 100644 --- a/projects/openttd_vs140.vcxproj.filters +++ b/projects/openttd_vs140.vcxproj.filters @@ -315,6 +315,9 @@ Source Files + + Source Files + Source Files @@ -432,6 +435,9 @@ Header Files + + Header Files + Header Files @@ -831,12 +837,18 @@ Header Files + + Header Files + Header Files Header Files + + Header Files + Header Files @@ -927,6 +939,9 @@ Header Files + + Header Files + Header Files @@ -954,12 +969,18 @@ Header Files + + Header Files + Header Files Header Files + + Header Files + Header Files @@ -1023,6 +1044,9 @@ Header Files + + Header Files + Header Files @@ -1125,6 +1149,9 @@ Header Files + + Header Files + Header Files @@ -1173,6 +1200,9 @@ Header Files + + Header Files + Header Files @@ -1257,6 +1287,9 @@ Core Source Code + + Core Source Code + Core Source Code @@ -1299,9 +1332,6 @@ Core Source Code - - Core Source Code - Core Source Code @@ -1605,6 +1635,9 @@ Widgets + + Widgets + Widgets @@ -1929,6 +1962,9 @@ Tables + + Tables + Tables @@ -2343,6 +2379,9 @@ Script API + + Script API + Script API @@ -2541,6 +2580,9 @@ Script API Implementation + + Script API Implementation + Script API Implementation @@ -2757,9 +2799,15 @@ NewGRF + + NewGRF + NewGRF + + NewGRF + NewGRF @@ -2946,12 +2994,6 @@ Pathfinder - - Pathfinder - - - Pathfinder - Pathfinder @@ -3042,6 +3084,9 @@ Video + + Video + Video @@ -3063,6 +3108,9 @@ Sound + + Sound + Sound @@ -3081,12 +3129,9 @@ Windows files - + Threading - - Threading - diff --git a/projects/openttd_vs140.vcxproj.in b/projects/openttd_vs140.vcxproj.in index 8a9b9a8f97..b5628a23d3 100644 --- a/projects/openttd_vs140.vcxproj.in +++ b/projects/openttd_vs140.vcxproj.in @@ -107,7 +107,7 @@ Size true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions) + NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";WITH_ASSERT;%(PreprocessorDefinitions) true Sync MultiThreaded @@ -172,7 +172,7 @@ Disabled true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - _DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions) + _DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebug @@ -230,7 +230,7 @@ Size true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions) + NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;WITH_ASSERT;%(PreprocessorDefinitions) true Sync MultiThreaded @@ -293,7 +293,7 @@ Disabled true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - _DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions) + _DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebug diff --git a/projects/openttd_vs141.vcxproj b/projects/openttd_vs141.vcxproj index 2cde5b1d86..ecfed4a038 100644 --- a/projects/openttd_vs141.vcxproj +++ b/projects/openttd_vs141.vcxproj @@ -107,7 +107,7 @@ Size true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions) + NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";WITH_ASSERT;%(PreprocessorDefinitions) true Sync MultiThreaded @@ -172,7 +172,7 @@ Disabled true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - _DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions) + _DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebug @@ -230,7 +230,7 @@ Size true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions) + NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;WITH_ASSERT;%(PreprocessorDefinitions) true Sync MultiThreaded @@ -293,7 +293,7 @@ Disabled true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - _DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions) + _DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebug @@ -409,6 +409,7 @@ + @@ -448,6 +449,7 @@ + @@ -581,8 +583,10 @@ + + @@ -613,6 +617,7 @@ + @@ -622,8 +627,10 @@ + + @@ -645,6 +652,7 @@ + @@ -679,6 +687,7 @@ + @@ -695,6 +704,7 @@ + @@ -723,6 +733,7 @@ + @@ -737,7 +748,6 @@ - @@ -839,6 +849,7 @@ + @@ -947,6 +958,7 @@ + @@ -1085,6 +1097,7 @@ + @@ -1151,6 +1164,7 @@ + @@ -1223,7 +1237,9 @@ + + @@ -1286,8 +1302,6 @@ - - @@ -1318,6 +1332,7 @@ + @@ -1325,14 +1340,14 @@ + - - + diff --git a/projects/openttd_vs141.vcxproj.filters b/projects/openttd_vs141.vcxproj.filters index 751e54887c..0405740d4c 100644 --- a/projects/openttd_vs141.vcxproj.filters +++ b/projects/openttd_vs141.vcxproj.filters @@ -315,6 +315,9 @@ Source Files + + Source Files + Source Files @@ -432,6 +435,9 @@ Header Files + + Header Files + Header Files @@ -831,12 +837,18 @@ Header Files + + Header Files + Header Files Header Files + + Header Files + Header Files @@ -927,6 +939,9 @@ Header Files + + Header Files + Header Files @@ -954,12 +969,18 @@ Header Files + + Header Files + Header Files Header Files + + Header Files + Header Files @@ -1023,6 +1044,9 @@ Header Files + + Header Files + Header Files @@ -1125,6 +1149,9 @@ Header Files + + Header Files + Header Files @@ -1173,6 +1200,9 @@ Header Files + + Header Files + Header Files @@ -1257,6 +1287,9 @@ Core Source Code + + Core Source Code + Core Source Code @@ -1299,9 +1332,6 @@ Core Source Code - - Core Source Code - Core Source Code @@ -1605,6 +1635,9 @@ Widgets + + Widgets + Widgets @@ -1929,6 +1962,9 @@ Tables + + Tables + Tables @@ -2343,6 +2379,9 @@ Script API + + Script API + Script API @@ -2541,6 +2580,9 @@ Script API Implementation + + Script API Implementation + Script API Implementation @@ -2757,9 +2799,15 @@ NewGRF + + NewGRF + NewGRF + + NewGRF + NewGRF @@ -2946,12 +2994,6 @@ Pathfinder - - Pathfinder - - - Pathfinder - Pathfinder @@ -3042,6 +3084,9 @@ Video + + Video + Video @@ -3063,6 +3108,9 @@ Sound + + Sound + Sound @@ -3081,12 +3129,9 @@ Windows files - + Threading - - Threading - diff --git a/projects/openttd_vs141.vcxproj.in b/projects/openttd_vs141.vcxproj.in index 57e153fc7d..015c23d3c5 100644 --- a/projects/openttd_vs141.vcxproj.in +++ b/projects/openttd_vs141.vcxproj.in @@ -107,7 +107,7 @@ Size true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions) + NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";WITH_ASSERT;%(PreprocessorDefinitions) true Sync MultiThreaded @@ -172,7 +172,7 @@ Disabled true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - _DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions) + _DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebug @@ -230,7 +230,7 @@ Size true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions) + NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;WITH_ASSERT;%(PreprocessorDefinitions) true Sync MultiThreaded @@ -293,7 +293,7 @@ Disabled true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - _DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions) + _DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebug diff --git a/projects/openttd_vs142.vcxproj b/projects/openttd_vs142.vcxproj index 997ec829b5..49858a3e1d 100644 --- a/projects/openttd_vs142.vcxproj +++ b/projects/openttd_vs142.vcxproj @@ -78,16 +78,16 @@ $(SolutionDir)..\objs\$(Platform)\$(Configuration)\ $(SolutionDir)..\objs\$(Platform)\$(Configuration)\ - AllRules.ruleset + NativeMinimumRules.ruleset - AllRules.ruleset + NativeMinimumRules.ruleset - AllRules.ruleset + NativeMinimumRules.ruleset - AllRules.ruleset + NativeMinimumRules.ruleset $(SolutionDir)..\objs\$(Platform)\$(Configuration)\ @@ -107,7 +107,7 @@ Size true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions) + NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";WITH_ASSERT;%(PreprocessorDefinitions) true Sync MultiThreaded @@ -172,7 +172,7 @@ Disabled true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - _DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions) + _DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebug @@ -230,7 +230,7 @@ Size true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions) + NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;WITH_ASSERT;%(PreprocessorDefinitions) true Sync MultiThreaded @@ -293,7 +293,7 @@ Disabled true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - _DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions) + _DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebug @@ -409,6 +409,7 @@ + @@ -448,6 +449,7 @@ + @@ -581,8 +583,10 @@ + + @@ -613,6 +617,7 @@ + @@ -622,8 +627,10 @@ + + @@ -645,6 +652,7 @@ + @@ -676,10 +684,10 @@ - + @@ -696,6 +704,7 @@ + @@ -724,6 +733,7 @@ + @@ -738,7 +748,6 @@ - @@ -840,6 +849,7 @@ + @@ -948,6 +958,7 @@ + @@ -1086,6 +1097,7 @@ + @@ -1152,6 +1164,7 @@ + @@ -1224,7 +1237,9 @@ + + @@ -1287,8 +1302,6 @@ - - @@ -1319,6 +1332,7 @@ + @@ -1326,14 +1340,14 @@ + - - + diff --git a/projects/openttd_vs142.vcxproj.filters b/projects/openttd_vs142.vcxproj.filters index a301b9ddcc..1f65f54170 100644 --- a/projects/openttd_vs142.vcxproj.filters +++ b/projects/openttd_vs142.vcxproj.filters @@ -315,6 +315,9 @@ Source Files + + Source Files + Source Files @@ -432,6 +435,9 @@ Header Files + + Header Files + Header Files @@ -831,12 +837,18 @@ Header Files + + Header Files + Header Files Header Files + + Header Files + Header Files @@ -927,6 +939,9 @@ Header Files + + Header Files + Header Files @@ -954,12 +969,18 @@ Header Files + + Header Files + Header Files Header Files + + Header Files + Header Files @@ -1023,6 +1044,9 @@ Header Files + + Header Files + Header Files @@ -1128,6 +1152,9 @@ Header Files + + Header Files + Header Files @@ -1176,6 +1203,9 @@ Header Files + + Header Files + Header Files @@ -1260,6 +1290,9 @@ Core Source Code + + Core Source Code + Core Source Code @@ -1302,9 +1335,6 @@ Core Source Code - - Core Source Code - Core Source Code @@ -1608,6 +1638,9 @@ Widgets + + Widgets + Widgets @@ -1932,6 +1965,9 @@ Tables + + Tables + Tables @@ -2346,6 +2382,9 @@ Script API + + Script API + Script API @@ -2544,6 +2583,9 @@ Script API Implementation + + Script API Implementation + Script API Implementation @@ -2760,9 +2802,15 @@ NewGRF + + NewGRF + NewGRF + + NewGRF + NewGRF @@ -2949,12 +2997,6 @@ Pathfinder - - Pathfinder - - - Pathfinder - Pathfinder @@ -3045,6 +3087,9 @@ Video + + Video + Video @@ -3066,6 +3111,9 @@ Sound + + Sound + Sound @@ -3084,12 +3132,9 @@ Windows files - + Threading - - Threading - diff --git a/projects/openttd_vs142.vcxproj.in b/projects/openttd_vs142.vcxproj.in index 7176fea58a..83befcd8d0 100644 --- a/projects/openttd_vs142.vcxproj.in +++ b/projects/openttd_vs142.vcxproj.in @@ -78,16 +78,16 @@ $(SolutionDir)..\objs\$(Platform)\$(Configuration)\ $(SolutionDir)..\objs\$(Platform)\$(Configuration)\ - AllRules.ruleset + NativeMinimumRules.ruleset - AllRules.ruleset + NativeMinimumRules.ruleset - AllRules.ruleset + NativeMinimumRules.ruleset - AllRules.ruleset + NativeMinimumRules.ruleset $(SolutionDir)..\objs\$(Platform)\$(Configuration)\ @@ -107,7 +107,7 @@ Size true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions) + NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";WITH_ASSERT;%(PreprocessorDefinitions) true Sync MultiThreaded @@ -172,7 +172,7 @@ Disabled true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - _DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions) + _DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebug @@ -230,7 +230,7 @@ Size true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions) + NDEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;WITH_ASSERT;%(PreprocessorDefinitions) true Sync MultiThreaded @@ -293,7 +293,7 @@ Disabled true ..\objs\langs;..\objs\settings;..\src\3rdparty\squirrel\include;%(AdditionalIncludeDirectories) - _DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LZMA;WITH_PNG;WITH_FREETYPE;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions) + _DEBUG;_CONSOLE;WIN32_ENABLE_DIRECTMUSIC_SUPPORT;WITH_XAUDIO2;WITH_SSE;WITH_ZLIB;WITH_LZO;WITH_LIBLZMA;WITH_PNG;WITH_UNISCRIBE;ENABLE_NETWORK;WITH_PERSONAL_DIR;PERSONAL_DIR="OpenTTD";_SQ64;%(PreprocessorDefinitions) EnableFastChecks MultiThreadedDebug diff --git a/projects/settingsgen_vs142.vcxproj b/projects/settingsgen_vs142.vcxproj index ca0418c15c..23a4e18562 100644 --- a/projects/settingsgen_vs142.vcxproj +++ b/projects/settingsgen_vs142.vcxproj @@ -10,7 +10,6 @@ settingsgen {E9548DE9-F089-49B7-93A6-30BE2CC311C7} settings - 8.1 diff --git a/projects/strgen_vs142.vcxproj b/projects/strgen_vs142.vcxproj index 5329d68daa..554109b045 100644 --- a/projects/strgen_vs142.vcxproj +++ b/projects/strgen_vs142.vcxproj @@ -10,7 +10,6 @@ strgen {A133A442-BD0A-4ADE-B117-AD7545E4BDD1} strgen - 8.1 @@ -30,9 +29,9 @@ $(SolutionDir)..\objs\strgen\ $(SolutionDir)..\objs\strgen\ false - AllRules.ruleset - - + NativeMinimumRules.ruleset + + diff --git a/source.list b/source.list index c9ba04c0ee..d674d9df35 100644 --- a/source.list +++ b/source.list @@ -70,6 +70,7 @@ rail.cpp rev.cpp road.cpp roadstop.cpp +screenshot_gui.cpp screenshot.cpp settings.cpp signal.cpp @@ -111,8 +112,8 @@ tutorial_gui.cpp vehicle.cpp vehiclelist.cpp viewport.cpp -#if SSE -viewport_sprite_sorter_sse4.cpp +#if USE_SSE + viewport_sprite_sorter_sse4.cpp #end waypoint.cpp widget.cpp @@ -136,6 +137,7 @@ autoslope.h base_media_base.h base_media_func.h base_station_base.h +bitmap_type.h bmp.h bridge.h build_confirmation_func.h @@ -270,8 +272,10 @@ newgrf_house.h newgrf_industries.h newgrf_industrytiles.h newgrf_object.h +newgrf_profiling.h newgrf_properties.h newgrf_railtype.h +newgrf_roadtype.h newgrf_sound.h newgrf_spritegroup.h newgrf_station.h @@ -302,6 +306,7 @@ rail.h rail_gui.h rail_type.h rev.h +road.h road_cmd.h road_func.h road_gui.h @@ -311,8 +316,10 @@ roadstop_base.h roadveh.h safeguards.h screenshot.h +screenshot_gui.h sound/sdl_s.h video/sdl_v.h +video/sdl2_v.h settings_func.h settings_gui.h settings_internal.h @@ -334,6 +341,7 @@ spritecache.h station_base.h station_func.h station_gui.h +station_kdtree.h station_type.h statusbar_gui.h stdafx.h @@ -369,6 +377,7 @@ toolbar_type.h toolbar_gui.h town.h town_type.h +town_kdtree.h townname_func.h townname_type.h track_func.h @@ -385,6 +394,7 @@ vehicle_gui_base.h vehicle_type.h vehiclelist.h viewport_func.h +viewport_kdtree.h viewport_sprite_sorter.h viewport_type.h water.h @@ -403,20 +413,19 @@ zoom_func.h zoom_type.h #if WIN32 #else -music/bemidi.h -music/cocoa_m.h -music/extmidi.h -music/libtimidity.h -music/fluidsynth.h -music/os2_m.h -music/qtmidi.h -os/macosx/macos.h -os/macosx/osx_stdafx.h -os/macosx/splash.h -os/macosx/string_osx.h -sound/cocoa_s.h -video/cocoa/cocoa_keys.h -video/cocoa/cocoa_v.h + music/bemidi.h + music/cocoa_m.h + music/extmidi.h + music/fluidsynth.h + music/os2_m.h + music/qtmidi.h + os/macosx/macos.h + os/macosx/osx_stdafx.h + os/macosx/splash.h + os/macosx/string_osx.h + sound/cocoa_s.h + video/cocoa/cocoa_keys.h + video/cocoa/cocoa_v.h #end # Core Source Code @@ -432,6 +441,7 @@ core/enum_type.hpp core/geometry_func.cpp core/geometry_func.hpp core/geometry_type.hpp +core/kdtree.hpp core/math_func.cpp core/math_func.hpp core/mem_func.hpp @@ -446,7 +456,6 @@ core/smallmap_type.hpp core/smallmatrix_type.hpp core/smallstack_type.hpp core/smallvec_type.hpp -core/sort_func.hpp core/string_compare_type.hpp # GUI Source Code @@ -553,6 +562,7 @@ widgets/order_widget.h widgets/osk_widget.h widgets/rail_widget.h widgets/road_widget.h +widgets/screenshot_widget.h widgets/settings_widget.h widgets/sign_widget.h widgets/smallmap_widget.h @@ -667,6 +677,7 @@ table/pricebase.h table/railtypes.h table/road_land.h table/roadveh_movement.h +table/roadtypes.h ../objs/settings/table/settings.h table/sprites.h table/station_land.h @@ -823,6 +834,7 @@ script/api/script_order.hpp script/api/script_rail.hpp script/api/script_railtypelist.hpp script/api/script_road.hpp +script/api/script_roadtypelist.hpp script/api/script_sign.hpp script/api/script_signlist.hpp script/api/script_station.hpp @@ -891,6 +903,7 @@ script/api/script_order.cpp script/api/script_rail.cpp script/api/script_railtypelist.cpp script/api/script_road.cpp +script/api/script_roadtypelist.cpp script/api/script_sign.cpp script/api/script_signlist.cpp script/api/script_station.cpp @@ -917,42 +930,42 @@ script/api/script_window.cpp # Blitters #if DEDICATED #else -blitter/16bpp_base.cpp -blitter/16bpp_base.hpp -blitter/16bpp_anim.cpp -blitter/16bpp_anim.hpp -blitter/16bpp_simple.cpp -blitter/16bpp_simple.hpp -blitter/32bpp_anim.cpp -blitter/32bpp_anim.hpp -#if SSE -blitter/32bpp_anim_sse2.cpp -blitter/32bpp_anim_sse2.hpp -blitter/32bpp_anim_sse4.cpp -blitter/32bpp_anim_sse4.hpp -#end -blitter/32bpp_base.cpp -blitter/32bpp_base.hpp -blitter/32bpp_optimized.cpp -blitter/32bpp_optimized.hpp -blitter/32bpp_simple.cpp -blitter/32bpp_simple.hpp -#if SSE -blitter/32bpp_sse_func.hpp -blitter/32bpp_sse_type.h -blitter/32bpp_sse2.cpp -blitter/32bpp_sse2.hpp -blitter/32bpp_sse4.cpp -blitter/32bpp_sse4.hpp -blitter/32bpp_ssse3.cpp -blitter/32bpp_ssse3.hpp -#end -blitter/8bpp_base.cpp -blitter/8bpp_base.hpp -blitter/8bpp_optimized.cpp -blitter/8bpp_optimized.hpp -blitter/8bpp_simple.cpp -blitter/8bpp_simple.hpp + blitter/16bpp_base.cpp + blitter/16bpp_base.hpp + blitter/16bpp_anim.cpp + blitter/16bpp_anim.hpp + blitter/16bpp_simple.cpp + blitter/16bpp_simple.hpp + blitter/32bpp_anim.cpp + blitter/32bpp_anim.hpp + #if USE_SSE + blitter/32bpp_anim_sse2.cpp + blitter/32bpp_anim_sse2.hpp + blitter/32bpp_anim_sse4.cpp + blitter/32bpp_anim_sse4.hpp + #end + blitter/32bpp_base.cpp + blitter/32bpp_base.hpp + blitter/32bpp_optimized.cpp + blitter/32bpp_optimized.hpp + blitter/32bpp_simple.cpp + blitter/32bpp_simple.hpp + #if USE_SSE + blitter/32bpp_sse_func.hpp + blitter/32bpp_sse_type.h + blitter/32bpp_sse2.cpp + blitter/32bpp_sse2.hpp + blitter/32bpp_sse4.cpp + blitter/32bpp_sse4.hpp + blitter/32bpp_ssse3.cpp + blitter/32bpp_ssse3.hpp + #end + blitter/8bpp_base.cpp + blitter/8bpp_base.hpp + blitter/8bpp_optimized.cpp + blitter/8bpp_optimized.hpp + blitter/8bpp_simple.cpp + blitter/8bpp_simple.hpp #end blitter/base.hpp blitter/common.hpp @@ -984,7 +997,9 @@ newgrf_house.cpp newgrf_industries.cpp newgrf_industrytiles.cpp newgrf_object.cpp +newgrf_profiling.cpp newgrf_railtype.cpp +newgrf_roadtype.cpp newgrf_sound.cpp newgrf_spritegroup.cpp newgrf_station.cpp @@ -1055,8 +1070,6 @@ network/core/udp.h # Pathfinder pathfinder/follow_track.hpp -pathfinder/opf/opf_ship.cpp -pathfinder/opf/opf_ship.h pathfinder/pathfinder_func.h pathfinder/pathfinder_type.h pathfinder/pf_performance_timer.hpp @@ -1094,67 +1107,66 @@ video/dedicated_v.cpp video/null_v.cpp #if DEDICATED #else -#if ALLEGRO - video/allegro_v.cpp -#end -#if SDL - video/sdl_v.cpp -#end -#if WIN32 - video/win32_v.cpp -#end + #if ALLEGRO + video/allegro_v.cpp + #end + #if SDL + video/sdl_v.cpp + #end + #if SDL2 + video/sdl2_v.cpp + #end + #if WIN32 + video/win32_v.cpp + #end #end # Music #if DEDICATED #else -#if ALLEGRO - music/allegro_m.cpp -#end -#if DIRECTMUSIC - music/dmusic.cpp -#end + #if ALLEGRO + music/allegro_m.cpp + #end + #if DIRECTMUSIC + music/dmusic.cpp + #end #end music/null_m.cpp music/midifile.cpp #if DEDICATED #else -#if WIN32 - music/win32_m.cpp -#else - #if DOS + #if WIN32 + music/win32_m.cpp #else - #if MORPHOS - #else - music/extmidi.cpp - #end + music/extmidi.cpp + #end + #if HAIKU + music/bemidi.cpp + #end + #if FLUIDSYNTH + music/fluidsynth.cpp #end -#end -#if BEOS - music/bemidi.cpp -#end -#if LIBTIMIDITY - music/libtimidity.cpp -#end -#if FLUIDSYNTH - music/fluidsynth.cpp -#end #end # Sound sound/null_s.cpp #if DEDICATED #else -#if ALLEGRO - sound/allegro_s.cpp -#end -#if SDL - sound/sdl_s.cpp -#end -#if WIN32 - sound/win32_s.cpp - sound/xaudio2_s.cpp -#end + #if ALLEGRO + sound/allegro_s.cpp + #end + #if SDL + sound/sdl_s.cpp + #end + #if SDL2 + sound/sdl2_s.cpp + #end + #if WIN32 + sound/win32_s.cpp + #if USE_XAUDIO2 + sound/xaudio2_s.cpp + #end + #end #end #if OSX @@ -1188,21 +1200,4 @@ sound/null_s.cpp #end # Threading -thread/thread.h -#if HAVE_THREAD - #if WIN32 - thread/thread_win32.cpp - #else - #if OS2 - thread/thread_os2.cpp - #else - #if MORPHOS - thread/thread_morphos.cpp - #else - thread/thread_pthread.cpp - #end - #end - #end -#else - thread/thread_none.cpp -#end +thread.h diff --git a/src/3rdparty/md5/md5.cpp b/src/3rdparty/md5/md5.cpp index 2111a8eb81..d8e5eeb515 100644 --- a/src/3rdparty/md5/md5.cpp +++ b/src/3rdparty/md5/md5.cpp @@ -1,5 +1,3 @@ -/* $Id$ */ - /** @file md5.cpp Creating MD5 checksums of files. */ /* diff --git a/src/3rdparty/md5/md5.h b/src/3rdparty/md5/md5.h index 9748dc444f..049c001d8d 100644 --- a/src/3rdparty/md5/md5.h +++ b/src/3rdparty/md5/md5.h @@ -1,5 +1,3 @@ -/* $Id$ */ - /** @file md5.h Functions to create MD5 checksums. */ /* diff --git a/src/3rdparty/squirrel/sqstdlib/sqstdaux.cpp b/src/3rdparty/squirrel/sqstdlib/sqstdaux.cpp index 540975fb5c..a4f4e21c33 100644 --- a/src/3rdparty/squirrel/sqstdlib/sqstdaux.cpp +++ b/src/3rdparty/squirrel/sqstdlib/sqstdaux.cpp @@ -38,7 +38,7 @@ void sqstd_printcallstack(HSQUIRRELVM v) src = si.source; } } - pf(v,"*FUNCTION [%s()] %s line [%d]\n",fn,src,si.line); + pf(v,"*FUNCTION [%s()] %s line [" OTTD_PRINTF64 "]\n",fn,src,si.line); level++; } level=0; @@ -56,7 +56,7 @@ void sqstd_printcallstack(HSQUIRRELVM v) break; case OT_INTEGER: sq_getinteger(v,-1,&i); - pf(v,"[%s] %d\n",name,i); + pf(v,"[%s] " OTTD_PRINTF64 "\n",name,i); break; case OT_FLOAT: sq_getfloat(v,-1,&f); @@ -134,7 +134,7 @@ void _sqstd_compiler_error(HSQUIRRELVM v,const SQChar *sErr,const SQChar *sSourc { SQPRINTFUNCTION pf = sq_getprintfunc(v); if(pf) { - pf(v,"%s line = (%d) column = (%d) : error %s\n",sSource,line,column,sErr); + pf(v,"%s line = (" OTTD_PRINTF64 ") column = (" OTTD_PRINTF64 ") : error %s\n",sSource,line,column,sErr); } } diff --git a/src/3rdparty/squirrel/squirrel/sqbaselib.cpp b/src/3rdparty/squirrel/squirrel/sqbaselib.cpp index 86a1b11858..e5de01a635 100644 --- a/src/3rdparty/squirrel/squirrel/sqbaselib.cpp +++ b/src/3rdparty/squirrel/squirrel/sqbaselib.cpp @@ -219,7 +219,7 @@ static SQInteger base_array(HSQUIRRELVM v) SQInteger nInitialSize = tointeger(stack_get(v,2)); SQInteger ret = 1; if (nInitialSize < 0) { - v->Raise_Error("can't create/resize array with/to size %d", nInitialSize); + v->Raise_Error("can't create/resize array with/to size " OTTD_PRINTF64, nInitialSize); nInitialSize = 0; ret = -1; } diff --git a/src/3rdparty/squirrel/squirrel/sqcompiler.cpp b/src/3rdparty/squirrel/squirrel/sqcompiler.cpp index ace9d201e9..854d080d2b 100644 --- a/src/3rdparty/squirrel/squirrel/sqcompiler.cpp +++ b/src/3rdparty/squirrel/squirrel/sqcompiler.cpp @@ -142,7 +142,7 @@ public: break; } Lex(); - return ret; + return std::move(ret); } bool IsEndOfStatement() { return ((_lex._prevtoken == '\n') || (_token == SQUIRREL_EOB) || (_token == '}') || (_token == ';')); } void OptionalSemicolon() diff --git a/src/3rdparty/squirrel/squirrel/sqdebug.cpp b/src/3rdparty/squirrel/squirrel/sqdebug.cpp index 2f24e83b66..44f767c297 100644 --- a/src/3rdparty/squirrel/squirrel/sqdebug.cpp +++ b/src/3rdparty/squirrel/squirrel/sqdebug.cpp @@ -122,5 +122,5 @@ void SQVM::Raise_ParamTypeError(SQInteger nparam,SQInteger typemask,SQInteger ty StringCat(exptypes,SQString::Create(_ss(this), IdType2Name((SQObjectType)mask), -1), exptypes); } } - Raise_Error("parameter %d has an invalid type '%s' ; expected: '%s'", nparam, IdType2Name((SQObjectType)type), _stringval(exptypes)); + Raise_Error("parameter " OTTD_PRINTF64 " has an invalid type '%s' ; expected: '%s'", nparam, IdType2Name((SQObjectType)type), _stringval(exptypes)); } diff --git a/src/3rdparty/squirrel/squirrel/sqfuncproto.h b/src/3rdparty/squirrel/squirrel/sqfuncproto.h index e58ccd2994..2966d06544 100644 --- a/src/3rdparty/squirrel/squirrel/sqfuncproto.h +++ b/src/3rdparty/squirrel/squirrel/sqfuncproto.h @@ -20,12 +20,6 @@ struct SQOuterVar _src=src; _type=t; } - SQOuterVar(const SQOuterVar &ov) - { - _type=ov._type; - _src=ov._src; - _name=ov._name; - } SQOuterType _type; SQObjectPtr _name; SQObjectPtr _src; @@ -34,13 +28,6 @@ struct SQOuterVar struct SQLocalVarInfo { SQLocalVarInfo():_start_op(0),_end_op(0), _pos(0){} - SQLocalVarInfo(const SQLocalVarInfo &lvi) - { - _name=lvi._name; - _start_op=lvi._start_op; - _end_op=lvi._end_op; - _pos=lvi._pos; - } SQObjectPtr _name; SQUnsignedInteger _start_op; SQUnsignedInteger _end_op; diff --git a/src/3rdparty/squirrel/squirrel/sqfuncstate.cpp b/src/3rdparty/squirrel/squirrel/sqfuncstate.cpp index 5415b566e8..c8548bac36 100644 --- a/src/3rdparty/squirrel/squirrel/sqfuncstate.cpp +++ b/src/3rdparty/squirrel/squirrel/sqfuncstate.cpp @@ -502,14 +502,14 @@ SQObject SQFuncState::CreateString(const SQChar *s,SQInteger len) { SQObjectPtr ns(SQString::Create(_sharedstate,s,len)); _table(_strings)->NewSlot(ns,(SQInteger)1); - return ns; + return std::move(ns); } SQObject SQFuncState::CreateTable() { SQObjectPtr nt(SQTable::Create(_sharedstate,0)); _table(_strings)->NewSlot(nt,(SQInteger)1); - return nt; + return std::move(nt); } SQFunctionProto *SQFuncState::BuildProto() diff --git a/src/3rdparty/squirrel/squirrel/sqmem.cpp b/src/3rdparty/squirrel/squirrel/sqmem.cpp index 5c1b3966aa..f4fa6309ed 100644 --- a/src/3rdparty/squirrel/squirrel/sqmem.cpp +++ b/src/3rdparty/squirrel/squirrel/sqmem.cpp @@ -9,8 +9,10 @@ #include "../../../core/alloc_func.hpp" #include "../../../safeguards.h" -void *sq_vm_malloc(SQUnsignedInteger size){ return MallocT((size_t)size); } +#ifdef SQUIRREL_DEFAULT_ALLOCATOR +void *sq_vm_malloc(SQUnsignedInteger size) { return MallocT((size_t)size); } -void *sq_vm_realloc(void *p, SQUnsignedInteger oldsize, SQUnsignedInteger size){ return ReallocT(static_cast(p), (size_t)size); } +void *sq_vm_realloc(void *p, SQUnsignedInteger oldsize, SQUnsignedInteger size) { return ReallocT(static_cast(p), (size_t)size); } -void sq_vm_free(void *p, SQUnsignedInteger size){ free(p); } +void sq_vm_free(void *p, SQUnsignedInteger size) { free(p); } +#endif diff --git a/src/3rdparty/squirrel/squirrel/sqvm.h b/src/3rdparty/squirrel/squirrel/sqvm.h index 89a592e136..97557b1332 100644 --- a/src/3rdparty/squirrel/squirrel/sqvm.h +++ b/src/3rdparty/squirrel/squirrel/sqvm.h @@ -12,9 +12,8 @@ void sq_base_register(HSQUIRRELVM v); struct SQExceptionTrap{ - SQExceptionTrap() {} - SQExceptionTrap(SQInteger ss, SQInteger stackbase,SQInstruction *ip, SQInteger ex_target){ _stacksize = ss; _stackbase = stackbase; _ip = ip; _extarget = ex_target;} - SQExceptionTrap(const SQExceptionTrap &et) { (*this) = et; } + SQExceptionTrap(SQInteger ss, SQInteger stackbase,SQInstruction *ip, SQInteger ex_target) + : _stackbase(stackbase), _stacksize(ss), _ip(ip), _extarget(ex_target) {} SQInteger _stackbase; SQInteger _stacksize; SQInstruction *_ip; diff --git a/src/ai/ai.hpp b/src/ai/ai.hpp index 065367d03b..713d96a868 100644 --- a/src/ai/ai.hpp +++ b/src/ai/ai.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. @@ -164,11 +162,9 @@ public: /** Gets the ScriptScanner instance that is used to find AI Libraries */ static AIScannerLibrary *GetScannerLibrary(); -#if defined(ENABLE_NETWORK) /** Wrapper function for AIScanner::HasAI */ static bool HasAI(const struct ContentInfo *ci, bool md5sum); static bool HasAILibrary(const ContentInfo *ci, bool md5sum); -#endif private: static uint frame_counter; ///< Tick counter for the AI code static class AIScannerInfo *scanner_info; ///< ScriptScanner instance that is used to find AIs diff --git a/src/ai/ai_config.cpp b/src/ai/ai_config.cpp index ea26f32679..c3c9a5c205 100644 --- a/src/ai/ai_config.cpp +++ b/src/ai/ai_config.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. @@ -31,7 +29,7 @@ ScriptConfigItem _start_date_config = { AI::START_NEXT_DEVIATION, 30, SCRIPTCONFIG_NONE, - NULL, + nullptr, false }; @@ -52,7 +50,7 @@ AIConfig::AIConfig(const AIConfig *config) : ScriptConfig(config) } else { config = &_settings_game.ai_config[company]; } - if (*config == NULL) *config = new AIConfig(); + if (*config == nullptr) *config = new AIConfig(); return *config; } @@ -69,7 +67,7 @@ ScriptInfo *AIConfig::FindInfo(const char *name, int version, bool force_exact_m bool AIConfig::ResetInfo(bool force_exact_match) { this->info = (ScriptInfo *)AI::FindInfo(this->name, force_exact_match ? this->version : -1, force_exact_match); - return this->info != NULL; + return this->info != nullptr; } void AIConfig::PushExtraConfigList() @@ -90,7 +88,7 @@ void AIConfig::ClearConfigList() int AIConfig::GetSetting(const char *name) const { - if (this->info == NULL) { + if (this->info == nullptr) { SettingValueList::const_iterator it = this->settings.find(name); if (it == this->settings.end()) { assert(strcmp("start_date", name) == 0); @@ -111,7 +109,7 @@ int AIConfig::GetSetting(const char *name) const void AIConfig::SetSetting(const char *name, int value) { - if (this->info == NULL) { + if (this->info == nullptr) { if (strcmp("start_date", name) != 0) return; value = Clamp(value, AI::START_NEXT_MIN, AI::START_NEXT_MAX); diff --git a/src/ai/ai_config.hpp b/src/ai/ai_config.hpp index 12cc02a497..6c861126e0 100644 --- a/src/ai/ai_config.hpp +++ b/src/ai/ai_config.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. @@ -30,8 +28,9 @@ public: class AIInfo *GetInfo() const; - /* virtual */ int GetSetting(const char *name) const; - /* virtual */ void SetSetting(const char *name, int value); + int GetSetting(const char *name) const override; + void SetSetting(const char *name, int value) override; + void AddRandomDeviation() override; /** * When ever the AI Scanner is reloaded, all infos become invalid. This @@ -44,9 +43,9 @@ public: bool ResetInfo(bool force_exact_match); protected: - /* virtual */ void PushExtraConfigList(); - /* virtual */ void ClearConfigList(); - /* virtual */ ScriptInfo *FindInfo(const char *name, int version, bool force_exact_match); + void PushExtraConfigList() override; + void ClearConfigList() override; + ScriptInfo *FindInfo(const char *name, int version, bool force_exact_match) override; }; #endif /* AI_CONFIG_HPP */ diff --git a/src/ai/ai_core.cpp b/src/ai/ai_core.cpp index 51522edaff..95c971af8e 100644 --- a/src/ai/ai_core.cpp +++ b/src/ai/ai_core.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. @@ -26,8 +24,8 @@ #include "../safeguards.h" /* static */ uint AI::frame_counter = 0; -/* static */ AIScannerInfo *AI::scanner_info = NULL; -/* static */ AIScannerLibrary *AI::scanner_library = NULL; +/* static */ AIScannerInfo *AI::scanner_info = nullptr; +/* static */ AIScannerLibrary *AI::scanner_library = nullptr; /* static */ bool AI::CanStartNew() { @@ -44,19 +42,19 @@ AIConfig *config = AIConfig::GetConfig(company, AIConfig::SSS_FORCE_GAME); AIInfo *info = config->GetInfo(); - if (info == NULL || (rerandomise_ai && config->IsRandom())) { + if (info == nullptr || (rerandomise_ai && config->IsRandom())) { info = AI::scanner_info->SelectRandomAI(); - assert(info != NULL); + assert(info != nullptr); /* Load default data and store the name in the settings */ config->Change(info->GetName(), -1, false, true); } config->AnchorUnchangeableSettings(); - Backup cur_company(_current_company, company, FILE_LINE); + Backup cur_company(_current_company, company, FILE_LINE); Company *c = Company::Get(company); c->ai_info = info; - assert(c->ai_instance == NULL); + assert(c->ai_instance == nullptr); c->ai_instance = new AIInstance(); c->ai_instance->Initialize(info); @@ -76,9 +74,8 @@ assert(_settings_game.difficulty.competitor_speed <= 4); if ((AI::frame_counter & ((1 << (4 - _settings_game.difficulty.competitor_speed)) - 1)) != 0) return; - Backup cur_company(_current_company, FILE_LINE); - const Company *c; - FOR_ALL_COMPANIES(c) { + Backup cur_company(_current_company, FILE_LINE); + for (const Company *c : Company::Iterate()) { if (c->is_ai) { PerformanceMeasurer framerate((PerformanceElement)(PFE_AI0 + c->index)); cur_company.Change(c->index); @@ -107,12 +104,12 @@ if (_networking && !_network_server) return; PerformanceMeasurer::SetInactive((PerformanceElement)(PFE_AI0 + company)); - Backup cur_company(_current_company, company, FILE_LINE); + Backup cur_company(_current_company, company, FILE_LINE); Company *c = Company::Get(company); delete c->ai_instance; - c->ai_instance = NULL; - c->ai_info = NULL; + c->ai_instance = nullptr; + c->ai_info = nullptr; cur_company.Restore(); @@ -127,7 +124,7 @@ * for the server owner to unpause the script again. */ if (_network_dedicated) return; - Backup cur_company(_current_company, company, FILE_LINE); + Backup cur_company(_current_company, company, FILE_LINE); Company::Get(company)->ai_instance->Pause(); cur_company.Restore(); @@ -135,7 +132,7 @@ /* static */ void AI::Unpause(CompanyID company) { - Backup cur_company(_current_company, company, FILE_LINE); + Backup cur_company(_current_company, company, FILE_LINE); Company::Get(company)->ai_instance->Unpause(); cur_company.Restore(); @@ -143,7 +140,7 @@ /* static */ bool AI::IsPaused(CompanyID company) { - Backup cur_company(_current_company, company, FILE_LINE); + Backup cur_company(_current_company, company, FILE_LINE); bool paused = Company::Get(company)->ai_instance->IsPaused(); cur_company.Restore(); @@ -156,18 +153,17 @@ /* It might happen there are no companies .. than we have nothing to loop */ if (Company::GetPoolSize() == 0) return; - const Company *c; - FOR_ALL_COMPANIES(c) { + for (const Company *c : Company::Iterate()) { if (c->is_ai) AI::Stop(c->index); } } /* static */ void AI::Initialize() { - if (AI::scanner_info != NULL) AI::Uninitialize(true); + if (AI::scanner_info != nullptr) AI::Uninitialize(true); AI::frame_counter = 0; - if (AI::scanner_info == NULL) { + if (AI::scanner_info == nullptr) { TarScanner::DoScan(TarScanner::AI); AI::scanner_info = new AIScannerInfo(); AI::scanner_info->Initialize(); @@ -187,17 +183,17 @@ } else { delete AI::scanner_info; delete AI::scanner_library; - AI::scanner_info = NULL; - AI::scanner_library = NULL; + AI::scanner_info = nullptr; + AI::scanner_library = nullptr; for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) { - if (_settings_game.ai_config[c] != NULL) { + if (_settings_game.ai_config[c] != nullptr) { delete _settings_game.ai_config[c]; - _settings_game.ai_config[c] = NULL; + _settings_game.ai_config[c] = nullptr; } - if (_settings_newgame.ai_config[c] != NULL) { + if (_settings_newgame.ai_config[c] != nullptr) { delete _settings_newgame.ai_config[c]; - _settings_newgame.ai_config[c] = NULL; + _settings_newgame.ai_config[c] = nullptr; } } } @@ -209,10 +205,10 @@ * the AIConfig. If not, remove the AI from the list (which will assign * a random new AI on reload). */ for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) { - if (_settings_game.ai_config[c] != NULL && _settings_game.ai_config[c]->HasScript()) { + if (_settings_game.ai_config[c] != nullptr && _settings_game.ai_config[c]->HasScript()) { if (!_settings_game.ai_config[c]->ResetInfo(true)) { DEBUG(script, 0, "After a reload, the AI by the name '%s' was no longer found, and removed from the list.", _settings_game.ai_config[c]->GetName()); - _settings_game.ai_config[c]->Change(NULL); + _settings_game.ai_config[c]->Change(nullptr); if (Company::IsValidAiID(c)) { /* The code belonging to an already running AI was deleted. We can only do * one thing here to keep everything sane and that is kill the AI. After @@ -226,10 +222,10 @@ Company::Get(c)->ai_info = _settings_game.ai_config[c]->GetInfo(); } } - if (_settings_newgame.ai_config[c] != NULL && _settings_newgame.ai_config[c]->HasScript()) { + if (_settings_newgame.ai_config[c] != nullptr && _settings_newgame.ai_config[c]->HasScript()) { if (!_settings_newgame.ai_config[c]->ResetInfo(false)) { DEBUG(script, 0, "After a reload, the AI by the name '%s' was no longer found, and removed from the list.", _settings_newgame.ai_config[c]->GetName()); - _settings_newgame.ai_config[c]->Change(NULL); + _settings_newgame.ai_config[c]->Change(nullptr); } } } @@ -253,7 +249,7 @@ } /* Queue the event */ - Backup cur_company(_current_company, company, FILE_LINE); + Backup cur_company(_current_company, company, FILE_LINE); Company::Get(_current_company)->ai_instance->InsertEvent(event); cur_company.Restore(); @@ -283,9 +279,9 @@ { if (!_networking || _network_server) { Company *c = Company::GetIfValid(company); - assert(c != NULL && c->ai_instance != NULL); + assert(c != nullptr && c->ai_instance != nullptr); - Backup cur_company(_current_company, company, FILE_LINE); + Backup cur_company(_current_company, company, FILE_LINE); c->ai_instance->Save(); cur_company.Restore(); } else { @@ -297,9 +293,9 @@ { if (!_networking || _network_server) { Company *c = Company::GetIfValid(company); - assert(c != NULL && c->ai_instance != NULL); + assert(c != nullptr && c->ai_instance != nullptr); - Backup cur_company(_current_company, company, FILE_LINE); + Backup cur_company(_current_company, company, FILE_LINE); c->ai_instance->Load(version); cur_company.Restore(); } else { @@ -362,8 +358,6 @@ InvalidateWindowClassesData(WC_AI_SETTINGS); } -#if defined(ENABLE_NETWORK) - /** * Check whether we have an AI (library) with the exact characteristics as ci. * @param ci the characteristics to search on (shortname and md5sum) @@ -380,8 +374,6 @@ return AI::scanner_library->HasScript(ci, md5sum); } -#endif /* defined(ENABLE_NETWORK) */ - /* static */ AIScannerInfo *AI::GetScannerInfo() { return AI::scanner_info; diff --git a/src/ai/ai_gui.cpp b/src/ai/ai_gui.cpp index 4a949267fd..b3da614c6e 100644 --- a/src/ai/ai_gui.cpp +++ b/src/ai/ai_gui.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. @@ -98,7 +96,7 @@ struct AIListWindow : public Window { } } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { switch (widget) { case WID_AIL_CAPTION: @@ -107,7 +105,7 @@ struct AIListWindow : public Window { } } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { if (widget == WID_AIL_LIST) { this->line_height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM); @@ -118,7 +116,7 @@ struct AIListWindow : public Window { } } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { switch (widget) { case WID_AIL_LIST: { @@ -139,13 +137,13 @@ struct AIListWindow : public Window { break; } case WID_AIL_INFO_BG: { - AIInfo *selected_info = NULL; + AIInfo *selected_info = nullptr; ScriptInfoList::const_iterator it = this->info_list->begin(); - for (int i = 1; selected_info == NULL && it != this->info_list->end(); i++, it++) { + for (int i = 1; selected_info == nullptr && it != this->info_list->end(); i++, it++) { if (this->selected == i - 1) selected_info = static_cast((*it).second); } /* Some info about the currently selected AI. */ - if (selected_info != NULL) { + 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); @@ -153,7 +151,7 @@ struct AIListWindow : public Window { 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() != NULL) { + 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; @@ -172,7 +170,7 @@ struct AIListWindow : public Window { void ChangeAI() { if (this->selected == -1) { - GetConfig(slot)->Change(NULL); + GetConfig(slot)->Change(nullptr); } else { ScriptInfoList::const_iterator it = this->info_list->begin(); for (int i = 0; i < this->selected; i++) it++; @@ -181,9 +179,10 @@ struct AIListWindow : public Window { InvalidateWindowData(WC_GAME_OPTIONS, WN_GAME_OPTIONS_AI); InvalidateWindowClassesData(WC_AI_SETTINGS); DeleteWindowByClass(WC_QUERY_STRING); + InvalidateWindowClassesData(WC_TEXTFILE); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_AIL_LIST: { // Select one of the AIs @@ -211,7 +210,7 @@ struct AIListWindow : public Window { } } - virtual void OnResize() + void OnResize() override { this->vscroll->SetCapacityFromWidget(this, WID_AIL_LIST); } @@ -221,7 +220,7 @@ struct AIListWindow : public Window { * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (_game_mode == GM_NORMAL && Company::IsValidID(this->slot)) { delete this; @@ -317,7 +316,7 @@ struct AISettingsWindow : public Window { this->RebuildVisibleSettings(); } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { switch (widget) { case WID_AIS_CAPTION: @@ -346,7 +345,7 @@ struct AISettingsWindow : public Window { this->vscroll->SetCount((int)this->visible_settings.size()); } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { if (widget == WID_AIS_BACKGROUND) { this->line_height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM); @@ -357,7 +356,7 @@ struct AISettingsWindow : public Window { } } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { if (widget != WID_AIS_BACKGROUND) return; @@ -406,7 +405,7 @@ struct AISettingsWindow : public Window { } 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 != NULL && config_item.labels->Contains(current_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 { @@ -420,7 +419,7 @@ struct AISettingsWindow : public Window { } } - virtual void OnPaint() + void OnPaint() override { if (this->closing_dropdown) { this->closing_dropdown = false; @@ -429,7 +428,7 @@ struct AISettingsWindow : public Window { this->DrawWidgets(); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_AIS_BACKGROUND: { @@ -478,12 +477,12 @@ struct AISettingsWindow : public Window { this->clicked_dropdown = true; this->closing_dropdown = false; - DropDownList *list = new DropDownList(); + DropDownList list; for (int i = config_item.min_value; i <= config_item.max_value; i++) { - *list->Append() = new DropDownListCharStringItem(config_item.labels->Find(i)->second, i, false); + list.emplace_back(new DropDownListCharStringItem(config_item.labels->Find(i)->second, i, false)); } - ShowDropDownListAt(this, list, old_val, -1, wi_rect, COLOUR_ORANGE, true); + ShowDropDownListAt(this, std::move(list), old_val, -1, wi_rect, COLOUR_ORANGE, true); } } } else if (IsInsideMM(x, 0, SETTING_BUTTON_WIDTH)) { @@ -529,7 +528,7 @@ struct AISettingsWindow : public Window { } } - virtual void OnQueryTextFinished(char *str) + void OnQueryTextFinished(char *str) override { if (StrEmpty(str)) return; VisibleSettingsList::const_iterator it = this->visible_settings.begin(); @@ -541,7 +540,7 @@ struct AISettingsWindow : public Window { this->SetDirty(); } - virtual void OnDropdownSelect(int widget, int index) + void OnDropdownSelect(int widget, int index) override { assert(this->clicked_dropdown); VisibleSettingsList::const_iterator it = this->visible_settings.begin(); @@ -552,7 +551,7 @@ struct AISettingsWindow : public Window { this->SetDirty(); } - virtual void OnDropdownClose(Point pt, int widget, int index, bool instant_close) + 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. @@ -563,12 +562,12 @@ struct AISettingsWindow : public Window { this->SetDirty(); } - virtual void OnResize() + void OnResize() override { this->vscroll->SetCapacityFromWidget(this, WID_AIS_BACKGROUND); } - virtual void OnRealtimeTick(uint delta_ms) + void OnRealtimeTick(uint delta_ms) override { if (this->timeout.Elapsed(delta_ms)) { this->clicked_button = -1; @@ -581,7 +580,7 @@ struct AISettingsWindow : public Window { * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { this->RebuildVisibleSettings(); HideDropDownMenu(this); @@ -641,15 +640,24 @@ struct ScriptTextfileWindow : public TextfileWindow { ScriptTextfileWindow(TextfileType file_type, CompanyID slot) : TextfileWindow(file_type), slot(slot) { - const char *textfile = GetConfig(slot)->GetTextfile(file_type, slot); - this->LoadTextfile(textfile, (slot == OWNER_DEITY) ? GAME_DIR : AI_DIR); + this->OnInvalidateData(); } - /* virtual */ void SetStringParameters(int widget) const + 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)->GetName()); + 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) { + delete this; + } else { + this->LoadTextfile(textfile, (slot == OWNER_DEITY) ? GAME_DIR : AI_DIR); } } }; @@ -744,7 +752,7 @@ struct AIConfigWindow : public Window { DeleteWindowByClass(WC_AI_SETTINGS); } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { switch (widget) { case WID_AIC_NUMBER: @@ -768,7 +776,7 @@ struct AIConfigWindow : public Window { } } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_AIC_GAMELIST: @@ -806,12 +814,12 @@ struct AIConfigWindow : public Window { */ static bool IsEditable(CompanyID slot) { - if (slot == OWNER_DEITY) return _game_mode != GM_NORMAL || Game::GetInstance() != NULL; + 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; } - if (Company::IsValidID(slot) || slot < 0) return false; + if (Company::IsValidID(slot)) return false; int max_slot = GetGameSettings().difficulty.max_no_competitors; for (CompanyID cid = COMPANY_FIRST; cid < (CompanyID)max_slot && cid < MAX_COMPANIES; cid++) { @@ -820,13 +828,13 @@ struct AIConfigWindow : public Window { return slot < max_slot; } - virtual void DrawWidget(const Rect &r, int widget) const + 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() != NULL) { + if (GameConfig::GetConfig()->GetInfo() != nullptr) { SetDParamStr(0, GameConfig::GetConfig()->GetInfo()->GetName()); text = STR_JUST_RAW_STRING; } @@ -844,7 +852,7 @@ struct AIConfigWindow : public Window { if ((_game_mode != GM_NORMAL && i == 0) || (_game_mode == GM_NORMAL && Company::IsValidHumanID(i))) { text = STR_AI_CONFIG_HUMAN_PLAYER; - } else if (AIConfig::GetConfig((CompanyID)i)->GetInfo() != NULL) { + } else if (AIConfig::GetConfig((CompanyID)i)->GetInfo() != nullptr) { SetDParamStr(0, AIConfig::GetConfig((CompanyID)i)->GetInfo()->GetName()); text = STR_JUST_RAW_STRING; } else { @@ -859,10 +867,10 @@ struct AIConfigWindow : public Window { } } - virtual void OnClick(Point pt, int widget, int click_count) + 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) == NULL) return; + if (this->selected_slot == INVALID_COMPANY || GetConfig(this->selected_slot) == nullptr) return; ShowScriptTextfileWindow((TextfileType)(widget - WID_AIC_TEXTFILE), this->selected_slot); return; @@ -929,9 +937,7 @@ struct AIConfigWindow : public Window { if (!_network_available) { ShowErrorMessage(STR_NETWORK_ERROR_NOTAVAILABLE, INVALID_STRING_ID, WL_ERROR); } else { -#if defined(ENABLE_NETWORK) - ShowNetworkContentListWindow(NULL, CONTENT_TYPE_AI, CONTENT_TYPE_GAME); -#endif + ShowNetworkContentListWindow(nullptr, CONTENT_TYPE_AI, CONTENT_TYPE_GAME); } break; } @@ -942,7 +948,7 @@ struct AIConfigWindow : public Window { * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!IsEditable(this->selected_slot)) { this->selected_slot = INVALID_COMPANY; @@ -958,7 +964,7 @@ struct AIConfigWindow : public Window { this->SetWidgetDisabledState(WID_AIC_MOVE_DOWN, this->selected_slot == OWNER_DEITY || 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) == NULL)); + this->SetWidgetDisabledState(WID_AIC_TEXTFILE + tft, this->selected_slot == INVALID_COMPANY || (GetConfig(this->selected_slot)->GetTextfile(tft, this->selected_slot) == nullptr)); } } }; @@ -1027,7 +1033,7 @@ struct AIDebugWindow : public Window { { if (ai_debug_company == OWNER_DEITY) { GameInstance *game = Game::GetInstance(); - return game == NULL || game->IsDead(); + return game == nullptr || game->IsDead(); } return !Company::IsValidAiID(ai_debug_company) || Company::Get(ai_debug_company)->ai_instance->IsDead(); } @@ -1041,7 +1047,7 @@ struct AIDebugWindow : public Window { { switch (company) { case INVALID_COMPANY: return false; - case OWNER_DEITY: return Game::GetInstance() != NULL; + case OWNER_DEITY: return Game::GetInstance() != nullptr; default: return Company::IsValidAiID(company); } } @@ -1057,8 +1063,7 @@ struct AIDebugWindow : public Window { ai_debug_company = INVALID_COMPANY; - const Company *c; - FOR_ALL_COMPANIES(c) { + for (const Company *c : Company::Iterate()) { if (c->is_ai) { ChangeToAI(c->index); return; @@ -1066,7 +1071,7 @@ struct AIDebugWindow : public Window { } /* If no AI is available, see if there is a game script. */ - if (Game::GetInstance() != NULL) ChangeToAI(OWNER_DEITY); + if (Game::GetInstance() != nullptr) ChangeToAI(OWNER_DEITY); } /** @@ -1099,7 +1104,7 @@ struct AIDebugWindow : public Window { this->InvalidateData(-1); } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { if (widget == WID_AID_LOG_PANEL) { resize->height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL); @@ -1107,7 +1112,7 @@ struct AIDebugWindow : public Window { } } - virtual void OnPaint() + void OnPaint() override { this->SelectValidDebugCompany(); @@ -1145,7 +1150,7 @@ struct AIDebugWindow : public Window { /* Set button colour for Game Script. */ GameInstance *game = Game::GetInstance(); - bool valid = game != NULL; + bool valid = game != nullptr; bool dead = valid && game->IsDead(); bool paused = valid && game->IsPaused(); @@ -1159,7 +1164,7 @@ struct AIDebugWindow : public Window { ScriptLog::LogData *log = this->GetLogPointer(); - int scroll_count = (log == NULL) ? 0 : log->used; + int scroll_count = (log == nullptr) ? 0 : log->used; if (this->vscroll->GetCount() != scroll_count) { this->vscroll->SetCount(scroll_count); @@ -1167,7 +1172,7 @@ struct AIDebugWindow : public Window { this->SetWidgetDirty(WID_AID_SCROLLBAR); } - if (log == NULL) return; + if (log == nullptr) return; /* Detect when the user scrolls the window. Enable autoscroll when the * bottom-most line becomes visible. */ @@ -1187,13 +1192,13 @@ struct AIDebugWindow : public Window { this->last_vscroll_pos = this->vscroll->GetPosition(); } - virtual void SetStringParameters(int widget) const + 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 != NULL); + assert(info != nullptr); SetDParam(0, STR_AI_DEBUG_NAME_AND_VERSION); SetDParamStr(1, info->GetName()); SetDParam(2, info->GetVersion()); @@ -1201,7 +1206,7 @@ struct AIDebugWindow : public Window { SetDParam(0, STR_EMPTY); } else { const AIInfo *info = Company::Get(ai_debug_company)->ai_info; - assert(info != NULL); + assert(info != nullptr); SetDParam(0, STR_AI_DEBUG_NAME_AND_VERSION); SetDParamStr(1, info->GetName()); SetDParam(2, info->GetVersion()); @@ -1210,19 +1215,19 @@ struct AIDebugWindow : public Window { } } - virtual void DrawWidget(const Rect &r, int widget) const + 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 == NULL) return; + if (log == nullptr) return; int y = Center(this->top_offset, this->resize.step_height); 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] == NULL) break; + if (log->lines[pos] == nullptr) break; TextColour colour; switch (log->type[pos]) { @@ -1269,7 +1274,7 @@ struct AIDebugWindow : public Window { this->last_vscroll_pos = this->vscroll->GetPosition(); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { /* Also called for hotkeys, so check for disabledness */ if (this->IsWidgetDisabled(widget)) return; @@ -1287,7 +1292,7 @@ struct AIDebugWindow : public Window { 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 */ - DoCommandP(0, CCA_DELETE | ai_debug_company << 16, CRR_MANUAL, CMD_COMPANY_CTRL); + DoCommandP(0, CCA_DELETE | ai_debug_company << 16 | CRR_MANUAL << 24, 0, CMD_COMPANY_CTRL); DoCommandP(0, CCA_NEW_AI | ai_debug_company << 16, 0, CMD_COMPANY_CTRL); break; @@ -1319,8 +1324,7 @@ struct AIDebugWindow : public Window { if ((_pause_mode & PM_PAUSED_NORMAL) == PM_PAUSED_NORMAL) { bool all_unpaused = !Game::IsPaused(); if (all_unpaused) { - Company *c; - FOR_ALL_COMPANIES(c) { + for (const Company *c : Company::Iterate()) { if (c->is_ai && AI::IsPaused(c->index)) { all_unpaused = false; break; @@ -1339,7 +1343,7 @@ struct AIDebugWindow : public Window { } } - virtual void OnEditboxChanged(int wid) + 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. */ @@ -1354,7 +1358,7 @@ struct AIDebugWindow : public Window { * 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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + 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. */ @@ -1362,7 +1366,7 @@ struct AIDebugWindow : public Window { /* Get the log instance of the active company */ ScriptLog::LogData *log = this->GetLogPointer(); - if (log != NULL) { + if (log != nullptr) { this->break_string_filter.ResetState(); this->break_string_filter.AddLine(log->lines[log->pos]); if (this->break_string_filter.GetState()) { @@ -1390,8 +1394,8 @@ struct AIDebugWindow : public Window { this->SelectValidDebugCompany(); - ScriptLog::LogData *log = ai_debug_company != INVALID_COMPANY ? this->GetLogPointer() : NULL; - this->vscroll->SetCount((log == NULL) ? 0 : log->used); + 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++) { @@ -1399,7 +1403,7 @@ struct AIDebugWindow : public Window { this->SetWidgetLoweredState(i + WID_AID_COMPANY_BUTTON_START, ai_debug_company == i); } - this->SetWidgetDisabledState(WID_AID_SCRIPT_GAME, Game::GetGameInstance() == NULL); + 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); @@ -1411,7 +1415,7 @@ struct AIDebugWindow : public Window { (ai_debug_company == OWNER_DEITY ? !Game::IsPaused() : !AI::IsPaused(ai_debug_company))); } - virtual void OnResize() + void OnResize() override { this->vscroll->SetCapacityFromWidget(this, WID_AID_LOG_PANEL); } @@ -1442,7 +1446,7 @@ static EventState AIDebugGlobalHotkeys(int hotkey) { if (_game_mode != GM_NORMAL) return ES_NOT_HANDLED; Window *w = ShowAIDebugWindow(INVALID_COMPANY); - if (w == NULL) return ES_NOT_HANDLED; + if (w == nullptr) return ES_NOT_HANDLED; return w->OnHotkey(hotkey); } @@ -1535,14 +1539,14 @@ Window *ShowAIDebugWindow(CompanyID show_company) { if (!_networking || _network_server) { AIDebugWindow *w = (AIDebugWindow *)BringWindowToFrontById(WC_AI_DEBUG, 0); - if (w == NULL) w = new AIDebugWindow(&_ai_debug_desc, 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 NULL; + return nullptr; } /** @@ -1559,8 +1563,7 @@ void ShowAIDebugWindowIfAIError() /* Network clients can't debug AIs. */ if (_networking && !_network_server) return; - Company *c; - FOR_ALL_COMPANIES(c) { + for (const Company *c : Company::Iterate()) { if (c->is_ai && c->ai_instance->IsDead()) { ShowAIDebugWindow(c->index); break; @@ -1568,7 +1571,7 @@ void ShowAIDebugWindowIfAIError() } GameInstance *g = Game::GetGameInstance(); - if (g != NULL && g->IsDead()) { + if (g != nullptr && g->IsDead()) { ShowAIDebugWindow(OWNER_DEITY); } } diff --git a/src/ai/ai_gui.hpp b/src/ai/ai_gui.hpp index ad6eed8fd1..12c8ca859b 100644 --- a/src/ai/ai_gui.hpp +++ b/src/ai/ai_gui.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/ai/ai_info.cpp b/src/ai/ai_info.cpp index 43a4345460..2d80003f6b 100644 --- a/src/ai/ai_info.cpp +++ b/src/ai/ai_info.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. @@ -29,7 +27,7 @@ static bool CheckAPIVersion(const char *api_version) return strcmp(api_version, "0.7") == 0 || strcmp(api_version, "1.0") == 0 || strcmp(api_version, "1.1") == 0 || strcmp(api_version, "1.2") == 0 || strcmp(api_version, "1.3") == 0 || strcmp(api_version, "1.4") == 0 || strcmp(api_version, "1.5") == 0 || strcmp(api_version, "1.6") == 0 || strcmp(api_version, "1.7") == 0 || - strcmp(api_version, "1.8") == 0 || strcmp(api_version, "1.9") == 0; + strcmp(api_version, "1.8") == 0 || strcmp(api_version, "1.9") == 0 || strcmp(api_version, "1.10") == 0; } #if defined(_WIN32) @@ -65,8 +63,8 @@ template <> const char *GetClassName() { return "AIInfo"; } /* static */ SQInteger AIInfo::Constructor(HSQUIRRELVM vm) { /* Get the AIInfo */ - SQUserPointer instance = NULL; - if (SQ_FAILED(sq_getinstanceup(vm, 2, &instance, 0)) || instance == NULL) return sq_throwerror(vm, "Pass an instance of a child class of AIInfo to RegisterAI"); + SQUserPointer instance = nullptr; + if (SQ_FAILED(sq_getinstanceup(vm, 2, &instance, 0)) || instance == nullptr) return sq_throwerror(vm, "Pass an instance of a child class of AIInfo to RegisterAI"); AIInfo *info = (AIInfo *)instance; SQInteger res = ScriptInfo::Constructor(vm, info); @@ -100,7 +98,7 @@ template <> const char *GetClassName() { return "AIInfo"; } } /* Remove the link to the real instance, else it might get deleted by RegisterAI() */ - sq_setinstanceup(vm, 2, NULL); + sq_setinstanceup(vm, 2, nullptr); /* Register the AI to the base system */ info->GetScanner()->RegisterScript(info); return 0; @@ -112,7 +110,7 @@ template <> const char *GetClassName() { return "AIInfo"; } SQUserPointer instance; sq_getinstanceup(vm, 2, &instance, 0); AIInfo *info = (AIInfo *)instance; - info->api_version = NULL; + info->api_version = nullptr; SQInteger res = ScriptInfo::Constructor(vm, info); if (res != 0) return res; @@ -122,7 +120,7 @@ template <> const char *GetClassName() { return "AIInfo"; } info->api_version = stredup(buf); /* Remove the link to the real instance, else it might get deleted by RegisterAI() */ - sq_setinstanceup(vm, 2, NULL); + sq_setinstanceup(vm, 2, nullptr); /* Register the AI to the base system */ static_cast(info->GetScanner())->SetDummyAI(info); return 0; @@ -131,7 +129,7 @@ template <> const char *GetClassName() { return "AIInfo"; } AIInfo::AIInfo() : min_loadable_version(0), use_as_random(false), - api_version(NULL) + api_version(nullptr) { } diff --git a/src/ai/ai_info.hpp b/src/ai/ai_info.hpp index 51cfb7d8a0..8f236e09ab 100644 --- a/src/ai/ai_info.hpp +++ b/src/ai/ai_info.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. @@ -59,7 +57,7 @@ private: /** All static information from an AI library like name, version, etc. */ class AILibrary : public ScriptInfo { public: - AILibrary() : ScriptInfo(), category(NULL) {}; + AILibrary() : ScriptInfo(), category(nullptr) {}; ~AILibrary(); /** diff --git a/src/ai/ai_instance.cpp b/src/ai/ai_instance.cpp index c03e745992..a4d06763fa 100644 --- a/src/ai/ai_instance.cpp +++ b/src/ai/ai_instance.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. @@ -62,6 +60,7 @@ #include "../script/api/ai/ai_rail.hpp.sq" #include "../script/api/ai/ai_railtypelist.hpp.sq" #include "../script/api/ai/ai_road.hpp.sq" +#include "../script/api/ai/ai_roadtypelist.hpp.sq" #include "../script/api/ai/ai_sign.hpp.sq" #include "../script/api/ai/ai_signlist.hpp.sq" #include "../script/api/ai/ai_station.hpp.sq" @@ -145,6 +144,7 @@ void AIInstance::RegisterAPI() SQAIEventSubsidyOffer_Register(this->engine); SQAIEventSubsidyOfferExpired_Register(this->engine); SQAIEventTownFounded_Register(this->engine); + SQAIEventVehicleAutoReplaced_Register(this->engine); SQAIEventVehicleCrashed_Register(this->engine); SQAIEventVehicleLost_Register(this->engine); SQAIEventVehicleUnprofitable_Register(this->engine); @@ -167,6 +167,7 @@ void AIInstance::RegisterAPI() SQAIRail_Register(this->engine); SQAIRailTypeList_Register(this->engine); SQAIRoad_Register(this->engine); + SQAIRoadTypeList_Register(this->engine); SQAISign_Register(this->engine); SQAISignList_Register(this->engine); SQAIStation_Register(this->engine); @@ -216,10 +217,10 @@ void AIInstance::Died() ShowAIDebugWindow(_current_company); const AIInfo *info = AIConfig::GetConfig(_current_company, AIConfig::SSS_FORCE_GAME)->GetInfo(); - if (info != NULL) { + if (info != nullptr) { ShowErrorMessage(STR_ERROR_AI_PLEASE_REPORT_CRASH, INVALID_STRING_ID, WL_WARNING); - if (info->GetURL() != NULL) { + if (info->GetURL() != nullptr) { ScriptLog::Info("Please report the error to the following URL:"); ScriptLog::Info(info->GetURL()); } @@ -228,6 +229,7 @@ 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"); } @@ -248,8 +250,9 @@ ScriptInfo *AIInstance::FindLibrary(const char *library, int version) * @param tile The tile on which the command was executed. * @param p1 p1 as given to DoCommandPInternal. * @param p2 p2 as given to DoCommandPInternal. + * @param cmd cmd as given to DoCommandPInternal. */ -void CcAI(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) +void CcAI(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) { /* * The company might not exist anymore. Check for this. @@ -258,10 +261,11 @@ void CcAI(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) * when the company does not exist anymore. */ const Company *c = Company::GetIfValid(_current_company); - if (c == NULL || c->ai_instance == NULL) return; + if (c == nullptr || c->ai_instance == nullptr) return; - c->ai_instance->DoCommandCallback(result, tile, p1, p2); - c->ai_instance->Continue(); + if (c->ai_instance->DoCommandCallback(result, tile, p1, p2, cmd)) { + c->ai_instance->Continue(); + } } CommandCallback *AIInstance::GetDoCommandCallback() diff --git a/src/ai/ai_instance.hpp b/src/ai/ai_instance.hpp index 204bf9712a..f8d2100b1c 100644 --- a/src/ai/ai_instance.hpp +++ b/src/ai/ai_instance.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. @@ -25,14 +23,14 @@ public: */ void Initialize(class AIInfo *info); - /* virtual */ int GetSetting(const char *name); - /* virtual */ ScriptInfo *FindLibrary(const char *library, int version); + int GetSetting(const char *name) override; + ScriptInfo *FindLibrary(const char *library, int version) override; private: - /* virtual */ void RegisterAPI(); - /* virtual */ void Died(); - /* virtual */ CommandCallback *GetDoCommandCallback(); - /* virtual */ void LoadDummyScript(); + void RegisterAPI() override; + void Died() override; + CommandCallback *GetDoCommandCallback() override; + void LoadDummyScript() override; }; #endif /* AI_INSTANCE_HPP */ diff --git a/src/ai/ai_scanner.cpp b/src/ai/ai_scanner.cpp index 5f16de3f91..ee14fd2147 100644 --- a/src/ai/ai_scanner.cpp +++ b/src/ai/ai_scanner.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. @@ -23,7 +21,7 @@ AIScannerInfo::AIScannerInfo() : ScriptScanner(), - info_dummy(NULL) + info_dummy(nullptr) { } @@ -31,6 +29,8 @@ void AIScannerInfo::Initialize() { ScriptScanner::Initialize("AIScanner"); + ScriptAllocatorScope alloc_scope(this->engine); + /* Create the dummy AI */ free(this->main_script); this->main_script = stredup("%_dummy"); @@ -94,14 +94,14 @@ AIInfo *AIScannerInfo::SelectRandomAI() const AIInfo *AIScannerInfo::FindInfo(const char *nameParam, int versionParam, bool force_exact_match) { - if (this->info_list.size() == 0) return NULL; - if (nameParam == NULL) return NULL; + if (this->info_list.size() == 0) return nullptr; + if (nameParam == nullptr) return nullptr; char ai_name[1024]; strecpy(ai_name, nameParam, lastof(ai_name)); strtolower(ai_name); - AIInfo *info = NULL; + AIInfo *info = nullptr; int version = -1; if (versionParam == -1) { @@ -110,7 +110,7 @@ AIInfo *AIScannerInfo::FindInfo(const char *nameParam, int versionParam, bool fo /* If we didn't find a match AI, maybe the user included a version */ char *e = strrchr(ai_name, '.'); - if (e == NULL) return NULL; + if (e == nullptr) return nullptr; *e = '\0'; e++; versionParam = atoi(e); @@ -165,7 +165,7 @@ AILibrary *AIScannerLibrary::FindLibrary(const char *library, int version) /* Check if the library + version exists */ ScriptInfoList::iterator iter = this->info_list.find(library_name); - if (iter == this->info_list.end()) return NULL; + if (iter == this->info_list.end()) return nullptr; return static_cast((*iter).second); } diff --git a/src/ai/ai_scanner.hpp b/src/ai/ai_scanner.hpp index d8e8a6993d..4faee9c62f 100644 --- a/src/ai/ai_scanner.hpp +++ b/src/ai/ai_scanner.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. @@ -19,7 +17,7 @@ public: AIScannerInfo(); ~AIScannerInfo(); - /* virtual */ void Initialize(); + void Initialize() override; /** * Select a random AI. @@ -32,7 +30,7 @@ public: * @param nameParam The name of the AI. * @param versionParam The version of the AI, or -1 if you want the latest. * @param force_exact_match Only match name+version, never latest. - * @return NULL if no match found, otherwise the AI that matched. + * @return nullptr if no match found, otherwise the AI that matched. */ class AIInfo *FindInfo(const char *nameParam, int versionParam, bool force_exact_match); @@ -42,11 +40,11 @@ public: void SetDummyAI(class AIInfo *info); protected: - /* virtual */ void GetScriptName(ScriptInfo *info, char *name, const char *last); - /* virtual */ const char *GetFileName() const { return PATHSEP "info.nut"; } - /* virtual */ Subdirectory GetDirectory() const { return AI_DIR; } - /* virtual */ const char *GetScannerName() const { return "AIs"; } - /* virtual */ void RegisterAPI(class Squirrel *engine); + void GetScriptName(ScriptInfo *info, char *name, const char *last) override; + const char *GetFileName() const override { return PATHSEP "info.nut"; } + Subdirectory GetDirectory() const override { return AI_DIR; } + const char *GetScannerName() const override { return "AIs"; } + void RegisterAPI(class Squirrel *engine) override; private: AIInfo *info_dummy; ///< The dummy AI. @@ -54,22 +52,22 @@ private: class AIScannerLibrary : public ScriptScanner { public: - /* virtual */ void Initialize(); + void Initialize() override; /** * Find a library in the pool. * @param library The library name to find. * @param version The version the library should have. - * @return The library if found, NULL otherwise. + * @return The library if found, nullptr otherwise. */ class AILibrary *FindLibrary(const char *library, int version); protected: - /* virtual */ void GetScriptName(ScriptInfo *info, char *name, const char *last); - /* virtual */ const char *GetFileName() const { return PATHSEP "library.nut"; } - /* virtual */ Subdirectory GetDirectory() const { return AI_LIBRARY_DIR; } - /* virtual */ const char *GetScannerName() const { return "AI Libraries"; } - /* virtual */ void RegisterAPI(class Squirrel *engine); + void GetScriptName(ScriptInfo *info, char *name, const char *last) override; + const char *GetFileName() const override { return PATHSEP "library.nut"; } + Subdirectory GetDirectory() const override { return AI_LIBRARY_DIR; } + const char *GetScannerName() const override { return "AI Libraries"; } + void RegisterAPI(class Squirrel *engine) override; }; #endif /* AI_SCANNER_HPP */ diff --git a/src/aircraft.h b/src/aircraft.h index f4fce09be1..d201743a6f 100644 --- a/src/aircraft.h +++ b/src/aircraft.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. @@ -79,7 +77,7 @@ struct Aircraft FINAL : public SpecializedVehicle { byte previous_pos; ///< Previous desired position of the aircraft. StationID targetairport; ///< Airport to go to next. byte state; ///< State of the airport. @see AirportMovementStates - DirectionByte last_direction; + Direction last_direction; byte number_consecutive_turns; ///< Protection to prevent the aircraft of making a lot of turns in order to reach a specific point. byte turn_counter; ///< Ticks between each turn to prevent > 45 degree turns. byte flags; ///< Aircraft flags. @see AirVehicleFlags @@ -138,11 +136,6 @@ struct Aircraft FINAL : public SpecializedVehicle { } }; -/** - * Macro for iterating over all aircraft. - */ -#define FOR_ALL_AIRCRAFT(var) FOR_ALL_VEHICLES_OF_TYPE(Aircraft, var) - void GetRotorImage(const Aircraft *v, EngineImageType image_type, VehicleSpriteSeq *result); Station *GetTargetAirportIfValid(const Aircraft *v); diff --git a/src/aircraft_cmd.cpp b/src/aircraft_cmd.cpp index 08c634ba20..e13658d6fe 100644 --- a/src/aircraft_cmd.cpp +++ b/src/aircraft_cmd.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. @@ -121,13 +119,27 @@ enum HelicopterRotorStates { */ static StationID FindNearestHangar(const Aircraft *v) { - const Station *st; uint best = 0; StationID index = INVALID_STATION; TileIndex vtile = TileVirtXY(v->x_pos, v->y_pos); const AircraftVehicleInfo *avi = AircraftVehInfo(v->engine_type); + uint max_range = v->acache.cached_max_range_sqr; - FOR_ALL_STATIONS(st) { + /* Determine destinations where it's coming from and where it's heading to */ + const Station *last_dest = nullptr; + const Station *next_dest = nullptr; + if (max_range != 0) { + if (v->current_order.IsType(OT_GOTO_STATION) || + (v->current_order.IsType(OT_GOTO_DEPOT) && v->current_order.GetDepotActionType() != ODATFB_NEAREST_DEPOT)) { + last_dest = Station::GetIfValid(v->last_station_visited); + next_dest = Station::GetIfValid(v->current_order.GetDestination()); + } else { + last_dest = GetTargetAirportIfValid(v); + next_dest = Station::GetIfValid(v->GetNextStoppingStation().value); + } + } + + for (const Station *st : Station::Iterate()) { if (st->owner != v->owner || !(st->facilities & FACIL_AIRPORT) || !st->airport.HasHangar()) continue; const AirportFTAClass *afc = st->airport.GetFTA(); @@ -138,13 +150,15 @@ static StationID FindNearestHangar(const Aircraft *v) /* the plane won't land at any helicopter station */ if (!(afc->flags & AirportFTAClass::AIRPLANES) && (avi->subtype & AIR_CTOL)) continue; + /* Check if our last and next destinations can be reached from the depot airport. */ + if (max_range != 0) { + uint last_dist = (last_dest != nullptr && last_dest->airport.tile != INVALID_TILE) ? DistanceSquare(st->airport.tile, last_dest->airport.tile) : 0; + uint next_dist = (next_dest != nullptr && next_dest->airport.tile != INVALID_TILE) ? DistanceSquare(st->airport.tile, next_dest->airport.tile) : 0; + if (last_dist > max_range || next_dist > max_range) continue; + } + /* v->tile can't be used here, when aircraft is flying v->tile is set to 0 */ uint distance = DistanceSquare(vtile, st->airport.tile); - if (v->acache.cached_max_range_sqr != 0) { - /* Check if our current destination can be reached from the depot airport. */ - const Station *cur_dest = GetTargetAirportIfValid(v); - if (cur_dest != NULL && DistanceSquare(st->airport.tile, cur_dest->airport.tile) > v->acache.cached_max_range_sqr) continue; - } if (distance < best || index == INVALID_STATION) { best = distance; index = st->index; @@ -295,7 +309,7 @@ CommandCost CmdBuildAircraft(TileIndex tile, DoCommandFlag flags, const Engine * v->cargo_type = e->GetDefaultCargoType(); u->cargo_type = CT_MAIL; - v->name = NULL; + v->name = nullptr; v->last_station_visited = INVALID_STATION; v->last_loading_station = INVALID_STATION; @@ -379,7 +393,7 @@ bool Aircraft::FindClosestDepot(TileIndex *location, DestinationID *destination, { const Station *st = GetTargetAirportIfValid(this); /* If the station is not a valid airport or if it has no hangars */ - if (st == NULL || !CanVehicleUseStation(this, st) || !st->airport.HasHangar()) { + if (st == nullptr || !CanVehicleUseStation(this, st) || !st->airport.HasHangar()) { /* the aircraft has to search for a hangar on its own */ StationID station = FindNearestHangar(this); @@ -388,8 +402,8 @@ bool Aircraft::FindClosestDepot(TileIndex *location, DestinationID *destination, st = Station::Get(station); } - if (location != NULL) *location = st->xy; - if (destination != NULL) *destination = st->index; + if (location != nullptr) *location = st->xy; + if (destination != nullptr) *destination = st->index; return true; } @@ -408,7 +422,7 @@ static void CheckIfAircraftNeedsService(Aircraft *v) const Station *st = Station::Get(v->current_order.GetDestination()); - assert(st != NULL); + assert(st != nullptr); /* only goto depot if the target airport has a depot */ if (st->airport.HasHangar() && CanVehicleUseStation(v, st)) { @@ -531,7 +545,7 @@ void SetAircraftPosition(Aircraft *v, int x, int y, int z) u->UpdatePositionAndViewport(); u = u->Next(); - if (u != NULL) { + if (u != nullptr) { u->x_pos = x; u->y_pos = y; u->z_pos = z + ROTOR_Z_OFFSET; @@ -552,7 +566,7 @@ void HandleAircraftEnterHangar(Aircraft *v) Aircraft *u = v->Next(); u->vehstatus |= VS_HIDDEN; u = u->Next(); - if (u != NULL) { + if (u != nullptr) { u->vehstatus |= VS_HIDDEN; u->cur_speed = 0; } @@ -725,8 +739,8 @@ void GetAircraftFlightLevelBounds(const Vehicle *v, int *min_level, int *max_lev /* Make faster planes fly higher so that they can overtake slower ones */ base_altitude += min(20 * (v->vcache.cached_max_speed / 200) - 90, 0); - if (min_level != NULL) *min_level = base_altitude + AIRCRAFT_MIN_FLYING_ALTITUDE; - if (max_level != NULL) *max_level = base_altitude + AIRCRAFT_MAX_FLYING_ALTITUDE; + if (min_level != nullptr) *min_level = base_altitude + AIRCRAFT_MIN_FLYING_ALTITUDE; + if (max_level != nullptr) *max_level = base_altitude + AIRCRAFT_MAX_FLYING_ALTITUDE; } /** @@ -801,8 +815,8 @@ template int GetAircraftFlightLevel(Aircraft *v, bool takeoff); */ static byte AircraftGetEntryPoint(const Aircraft *v, const AirportFTAClass *apc, Direction rotation) { - assert(v != NULL); - assert(apc != NULL); + assert(v != nullptr); + assert(apc != nullptr); /* In the case the station doesn't exit anymore, set target tile 0. * It doesn't hurt much, aircraft will go to next order, nearest hangar @@ -810,7 +824,7 @@ static byte AircraftGetEntryPoint(const Aircraft *v, const AirportFTAClass *apc, TileIndex tile = 0; const Station *st = Station::GetIfValid(v->targetairport); - if (st != NULL) { + if (st != nullptr) { /* Make sure we don't go to INVALID_TILE if the airport has been removed. */ tile = (st->airport.tile != INVALID_TILE) ? st->airport.tile : st->xy; } @@ -844,13 +858,13 @@ static bool AircraftController(Aircraft *v) { int count; - /* NULL if station is invalid */ + /* nullptr if station is invalid */ const Station *st = Station::GetIfValid(v->targetairport); /* INVALID_TILE if there is no station */ TileIndex tile = INVALID_TILE; Direction rotation = DIR_N; uint size_x = 1, size_y = 1; - if (st != NULL) { + if (st != nullptr) { if (st->airport.tile != INVALID_TILE) { tile = st->airport.tile; rotation = st->airport.rotation; @@ -864,7 +878,7 @@ static bool AircraftController(Aircraft *v) const AirportFTAClass *afc = tile == INVALID_TILE ? GetAirport(AT_DUMMY) : st->airport.GetFTA(); /* prevent going to INVALID_TILE if airport is deleted. */ - if (st == NULL || st->airport.tile == INVALID_TILE) { + if (st == nullptr || st->airport.tile == INVALID_TILE) { /* Jump into our "holding pattern" state machine if possible */ if (v->pos >= afc->nofelements) { v->pos = v->previous_pos = AircraftGetEntryPoint(v, afc, DIR_N); @@ -904,7 +918,7 @@ static bool AircraftController(Aircraft *v) v->tile = 0; int z_dest; - GetAircraftFlightLevelBounds(v, &z_dest, NULL); + GetAircraftFlightLevelBounds(v, &z_dest, nullptr); /* Reached altitude? */ if (v->z_pos >= z_dest) { @@ -921,7 +935,7 @@ static bool AircraftController(Aircraft *v) if (amd.flag & AMED_HELI_LOWER) { SetBit(v->flags, VAF_HELI_DIRECT_DESCENT); - if (st == NULL) { + if (st == nullptr) { /* FIXME - AircraftController -> if station no longer exists, do not land * helicopter will circle until sign disappears, then go to next order * what to do when it is the only order left, right now it just stays in 1 place */ @@ -1127,7 +1141,7 @@ static bool HandleCrashedAircraft(Aircraft *v) Station *st = GetTargetAirportIfValid(v); /* make aircraft crash down to the ground */ - if (v->crashed_counter < 500 && st == NULL && ((v->crashed_counter % 3) == 0) ) { + 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)); v->z_pos -= 1; if (v->z_pos == z) { @@ -1158,7 +1172,7 @@ static bool HandleCrashedAircraft(Aircraft *v) /* clear runway-in on all airports, set by crashing plane * small airports use AIRPORT_BUSY, city airports use RUNWAY_IN_OUT_block, etc. * but they all share the same number */ - if (st != NULL) { + if (st != nullptr) { CLRBITS(st->airport.flags, RUNWAY_IN_block); CLRBITS(st->airport.flags, RUNWAY_IN_OUT_block); // commuter airport CLRBITS(st->airport.flags, RUNWAY_IN2_block); // intercontinental @@ -1232,8 +1246,8 @@ void HandleMissingAircraftOrders(Aircraft *v) * actually stops. */ const Station *st = GetTargetAirportIfValid(v); - if (st == NULL) { - Backup cur_company(_current_company, v->owner, FILE_LINE); + if (st == nullptr) { + Backup cur_company(_current_company, v->owner, FILE_LINE); CommandCost ret = DoCommand(v->tile, v->index, 0, DC_EXEC, CMD_SEND_VEHICLE_TO_DEPOT); cur_company.Restore(); @@ -1288,17 +1302,17 @@ static void CrashAirplane(Aircraft *v) v->Next()->cargo.Truncate(); const Station *st = GetTargetAirportIfValid(v); StringID newsitem; - if (st == NULL) { + if (st == nullptr) { newsitem = STR_NEWS_PLANE_CRASH_OUT_OF_FUEL; } else { SetDParam(1, st->index); newsitem = STR_NEWS_AIRCRAFT_CRASH; } - AI::NewEvent(v->owner, new ScriptEventVehicleCrashed(v->index, v->tile, st == NULL ? ScriptEventVehicleCrashed::CRASH_AIRCRAFT_NO_AIRPORT : ScriptEventVehicleCrashed::CRASH_PLANE_LANDING)); - Game::NewEvent(new ScriptEventVehicleCrashed(v->index, v->tile, st == NULL ? ScriptEventVehicleCrashed::CRASH_AIRCRAFT_NO_AIRPORT : ScriptEventVehicleCrashed::CRASH_PLANE_LANDING)); + AI::NewEvent(v->owner, new ScriptEventVehicleCrashed(v->index, v->tile, st == nullptr ? ScriptEventVehicleCrashed::CRASH_AIRCRAFT_NO_AIRPORT : ScriptEventVehicleCrashed::CRASH_PLANE_LANDING)); + Game::NewEvent(new ScriptEventVehicleCrashed(v->index, v->tile, st == nullptr ? ScriptEventVehicleCrashed::CRASH_AIRCRAFT_NO_AIRPORT : ScriptEventVehicleCrashed::CRASH_PLANE_LANDING)); - AddVehicleNewsItem(newsitem, NT_ACCIDENT, v->index, st != NULL ? st->index : INVALID_STATION); + AddVehicleNewsItem(newsitem, NT_ACCIDENT, v->index, st != nullptr ? st->index : INVALID_STATION); ModifyStationRatingAround(v->tile, v->owner, -160, 30); if (_settings_client.sound.disaster) SndPlayVehicleFx(SND_12_EXPLOSION, v); @@ -1310,18 +1324,17 @@ static void CrashAirplane(Aircraft *v) */ static void MaybeCrashAirplane(Aircraft *v) { - if (_settings_game.vehicle.plane_crashes == 0) return; Station *st = Station::Get(v->targetairport); - /* FIXME -- MaybeCrashAirplane -> increase crashing chances of very modern airplanes on smaller than AT_METROPOLITAN airports */ - uint32 prob = (0x4000 << _settings_game.vehicle.plane_crashes); + uint32 prob; if ((st->airport.GetFTA()->flags & AirportFTAClass::SHORT_STRIP) && (AircraftVehInfo(v->engine_type)->subtype & AIR_FAST) && !_cheats.no_jetcrash.value) { - prob /= 20; + prob = 3276; } else { - prob /= 1500; + if (_settings_game.vehicle.plane_crashes == 0) return; + prob = (0x4000 << _settings_game.vehicle.plane_crashes) / 1500; } if (GB(Random(), 0, 22) > prob) return; @@ -1393,8 +1406,8 @@ void AircraftNextAirportPos_and_Order(Aircraft *v) } const Station *st = GetTargetAirportIfValid(v); - const AirportFTAClass *apc = st == NULL ? GetAirport(AT_DUMMY) : st->airport.GetFTA(); - Direction rotation = st == NULL ? DIR_N : st->airport.rotation; + const AirportFTAClass *apc = st == nullptr ? GetAirport(AT_DUMMY) : st->airport.GetFTA(); + Direction rotation = st == nullptr ? DIR_N : st->airport.rotation; v->pos = v->previous_pos = AircraftGetEntryPoint(v, apc, rotation); } @@ -1419,7 +1432,7 @@ void AircraftLeaveHangar(Aircraft *v, Direction exit_dir) /* Rotor blades */ u = u->Next(); - if (u != NULL) { + if (u != nullptr) { u->vehstatus &= ~VS_HIDDEN; u->cur_speed = 80; } @@ -1589,7 +1602,7 @@ static void AircraftEventHandler_HeliTakeOff(Aircraft *v, const AirportFTAClass /* Send the helicopter to a hangar if needed for replacement */ if (v->NeedsAutomaticServicing()) { - Backup cur_company(_current_company, v->owner, FILE_LINE); + Backup cur_company(_current_company, v->owner, FILE_LINE); DoCommand(v->tile, v->index | DEPOT_SERVICE | DEPOT_LOCATE_HANGAR, 0, DC_EXEC, CMD_SEND_VEHICLE_TO_DEPOT); cur_company.Restore(); } @@ -1606,7 +1619,7 @@ static void AircraftEventHandler_Flying(Aircraft *v, const AirportFTAClass *apc) * it is possible to choose from multiple landing runways, so loop until a free one is found */ byte landingtype = (v->subtype == AIR_HELICOPTER) ? HELILANDING : LANDING; const AirportFTA *current = apc->layout[v->pos].next; - while (current != NULL) { + while (current != nullptr) { if (current->heading == landingtype) { /* save speed before, since if AirportHasBlock is false, it resets them to 0 * we don't want that for plane in air @@ -1640,7 +1653,7 @@ static void AircraftEventHandler_Landing(Aircraft *v, const AirportFTAClass *apc /* check if the aircraft needs to be replaced or renewed and send it to a hangar if needed */ if (v->NeedsAutomaticServicing()) { - Backup cur_company(_current_company, v->owner, FILE_LINE); + Backup cur_company(_current_company, v->owner, FILE_LINE); DoCommand(v->tile, v->index | DEPOT_SERVICE, 0, DC_EXEC, CMD_SEND_VEHICLE_TO_DEPOT); cur_company.Restore(); } @@ -1762,7 +1775,7 @@ static bool AirportMove(Aircraft *v, const AirportFTAClass *apc) v->previous_pos = v->pos; // save previous location /* there is only one choice to move to */ - if (current->next == NULL) { + if (current->next == nullptr) { if (AirportSetBlocks(v, current, apc)) { v->pos = current->next_position; UpdateAircraftCache(v); @@ -1781,7 +1794,7 @@ static bool AirportMove(Aircraft *v, const AirportFTAClass *apc) return false; } current = current->next; - } while (current != NULL); + } while (current != nullptr); DEBUG(misc, 0, "[Ap] cannot move further on Airport! (pos %d state %d) for vehicle %d", v->pos, v->state, v->index); NOT_REACHED(); @@ -1816,7 +1829,7 @@ static bool AirportHasBlock(Aircraft *v, const AirportFTA *current_pos, const Ai * "reserve" a block for the plane * @param v airplane that requires the operation * @param current_pos of the vehicle in the list of blocks - * @param apc airport on which block is requsted to be set + * @param apc airport on which block is requested to be set * @returns true on success. Eg, next block was free and we have occupied it */ static bool AirportSetBlocks(Aircraft *v, const AirportFTA *current_pos, const AirportFTAClass *apc) @@ -1831,7 +1844,7 @@ static bool AirportSetBlocks(Aircraft *v, const AirportFTA *current_pos, const A * this means more blocks should be checked/set */ const AirportFTA *current = current_pos; if (current == reference) current = current->next; - while (current != NULL) { + while (current != nullptr) { if (current->heading == current_pos->heading && current->block != 0) { airport_flags |= current->block; break; @@ -1926,8 +1939,8 @@ static uint GetNumTerminals(const AirportFTAClass *apc) static bool AirportFindFreeTerminal(Aircraft *v, const AirportFTAClass *apc) { /* example of more terminalgroups - * {0,HANGAR,NOTHING_block,1}, {0,255,TERM_GROUP1_block,0}, {0,255,TERM_GROUP2_ENTER_block,1}, {0,0,N,1}, - * Heading 255 denotes a group. We see 2 groups here: + * {0,HANGAR,NOTHING_block,1}, {0,TERMGROUP,TERM_GROUP1_block,0}, {0,TERMGROUP,TERM_GROUP2_ENTER_block,1}, {0,0,N,1}, + * Heading TERMGROUP denotes a group. We see 2 groups here: * 1. group 0 -- TERM_GROUP1_block (check block) * 2. group 1 -- TERM_GROUP2_ENTER_block (check block) * First in line is checked first, group 0. If the block (TERM_GROUP1_block) is free, it @@ -1939,8 +1952,8 @@ static bool AirportFindFreeTerminal(Aircraft *v, const AirportFTAClass *apc) const Station *st = Station::Get(v->targetairport); const AirportFTA *temp = apc->layout[v->pos].next; - while (temp != NULL) { - if (temp->heading == 255) { + while (temp != nullptr) { + if (temp->heading == TERMGROUP) { if (!(st->airport.flags & temp->block)) { /* read which group do we want to go to? * (the first free group) */ @@ -2038,9 +2051,9 @@ static bool AircraftEventHandler(Aircraft *v, int loop) /* Check the distance to the next destination. This code works because the target * airport is only updated after take off and not on the ground. */ Station *cur_st = Station::GetIfValid(v->targetairport); - Station *next_st = v->current_order.IsType(OT_GOTO_STATION) || v->current_order.IsType(OT_GOTO_DEPOT) ? Station::GetIfValid(v->current_order.GetDestination()) : NULL; + Station *next_st = v->current_order.IsType(OT_GOTO_STATION) || v->current_order.IsType(OT_GOTO_DEPOT) ? Station::GetIfValid(v->current_order.GetDestination()) : nullptr; - if (cur_st != NULL && cur_st->airport.tile != INVALID_TILE && next_st != NULL && next_st->airport.tile != INVALID_TILE) { + if (cur_st != nullptr && cur_st->airport.tile != INVALID_TILE && next_st != nullptr && next_st->airport.tile != INVALID_TILE) { uint dist = DistanceSquare(cur_st->airport.tile, next_st->airport.tile); AircraftHandleDestTooFar(v, dist > v->acache.cached_max_range_sqr); } @@ -2078,16 +2091,16 @@ bool Aircraft::Tick() * Returns aircraft's target station if v->target_airport * is a valid station with airport. * @param v vehicle to get target airport for - * @return pointer to target station, NULL if invalid + * @return pointer to target station, nullptr if invalid */ Station *GetTargetAirportIfValid(const Aircraft *v) { assert(v->type == VEH_AIRCRAFT); Station *st = Station::GetIfValid(v->targetairport); - if (st == NULL) return NULL; + if (st == nullptr) return nullptr; - return st->airport.tile == INVALID_TILE ? NULL : st; + return st->airport.tile == INVALID_TILE ? nullptr : st; } /** @@ -2100,8 +2113,7 @@ void UpdateAirplanesOnNewStation(const Station *st) const AirportFTAClass *ap = st->airport.GetFTA(); Direction rotation = st->airport.tile == INVALID_TILE ? DIR_N : st->airport.rotation; - Aircraft *v; - FOR_ALL_AIRCRAFT(v) { + for (Aircraft *v : Aircraft::Iterate()) { if (!v->IsNormalAircraft() || v->targetairport != st->index) continue; assert(v->state == FLYING); diff --git a/src/aircraft_gui.cpp b/src/aircraft_gui.cpp index 6693b1f8ad..311bc497bf 100644 --- a/src/aircraft_gui.cpp +++ b/src/aircraft_gui.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. @@ -36,7 +34,7 @@ void DrawAircraftDetails(const Aircraft *v, int left, int right, int y) int y_offset = (v->Next()->cargo_cap != 0) ? -(FONT_HEIGHT_NORMAL + 1): 0; Money feeder_share = 0; - for (const Aircraft *u = v; u != NULL; u = u->Next()) { + for (const Aircraft *u = v; u != nullptr; u = u->Next()) { if (u->IsNormalAircraft()) { SetDParam(0, u->engine_type); SetDParam(1, u->build_year); diff --git a/src/airport.cpp b/src/airport.cpp index 7985e017aa..808d14d6ba 100644 --- a/src/airport.cpp +++ b/src/airport.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. @@ -46,7 +44,7 @@ * @param delta_z Height of the airport above the land. */ #define HELIPORT(name, num_helipads, delta_z) \ - AIRPORT_GENERIC(name, NULL, num_helipads, AirportFTAClass::HELICOPTERS, delta_z) + AIRPORT_GENERIC(name, nullptr, num_helipads, AirportFTAClass::HELICOPTERS, delta_z) AIRPORT(country, 0, true) AIRPORT(city, 0, false) @@ -58,7 +56,7 @@ HELIPORT(helidepot, 1, 0) AIRPORT(intercontinental, 2, false) HELIPORT(helistation, 3, 0) HELIPORT(oilrig, 1, 54) -AIRPORT_GENERIC(dummy, NULL, 0, AirportFTAClass::ALL, 0) +AIRPORT_GENERIC(dummy, nullptr, 0, AirportFTAClass::ALL, 0) #undef HELIPORT #undef AIRPORT @@ -135,7 +133,7 @@ AirportFTAClass::~AirportFTAClass() { for (uint i = 0; i < nofelements; i++) { AirportFTA *current = layout[i].next; - while (current != NULL) { + while (current != nullptr) { AirportFTA *next = current->next; free(current); current = next; @@ -195,7 +193,7 @@ static AirportFTA *AirportBuildAutomata(uint nofelements, const AirportFTAbuildu current = current->next; internalcounter++; } - current->next = NULL; + current->next = nullptr; internalcounter++; } return FAutomata; diff --git a/src/airport.h b/src/airport.h index 31c68ef002..6b87dd1852 100644 --- a/src/airport.h +++ b/src/airport.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. @@ -60,29 +58,30 @@ enum AirportMovingDataFlags { /** Movement States on Airports (headings target) */ enum AirportMovementStates { - TO_ALL = 0, ///< Go in this direction for every target. - HANGAR = 1, ///< Heading for hangar. - TERM1 = 2, ///< Heading for terminal 1. - TERM2 = 3, ///< Heading for terminal 2. - TERM3 = 4, ///< Heading for terminal 3. - TERM4 = 5, ///< Heading for terminal 4. - TERM5 = 6, ///< Heading for terminal 5. - TERM6 = 7, ///< Heading for terminal 6. - HELIPAD1 = 8, ///< Heading for helipad 1. - HELIPAD2 = 9, ///< Heading for helipad 2. - TAKEOFF = 10, ///< Airplane wants to leave the airport. - STARTTAKEOFF = 11, ///< Airplane has arrived at a runway for take-off. - ENDTAKEOFF = 12, ///< Airplane has reached end-point of the take-off runway. - HELITAKEOFF = 13, ///< Helicopter wants to leave the airport. - FLYING = 14, ///< %Vehicle is flying in the air. - LANDING = 15, ///< Airplane wants to land. - ENDLANDING = 16, ///< Airplane wants to finish landing. - HELILANDING = 17, ///< Helicopter wants to land. - HELIENDLANDING = 18, ///< Helicopter wants to finish landing. - TERM7 = 19, ///< Heading for terminal 7. - TERM8 = 20, ///< Heading for terminal 8. - HELIPAD3 = 21, ///< Heading for helipad 3. - MAX_HEADINGS = 21, ///< Last valid target to head for. + TO_ALL = 0, ///< Go in this direction for every target. + HANGAR = 1, ///< Heading for hangar. + TERM1 = 2, ///< Heading for terminal 1. + TERM2 = 3, ///< Heading for terminal 2. + TERM3 = 4, ///< Heading for terminal 3. + TERM4 = 5, ///< Heading for terminal 4. + TERM5 = 6, ///< Heading for terminal 5. + TERM6 = 7, ///< Heading for terminal 6. + HELIPAD1 = 8, ///< Heading for helipad 1. + HELIPAD2 = 9, ///< Heading for helipad 2. + TAKEOFF = 10, ///< Airplane wants to leave the airport. + STARTTAKEOFF = 11, ///< Airplane has arrived at a runway for take-off. + ENDTAKEOFF = 12, ///< Airplane has reached end-point of the take-off runway. + HELITAKEOFF = 13, ///< Helicopter wants to leave the airport. + FLYING = 14, ///< %Vehicle is flying in the air. + LANDING = 15, ///< Airplane wants to land. + ENDLANDING = 16, ///< Airplane wants to finish landing. + HELILANDING = 17, ///< Helicopter wants to land. + HELIENDLANDING = 18, ///< Helicopter wants to finish landing. + TERM7 = 19, ///< Heading for terminal 7. + TERM8 = 20, ///< Heading for terminal 8. + HELIPAD3 = 21, ///< Heading for helipad 3. + MAX_HEADINGS = 21, ///< Last valid target to head for. + TERMGROUP = 255, ///< Aircraft is looking for a free terminal in a terminalgroup. }; /** Movement Blocks on Airports blocks (eg_airport_flags). */ @@ -130,10 +129,10 @@ static const uint64 /** A single location on an airport where aircraft can move to. */ struct AirportMovingData { - int16 x; ///< x-coordinate of the destination. - int16 y; ///< y-coordinate of the destination. - uint16 flag; ///< special flags when moving towards the destination. - DirectionByte direction; ///< Direction to turn the aircraft after reaching the destination. + int16 x; ///< x-coordinate of the destination. + int16 y; ///< y-coordinate of the destination. + uint16 flag; ///< special flags when moving towards the destination. + Direction direction; ///< Direction to turn the aircraft after reaching the destination. }; AirportMovingData RotateAirportMovingData(const AirportMovingData *orig, Direction rotation, uint num_tiles_x, uint num_tiles_y); diff --git a/src/airport_gui.cpp b/src/airport_gui.cpp index efd9d1b97a..48c2154eda 100644 --- a/src/airport_gui.cpp +++ b/src/airport_gui.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. @@ -44,7 +42,7 @@ static void ShowBuildAirportPicker(Window *parent); SpriteID GetCustomAirportSprite(const AirportSpec *as, byte layout); -void CcBuildAirport(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) +void CcBuildAirport(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) { if (result.Failed()) return; @@ -82,6 +80,7 @@ struct BuildAirToolbarWindow : Window { ~BuildAirToolbarWindow() { if (_thd.GetCallbackWnd() == this) this->OnPlaceObjectAbort(); + if (this->IsWidgetLowered(WID_AT_AIRPORT)) SetViewportCatchmentStation(nullptr, true); if (_settings_client.gui.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0, false); } @@ -90,14 +89,14 @@ struct BuildAirToolbarWindow : Window { * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; if (!CanBuildVehicleInfrastructure(VEH_AIRCRAFT)) delete this; } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_AT_AIRPORT: @@ -116,7 +115,8 @@ struct BuildAirToolbarWindow : Window { } } - virtual void OnPlaceObject(Point pt, TileIndex tile) + + void OnPlaceObject(Point pt, TileIndex tile) override { switch (this->last_user_action) { case WID_AT_AIRPORT: { @@ -133,12 +133,12 @@ struct BuildAirToolbarWindow : Window { MoveAllWindowsOffScreen(); } - virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) + void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) override { VpSelectTilesWithMethod(pt.x, pt.y, select_method); } - virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) + void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) override { if (pt.x == -1) return; MoveAllHiddenWindowsBackToScreen(); @@ -154,8 +154,10 @@ struct BuildAirToolbarWindow : Window { } } - virtual void OnPlaceObjectAbort() + void OnPlaceObjectAbort() override { + if (this->IsWidgetLowered(WID_AT_AIRPORT)) SetViewportCatchmentStation(nullptr, true); + MoveAllHiddenWindowsBackToScreen(); this->RaiseButtons(); if (!ConfirmationWindowShown()) { @@ -177,7 +179,7 @@ static EventState AirportToolbarGlobalHotkeys(int hotkey) { if (_game_mode != GM_NORMAL || !CanBuildVehicleInfrastructure(VEH_AIRCRAFT)) return ES_NOT_HANDLED; Window *w = ShowBuildAirToolbar(); - if (w == NULL) return ES_NOT_HANDLED; + if (w == nullptr) return ES_NOT_HANDLED; return w->OnHotkey(hotkey); } @@ -214,11 +216,11 @@ static WindowDesc _air_toolbar_desc( * * If the terraform toolbar is linked to the toolbar, that window is also opened. * - * @return newly opened airport toolbar, or NULL if the toolbar could not be opened. + * @return newly opened airport toolbar, or nullptr if the toolbar could not be opened. */ Window *ShowBuildAirToolbar() { - if (!Company::IsValidID(_local_company)) return NULL; + if (!Company::IsValidID(_local_company)) return nullptr; DeleteToolbarLinkedWindows(); return AllocateWindowDescFront(&_air_toolbar_desc, TRANSPORT_AIR); @@ -230,12 +232,12 @@ class BuildAirportWindow : public PickerWindowBase { Scrollbar *vscroll; /** Build a dropdown list of available airport classes */ - static DropDownList *BuildAirportClassDropDown() + static DropDownList BuildAirportClassDropDown() { - DropDownList *list = new DropDownList(); + DropDownList list; for (uint i = 0; i < AirportClass::GetClassCount(); i++) { - *list->Append() = new DropDownListStringItem(AirportClass::Get((AirportClassID)i)->name, i, false); + list.emplace_back(new DropDownListStringItem(AirportClass::Get((AirportClassID)i)->name, i, false)); } return list; @@ -284,7 +286,7 @@ public: DeleteWindowById(WC_SELECT_STATION, 0); } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { switch (widget) { case WID_AP_CLASS_DROPDOWN: @@ -309,7 +311,7 @@ public: } } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_AP_CLASS_DROPDOWN: { @@ -374,7 +376,7 @@ public: } } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { switch (widget) { case WID_AP_AIRPORT_LIST: { @@ -413,7 +415,7 @@ public: } } - virtual void OnPaint() + void OnPaint() override { this->DrawWidgets(); @@ -481,7 +483,7 @@ public: } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_AP_CLASS_DROPDOWN: @@ -554,7 +556,7 @@ public: this->SelectOtherAirport(-1); } - virtual void OnDropdownSelect(int widget, int index) + void OnDropdownSelect(int widget, int index) override { assert(widget == WID_AP_CLASS_DROPDOWN); _selected_airport_class = (AirportClassID)index; @@ -562,7 +564,7 @@ public: this->SelectFirstAvailableAirport(false); } - virtual void OnRealtimeTick(uint delta_ms) + void OnRealtimeTick(uint delta_ms) override { CheckRedrawStationCoverage(this); } diff --git a/src/animated_tile.cpp b/src/animated_tile.cpp index 2a4cd89583..5329b2b506 100644 --- a/src/animated_tile.cpp +++ b/src/animated_tile.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. @@ -19,7 +17,7 @@ #include "safeguards.h" /** The table/list with animated tiles. */ -SmallVector _animated_tiles; +std::vector _animated_tiles; /** * Removes the given tile from the animated tile table. @@ -27,10 +25,10 @@ SmallVector _animated_tiles; */ void DeleteAnimatedTile(TileIndex tile) { - TileIndex *to_remove = _animated_tiles.Find(tile); - if (to_remove != _animated_tiles.End()) { + auto to_remove = std::find(_animated_tiles.begin(), _animated_tiles.end(), tile); + if (to_remove != _animated_tiles.end()) { /* The order of the remaining elements must stay the same, otherwise the animation loop may miss a tile. */ - _animated_tiles.ErasePreservingOrder(to_remove); + _animated_tiles.erase(to_remove); MarkTileDirtyByTile(tile); } } @@ -43,7 +41,7 @@ void DeleteAnimatedTile(TileIndex tile) void AddAnimatedTile(TileIndex tile) { MarkTileDirtyByTile(tile); - _animated_tiles.Include(tile); + include(_animated_tiles, tile); } /** @@ -53,8 +51,8 @@ void AnimateAnimatedTiles() { PerformanceAccumulator framerate(PFE_GL_LANDSCAPE); - const TileIndex *ti = _animated_tiles.Begin(); - while (ti < _animated_tiles.End()) { + const TileIndex *ti = _animated_tiles.data(); + while (ti < _animated_tiles.data() + _animated_tiles.size()) { const TileIndex curr = *ti; AnimateTile(curr); /* During the AnimateTile call, DeleteAnimatedTile could have been called, @@ -75,5 +73,5 @@ void AnimateAnimatedTiles() */ void InitializeAnimatedTiles() { - _animated_tiles.Clear(); + _animated_tiles.clear(); } diff --git a/src/animated_tile_func.h b/src/animated_tile_func.h index 9634ecdee3..6a871f1bc5 100644 --- a/src/animated_tile_func.h +++ b/src/animated_tile_func.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/articulated_vehicles.cpp b/src/articulated_vehicles.cpp index 44ad587895..7e828bf439 100644 --- a/src/articulated_vehicles.cpp +++ b/src/articulated_vehicles.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. @@ -31,9 +29,9 @@ static const uint MAX_ARTICULATED_PARTS = 100; ///< Maximum of articulated parts * @param mirrored Returns whether the part shall be flipped. * @return engine to add or INVALID_ENGINE */ -static EngineID GetNextArticulatedPart(uint index, EngineID front_type, Vehicle *front = NULL, bool *mirrored = NULL) +static EngineID GetNextArticulatedPart(uint index, EngineID front_type, Vehicle *front = nullptr, bool *mirrored = nullptr) { - assert(front == NULL || front->engine_type == front_type); + assert(front == nullptr || front->engine_type == front_type); const Engine *front_engine = Engine::Get(front_type); @@ -44,12 +42,12 @@ static EngineID GetNextArticulatedPart(uint index, EngineID front_type, Vehicle /* 8 bits, bit 7 for mirroring */ callback = GB(callback, 0, 8); if (callback == 0xFF) return INVALID_ENGINE; - if (mirrored != NULL) *mirrored = HasBit(callback, 7); + if (mirrored != nullptr) *mirrored = HasBit(callback, 7); callback = GB(callback, 0, 7); } else { /* 15 bits, bit 14 for mirroring */ if (callback == 0x7FFF) return INVALID_ENGINE; - if (mirrored != NULL) *mirrored = HasBit(callback, 14); + if (mirrored != nullptr) *mirrored = HasBit(callback, 14); callback = GB(callback, 0, 14); } @@ -80,7 +78,7 @@ uint CountArticulatedParts(EngineID engine_type, bool purchase_window) * either, so it doesn't matter how many articulated parts there are. */ if (!Vehicle::CanAllocateItem()) return 0; - Vehicle *v = NULL; + Vehicle *v = nullptr; if (!purchase_window) { v = new Vehicle(); v->engine_type = engine_type; @@ -108,7 +106,7 @@ static inline uint16 GetVehicleDefaultCapacity(EngineID engine, CargoID *cargo_t { const Engine *e = Engine::Get(engine); CargoID cargo = (e->CanCarryCargo() ? e->GetDefaultCargoType() : (CargoID)CT_INVALID); - if (cargo_type != NULL) *cargo_type = cargo; + if (cargo_type != nullptr) *cargo_type = cargo; if (cargo == CT_INVALID) return 0; return e->GetDisplayDefaultCapacity(); } @@ -168,16 +166,16 @@ CargoArray GetCapacityOfArticulatedParts(EngineID engine) * @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) +void GetArticulatedVehicleCargoesAndRefits(EngineID engine, CargoArray *cargoes, CargoTypes *refits, CargoID cargo_type, uint16 cargo_capacity) { cargoes->Clear(); *refits = 0; const Engine *e = Engine::Get(engine); - CargoID cargo_type; - uint16 cargo_capacity = GetVehicleDefaultCapacity(engine, &cargo_type); if (cargo_type < NUM_CARGO && cargo_capacity > 0) { (*cargoes)[cargo_type] += cargo_capacity; if (IsEngineRefittable(engine)) SetBit(*refits, cargo_type); @@ -290,15 +288,15 @@ bool IsArticulatedVehicleCarryingDifferentCargoes(const Vehicle *v, CargoID *car if (v->cargo_type != CT_INVALID && v->GetEngine()->CanCarryCargo()) { if (first_cargo == CT_INVALID) first_cargo = v->cargo_type; if (first_cargo != v->cargo_type) { - if (cargo_type != NULL) *cargo_type = CT_INVALID; + if (cargo_type != nullptr) *cargo_type = CT_INVALID; return true; } } - v = v->HasArticulatedPart() ? v->GetNextArticulatedPart() : NULL; - } while (v != NULL); + v = v->HasArticulatedPart() ? v->GetNextArticulatedPart() : nullptr; + } while (v != nullptr); - if (cargo_type != NULL) *cargo_type = first_cargo; + if (cargo_type != nullptr) *cargo_type = first_cargo; return false; } @@ -330,8 +328,8 @@ void CheckConsistencyOfArticulatedVehicle(const Vehicle *v) assert(v->cargo_type < NUM_CARGO); real_default_capacity[v->cargo_type] += v->cargo_cap; - v = v->HasArticulatedPart() ? v->GetNextArticulatedPart() : NULL; - } while (v != NULL); + v = v->HasArticulatedPart() ? v->GetNextArticulatedPart() : nullptr; + } while (v != nullptr); /* Check whether the vehicle carries more cargoes than expected */ bool carries_more = false; diff --git a/src/articulated_vehicles.h b/src/articulated_vehicles.h index 77322fb4c7..a98833b003 100644 --- a/src/articulated_vehicles.h +++ b/src/articulated_vehicles.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/autoreplace.cpp b/src/autoreplace.cpp index 3b7f739726..59980546ee 100644 --- a/src/autoreplace.cpp +++ b/src/autoreplace.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. @@ -29,11 +27,11 @@ static EngineRenew *GetEngineReplacement(EngineRenewList erl, EngineID engine, G { EngineRenew *er = (EngineRenew *)erl; - while (er != NULL) { + while (er != nullptr) { if (er->from == engine && GroupIsInGroup(group, er->group_id)) return er; er = er->next; } - return NULL; + return nullptr; } /** @@ -46,12 +44,12 @@ void RemoveAllEngineReplacement(EngineRenewList *erl) EngineRenew *er = (EngineRenew *)(*erl); EngineRenew *next; - while (er != NULL) { + while (er != nullptr) { next = er->next; delete er; er = next; } - *erl = NULL; // Empty list + *erl = nullptr; // Empty list } /** @@ -66,12 +64,12 @@ void RemoveAllEngineReplacement(EngineRenewList *erl) EngineID EngineReplacement(EngineRenewList erl, EngineID engine, GroupID group, bool *replace_when_old) { const EngineRenew *er = GetEngineReplacement(erl, engine, group); - if (er == NULL && (group == DEFAULT_GROUP || (Group::IsValidID(group) && !Group::Get(group)->replace_protection))) { + if (er == nullptr && (group == DEFAULT_GROUP || (Group::IsValidID(group) && !Group::Get(group)->replace_protection))) { /* 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 != NULL) *replace_when_old = er == NULL ? false : er->replace_when_old; - return er == NULL ? INVALID_ENGINE : er->to; + if (replace_when_old != nullptr) *replace_when_old = er == nullptr ? false : er->replace_when_old; + return er == nullptr ? INVALID_ENGINE : er->to; } /** @@ -88,7 +86,7 @@ CommandCost AddEngineReplacement(EngineRenewList *erl, EngineID old_engine, Engi { /* Check if the old vehicle is already in the list */ EngineRenew *er = GetEngineReplacement(*erl, old_engine, group); - if (er != NULL) { + if (er != nullptr) { if (flags & DC_EXEC) { er->to = new_engine; er->replace_when_old = replace_when_old; @@ -122,12 +120,12 @@ CommandCost AddEngineReplacement(EngineRenewList *erl, EngineID old_engine, Engi CommandCost RemoveEngineReplacement(EngineRenewList *erl, EngineID engine, GroupID group, DoCommandFlag flags) { EngineRenew *er = (EngineRenew *)(*erl); - EngineRenew *prev = NULL; + EngineRenew *prev = nullptr; - while (er != NULL) { + while (er != nullptr) { if (er->from == engine && er->group_id == group) { if (flags & DC_EXEC) { - if (prev == NULL) { // First element + if (prev == nullptr) { // First element /* The second becomes the new first element */ *erl = (EngineRenewList)er->next; } else { diff --git a/src/autoreplace_base.h b/src/autoreplace_base.h index 5d265866d8..c342223a71 100644 --- a/src/autoreplace_base.h +++ b/src/autoreplace_base.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. @@ -43,7 +41,4 @@ struct EngineRenew : EngineRenewPool::PoolItem<&_enginerenew_pool> { ~EngineRenew() {} }; -#define FOR_ALL_ENGINE_RENEWS_FROM(var, start) FOR_ALL_ITEMS_FROM(EngineRenew, enginerenew_index, var, start) -#define FOR_ALL_ENGINE_RENEWS(var) FOR_ALL_ENGINE_RENEWS_FROM(var, 0) - #endif /* AUTOREPLACE_BASE_H */ diff --git a/src/autoreplace_cmd.cpp b/src/autoreplace_cmd.cpp index 95568e3811..4b444ae196 100644 --- a/src/autoreplace_cmd.cpp +++ b/src/autoreplace_cmd.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. @@ -20,6 +18,8 @@ #include "articulated_vehicles.h" #include "core/random_func.hpp" #include "vehiclelist.h" +#include "road.h" +#include "ai/ai.hpp" #include "table/strings.h" @@ -74,6 +74,9 @@ bool CheckAutoreplaceValidity(EngineID from, EngineID to, CompanyID company) } case VEH_ROAD: + /* make sure the roadtypes are compatible */ + if ((GetRoadTypeInfo(e_from->u.road.roadtype)->powered_roadtypes & GetRoadTypeInfo(e_to->u.road.roadtype)->powered_roadtypes) == ROADTYPES_NONE) return false; + /* make sure that we do not replace a tram with a normal road vehicles or vice versa */ if (HasBit(e_from->info.misc_flags, EF_ROAD_TRAM) != HasBit(e_to->info.misc_flags, EF_ROAD_TRAM)) return false; break; @@ -98,9 +101,9 @@ bool CheckAutoreplaceValidity(EngineID from, EngineID to, CompanyID company) */ void CheckCargoCapacity(Vehicle *v) { - assert(v == NULL || v->First() == v); + assert(v == nullptr || v->First() == v); - for (Vehicle *src = v; src != NULL; src = src->Next()) { + for (Vehicle *src = v; src != nullptr; src = src->Next()) { assert(src->cargo.TotalCount() == src->cargo.ActionCount(VehicleCargoList::MTA_KEEP)); /* Do we need to more cargo away? */ @@ -108,7 +111,7 @@ void CheckCargoCapacity(Vehicle *v) /* We need to move a particular amount. Try that on the other vehicles. */ uint to_spread = src->cargo.TotalCount() - src->cargo_cap; - for (Vehicle *dest = v; dest != NULL && to_spread != 0; dest = dest->Next()) { + for (Vehicle *dest = v; dest != nullptr && to_spread != 0; dest = dest->Next()) { assert(dest->cargo.TotalCount() == dest->cargo.ActionCount(VehicleCargoList::MTA_KEEP)); if (dest->cargo.TotalCount() >= dest->cargo_cap || dest->cargo_type != src->cargo_type) continue; @@ -135,7 +138,7 @@ static void TransferCargo(Vehicle *old_veh, Vehicle *new_head, bool part_of_chai { assert(!part_of_chain || new_head->IsPrimaryVehicle()); /* Loop through source parts */ - for (Vehicle *src = old_veh; src != NULL; src = src->Next()) { + for (Vehicle *src = old_veh; src != nullptr; src = src->Next()) { assert(src->cargo.TotalCount() == src->cargo.ActionCount(VehicleCargoList::MTA_KEEP)); if (!part_of_chain && src->type == VEH_TRAIN && src != old_veh && src != Train::From(old_veh)->other_multiheaded_part && !src->IsArticulatedPart()) { /* Skip vehicles, which do not belong to old_veh */ @@ -145,7 +148,7 @@ static void TransferCargo(Vehicle *old_veh, Vehicle *new_head, bool part_of_chai if (src->cargo_type >= NUM_CARGO || src->cargo.TotalCount() == 0) continue; /* Find free space in the new chain */ - for (Vehicle *dest = new_head; dest != NULL && src->cargo.TotalCount() > 0; dest = dest->Next()) { + for (Vehicle *dest = new_head; dest != nullptr && src->cargo.TotalCount() > 0; dest = dest->Next()) { assert(dest->cargo.TotalCount() == dest->cargo.ActionCount(VehicleCargoList::MTA_KEEP)); if (!part_of_chain && dest->type == VEH_TRAIN && dest != new_head && dest != Train::From(new_head)->other_multiheaded_part && !dest->IsArticulatedPart()) { /* Skip vehicles, which do not belong to new_head */ @@ -216,7 +219,7 @@ static CargoID GetNewCargoTypeForReplace(Vehicle *v, EngineID engine_type, bool /* the old engine didn't have cargo capacity, but the new one does * now we will figure out what cargo the train is carrying and refit to fit this */ - for (v = v->First(); v != NULL; v = v->Next()) { + for (v = v->First(); v != nullptr; v = v->Next()) { if (!v->GetEngine()->CanCarryCargo()) continue; /* Now we found a cargo type being carried on the train and we will see if it is possible to carry to this one */ if (HasBit(available_cargo_types, v->cargo_type)) return v->cargo_type; @@ -280,7 +283,7 @@ static CommandCost GetNewEngineType(const Vehicle *v, const Company *c, bool alw */ static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehicle, bool part_of_chain) { - *new_vehicle = NULL; + *new_vehicle = nullptr; /* Shall the vehicle be replaced? */ const Company *c = Company::Get(_current_company); @@ -294,7 +297,7 @@ static CommandCost BuildReplacementVehicle(Vehicle *old_veh, Vehicle **new_vehic if (refit_cargo == CT_INVALID) return CommandCost(); // incompatible cargoes /* Build the new vehicle */ - cost = DoCommand(old_veh->tile, e, 0, DC_EXEC | DC_AUTOREPLACE, GetCmdBuildVeh(old_veh)); + cost = DoCommand(old_veh->tile, e | (CT_INVALID << 24), 0, DC_EXEC | DC_AUTOREPLACE, GetCmdBuildVeh(old_veh)); if (cost.Failed()) return cost; Vehicle *new_veh = Vehicle::Get(_new_vehicle_id); @@ -330,14 +333,14 @@ static inline CommandCost CmdStartStopVehicle(const Vehicle *v, bool evaluate_ca /** * Issue a train vehicle move command * @param v The vehicle to move - * @param after The vehicle to insert 'v' after, or NULL to start new chain + * @param after The vehicle to insert 'v' after, or nullptr to start new chain * @param flags the command flags to use * @param whole_chain move all vehicles following 'v' (true), or only 'v' (false) * @return success or error */ static inline CommandCost CmdMoveVehicle(const Vehicle *v, const Vehicle *after, DoCommandFlag flags, bool whole_chain) { - return DoCommand(0, v->index | (whole_chain ? 1 : 0) << 20, after != NULL ? after->index : INVALID_VEHICLE, flags | DC_NO_CARGO_CAP_CHECK, CMD_MOVE_RAIL_VEHICLE); + return DoCommand(0, v->index | (whole_chain ? 1 : 0) << 20, after != nullptr ? after->index : INVALID_VEHICLE, flags | DC_NO_CARGO_CAP_CHECK, CMD_MOVE_RAIL_VEHICLE); } /** @@ -395,11 +398,11 @@ static CommandCost ReplaceFreeUnit(Vehicle **single_unit, DoCommandFlag flags, b CommandCost cost = CommandCost(EXPENSES_NEW_VEHICLES, 0); /* Build and refit replacement vehicle */ - Vehicle *new_v = NULL; + Vehicle *new_v = nullptr; cost.AddCost(BuildReplacementVehicle(old_v, &new_v, false)); /* Was a new vehicle constructed? */ - if (cost.Succeeded() && new_v != NULL) { + if (cost.Succeeded() && new_v != nullptr) { *nothing_to_do = false; if ((flags & DC_EXEC) != 0) { @@ -415,6 +418,8 @@ static CommandCost ReplaceFreeUnit(Vehicle **single_unit, DoCommandFlag flags, b TransferCargo(old_v, new_v, false); *single_unit = new_v; + + AI::NewEvent(old_v->owner, new ScriptEventVehicleAutoReplaced(old_v->index, new_v->index)); } /* Sell the old vehicle */ @@ -449,17 +454,17 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon uint16 old_total_length = CeilDiv(Train::From(old_head)->gcache.cached_total_length, TILE_SIZE) * TILE_SIZE; int num_units = 0; ///< Number of units in the chain - for (Train *w = Train::From(old_head); w != NULL; w = w->GetNextUnit()) num_units++; + for (Train *w = Train::From(old_head); w != nullptr; w = w->GetNextUnit()) num_units++; Train **old_vehs = CallocT(num_units); ///< Will store vehicles of the old chain in their order - Train **new_vehs = CallocT(num_units); ///< New vehicles corresponding to old_vehs or NULL if no replacement + Train **new_vehs = CallocT(num_units); ///< New vehicles corresponding to old_vehs or nullptr if no replacement Money *new_costs = MallocT(num_units); ///< Costs for buying and refitting the new vehicles /* Collect vehicles and build replacements * Note: The replacement vehicles can only successfully build as long as the old vehicles are still in their chain */ int i; Train *w; - for (w = Train::From(old_head), i = 0; w != NULL; w = w->GetNextUnit(), i++) { + for (w = Train::From(old_head), i = 0; w != nullptr; w = w->GetNextUnit(), i++) { assert(i < num_units); old_vehs[i] = w; @@ -468,41 +473,41 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon if (cost.Failed()) break; new_costs[i] = ret.GetCost(); - if (new_vehs[i] != NULL) *nothing_to_do = false; + if (new_vehs[i] != nullptr) *nothing_to_do = false; } - Train *new_head = (new_vehs[0] != NULL ? new_vehs[0] : old_vehs[0]); + Train *new_head = (new_vehs[0] != nullptr ? new_vehs[0] : old_vehs[0]); /* Note: When autoreplace has already failed here, old_vehs[] is not completely initialized. But it is also not needed. */ if (cost.Succeeded()) { /* Separate the head, so we can start constructing the new chain */ Train *second = Train::From(old_head)->GetNextUnit(); - if (second != NULL) cost.AddCost(CmdMoveVehicle(second, NULL, DC_EXEC | DC_AUTOREPLACE, true)); + if (second != nullptr) cost.AddCost(CmdMoveVehicle(second, nullptr, DC_EXEC | DC_AUTOREPLACE, true)); - assert(Train::From(new_head)->GetNextUnit() == NULL); + assert(Train::From(new_head)->GetNextUnit() == nullptr); /* Append engines to the new chain * We do this from back to front, so that the head of the temporary vehicle chain does not change all the time. * That way we also have less trouble when exceeding the unitnumber limit. * OTOH the vehicle attach callback is more expensive this way :s */ - Train *last_engine = NULL; ///< Shall store the last engine unit after this step + Train *last_engine = nullptr; ///< Shall store the last engine unit after this step if (cost.Succeeded()) { for (int i = num_units - 1; i > 0; i--) { - Train *append = (new_vehs[i] != NULL ? new_vehs[i] : old_vehs[i]); + Train *append = (new_vehs[i] != nullptr ? new_vehs[i] : old_vehs[i]); if (RailVehInfo(append->engine_type)->railveh_type == RAILVEH_WAGON) continue; - if (new_vehs[i] != NULL) { + if (new_vehs[i] != nullptr) { /* Move the old engine to a separate row with DC_AUTOREPLACE. Else * moving the wagon in front may fail later due to unitnumber limit. * (We have to attach wagons without DC_AUTOREPLACE.) */ - CmdMoveVehicle(old_vehs[i], NULL, DC_EXEC | DC_AUTOREPLACE, false); + CmdMoveVehicle(old_vehs[i], nullptr, DC_EXEC | DC_AUTOREPLACE, false); } - if (last_engine == NULL) last_engine = append; + if (last_engine == nullptr) last_engine = append; cost.AddCost(CmdMoveVehicle(append, new_head, DC_EXEC, false)); if (cost.Failed()) break; } - if (last_engine == NULL) last_engine = new_head; + if (last_engine == nullptr) last_engine = new_head; } /* When wagon removal is enabled and the new engines without any wagons are already longer than the old, we have to fail */ @@ -513,8 +518,8 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon */ if (cost.Succeeded()) { for (int i = num_units - 1; i > 0; i--) { - assert(last_engine != NULL); - Vehicle *append = (new_vehs[i] != NULL ? new_vehs[i] : old_vehs[i]); + assert(last_engine != nullptr); + Vehicle *append = (new_vehs[i] != nullptr ? new_vehs[i] : old_vehs[i]); if (RailVehInfo(append->engine_type)->railveh_type == RAILVEH_WAGON) { /* Insert wagon after 'last_engine' */ @@ -524,7 +529,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon * to the train becoming too long, or the train becoming longer * would move the vehicle to the empty vehicle chain. */ if (wagon_removal && (res.Failed() ? res.GetErrorMessage() == STR_ERROR_TRAIN_TOO_LONG : new_head->gcache.cached_total_length > old_total_length)) { - CmdMoveVehicle(append, NULL, DC_EXEC | DC_AUTOREPLACE, false); + CmdMoveVehicle(append, nullptr, DC_EXEC | DC_AUTOREPLACE, false); break; } @@ -543,7 +548,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon assert(new_head->gcache.cached_total_length <= _settings_game.vehicle.max_train_length * TILE_SIZE); for (int i = 1; i < num_units; i++) { Vehicle *wagon = new_vehs[i]; - if (wagon == NULL) continue; + if (wagon == nullptr) continue; if (wagon->First() == new_head) break; assert(RailVehInfo(wagon->engine_type)->railveh_type == RAILVEH_WAGON); @@ -551,7 +556,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon /* Sell wagon */ CommandCost ret = DoCommand(0, wagon->index, 0, DC_EXEC, GetCmdSellVeh(wagon)); assert(ret.Succeeded()); - new_vehs[i] = NULL; + new_vehs[i] = nullptr; /* Revert the money subtraction when the vehicle was built. * This value is different from the sell value, esp. because of refitting */ @@ -572,18 +577,21 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon for (int i = 0; i < num_units; i++) { Vehicle *w = old_vehs[i]; /* Is the vehicle again part of the new chain? - * Note: We cannot test 'new_vehs[i] != NULL' as wagon removal might cause to remove both */ + * Note: We cannot test 'new_vehs[i] != nullptr' as wagon removal might cause to remove both */ if (w->First() == new_head) continue; if ((flags & DC_EXEC) != 0) TransferCargo(w, new_head, true); /* Sell the vehicle. - * Note: This might temporarly construct new trains, so use DC_AUTOREPLACE to prevent + * Note: This might temporarily construct new trains, so use DC_AUTOREPLACE to prevent * it from failing due to engine limits. */ cost.AddCost(DoCommand(0, w->index, 0, flags | DC_AUTOREPLACE, GetCmdSellVeh(w))); if ((flags & DC_EXEC) != 0) { - old_vehs[i] = NULL; - if (i == 0) old_head = NULL; + old_vehs[i] = nullptr; + if (i == 0) { + AI::NewEvent(old_head->owner, new ScriptEventVehicleAutoReplaced(old_head->index, new_head->index)); + old_head = nullptr; + } } } @@ -596,9 +604,9 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon if ((flags & DC_EXEC) == 0) { /* Separate the head, so we can reattach the old vehicles */ Train *second = Train::From(old_head)->GetNextUnit(); - if (second != NULL) CmdMoveVehicle(second, NULL, DC_EXEC | DC_AUTOREPLACE, true); + if (second != nullptr) CmdMoveVehicle(second, nullptr, DC_EXEC | DC_AUTOREPLACE, true); - assert(Train::From(old_head)->GetNextUnit() == NULL); + assert(Train::From(old_head)->GetNextUnit() == nullptr); for (int i = num_units - 1; i > 0; i--) { CommandCost ret = CmdMoveVehicle(old_vehs[i], old_head, DC_EXEC | DC_AUTOREPLACE, false); @@ -610,9 +618,9 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon /* Finally undo buying of new vehicles */ if ((flags & DC_EXEC) == 0) { for (int i = num_units - 1; i >= 0; i--) { - if (new_vehs[i] != NULL) { + if (new_vehs[i] != nullptr) { DoCommand(0, new_vehs[i]->index, 0, DC_EXEC, GetCmdSellVeh(new_vehs[i])); - new_vehs[i] = NULL; + new_vehs[i] = nullptr; } } } @@ -622,11 +630,11 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon free(new_costs); } else { /* Build and refit replacement vehicle */ - Vehicle *new_head = NULL; + Vehicle *new_head = nullptr; cost.AddCost(BuildReplacementVehicle(old_head, &new_head, true)); /* Was a new vehicle constructed? */ - if (cost.Succeeded() && new_head != NULL) { + if (cost.Succeeded() && new_head != nullptr) { *nothing_to_do = false; /* The new vehicle is constructed, now take over orders and everything... */ @@ -637,6 +645,8 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon if ((flags & DC_EXEC) != 0) { TransferCargo(old_head, new_head, true); *chain = new_head; + + AI::NewEvent(old_head->owner, new ScriptEventVehicleAutoReplaced(old_head->index, new_head->index)); } /* Sell the old vehicle */ @@ -666,7 +676,7 @@ static CommandCost ReplaceChain(Vehicle **chain, DoCommandFlag flags, bool wagon CommandCost CmdAutoreplaceVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { Vehicle *v = Vehicle::GetIfValid(p1); - if (v == NULL) return CMD_ERROR; + if (v == nullptr) return CMD_ERROR; CommandCost ret = CheckOwnership(v->owner); if (ret.Failed()) return ret; @@ -690,12 +700,12 @@ CommandCost CmdAutoreplaceVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1 /* Test whether any replacement is set, before issuing a whole lot of commands that would end in nothing changed */ Vehicle *w = v; bool any_replacements = false; - while (w != NULL) { + while (w != nullptr) { EngineID e; CommandCost cost = GetNewEngineType(w, c, false, e); if (cost.Failed()) return cost; any_replacements |= (e != INVALID_ENGINE); - w = (!free_wagon && w->type == VEH_TRAIN ? Train::From(w)->GetNextUnit() : NULL); + w = (!free_wagon && w->type == VEH_TRAIN ? Train::From(w)->GetNextUnit() : nullptr); } CommandCost cost = CommandCost(EXPENSES_NEW_VEHICLES, 0); @@ -756,7 +766,7 @@ CommandCost CmdAutoreplaceVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1 CommandCost CmdSetAutoReplace(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { Company *c = Company::GetIfValid(_current_company); - if (c == NULL) return CMD_ERROR; + if (c == nullptr) return CMD_ERROR; EngineID old_engine_type = GB(p2, 0, 16); EngineID new_engine_type = GB(p2, 16, 16); diff --git a/src/autoreplace_func.h b/src/autoreplace_func.h index 3a6fc83a81..72b551436f 100644 --- a/src/autoreplace_func.h +++ b/src/autoreplace_func.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. @@ -16,7 +14,7 @@ #include "company_base.h" void RemoveAllEngineReplacement(EngineRenewList *erl); -EngineID EngineReplacement(EngineRenewList erl, EngineID engine, GroupID group, bool *replace_when_old = NULL); +EngineID EngineReplacement(EngineRenewList erl, EngineID engine, GroupID group, bool *replace_when_old = nullptr); CommandCost AddEngineReplacement(EngineRenewList *erl, EngineID old_engine, EngineID new_engine, GroupID group, bool replace_when_old, DoCommandFlag flags); CommandCost RemoveEngineReplacement(EngineRenewList *erl, EngineID engine, GroupID group, DoCommandFlag flags); @@ -38,7 +36,7 @@ static inline void RemoveAllEngineReplacementForCompany(Company *c) * @return The engine type to replace with, or INVALID_ENGINE if no * replacement is in the list. */ -static inline EngineID EngineReplacementForCompany(const Company *c, EngineID engine, GroupID group, bool *replace_when_old = NULL) +static inline EngineID EngineReplacementForCompany(const Company *c, EngineID engine, GroupID group, bool *replace_when_old = nullptr) { return EngineReplacement(c->engine_renew_list, engine, group, replace_when_old); } diff --git a/src/autoreplace_gui.cpp b/src/autoreplace_gui.cpp index 7f18efc862..6dc7a3f4b7 100644 --- a/src/autoreplace_gui.cpp +++ b/src/autoreplace_gui.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. @@ -14,6 +12,7 @@ #include "vehicle_gui.h" #include "newgrf_engine.h" #include "rail.h" +#include "road.h" #include "strings_func.h" #include "window_func.h" #include "autoreplace_func.h" @@ -25,6 +24,7 @@ #include "settings_gui.h" #include "core/geometry_func.hpp" #include "rail_gui.h" +#include "road_gui.h" #include "widgets/dropdown_func.h" #include "widgets/autoreplace_widget.h" @@ -33,11 +33,9 @@ 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); -static int CDECL EngineNumberSorter(const EngineID *a, const EngineID *b) +static bool EngineNumberSorter(const EngineID &a, const EngineID &b) { - int r = Engine::Get(*a)->list_position - Engine::Get(*b)->list_position; - - return r; + return Engine::Get(a)->list_position < Engine::Get(b)->list_position; } /** @@ -89,6 +87,7 @@ class ReplaceVehicleWindow : public Window { bool descending_sort_order; ///< Order of sorting vehicles. bool show_hidden_engines; ///< Whether to show the hidden engines. RailType sel_railtype; ///< Type of rail tracks selected. #INVALID_RAILTYPE to show all. + RoadType sel_roadtype; ///< Type of road selected. #INVALID_ROADTYPE to show all. Scrollbar *vscroll[2]; /** @@ -124,13 +123,26 @@ class ReplaceVehicleWindow : public Window { byte side = draw_left ? 0 : 1; GUIEngineList *list = &this->engines[side]; - list->Clear(); + list->clear(); - const Engine *e; - FOR_ALL_ENGINES_OF_TYPE(e, type) { + for (const Engine *e : Engine::IterateType(type)) { if (!draw_left && !this->show_hidden_engines && e->IsHidden(_local_company)) continue; EngineID eid = e->index; - if (type == VEH_TRAIN && !this->GenerateReplaceRailList(eid, draw_left, this->replace_engines)) continue; // special rules for trains + switch (type) { + case VEH_TRAIN: + if (!this->GenerateReplaceRailList(eid, draw_left, this->replace_engines)) continue; // special rules for trains + break; + + case VEH_ROAD: + if (draw_left && this->sel_roadtype != INVALID_ROADTYPE) { + /* Ensure that the roadtype is specific to the selected one */ + if (e->u.road.roadtype != this->sel_roadtype) continue; + } + break; + + default: + break; + } if (draw_left) { const uint num_engines = GetGroupNumEngines(_local_company, this->sel_group, eid); @@ -141,7 +153,7 @@ class ReplaceVehicleWindow : public Window { if (!CheckAutoreplaceValidity(this->sel_engine[0], eid, _local_company)) continue; } - *list->Append() = eid; + list->push_back(eid); if (eid == this->sel_engine[side]) selected_engine = eid; // The selected engine is still in the list } this->sel_engine[side] = selected_engine; // update which engine we selected (the same or none, if it's not in the list anymore) @@ -161,8 +173,8 @@ class ReplaceVehicleWindow : public Window { if (this->engines[0].NeedRebuild()) { /* We need to rebuild the left engines list */ this->GenerateReplaceVehList(true); - this->vscroll[0]->SetCount(this->engines[0].Length()); - if (this->reset_sel_engine && this->sel_engine[0] == INVALID_ENGINE && this->engines[0].Length() != 0) { + 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]; } } @@ -171,7 +183,7 @@ class ReplaceVehicleWindow : public Window { /* Either we got a request to rebuild the right engines list, or the left engines list selected a different engine */ if (this->sel_engine[0] == INVALID_ENGINE) { /* Always empty the right engines list when nothing is selected in the left engines list */ - this->engines[1].Clear(); + this->engines[1].clear(); this->sel_engine[1] = INVALID_ENGINE; } else { if (this->reset_sel_engine && this->sel_engine[0] != INVALID_ENGINE) { @@ -181,11 +193,11 @@ class ReplaceVehicleWindow : public Window { } /* Regenerate the list on the right. Note: This resets sel_engine[1] to INVALID_ENGINE, if it is no longer available. */ this->GenerateReplaceVehList(false); - this->vscroll[1]->SetCount(this->engines[1].Length()); + 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 *it = this->engines[1].Begin(); it != this->engines[1].End(); ++it) { - if (*it == this->sel_engine[1]) break; + for (EngineID &eid : this->engines[1]) { + if (eid == this->sel_engine[1]) break; ++position; } this->vscroll[1]->ScrollTowards(position); @@ -213,6 +225,7 @@ public: ReplaceVehicleWindow(WindowDesc *desc, VehicleType vehicletype, GroupID id_g) : Window(desc) { this->sel_railtype = INVALID_RAILTYPE; + this->sel_roadtype = INVALID_ROADTYPE; this->replace_engines = true; // start with locomotives (all other vehicles will not read this bool) this->engines[0].ForceRebuild(); this->engines[1].ForceRebuild(); @@ -232,13 +245,18 @@ public: widget->SetLowered(this->show_hidden_engines); this->FinishInitNested(vehicletype); + if (vehicletype == VEH_TRAIN || vehicletype == VEH_ROAD) { + widget = this->GetWidget(WID_RV_RAIL_ROAD_TYPE_DROPDOWN); + widget->tool_tip = STR_REPLACE_HELP_RAILTYPE + vehicletype; + } + this->sort_criteria = _engine_sort_last_criteria[vehicletype]; this->descending_sort_order = _engine_sort_last_order[vehicletype]; this->owner = _local_company; this->sel_group = id_g; } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_RV_SORT_ASCENDING_DESCENDING: { @@ -290,13 +308,28 @@ public: break; } - case WID_RV_TRAIN_RAILTYPE_DROPDOWN: { + case WID_RV_RAIL_ROAD_TYPE_DROPDOWN: { Dimension d = {0, 0}; - for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) { - const RailtypeInfo *rti = GetRailTypeInfo(rt); - /* Skip rail type if it has no label */ - if (rti->label == 0) continue; - d = maxdim(d, GetStringBoundingBox(rti->strings.replace_text)); + switch (this->window_number) { + case VEH_TRAIN: + for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) { + const RailtypeInfo *rti = GetRailTypeInfo(rt); + /* Skip rail type if it has no label */ + if (rti->label == 0) continue; + d = maxdim(d, GetStringBoundingBox(rti->strings.replace_text)); + } + break; + + case VEH_ROAD: + for (RoadType rt = ROADTYPE_BEGIN; rt < ROADTYPE_END; rt++) { + const RoadTypeInfo *rti = GetRoadTypeInfo(rt); + /* Skip road type if it has no label */ + if (rti->label == 0) continue; + d = maxdim(d, GetStringBoundingBox(rti->strings.replace_text)); + } + break; + + default: NOT_REACHED(); } d.width += padding.width; d.width += SETTING_BUTTON_HEIGHT; @@ -319,7 +352,7 @@ public: } } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { switch (widget) { case WID_RV_CAPTION: @@ -356,7 +389,7 @@ public: } } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { switch (widget) { case WID_RV_SORT_ASCENDING_DESCENDING: @@ -387,7 +420,7 @@ public: case WID_RV_RIGHT_MATRIX: { int side = (widget == WID_RV_LEFT_MATRIX) ? 0 : 1; EngineID start = this->vscroll[side]->GetPosition(); // what is the offset for the start (scrolling) - EngineID end = min(this->vscroll[side]->GetCapacity() + start, this->engines[side].Length()); + EngineID end = min(this->vscroll[side]->GetCapacity() + start, (uint)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, @@ -397,7 +430,7 @@ public: } } - virtual void OnPaint() + void OnPaint() override { if (this->engines[0].NeedRebuild() || this->engines[1].NeedRebuild()) this->GenerateLists(); @@ -414,9 +447,18 @@ public: * or The selected vehicle has no replacement set up */ this->SetWidgetDisabledState(WID_RV_STOP_REPLACE, this->sel_engine[0] == INVALID_ENGINE || !EngineHasReplacementForCompany(c, this->sel_engine[0], this->sel_group)); - if (this->window_number == VEH_TRAIN) { - /* Show the selected railtype in the pulldown menu */ - this->GetWidget(WID_RV_TRAIN_RAILTYPE_DROPDOWN)->widget_data = sel_railtype == INVALID_RAILTYPE ? STR_REPLACE_ALL_RAILTYPE : GetRailTypeInfo(sel_railtype)->strings.replace_text; + switch (this->window_number) { + case VEH_TRAIN: + /* Show the selected railtype in the pulldown menu */ + this->GetWidget(WID_RV_RAIL_ROAD_TYPE_DROPDOWN)->widget_data = sel_railtype == INVALID_RAILTYPE ? STR_REPLACE_ALL_RAILTYPE : GetRailTypeInfo(sel_railtype)->strings.replace_text; + break; + + case VEH_ROAD: + /* Show the selected roadtype in the pulldown menu */ + this->GetWidget(WID_RV_RAIL_ROAD_TYPE_DROPDOWN)->widget_data = sel_roadtype == INVALID_ROADTYPE ? STR_REPLACE_ALL_ROADTYPE : GetRoadTypeInfo(sel_roadtype)->strings.replace_text; + break; + + default: break; } this->DrawWidgets(); @@ -426,9 +468,16 @@ public: /* Draw details panels. */ for (int side = 0; side < 2; side++) { if (this->sel_engine[side] != INVALID_ENGINE) { + /* Use default engine details without refitting */ + 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); + 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]); + nwi->pos_y + WD_FRAMERECT_TOP, this->sel_engine[side], ted); needed_height = max(needed_height, text_end - (int)nwi->pos_y + WD_FRAMERECT_BOTTOM); } } @@ -440,7 +489,7 @@ public: } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_RV_SORT_ASCENDING_DESCENDING: @@ -463,15 +512,23 @@ public: break; case WID_RV_TRAIN_ENGINEWAGON_DROPDOWN: { - DropDownList *list = new DropDownList(); - *list->Append() = new DropDownListStringItem(STR_REPLACE_ENGINES, 1, false); - *list->Append() = new DropDownListStringItem(STR_REPLACE_WAGONS, 0, false); - ShowDropDownList(this, list, this->replace_engines ? 1 : 0, WID_RV_TRAIN_ENGINEWAGON_DROPDOWN); + DropDownList list; + list.emplace_back(new DropDownListStringItem(STR_REPLACE_ENGINES, 1, false)); + list.emplace_back(new DropDownListStringItem(STR_REPLACE_WAGONS, 0, false)); + ShowDropDownList(this, std::move(list), this->replace_engines ? 1 : 0, WID_RV_TRAIN_ENGINEWAGON_DROPDOWN); break; } - case WID_RV_TRAIN_RAILTYPE_DROPDOWN: // Railtype selection dropdown menu - ShowDropDownList(this, GetRailTypeDropDownList(true, true), sel_railtype, WID_RV_TRAIN_RAILTYPE_DROPDOWN); + case WID_RV_RAIL_ROAD_TYPE_DROPDOWN: // Rail/roadtype selection dropdown menu + switch (this->window_number) { + case VEH_TRAIN: + ShowDropDownList(this, GetRailTypeDropDownList(true, true), sel_railtype, WID_RV_RAIL_ROAD_TYPE_DROPDOWN); + break; + + case VEH_ROAD: + ShowDropDownList(this, GetRoadTypeDropDownList(RTTB_ROAD | RTTB_TRAM, true, true), sel_roadtype, WID_RV_RAIL_ROAD_TYPE_DROPDOWN); + break; + } break; case WID_RV_TRAIN_WAGONREMOVE_TOGGLE: // toggle renew_keep_length @@ -504,7 +561,7 @@ public: click_side = 1; } uint i = this->vscroll[click_side]->GetScrolledRowFromWidget(pt.y, this, widget); - size_t engine_count = this->engines[click_side].Length(); + size_t engine_count = this->engines[click_side].size(); EngineID e = engine_count > i ? this->engines[click_side][i] : INVALID_ENGINE; if (e == this->sel_engine[click_side]) break; // we clicked the one we already selected @@ -519,7 +576,7 @@ public: } } - virtual void OnDropdownSelect(int widget, int index) + void OnDropdownSelect(int widget, int index) override { switch (widget) { case WID_RV_SORT_DROPDOWN: @@ -531,10 +588,25 @@ public: } break; - case WID_RV_TRAIN_RAILTYPE_DROPDOWN: { - RailType temp = (RailType)index; - if (temp == sel_railtype) return; // we didn't select a new one. No need to change anything - sel_railtype = temp; + case WID_RV_RAIL_ROAD_TYPE_DROPDOWN: + switch (this->window_number) { + case VEH_TRAIN: { + RailType temp = (RailType)index; + if (temp == sel_railtype) return; // we didn't select a new one. No need to change anything + sel_railtype = temp; + break; + } + + case VEH_ROAD: { + RoadType temp = (RoadType)index; + if (temp == sel_roadtype) return; // we didn't select a new one. No need to change anything + sel_roadtype = temp; + break; + } + + default: NOT_REACHED(); + } + /* Reset scrollbar positions */ this->vscroll[0]->SetPosition(0); this->vscroll[1]->SetPosition(0); @@ -544,7 +616,6 @@ public: this->reset_sel_engine = true; this->SetDirty(); break; - } case WID_RV_TRAIN_ENGINEWAGON_DROPDOWN: { this->replace_engines = index != 0; @@ -560,7 +631,7 @@ public: } } - virtual void OnResize() + void OnResize() override { this->vscroll[0]->SetCapacityFromWidget(this, WID_RV_LEFT_MATRIX); this->vscroll[1]->SetCapacityFromWidget(this, WID_RV_RIGHT_MATRIX); @@ -571,7 +642,7 @@ public: * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + 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 */ @@ -601,7 +672,7 @@ static const NWidgetPart _nested_replace_rail_vehicle_widgets[] = { NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), NWidget(NWID_VERTICAL), NWidget(NWID_HORIZONTAL), - NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_TRAIN_RAILTYPE_DROPDOWN), SetMinimalSize(136, 12), SetDataTip(0x0, STR_REPLACE_HELP_RAILTYPE), SetFill(1, 0), SetResize(1, 0), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_RAIL_ROAD_TYPE_DROPDOWN), SetMinimalSize(136, 12), SetDataTip(0x0, STR_REPLACE_HELP_RAILTYPE), SetFill(1, 0), SetResize(1, 0), NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_TRAIN_ENGINEWAGON_DROPDOWN), SetDataTip(STR_BLACK_STRING, STR_REPLACE_ENGINE_WAGON_SELECT_HELP), EndContainer(), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_RV_TRAIN_WAGONREMOVE_TOGGLE), SetMinimalSize(138, 12), SetDataTip(STR_REPLACE_REMOVE_WAGON, STR_REPLACE_REMOVE_WAGON_HELP), SetFill(1, 0), SetResize(1, 0), @@ -642,6 +713,64 @@ static WindowDesc _replace_rail_vehicle_desc( _nested_replace_rail_vehicle_widgets, lengthof(_nested_replace_rail_vehicle_widgets) ); +static const NWidgetPart _nested_replace_road_vehicle_widgets[] = { + NWidget(NWID_HORIZONTAL), + NWidget(WWT_CLOSEBOX, COLOUR_GREY), + NWidget(WWT_CAPTION, COLOUR_GREY, WID_RV_CAPTION), SetDataTip(STR_REPLACE_VEHICLES_WHITE, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), + NWidget(WWT_SHADEBOX, COLOUR_GREY), + NWidget(WWT_DEFSIZEBOX, COLOUR_GREY), + NWidget(WWT_STICKYBOX, COLOUR_GREY), + EndContainer(), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), + NWidget(WWT_PANEL, COLOUR_GREY), + NWidget(WWT_LABEL, COLOUR_GREY), SetDataTip(STR_REPLACE_VEHICLE_VEHICLES_IN_USE, STR_REPLACE_VEHICLE_VEHICLES_IN_USE_TOOLTIP), SetFill(1, 1), SetMinimalSize(0, 12), SetResize(1, 0), + EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY), + NWidget(WWT_LABEL, COLOUR_GREY), SetDataTip(STR_REPLACE_VEHICLE_AVAILABLE_VEHICLES, STR_REPLACE_VEHICLE_AVAILABLE_VEHICLES_TOOLTIP), SetFill(1, 1), SetMinimalSize(0, 12), SetResize(1, 0), + EndContainer(), + EndContainer(), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), + NWidget(NWID_VERTICAL), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_RAIL_ROAD_TYPE_DROPDOWN), SetMinimalSize(136, 12), SetDataTip(0x0, STR_REPLACE_HELP_RAILTYPE), SetFill(1, 0), SetResize(1, 0), + NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0), EndContainer(), + EndContainer(), + NWidget(NWID_VERTICAL), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_RV_SORT_ASCENDING_DESCENDING), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER), SetFill(1, 1), + NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_RV_SORT_DROPDOWN), SetResize(1, 0), SetFill(1, 1), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_SORT_CRITERIA), + EndContainer(), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_RV_SHOW_HIDDEN_ENGINES), SetDataTip(STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN, STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN_TOOLTIP), + NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0), SetFill(1, 1), EndContainer(), + EndContainer(), + EndContainer(), + EndContainer(), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), + NWidget(WWT_MATRIX, COLOUR_GREY, WID_RV_LEFT_MATRIX), SetMinimalSize(216, 0), SetFill(1, 1), SetMatrixDataTip(1, 0, STR_REPLACE_HELP_LEFT_ARRAY), SetResize(1, 1), SetScrollbar(WID_RV_LEFT_SCROLLBAR), + NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_RV_LEFT_SCROLLBAR), + NWidget(WWT_MATRIX, COLOUR_GREY, WID_RV_RIGHT_MATRIX), SetMinimalSize(216, 0), SetFill(1, 1), SetMatrixDataTip(1, 0, STR_REPLACE_HELP_RIGHT_ARRAY), SetResize(1, 1), SetScrollbar(WID_RV_RIGHT_SCROLLBAR), + NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_RV_RIGHT_SCROLLBAR), + EndContainer(), + NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), + NWidget(WWT_PANEL, COLOUR_GREY, WID_RV_LEFT_DETAILS), SetMinimalSize(240, 122), SetResize(1, 0), EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY, WID_RV_RIGHT_DETAILS), SetMinimalSize(240, 122), SetResize(1, 0), EndContainer(), + EndContainer(), + NWidget(NWID_HORIZONTAL), + NWidget(NWID_PUSHBUTTON_DROPDOWN, COLOUR_GREY, WID_RV_START_REPLACE), SetMinimalSize(139, 12), SetDataTip(STR_REPLACE_VEHICLES_START, STR_REPLACE_HELP_START_BUTTON), + NWidget(WWT_PANEL, COLOUR_GREY, WID_RV_INFO_TAB), SetMinimalSize(167, 12), SetDataTip(0x0, STR_REPLACE_HELP_REPLACE_INFO_TAB), SetResize(1, 0), + EndContainer(), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_RV_STOP_REPLACE), SetMinimalSize(150, 12), SetDataTip(STR_REPLACE_VEHICLES_STOP, STR_REPLACE_HELP_STOP_BUTTON), + NWidget(WWT_RESIZEBOX, COLOUR_GREY), + EndContainer(), +}; + +static WindowDesc _replace_road_vehicle_desc( + WDP_AUTO, "replace_vehicle_road", 500, 140, + WC_REPLACE_VEHICLE, WC_NONE, + WDF_CONSTRUCTION, + _nested_replace_road_vehicle_widgets, lengthof(_nested_replace_road_vehicle_widgets) +); + static const NWidgetPart _nested_replace_vehicle_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_GREY), @@ -702,5 +831,11 @@ static WindowDesc _replace_vehicle_desc( void ShowReplaceGroupVehicleWindow(GroupID id_g, VehicleType vehicletype) { DeleteWindowById(WC_REPLACE_VEHICLE, vehicletype); - new ReplaceVehicleWindow(vehicletype == VEH_TRAIN ? &_replace_rail_vehicle_desc : &_replace_vehicle_desc, vehicletype, id_g); + WindowDesc *desc; + switch (vehicletype) { + case VEH_TRAIN: desc = &_replace_rail_vehicle_desc; break; + case VEH_ROAD: desc = &_replace_road_vehicle_desc; break; + default: desc = &_replace_vehicle_desc; break; + } + new ReplaceVehicleWindow(desc, vehicletype, id_g); } diff --git a/src/autoreplace_gui.h b/src/autoreplace_gui.h index 046ac89921..634629ec4c 100644 --- a/src/autoreplace_gui.h +++ b/src/autoreplace_gui.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/autoreplace_type.h b/src/autoreplace_type.h index 30ba7e2b44..458ee571b7 100644 --- a/src/autoreplace_type.h +++ b/src/autoreplace_type.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/autoslope.h b/src/autoslope.h index e504610c39..83d775b1fb 100644 --- a/src/autoslope.h +++ b/src/autoslope.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/base_consist.cpp b/src/base_consist.cpp index 200512786c..462f63f2e5 100644 --- a/src/base_consist.cpp +++ b/src/base_consist.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. @@ -30,7 +28,7 @@ void BaseConsist::CopyConsistPropertiesFrom(const BaseConsist *src) if (this == src) return; free(this->name); - this->name = src->name != NULL ? stredup(src->name) : NULL; + this->name = src->name != nullptr ? stredup(src->name) : nullptr; this->current_order_time = src->current_order_time; this->lateness_counter = src->lateness_counter; diff --git a/src/base_consist.h b/src/base_consist.h index 3679afd351..619229d2a6 100644 --- a/src/base_consist.h +++ b/src/base_consist.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. @@ -31,7 +29,7 @@ struct BaseConsist { uint16 vehicle_flags; ///< Used for gradual loading and other miscellaneous things (@see VehicleFlags enum) - BaseConsist() : name(NULL) {} + BaseConsist() : name(nullptr) {} virtual ~BaseConsist(); void CopyConsistPropertiesFrom(const BaseConsist *src); diff --git a/src/base_media_base.h b/src/base_media_base.h index b040abcf9d..0b006efbea 100644 --- a/src/base_media_base.h +++ b/src/base_media_base.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. @@ -76,9 +74,9 @@ struct BaseSet { { free(this->name); - for (TranslatedStrings::iterator iter = this->description.Begin(); iter != this->description.End(); iter++) { - free(iter->first); - free(iter->second); + for (auto &pair : this->description) { + free(pair.first); + free(pair.second); } for (uint i = 0; i < NUM_FILES; i++) { @@ -118,20 +116,20 @@ struct BaseSet { * @param isocode the isocode to search for * @return the description */ - const char *GetDescription(const char *isocode = NULL) const + const char *GetDescription(const char *isocode = nullptr) const { - if (isocode != NULL) { + if (isocode != nullptr) { /* First the full ISO code */ - for (TranslatedStrings::const_iterator iter = this->description.Begin(); iter != this->description.End(); iter++) { - if (strcmp(iter->first, isocode) == 0) return iter->second; + for (const auto &pair : this->description) { + if (strcmp(pair.first, isocode) == 0) return pair.second; } /* Then the first two characters */ - for (TranslatedStrings::const_iterator iter = this->description.Begin(); iter != this->description.End(); iter++) { - if (strncmp(iter->first, isocode, 2) == 0) return iter->second; + for (const auto &pair : this->description) { + if (strncmp(pair.first, isocode, 2) == 0) return pair.second; } } /* Then fall back */ - return this->description.Begin()->second; + return this->description.front().second; } /** @@ -151,17 +149,17 @@ struct BaseSet { /** * Search a textfile file next to this base media. * @param type The type of the textfile to search for. - * @return The filename for the textfile, \c NULL otherwise. + * @return The filename for the textfile, \c nullptr otherwise. */ const char *GetTextfile(TextfileType type) const { for (uint i = 0; i < NUM_FILES; i++) { const char *textfile = ::GetTextfile(type, BASESET_DIR, this->files[i].filename); - if (textfile != NULL) { + if (textfile != nullptr) { return textfile; } } - return NULL; + return nullptr; } }; @@ -176,7 +174,7 @@ protected: static Tbase_set *duplicate_sets; ///< All sets that aren't available, but needed for not downloading base sets when a newer version than the one on BaNaNaS is loaded. static const Tbase_set *used_set; ///< The currently used set - /* virtual */ bool AddFile(const char *filename, size_t basepath_length, const char *tar_filename); + bool AddFile(const char *filename, size_t basepath_length, const char *tar_filename) override; /** * Get the extension that is used to identify this set. @@ -231,7 +229,7 @@ template /* static */ Tbase_set *BaseMedia::duplica * @param ci The content info to compare it to. * @param md5sum Should the MD5 checksum be tested as well? * @param s The list with sets. - * @return The filename of the first file of the base set, or \c NULL if there is no match. + * @return The filename of the first file of the base set, or \c nullptr if there is no match. */ template const char *TryGetBaseSetFile(const ContentInfo *ci, bool md5sum, const Tbase_set *s); diff --git a/src/base_media_func.h b/src/base_media_func.h index f7afca0edb..01e184f8ca 100644 --- a/src/base_media_func.h +++ b/src/base_media_func.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. @@ -23,7 +21,7 @@ */ #define fetch_metadata(name) \ item = metadata->GetItem(name, false); \ - if (item == NULL || StrEmpty(item->value)) { \ + if (item == nullptr || StrEmpty(item->value)) { \ DEBUG(grf, 0, "Base " SET_TYPE "set detail loading: %s field missing.", name); \ DEBUG(grf, 0, " Is %s readable for the user running OpenTTD?", full_filename); \ return false; \ @@ -50,7 +48,7 @@ bool BaseSet::FillSetDetails(IniFile *ini, const this->description[stredup("")] = stredup(item->value); /* Add the translations of the descriptions too. */ - for (const IniItem *item = metadata->item; item != NULL; item = item->next) { + for (const IniItem *item = metadata->item; item != nullptr; item = item->next) { if (strncmp("description.", item->name, 12) != 0) continue; this->description[stredup(item->name + 12)] = stredup(item->value); @@ -65,7 +63,7 @@ bool BaseSet::FillSetDetails(IniFile *ini, const this->version = atoi(item->value); item = metadata->GetItem("fallback", false); - this->fallback = (item != NULL && strcmp(item->value, "0") != 0 && strcmp(item->value, "false") != 0); + this->fallback = (item != nullptr && strcmp(item->value, "0") != 0 && strcmp(item->value, "false") != 0); /* For each of the file types we want to find the file, MD5 checksums and warning messages. */ IniGroup *files = ini->GetGroup("files"); @@ -75,14 +73,14 @@ bool BaseSet::FillSetDetails(IniFile *ini, const MD5File *file = &this->files[i]; /* Find the filename first. */ item = files->GetItem(BaseSet::file_names[i], false); - if (item == NULL || (item->value == NULL && !allow_empty_filename)) { + if (item == nullptr || (item->value == nullptr && !allow_empty_filename)) { DEBUG(grf, 0, "No " SET_TYPE " file for: %s (in %s)", BaseSet::file_names[i], full_filename); return false; } const char *filename = item->value; - if (filename == NULL) { - file->filename = NULL; + if (filename == nullptr) { + file->filename = nullptr; /* If we list no file, that file must be valid */ this->valid_files++; this->found_files++; @@ -93,7 +91,7 @@ bool BaseSet::FillSetDetails(IniFile *ini, const /* Then find the MD5 checksum */ item = md5s->GetItem(filename, false); - if (item == NULL || item->value == NULL) { + if (item == nullptr || item->value == nullptr) { DEBUG(grf, 0, "No MD5 checksum specified for: %s (in %s)", filename, full_filename); return false; } @@ -119,8 +117,8 @@ bool BaseSet::FillSetDetails(IniFile *ini, const /* Then find the warning message when the file's missing */ item = origin->GetItem(filename, false); - if (item == NULL) item = origin->GetItem("default", false); - if (item == NULL) { + if (item == nullptr) item = origin->GetItem("default", false); + if (item == nullptr) { DEBUG(grf, 1, "No origin warning message specified for: %s", filename); file->missing_warning = stredup(""); } else { @@ -159,25 +157,25 @@ bool BaseMedia::AddFile(const char *filename, size_t basepath_length, Tbase_set *set = new Tbase_set(); IniFile *ini = new IniFile(); - ini->LoadFromDisk(filename, BASESET_DIR); - char *path = stredup(filename + basepath_length); + ini->LoadFromDisk(path, BASESET_DIR); + char *psep = strrchr(path, PATHSEPCHAR); - if (psep != NULL) { + if (psep != nullptr) { psep[1] = '\0'; } else { *path = '\0'; } if (set->FillSetDetails(ini, path, filename)) { - Tbase_set *duplicate = NULL; - for (Tbase_set *c = BaseMedia::available_sets; c != NULL; c = c->next) { + Tbase_set *duplicate = nullptr; + for (Tbase_set *c = BaseMedia::available_sets; c != nullptr; c = c->next) { if (strcmp(c->name, set->name) == 0 || c->shortname == set->shortname) { duplicate = c; break; } } - if (duplicate != NULL) { + if (duplicate != nullptr) { /* The more complete set takes precedence over the version number. */ if ((duplicate->valid_files == set->valid_files && duplicate->version >= set->version) || duplicate->valid_files > set->valid_files) { @@ -205,7 +203,7 @@ bool BaseMedia::AddFile(const char *filename, size_t basepath_length, } } else { Tbase_set **last = &BaseMedia::available_sets; - while (*last != NULL) last = &(*last)->next; + while (*last != nullptr) last = &(*last)->next; *last = set; ret = true; @@ -238,7 +236,7 @@ template return true; } - for (const Tbase_set *s = BaseMedia::available_sets; s != NULL; s = s->next) { + for (const Tbase_set *s = BaseMedia::available_sets; s != nullptr; s = s->next) { if (strcmp(name, s->name) == 0) { BaseMedia::used_set = s; CheckExternalFiles(); @@ -258,7 +256,7 @@ template /* static */ char *BaseMedia::GetSetsList(char *p, const char *last) { p += seprintf(p, last, "List of " SET_TYPE " sets:\n"); - for (const Tbase_set *s = BaseMedia::available_sets; s != NULL; s = s->next) { + for (const Tbase_set *s = BaseMedia::available_sets; s != nullptr; s = s->next) { p += seprintf(p, last, "%18s: %s", s->name, s->GetDescription()); int invalid = s->GetNumInvalid(); if (invalid != 0) { @@ -277,12 +275,11 @@ template return p; } -#if defined(ENABLE_NETWORK) #include "network/network_content.h" template const char *TryGetBaseSetFile(const ContentInfo *ci, bool md5sum, const Tbase_set *s) { - for (; s != NULL; s = s->next) { + for (; s != nullptr; s = s->next) { if (s->GetNumMissing() != 0) continue; if (s->shortname != ci->unique_id) continue; @@ -297,32 +294,16 @@ template const char *TryGetBaseSetFile(const ContentInfo *ci, } if (memcmp(md5, ci->md5sum, sizeof(md5)) == 0) return s->files[0].filename; } - return NULL; + return nullptr; } template /* static */ bool BaseMedia::HasSet(const ContentInfo *ci, bool md5sum) { - return (TryGetBaseSetFile(ci, md5sum, BaseMedia::available_sets) != NULL) || - (TryGetBaseSetFile(ci, md5sum, BaseMedia::duplicate_sets) != NULL); + return (TryGetBaseSetFile(ci, md5sum, BaseMedia::available_sets) != nullptr) || + (TryGetBaseSetFile(ci, md5sum, BaseMedia::duplicate_sets) != nullptr); } -#else - -template -const char *TryGetBaseSetFile(const ContentInfo *ci, bool md5sum, const Tbase_set *s) -{ - return NULL; -} - -template -/* static */ bool BaseMedia::HasSet(const ContentInfo *ci, bool md5sum) -{ - return false; -} - -#endif /* ENABLE_NETWORK */ - /** * Count the number of available graphics sets. * @return the number of sets @@ -331,7 +312,7 @@ template /* static */ int BaseMedia::GetNumSets() { int n = 0; - for (const Tbase_set *s = BaseMedia::available_sets; s != NULL; s = s->next) { + for (const Tbase_set *s = BaseMedia::available_sets; s != nullptr; s = s->next) { if (s != BaseMedia::used_set && s->GetNumMissing() != 0) continue; n++; } @@ -346,7 +327,7 @@ template /* static */ int BaseMedia::GetIndexOfUsedSet() { int n = 0; - for (const Tbase_set *s = BaseMedia::available_sets; s != NULL; s = s->next) { + for (const Tbase_set *s = BaseMedia::available_sets; s != nullptr; s = s->next) { if (s == BaseMedia::used_set) return n; if (s->GetNumMissing() != 0) continue; n++; @@ -361,7 +342,7 @@ template template /* static */ const Tbase_set *BaseMedia::GetSet(int index) { - for (const Tbase_set *s = BaseMedia::available_sets; s != NULL; s = s->next) { + for (const Tbase_set *s = BaseMedia::available_sets; s != nullptr; s = s->next) { if (s != BaseMedia::used_set && s->GetNumMissing() != 0) continue; if (index == 0) return s; index--; diff --git a/src/base_station_base.h b/src/base_station_base.h index cd512c5177..0467866e50 100644 --- a/src/base_station_base.h +++ b/src/base_station_base.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. @@ -53,15 +51,16 @@ struct StationRect : public Rect { /** Base class for all station-ish types */ struct BaseStation : StationPool::PoolItem<&_station_pool> { TileIndex xy; ///< Base tile of the station - ViewportSign sign; ///< NOSAVE: Dimensions of sign + TrackedViewportSign sign; ///< NOSAVE: Dimensions of sign byte delete_ctr; ///< Delete counter. If greater than 0 then it is decremented until it reaches 0; the waypoint is then is deleted. char *name; ///< Custom name StringID string_id; ///< Default name (town area) of station + mutable std::string cached_name; ///< NOSAVE: Cache of the resolved name of the station, if not using a custom name Town *town; ///< The town this station is associated with - OwnerByte owner; ///< The owner of this station - StationFacilityByte facilities; ///< The facilities that this station has + 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 @@ -110,6 +109,19 @@ struct BaseStation : StationPool::PoolItem<&_station_pool> { */ virtual void UpdateVirtCoord() = 0; + inline const char *GetCachedName() const + { + if (this->name != nullptr) return this->name; + if (this->cached_name.empty()) this->FillCachedName(); + return this->cached_name.c_str(); + } + + virtual void MoveSign(TileIndex new_xy) + { + this->xy = new_xy; + this->UpdateVirtCoord(); + } + /** * Get the tile area for a given station type. * @param ta tile area to fill. @@ -157,9 +169,10 @@ struct BaseStation : StationPool::PoolItem<&_station_pool> { } static void PostDestructor(size_t index); -}; -#define FOR_ALL_BASE_STATIONS(var) FOR_ALL_ITEMS_FROM(BaseStation, station_index, var, 0) +private: + void FillCachedName() const; +}; /** * Class defining several overloaded accessors so we don't @@ -214,7 +227,7 @@ struct SpecializedStation : public BaseStation { */ static inline T *GetIfValid(size_t index) { - return IsValidID(index) ? Get(index) : NULL; + return IsValidID(index) ? Get(index) : nullptr; } /** @@ -248,8 +261,13 @@ struct SpecializedStation : public BaseStation { assert(IsExpected(st)); return (const T *)st; } + + /** + * Returns an iterable ensemble of all valid stations of type T + * @param from index of the first station to consider + * @return an iterable ensemble of all valid stations of type T + */ + static Pool::IterateWrapper Iterate(size_t from = 0) { return Pool::IterateWrapper(from); } }; -#define FOR_ALL_BASE_STATIONS_OF_TYPE(name, var) FOR_ALL_ITEMS_FROM(name, station_index, var, 0) if (name::IsExpected(var)) - #endif /* BASE_STATION_BASE_H */ diff --git a/src/bitmap_type.h b/src/bitmap_type.h new file mode 100644 index 0000000000..99c29bf181 --- /dev/null +++ b/src/bitmap_type.h @@ -0,0 +1,135 @@ +/* + * 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 bitmap_type.hpp Bitmap functions. */ + +#ifndef BITMAP_TYPE_HPP +#define BITMAP_TYPE_HPP + +#include + +/** Represents a tile area containing containing individually set tiles. + * Each tile must be contained within the preallocated area. + * A std::vector is used to mark which tiles are contained. + */ +class BitmapTileArea : public TileArea { +protected: + std::vector data; + + inline uint Index(uint x, uint y) const { return y * this->w + x; } + + inline uint Index(TileIndex tile) const { return Index(TileX(tile) - TileX(this->tile), TileY(tile) - TileY(this->tile)); } + +public: + BitmapTileArea() + { + this->tile = INVALID_TILE; + this->w = 0; + this->h = 0; + } + + BitmapTileArea(const TileArea &ta) + { + this->tile = ta.tile; + this->w = ta.w; + this->h = ta.h; + this->data.resize(Index(this->w, this->h)); + } + + /** + * Reset and clear the BitmapTileArea. + */ + void Reset() + { + this->tile = INVALID_TILE; + this->w = 0; + this->h = 0; + this->data.clear(); + } + + /** + * Initialize the BitmapTileArea with the specified Rect. + * @param rect Rect to use. + */ + 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->data.clear(); + this->data.resize(Index(w, h)); + } + + void Initialize(const TileArea &ta) + { + this->tile = ta.tile; + this->w = ta.w; + this->h = ta.h; + this->data.clear(); + this->data.resize(Index(w, h)); + } + + /** + * Add a tile as part of the tile area. + * @param tile Tile to add. + */ + inline void SetTile(TileIndex tile) + { + assert(this->Contains(tile)); + this->data[Index(tile)] = true; + } + + /** + * Clear a tile from the tile area. + * @param tile Tile to clear + */ + inline void ClrTile(TileIndex tile) + { + assert(this->Contains(tile)); + this->data[Index(tile)] = false; + } + + /** + * Test if a tile is part of the tile area. + * @param tile Tile to check + */ + inline bool HasTile(TileIndex tile) const + { + return this->Contains(tile) && this->data[Index(tile)]; + } +}; + +/** Iterator to iterate over all tiles belonging to a bitmaptilearea. */ +class BitmapTileIterator : public OrthogonalTileIterator { +protected: + const BitmapTileArea *bitmap; +public: + /** + * Construct the iterator. + * @param bitmap BitmapTileArea to iterate. + */ + BitmapTileIterator(const BitmapTileArea &bitmap) : OrthogonalTileIterator(bitmap), bitmap(&bitmap) + { + if (!this->bitmap->HasTile(TileIndex(this->tile))) ++(*this); + } + + inline TileIterator& operator ++() + { + (*this).OrthogonalTileIterator::operator++(); + while (this->tile != INVALID_TILE && !this->bitmap->HasTile(TileIndex(this->tile))) { + (*this).OrthogonalTileIterator::operator++(); + } + return *this; + } + + virtual TileIterator *Clone() const + { + return new BitmapTileIterator(*this); + } +}; + +#endif /* BITMAP_TYPE_HPP */ diff --git a/src/blitter/32bpp_anim.cpp b/src/blitter/32bpp_anim.cpp index 27b1fbd5b8..a5228bc327 100644 --- a/src/blitter/32bpp_anim.cpp +++ b/src/blitter/32bpp_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. @@ -42,7 +40,7 @@ inline void Blitter_32bppAnim::Draw(const Blitter::BlitterParams *bp, ZoomLevel Colour *dst = (Colour *)bp->dst + bp->top * bp->pitch + bp->left; uint16 *anim = this->anim_buf + this->ScreenToAnimOffset((uint32 *)bp->dst) + bp->top * this->anim_buf_pitch + bp->left; - const byte *remap = bp->remap; // store so we don't have to access it via bp everytime + const byte *remap = bp->remap; // store so we don't have to access it via bp every time for (int y = 0; y < bp->height; y++) { Colour *dst_ln = dst + bp->pitch; @@ -414,7 +412,7 @@ void Blitter_32bppAnim::CopyToBuffer(const void *video, void *dst, int width, in uint32 *udst = (uint32 *)dst; const uint32 *src = (const uint32 *)video; - if (this->anim_buf == NULL) return; + if (this->anim_buf == nullptr) return; const uint16 *anim_line = this->ScreenToAnimOffset((const uint32 *)video) + this->anim_buf; diff --git a/src/blitter/32bpp_anim.hpp b/src/blitter/32bpp_anim.hpp index ecf6dcfca0..230b7e8342 100644 --- a/src/blitter/32bpp_anim.hpp +++ b/src/blitter/32bpp_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. @@ -26,8 +24,8 @@ protected: public: Blitter_32bppAnim() : - anim_buf(NULL), - anim_alloc(NULL), + anim_buf(nullptr), + anim_alloc(nullptr), anim_buf_width(0), anim_buf_height(0), anim_buf_pitch(0) @@ -37,21 +35,21 @@ public: ~Blitter_32bppAnim(); - /* virtual */ void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom); - /* virtual */ void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal); - /* virtual */ void SetPixel(void *video, int x, int y, uint8 colour); - /* virtual */ void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash); - /* virtual */ void DrawRect(void *video, int width, int height, uint8 colour); - /* virtual */ void CopyFromBuffer(void *video, const void *src, int width, int height); - /* virtual */ void CopyToBuffer(const void *video, void *dst, int width, int height); - /* virtual */ void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y); - /* virtual */ int BufferSize(int width, int height); - /* virtual */ void PaletteAnimate(const Palette &palette); - /* virtual */ Blitter::PaletteAnimation UsePaletteAnimation(); + void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override; + void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal) override; + void SetPixel(void *video, int x, int y, 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; + void DrawRect(void *video, int width, int height, uint8 colour) override; + 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; + void PaletteAnimate(const Palette &palette) override; + Blitter::PaletteAnimation UsePaletteAnimation() override; - /* virtual */ const char *GetName() { return "32bpp-anim"; } - /* virtual */ int GetBytesPerPixel() { return 6; } - /* virtual */ void PostResize(); + const char *GetName() override { return "32bpp-anim"; } + int GetBytesPerPixel() override { return 6; } + void PostResize() override; /** * Look up the colour in the current palette. @@ -77,7 +75,7 @@ public: class FBlitter_32bppAnim : public BlitterFactory { public: FBlitter_32bppAnim() : BlitterFactory("32bpp-anim", "32bpp Animation Blitter (palette animation)") {} - /* virtual */ Blitter *CreateInstance() { return new Blitter_32bppAnim(); } + Blitter *CreateInstance() override { return new Blitter_32bppAnim(); } }; #endif /* BLITTER_32BPP_ANIM_HPP */ diff --git a/src/blitter/32bpp_anim_sse2.cpp b/src/blitter/32bpp_anim_sse2.cpp index d5fa4268a8..5596d91af0 100644 --- a/src/blitter/32bpp_anim_sse2.cpp +++ b/src/blitter/32bpp_anim_sse2.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. diff --git a/src/blitter/32bpp_anim_sse2.hpp b/src/blitter/32bpp_anim_sse2.hpp index 0d4a5f1e65..8b84f703e7 100644 --- a/src/blitter/32bpp_anim_sse2.hpp +++ b/src/blitter/32bpp_anim_sse2.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. @@ -28,15 +26,15 @@ /** A partially 32 bpp blitter with palette animation. */ class Blitter_32bppSSE2_Anim : public Blitter_32bppAnim { public: - /* virtual */ void PaletteAnimate(const Palette &palette); - /* virtual */ const char *GetName() { return "32bpp-sse2-anim"; } + void PaletteAnimate(const Palette &palette) override; + const char *GetName() override { return "32bpp-sse2-anim"; } }; /** Factory for the partially 32bpp blitter with animation. */ class FBlitter_32bppSSE2_Anim : public BlitterFactory { public: FBlitter_32bppSSE2_Anim() : BlitterFactory("32bpp-sse2-anim", "32bpp partially SSE2 Animation Blitter (palette animation)", HasCPUIDFlag(1, 3, 26)) {} - /* virtual */ Blitter *CreateInstance() { return new Blitter_32bppSSE2_Anim(); } + Blitter *CreateInstance() override { return new Blitter_32bppSSE2_Anim(); } }; #endif /* WITH_SSE */ diff --git a/src/blitter/32bpp_anim_sse4.cpp b/src/blitter/32bpp_anim_sse4.cpp index 24d1d7531f..566ef0c0ff 100644 --- a/src/blitter/32bpp_anim_sse4.cpp +++ b/src/blitter/32bpp_anim_sse4.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. diff --git a/src/blitter/32bpp_anim_sse4.hpp b/src/blitter/32bpp_anim_sse4.hpp index 5ff1fb01be..7674182a8f 100644 --- a/src/blitter/32bpp_anim_sse4.hpp +++ b/src/blitter/32bpp_anim_sse4.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. @@ -35,19 +33,19 @@ private: public: template - /* virtual */ void Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom); - /* virtual */ void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom); - /* virtual */ Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator) { + void Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom); + void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override; + Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator) override { return Blitter_32bppSSE_Base::Encode(sprite, allocator); } - /* virtual */ const char *GetName() { return "32bpp-sse4-anim"; } + const char *GetName() override { return "32bpp-sse4-anim"; } }; /** Factory for the SSE4 32 bpp blitter (with palette animation). */ class FBlitter_32bppSSE4_Anim: public BlitterFactory { public: - FBlitter_32bppSSE4_Anim() : BlitterFactory("32bpp-sse4-anim", "SSE4 Blitter (palette animation)", HasCPUIDFlag(1, 2, 19)) {} - /* virtual */ Blitter *CreateInstance() { return new Blitter_32bppSSE4_Anim(); } + FBlitter_32bppSSE4_Anim() : BlitterFactory("32bpp-sse4-anim", "32bpp SSE4 Blitter (palette animation)", HasCPUIDFlag(1, 2, 19)) {} + Blitter *CreateInstance() override { return new Blitter_32bppSSE4_Anim(); } }; #endif /* WITH_SSE */ diff --git a/src/blitter/32bpp_base.cpp b/src/blitter/32bpp_base.cpp index b2e66b0be1..6fe11c2350 100644 --- a/src/blitter/32bpp_base.cpp +++ b/src/blitter/32bpp_base.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. diff --git a/src/blitter/32bpp_base.hpp b/src/blitter/32bpp_base.hpp index 697593da6a..f09719450a 100644 --- a/src/blitter/32bpp_base.hpp +++ b/src/blitter/32bpp_base.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,19 +18,19 @@ /** Base for all 32bpp blitters. */ class Blitter_32bppBase : public Blitter { public: - /* virtual */ uint8 GetScreenDepth() { return 32; } - /* virtual */ void *MoveTo(void *video, int x, int y); - /* virtual */ void SetPixel(void *video, int x, int y, uint8 colour); - /* virtual */ void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash); - /* virtual */ void DrawRect(void *video, int width, int height, uint8 colour); - /* virtual */ void CopyFromBuffer(void *video, const void *src, int width, int height); - /* virtual */ void CopyToBuffer(const void *video, void *dst, int width, int height); - /* virtual */ void CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch); - /* virtual */ void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y); - /* virtual */ int BufferSize(int width, int height); - /* virtual */ void PaletteAnimate(const Palette &palette); - /* virtual */ Blitter::PaletteAnimation UsePaletteAnimation(); - /* virtual */ int GetBytesPerPixel() { return 4; } + uint8 GetScreenDepth() override { return 32; } + void *MoveTo(void *video, int x, int y) override; + void SetPixel(void *video, int x, int y, 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; + void DrawRect(void *video, int width, int height, uint8 colour) override; + 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 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; + void PaletteAnimate(const Palette &palette) override; + Blitter::PaletteAnimation UsePaletteAnimation() override; + int GetBytesPerPixel() override { return 4; } /** * Look up the colour in the current palette. diff --git a/src/blitter/32bpp_optimized.cpp b/src/blitter/32bpp_optimized.cpp index cc056f5b59..59b857254d 100644 --- a/src/blitter/32bpp_optimized.cpp +++ b/src/blitter/32bpp_optimized.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. @@ -48,7 +46,7 @@ inline void Blitter_32bppOptimized::Draw(const Blitter::BlitterParams *bp, ZoomL /* skip lines in dst */ Colour *dst = (Colour *)bp->dst + bp->top * bp->pitch + bp->left; - /* store so we don't have to access it via bp everytime (compiler assumes pointer aliasing) */ + /* store so we don't have to access it via bp every time (compiler assumes pointer aliasing) */ const byte *remap = bp->remap; for (int y = 0; y < bp->height; y++) { @@ -66,7 +64,7 @@ inline void Blitter_32bppOptimized::Draw(const Blitter::BlitterParams *bp, ZoomL /* we will end this line when we reach this point */ Colour *dst_end = dst + bp->skip_left; - /* number of pixels with the same aplha channel class */ + /* number of pixels with the same alpha channel class */ uint n; while (dst < dst_end) { diff --git a/src/blitter/32bpp_optimized.hpp b/src/blitter/32bpp_optimized.hpp index c261aa33d6..a9c732902e 100644 --- a/src/blitter/32bpp_optimized.hpp +++ b/src/blitter/32bpp_optimized.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. @@ -23,10 +21,10 @@ public: byte data[]; ///< Data, all zoomlevels. }; - /* virtual */ void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom); - /* virtual */ Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator); + void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override; + Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator) override; - /* virtual */ const char *GetName() { return "32bpp-optimized"; } + const char *GetName() override { return "32bpp-optimized"; } template void Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom); }; @@ -35,7 +33,7 @@ public: class FBlitter_32bppOptimized : public BlitterFactory { public: FBlitter_32bppOptimized() : BlitterFactory("32bpp-optimized", "32bpp Optimized Blitter (no palette animation)") {} - /* virtual */ Blitter *CreateInstance() { return new Blitter_32bppOptimized(); } + Blitter *CreateInstance() override { return new Blitter_32bppOptimized(); } }; #endif /* BLITTER_32BPP_OPTIMIZED_HPP */ diff --git a/src/blitter/32bpp_simple.cpp b/src/blitter/32bpp_simple.cpp index 92375be165..7e7ef14530 100644 --- a/src/blitter/32bpp_simple.cpp +++ b/src/blitter/32bpp_simple.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. diff --git a/src/blitter/32bpp_simple.hpp b/src/blitter/32bpp_simple.hpp index 0751f6f753..6437a1a5cf 100644 --- a/src/blitter/32bpp_simple.hpp +++ b/src/blitter/32bpp_simple.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. @@ -26,18 +24,18 @@ class Blitter_32bppSimple : public Blitter_32bppBase { uint8 v; ///< Brightness-channel }; public: - /* virtual */ void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom); - /* virtual */ void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal); - /* virtual */ Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator); + 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; - /* virtual */ const char *GetName() { return "32bpp-simple"; } + const char *GetName() override { return "32bpp-simple"; } }; /** Factory for the simple 32 bpp blitter. */ class FBlitter_32bppSimple : public BlitterFactory { public: FBlitter_32bppSimple() : BlitterFactory("32bpp-simple", "32bpp Simple Blitter (no palette animation)") {} - /* virtual */ Blitter *CreateInstance() { return new Blitter_32bppSimple(); } + Blitter *CreateInstance() override { return new Blitter_32bppSimple(); } }; #endif /* BLITTER_32BPP_SIMPLE_HPP */ diff --git a/src/blitter/32bpp_sse2.cpp b/src/blitter/32bpp_sse2.cpp index ae2b3ccc52..2e5d32d655 100644 --- a/src/blitter/32bpp_sse2.cpp +++ b/src/blitter/32bpp_sse2.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. diff --git a/src/blitter/32bpp_sse2.hpp b/src/blitter/32bpp_sse2.hpp index d6b17f679c..4103eed487 100644 --- a/src/blitter/32bpp_sse2.hpp +++ b/src/blitter/32bpp_sse2.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. @@ -82,22 +80,22 @@ DECLARE_ENUM_AS_BIT_SET(Blitter_32bppSSE_Base::SpriteFlags); /** The SSE2 32 bpp blitter (without palette animation). */ class Blitter_32bppSSE2 : public Blitter_32bppSimple, public Blitter_32bppSSE_Base { public: - /* virtual */ void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom); + void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override; template void Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom); - /* virtual */ Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator) { + Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator) override { return Blitter_32bppSSE_Base::Encode(sprite, allocator); } - /* virtual */ const char *GetName() { return "32bpp-sse2"; } + const char *GetName() override { return "32bpp-sse2"; } }; /** Factory for the SSE2 32 bpp blitter (without palette animation). */ class FBlitter_32bppSSE2 : public BlitterFactory { public: FBlitter_32bppSSE2() : BlitterFactory("32bpp-sse2", "32bpp SSE2 Blitter (no palette animation)", HasCPUIDFlag(1, 3, 26)) {} - /* virtual */ Blitter *CreateInstance() { return new Blitter_32bppSSE2(); } + Blitter *CreateInstance() override { return new Blitter_32bppSSE2(); } }; #endif /* WITH_SSE */ diff --git a/src/blitter/32bpp_sse4.cpp b/src/blitter/32bpp_sse4.cpp index 723264f03f..aab9edb65d 100644 --- a/src/blitter/32bpp_sse4.cpp +++ b/src/blitter/32bpp_sse4.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. diff --git a/src/blitter/32bpp_sse4.hpp b/src/blitter/32bpp_sse4.hpp index 9c59d253f5..7d44926b88 100644 --- a/src/blitter/32bpp_sse4.hpp +++ b/src/blitter/32bpp_sse4.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. @@ -27,17 +25,17 @@ /** The SSE4 32 bpp blitter (without palette animation). */ class Blitter_32bppSSE4 : public Blitter_32bppSSSE3 { public: - /* virtual */ void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom); + void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override; template void Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom); - /* virtual */ const char *GetName() { return "32bpp-sse4"; } + const char *GetName() override { return "32bpp-sse4"; } }; /** Factory for the SSE4 32 bpp blitter (without palette animation). */ class FBlitter_32bppSSE4: public BlitterFactory { public: FBlitter_32bppSSE4() : BlitterFactory("32bpp-sse4", "32bpp SSE4 Blitter (no palette animation)", HasCPUIDFlag(1, 2, 19)) {} - /* virtual */ Blitter *CreateInstance() { return new Blitter_32bppSSE4(); } + Blitter *CreateInstance() override { return new Blitter_32bppSSE4(); } }; #endif /* WITH_SSE */ diff --git a/src/blitter/32bpp_sse_func.hpp b/src/blitter/32bpp_sse_func.hpp index fb0ce9eb6e..083839b959 100644 --- a/src/blitter/32bpp_sse_func.hpp +++ b/src/blitter/32bpp_sse_func.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/blitter/32bpp_sse_type.h b/src/blitter/32bpp_sse_type.h index 49c7a68c20..1d63d8052d 100644 --- a/src/blitter/32bpp_sse_type.h +++ b/src/blitter/32bpp_sse_type.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/blitter/32bpp_ssse3.cpp b/src/blitter/32bpp_ssse3.cpp index ab6c9eba5d..7d38272c00 100644 --- a/src/blitter/32bpp_ssse3.cpp +++ b/src/blitter/32bpp_ssse3.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. diff --git a/src/blitter/32bpp_ssse3.hpp b/src/blitter/32bpp_ssse3.hpp index e9cac8ff0b..cc710ed05b 100644 --- a/src/blitter/32bpp_ssse3.hpp +++ b/src/blitter/32bpp_ssse3.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. @@ -27,17 +25,17 @@ /** The SSSE3 32 bpp blitter (without palette animation). */ class Blitter_32bppSSSE3 : public Blitter_32bppSSE2 { public: - /* virtual */ void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom); + void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override; template void Draw(const Blitter::BlitterParams *bp, ZoomLevel zoom); - /* virtual */ const char *GetName() { return "32bpp-ssse3"; } + const char *GetName() override { return "32bpp-ssse3"; } }; /** Factory for the SSSE3 32 bpp blitter (without palette animation). */ class FBlitter_32bppSSSE3: public BlitterFactory { public: FBlitter_32bppSSSE3() : BlitterFactory("32bpp-ssse3", "32bpp SSSE3 Blitter (no palette animation)", HasCPUIDFlag(1, 2, 9)) {} - /* virtual */ Blitter *CreateInstance() { return new Blitter_32bppSSSE3(); } + Blitter *CreateInstance() override { return new Blitter_32bppSSSE3(); } }; #endif /* WITH_SSE */ diff --git a/src/blitter/8bpp_base.cpp b/src/blitter/8bpp_base.cpp index dccfda3d70..501ffc64e5 100644 --- a/src/blitter/8bpp_base.cpp +++ b/src/blitter/8bpp_base.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. diff --git a/src/blitter/8bpp_base.hpp b/src/blitter/8bpp_base.hpp index 8f75dda5d3..f6f67ad1a6 100644 --- a/src/blitter/8bpp_base.hpp +++ b/src/blitter/8bpp_base.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. @@ -17,20 +15,20 @@ /** Base for all 8bpp blitters. */ class Blitter_8bppBase : public Blitter { public: - /* virtual */ uint8 GetScreenDepth() { return 8; } - /* virtual */ void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal); - /* virtual */ void *MoveTo(void *video, int x, int y); - /* virtual */ void SetPixel(void *video, int x, int y, uint8 colour); - /* virtual */ void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash); - /* virtual */ void DrawRect(void *video, int width, int height, uint8 colour); - /* virtual */ void CopyFromBuffer(void *video, const void *src, int width, int height); - /* virtual */ void CopyToBuffer(const void *video, void *dst, int width, int height); - /* virtual */ void CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch); - /* virtual */ void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y); - /* virtual */ int BufferSize(int width, int height); - /* virtual */ void PaletteAnimate(const Palette &palette); - /* virtual */ Blitter::PaletteAnimation UsePaletteAnimation(); - /* virtual */ int GetBytesPerPixel() { return 1; } + uint8 GetScreenDepth() override { return 8; } + void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal) override; + void *MoveTo(void *video, int x, int y) override; + void SetPixel(void *video, int x, int y, 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; + void DrawRect(void *video, int width, int height, uint8 colour) override; + 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 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; + void PaletteAnimate(const Palette &palette) override; + Blitter::PaletteAnimation UsePaletteAnimation() override; + int GetBytesPerPixel() override { return 1; } }; #endif /* BLITTER_8BPP_BASE_HPP */ diff --git a/src/blitter/8bpp_optimized.cpp b/src/blitter/8bpp_optimized.cpp index 0f07e7c7bb..5c34bf0674 100644 --- a/src/blitter/8bpp_optimized.cpp +++ b/src/blitter/8bpp_optimized.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. @@ -167,7 +165,7 @@ Sprite *Blitter_8bppOptimized::Encode(const SpriteLoader::Sprite *sprite, Alloca uint trans = 0; uint pixels = 0; uint last_colour = 0; - byte *count_dst = NULL; + byte *count_dst = nullptr; /* Store the scaled image */ const SpriteLoader::CommonPixel *src = &sprite[i].data[y * sprite[i].width]; @@ -176,11 +174,11 @@ Sprite *Blitter_8bppOptimized::Encode(const SpriteLoader::Sprite *sprite, Alloca uint colour = src++->m; if (last_colour == 0 || colour == 0 || pixels == 255) { - if (count_dst != NULL) { + if (count_dst != nullptr) { /* Write how many non-transparent bytes we get */ *count_dst = pixels; pixels = 0; - count_dst = NULL; + count_dst = nullptr; } /* As long as we find transparency bytes, keep counting */ if (colour == 0 && trans != 255) { @@ -206,7 +204,7 @@ Sprite *Blitter_8bppOptimized::Encode(const SpriteLoader::Sprite *sprite, Alloca } } - if (count_dst != NULL) *count_dst = pixels; + if (count_dst != nullptr) *count_dst = pixels; /* Write line-ending */ *dst = 0; dst++; diff --git a/src/blitter/8bpp_optimized.hpp b/src/blitter/8bpp_optimized.hpp index b5b5324b91..a305c954da 100644 --- a/src/blitter/8bpp_optimized.hpp +++ b/src/blitter/8bpp_optimized.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. @@ -24,17 +22,17 @@ public: byte data[]; ///< Data, all zoomlevels. }; - /* virtual */ void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom); - /* virtual */ Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator); + void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override; + Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator) override; - /* virtual */ const char *GetName() { return "8bpp-optimized"; } + const char *GetName() override { return "8bpp-optimized"; } }; /** Factory for the 8bpp blitter optimised for speed. */ class FBlitter_8bppOptimized : public BlitterFactory { public: FBlitter_8bppOptimized() : BlitterFactory("8bpp-optimized", "8bpp Optimized Blitter (compression + all-ZoomLevel cache)") {} - /* virtual */ Blitter *CreateInstance() { return new Blitter_8bppOptimized(); } + Blitter *CreateInstance() override { return new Blitter_8bppOptimized(); } }; #endif /* BLITTER_8BPP_OPTIMIZED_HPP */ diff --git a/src/blitter/8bpp_simple.cpp b/src/blitter/8bpp_simple.cpp index 2131a04682..d40530536e 100644 --- a/src/blitter/8bpp_simple.cpp +++ b/src/blitter/8bpp_simple.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. diff --git a/src/blitter/8bpp_simple.hpp b/src/blitter/8bpp_simple.hpp index c00c75ac04..7f3c0a8aad 100644 --- a/src/blitter/8bpp_simple.hpp +++ b/src/blitter/8bpp_simple.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. @@ -18,17 +16,17 @@ /** Most trivial 8bpp blitter. */ class Blitter_8bppSimple FINAL : public Blitter_8bppBase { public: - /* virtual */ void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom); - /* virtual */ Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator); + void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) override; + Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator) override; - /* virtual */ const char *GetName() { return "8bpp-simple"; } + const char *GetName() override { return "8bpp-simple"; } }; /** Factory for the most trivial 8bpp blitter. */ class FBlitter_8bppSimple : public BlitterFactory { public: FBlitter_8bppSimple() : BlitterFactory("8bpp-simple", "8bpp Simple Blitter (relative slow, but never wrong)") {} - /* virtual */ Blitter *CreateInstance() { return new Blitter_8bppSimple(); } + Blitter *CreateInstance() override { return new Blitter_8bppSimple(); } }; #endif /* BLITTER_8BPP_SIMPLE_HPP */ diff --git a/src/blitter/base.hpp b/src/blitter/base.hpp index 388359441f..10dfce84b2 100644 --- a/src/blitter/base.hpp +++ b/src/blitter/base.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/blitter/common.hpp b/src/blitter/common.hpp index 3e4911d003..b5040b1275 100644 --- a/src/blitter/common.hpp +++ b/src/blitter/common.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/blitter/factory.hpp b/src/blitter/factory.hpp index 01faca68fd..e97fe53de7 100644 --- a/src/blitter/factory.hpp +++ b/src/blitter/factory.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. @@ -48,7 +46,7 @@ private: */ static Blitter **GetActiveBlitter() { - static Blitter *s_blitter = NULL; + static Blitter *s_blitter = nullptr; return &s_blitter; } @@ -58,8 +56,8 @@ protected: * @param name The name of the blitter. * @param description A longer description for the blitter. * @param usable Whether the blitter is usable (on the current computer). For example for disabling SSE blitters when the CPU can't handle them. - * @pre name != NULL. - * @pre description != NULL. + * @pre name != nullptr. + * @pre description != nullptr. * @pre There is no blitter registered with this name. */ BlitterFactory(const char *name, const char *description, bool usable = true) : @@ -96,7 +94,7 @@ public: static Blitter *SelectBlitter(const char *name) { BlitterFactory *b = GetBlitterFactory(name); - if (b == NULL) return NULL; + if (b == nullptr) return nullptr; Blitter *newb = b->CreateInstance(); delete *GetActiveBlitter(); @@ -109,7 +107,7 @@ public: /** * Get the blitter factory with the given name. * @param name the blitter factory to select. - * @return The blitter factory, or NULL when there isn't one with the wanted name. + * @return The blitter factory, or nullptr when there isn't one with the wanted name. */ static BlitterFactory *GetBlitterFactory(const char *name) { @@ -128,7 +126,7 @@ public: } #endif /* defined(WITH_COCOA) */ #endif /* defined(DEDICATED) */ - if (GetBlitters().size() == 0) return NULL; + if (GetBlitters().size() == 0) return nullptr; const char *bname = (StrEmpty(name)) ? default_blitter : name; Blitters::iterator it = GetBlitters().begin(); @@ -138,7 +136,7 @@ public: return b; } } - return NULL; + return nullptr; } /** diff --git a/src/blitter/null.cpp b/src/blitter/null.cpp index e968abe13f..29747b0f96 100644 --- a/src/blitter/null.cpp +++ b/src/blitter/null.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. diff --git a/src/blitter/null.hpp b/src/blitter/null.hpp index a6fed2ebca..7d5a672c56 100644 --- a/src/blitter/null.hpp +++ b/src/blitter/null.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. @@ -17,31 +15,31 @@ /** Blitter that does nothing. */ class Blitter_Null : public Blitter { public: - /* virtual */ uint8 GetScreenDepth() { return 0; } - /* virtual */ void Draw(Blitter::BlitterParams *bp, BlitterMode mode, ZoomLevel zoom) {}; - /* virtual */ void DrawColourMappingRect(void *dst, int width, int height, PaletteID pal) {}; - /* virtual */ Sprite *Encode(const SpriteLoader::Sprite *sprite, AllocatorProc *allocator); - /* virtual */ void *MoveTo(void *video, int x, int y) { return NULL; }; - /* virtual */ void SetPixel(void *video, int x, int y, uint8 colour) {}; - /* virtual */ void DrawRect(void *video, int width, int height, uint8 colour) {}; - /* virtual */ void DrawLine(void *video, int x, int y, int x2, int y2, int screen_width, int screen_height, uint8 colour, int width, int dash) {}; - /* virtual */ void CopyFromBuffer(void *video, const void *src, int width, int height) {}; - /* virtual */ void CopyToBuffer(const void *video, void *dst, int width, int height) {}; - /* virtual */ void CopyImageToBuffer(const void *video, void *dst, int width, int height, int dst_pitch) {}; - /* virtual */ void ScrollBuffer(void *video, int &left, int &top, int &width, int &height, int scroll_x, int scroll_y) {}; - /* virtual */ int BufferSize(int width, int height) { return 0; }; - /* virtual */ void PaletteAnimate(const Palette &palette) { }; - /* virtual */ Blitter::PaletteAnimation UsePaletteAnimation() { return Blitter::PALETTE_ANIMATION_NONE; }; + uint8 GetScreenDepth() override { return 0; } + 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; + void *MoveTo(void *video, int x, int y) override { return nullptr; }; + 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 {}; + 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 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; }; + void PaletteAnimate(const Palette &palette) override { }; + Blitter::PaletteAnimation UsePaletteAnimation() override { return Blitter::PALETTE_ANIMATION_NONE; }; - /* virtual */ const char *GetName() { return "null"; } - /* virtual */ int GetBytesPerPixel() { return 0; } + const char *GetName() override { return "null"; } + int GetBytesPerPixel() override { return 0; } }; /** Factory for the blitter that does nothing. */ class FBlitter_Null : public BlitterFactory { public: FBlitter_Null() : BlitterFactory("null", "Null Blitter (does nothing)") {} - /* virtual */ Blitter *CreateInstance() { return new Blitter_Null(); } + Blitter *CreateInstance() override { return new Blitter_Null(); } }; #endif /* BLITTER_NULL_HPP */ diff --git a/src/bmp.cpp b/src/bmp.cpp index 1033d89f11..2877d01470 100644 --- a/src/bmp.cpp +++ b/src/bmp.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. @@ -319,7 +317,7 @@ static inline bool BmpRead24(BmpBuffer *buffer, BmpInfo *info, BmpData *data) bool BmpReadHeader(BmpBuffer *buffer, BmpInfo *info, BmpData *data) { uint32 header_size; - assert(info != NULL); + assert(info != nullptr); MemSetT(info, 0); /* Reading BMP header */ @@ -390,7 +388,7 @@ bool BmpReadHeader(BmpBuffer *buffer, BmpInfo *info, BmpData *data) */ bool BmpReadBitmap(BmpBuffer *buffer, BmpInfo *info, BmpData *data) { - assert(info != NULL && data != NULL); + assert(info != nullptr && data != nullptr); data->bitmap = CallocT(info->width * info->height * ((info->bpp == 24) ? 3 : 1)); @@ -413,7 +411,7 @@ bool BmpReadBitmap(BmpBuffer *buffer, BmpInfo *info, BmpData *data) void BmpDestroyData(BmpData *data) { - assert(data != NULL); + assert(data != nullptr); free(data->palette); free(data->bitmap); } diff --git a/src/bmp.h b/src/bmp.h index cf2b538f39..3d5ded2a16 100644 --- a/src/bmp.h +++ b/src/bmp.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. @@ -15,7 +13,7 @@ #include "gfx_type.h" struct BmpInfo { - uint32 offset; ///< offset of bitmap data from .bmp file begining + uint32 offset; ///< offset of bitmap data from .bmp file beginning uint32 width; ///< bitmap width uint32 height; ///< bitmap height bool os2_bmp; ///< true if OS/2 1.x or windows 2.x bitmap diff --git a/src/bootstrap_gui.cpp b/src/bootstrap_gui.cpp index 3fb52a1f9e..d2445c23a4 100644 --- a/src/bootstrap_gui.cpp +++ b/src/bootstrap_gui.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. @@ -13,7 +11,7 @@ #include "base_media_base.h" #include "blitter/factory.hpp" -#if defined(ENABLE_NETWORK) && defined(WITH_FREETYPE) +#if defined(WITH_FREETYPE) || defined(WITH_UNISCRIBE) #include "core/geometry_func.hpp" #include "fontcache.h" @@ -40,7 +38,7 @@ static const struct NWidgetPart _background_widgets[] = { * Window description for the background window to prevent smearing. */ static WindowDesc _background_desc( - WDP_MANUAL, NULL, 0, 0, + WDP_MANUAL, nullptr, 0, 0, WC_BOOTSTRAP, WC_NONE, 0, _background_widgets, lengthof(_background_widgets) @@ -56,7 +54,7 @@ public: ResizeWindow(this, _screen.width, _screen.height); } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { GfxFillRect(r.left, r.top, r.right, r.bottom, 4, FILLRECT_OPAQUE); GfxFillRect(r.left, r.top, r.right, r.bottom, 0, FILLRECT_CHECKER); @@ -73,7 +71,7 @@ static const NWidgetPart _nested_boostrap_download_status_window_widgets[] = { /** Window description for the download window */ static WindowDesc _bootstrap_download_status_window_desc( - WDP_CENTER, NULL, 0, 0, + WDP_CENTER, nullptr, 0, 0, WC_NETWORK_STATUS_WINDOW, WC_NONE, WDF_MODAL, _nested_boostrap_download_status_window_widgets, lengthof(_nested_boostrap_download_status_window_widgets) @@ -88,7 +86,7 @@ public: { } - virtual void OnDownloadComplete(ContentID cid) + void OnDownloadComplete(ContentID cid) override { /* We have completed downloading. We can trigger finding the right set now. */ BaseGraphics::FindSets(); @@ -118,7 +116,7 @@ static const NWidgetPart _bootstrap_query_widgets[] = { /** The window description for the query. */ static WindowDesc _bootstrap_query_desc( - WDP_CENTER, NULL, 0, 0, + WDP_CENTER, nullptr, 0, 0, WC_CONFIRM_POPUP_QUERY, WC_NONE, 0, _bootstrap_query_widgets, lengthof(_bootstrap_query_widgets) @@ -142,7 +140,7 @@ public: _network_content_client.RemoveCallback(this); } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { /* We cache the button size. This is safe as no reinit can happen here. */ if (this->button_size.width == 0) { @@ -165,14 +163,14 @@ public: } } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { 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); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_BAFD_YES: @@ -189,13 +187,13 @@ public: } } - virtual void OnConnect(bool success) + void OnConnect(bool success) override { /* Once connected, request the metadata. */ _network_content_client.RequestContentList(CONTENT_TYPE_BASE_GRAPHICS); } - virtual void OnReceiveContentInfo(const ContentInfo *ci) + void OnReceiveContentInfo(const ContentInfo *ci) override { /* And once the meta data is received, start downloading it. */ _network_content_client.Select(ci->id); @@ -204,7 +202,7 @@ public: } }; -#endif /* defined(ENABLE_NETWORK) && defined(WITH_FREETYPE) */ +#endif /* defined(WITH_FREETYPE) */ /** * Handle all procedures for bootstrapping OpenTTD without a base graphics set. @@ -214,13 +212,13 @@ public: */ bool HandleBootstrap() { - if (BaseGraphics::GetUsedSet() != NULL) return true; + if (BaseGraphics::GetUsedSet() != nullptr) return true; /* 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 defined(ENABLE_NETWORK) && defined(WITH_FREETYPE) && (defined(WITH_FONTCONFIG) || defined(_WIN32) || defined(__APPLE__)) +#if (defined(_WIN32) && defined(WITH_UNISCRIBE)) || (defined(WITH_FREETYPE) && (defined(WITH_FONTCONFIG) || defined(__APPLE__))) if (!_network_available) goto failure; /* First tell the game we're bootstrapping. */ @@ -255,7 +253,7 @@ bool HandleBootstrap() if (_exit_game) return false; /* Try to probe the graphics. Should work this time. */ - if (!BaseGraphics::SetSet(NULL)) goto failure; + if (!BaseGraphics::SetSet(nullptr)) goto failure; /* Finally we can continue heading for the menu. */ _game_mode = GM_MENU; @@ -264,6 +262,6 @@ bool HandleBootstrap() /* Failure to get enough working to get a graphics set. */ failure: - usererror("Failed to find a graphics set. Please acquire a graphics set for OpenTTD. See section 4.1 of README.md."); + usererror("Failed to find a graphics set. Please acquire a graphics set for OpenTTD. See section 1.4 of README.md."); return false; } diff --git a/src/bridge.h b/src/bridge.h index badf045e39..3da95751df 100644 --- a/src/bridge.h +++ b/src/bridge.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/bridge_gui.cpp b/src/bridge_gui.cpp index b9122fafad..b8c5792c23 100644 --- a/src/bridge_gui.cpp +++ b/src/bridge_gui.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. @@ -13,6 +11,7 @@ #include "error.h" #include "command_func.h" #include "rail.h" +#include "road.h" #include "strings_func.h" #include "window_func.h" #include "sound_func.h" @@ -58,8 +57,9 @@ typedef GUIList GUIBridgeList; ///< List of bridges, used in #B * - p2 = (bit 0- 7) - bridge type (hi bh) * - p2 = (bit 8-13) - rail type or road types. * - p2 = (bit 15-16) - transport type. + * @param cmd unused */ -void CcBuildBridge(const CommandCost &result, TileIndex end_tile, uint32 p1, uint32 p2) +void CcBuildBridge(const CommandCost &result, TileIndex end_tile, uint32 p1, uint32 p2, uint32 cmd) { if (result.Failed()) return; if (_settings_client.sound.confirm) SndPlayTileFx(SND_27_BLACKSMITH_ANVIL, end_tile); @@ -94,31 +94,31 @@ private: Scrollbar *vscroll; /** Sort the bridges by their index */ - static int CDECL BridgeIndexSorter(const BuildBridgeData *a, const BuildBridgeData *b) + static bool BridgeIndexSorter(const BuildBridgeData &a, const BuildBridgeData &b) { - return a->index - b->index; + return a.index < b.index; } /** Sort the bridges by their price */ - static int CDECL BridgePriceSorter(const BuildBridgeData *a, const BuildBridgeData *b) + static bool BridgePriceSorter(const BuildBridgeData &a, const BuildBridgeData &b) { - return a->cost - b->cost; + return a.cost < b.cost; } /** Sort the bridges by their maximum speed */ - static int CDECL BridgeSpeedSorter(const BuildBridgeData *a, const BuildBridgeData *b) + static bool BridgeSpeedSorter(const BuildBridgeData &a, const BuildBridgeData &b) { - return a->spec->speed - b->spec->speed; + return a.spec->speed < b.spec->speed; } void BuildBridge(uint8 i) { switch ((TransportType)(this->type >> 15)) { - case TRANSPORT_RAIL: _last_railbridge_type = this->bridges->Get(i)->index; break; - case TRANSPORT_ROAD: _last_roadbridge_type = this->bridges->Get(i)->index; break; + case TRANSPORT_RAIL: _last_railbridge_type = this->bridges->at(i).index; break; + case TRANSPORT_ROAD: _last_roadbridge_type = this->bridges->at(i).index; break; default: break; } - DoCommandP(this->end_tile, this->start_tile, this->type | this->bridges->Get(i)->index, + DoCommandP(this->end_tile, this->start_tile, this->type | this->bridges->at(i).index, CMD_BUILD_BRIDGE | CMD_MSG(STR_ERROR_CAN_T_BUILD_BRIDGE_HERE), CcBuildBridge); } @@ -154,7 +154,7 @@ public: this->bridges->NeedResort(); this->SortBridgeList(); - this->vscroll->SetCount(bl->Length()); + this->vscroll->SetCount((uint)bl->size()); } ~BuildBridgeWindow() @@ -164,7 +164,7 @@ public: delete bridges; } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_BBS_DROPDOWN_ORDER: { @@ -187,11 +187,11 @@ public: 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->Length(); i++) { - const BridgeSpec *b = this->bridges->Get(i)->spec; + 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->Get(i)->cost); + 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)); @@ -209,7 +209,7 @@ public: } } - virtual Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number) + Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number) override { /* Position the window so hopefully the first bridge from the list is under the mouse pointer. */ NWidgetBase *list = this->GetWidget(WID_BBS_BRIDGE_LIST); @@ -219,7 +219,7 @@ public: return corner; } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { switch (widget) { case WID_BBS_DROPDOWN_ORDER: @@ -228,10 +228,10 @@ public: case WID_BBS_BRIDGE_LIST: { uint y = r.top; - for (int i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < (int)this->bridges->Length(); i++) { - const BridgeSpec *b = this->bridges->Get(i)->spec; + 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->Get(i)->cost); + SetDParam(2, this->bridges->at(i).cost); SetDParam(1, b->speed); SetDParam(0, b->material); @@ -246,10 +246,10 @@ public: } } - virtual EventState OnKeyPress(WChar key, uint16 keycode) + EventState OnKeyPress(WChar key, uint16 keycode) override { const uint8 i = keycode - '1'; - if (i < 9 && i < this->bridges->Length()) { + if (i < 9 && i < this->bridges->size()) { /* Build the requested bridge */ this->BuildBridge(i); delete this; @@ -258,13 +258,13 @@ public: return ES_NOT_HANDLED; } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { default: break; case WID_BBS_BRIDGE_LIST: { uint i = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_BBS_BRIDGE_LIST); - if (i < this->bridges->Length()) { + if (i < this->bridges->size()) { this->BuildBridge(i); delete this; } @@ -282,7 +282,7 @@ public: } } - virtual void OnDropdownSelect(int widget, int index) + void OnDropdownSelect(int widget, int index) override { if (widget == WID_BBS_DROPDOWN_CRITERIA && this->bridges->SortType() != index) { this->bridges->SetSortType(index); @@ -291,7 +291,7 @@ public: } } - virtual void OnResize() + void OnResize() override { this->vscroll->SetCapacityFromWidget(this, WID_BBS_BRIDGE_LIST); } @@ -395,7 +395,7 @@ void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transpo StringID errmsg = INVALID_STRING_ID; CommandCost ret = DoCommand(end, start, type, CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_BRIDGE)) | DC_QUERY_COST, CMD_BUILD_BRIDGE); - GUIBridgeList *bl = NULL; + GUIBridgeList *bl = nullptr; if (ret.Failed()) { errmsg = ret.GetErrorMessage(); } else { @@ -406,11 +406,25 @@ void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transpo Money infra_cost = 0; switch (transport_type) { - case TRANSPORT_ROAD: - infra_cost = (bridge_len + 2) * _price[PR_BUILD_ROAD] * 2; + case TRANSPORT_ROAD: { /* In case we add a new road type as well, we must be aware of those costs. */ - if (IsBridgeTile(start)) infra_cost *= CountBits(GetRoadTypes(start) | (RoadTypes)road_rail_type); + RoadType road_rt = INVALID_ROADTYPE; + RoadType tram_rt = INVALID_ROADTYPE; + if (IsBridgeTile(start)) { + road_rt = GetRoadTypeRoad(start); + tram_rt = GetRoadTypeTram(start); + } + if (RoadTypeIsRoad((RoadType)road_rail_type)) { + road_rt = (RoadType)road_rail_type; + } else { + tram_rt = (RoadType)road_rail_type; + } + + if (road_rt != INVALID_ROADTYPE) infra_cost += (bridge_len + 2) * 2 * RoadBuildCost(road_rt); + if (tram_rt != INVALID_ROADTYPE) infra_cost += (bridge_len + 2) * 2 * RoadBuildCost(tram_rt); + break; + } case TRANSPORT_RAIL: infra_cost = (bridge_len + 2) * RailBuildCost((RailType)road_rail_type); break; default: break; } @@ -419,17 +433,18 @@ void ShowBuildBridgeWindow(TileIndex start, TileIndex end, TransportType transpo for (BridgeType brd_type = 0; brd_type != MAX_BRIDGES; brd_type++) { if (CheckBridgeAvailability(brd_type, bridge_len).Succeeded()) { /* bridge is accepted, add to list */ - BuildBridgeData *item = bl->Append(); - item->index = brd_type; - item->spec = GetBridgeSpec(brd_type); + /*C++17: BuildBridgeData &item = */ bl->emplace_back(); + BuildBridgeData &item = bl->back(); + item.index = brd_type; + item.spec = GetBridgeSpec(brd_type); /* Add to terraforming & bulldozing costs the cost of the * bridge itself (not computed with DC_QUERY_COST) */ - item->cost = ret.GetCost() + (((int64)tot_bridgedata_len * _price[PR_BUILD_BRIDGE] * item->spec->price) >> 8) + infra_cost; + item.cost = ret.GetCost() + (((int64)tot_bridgedata_len * _price[PR_BUILD_BRIDGE] * item.spec->price) >> 8) + infra_cost; } } } - if (bl != NULL && bl->Length() != 0) { + if (bl != nullptr && bl->size() != 0) { new BuildBridgeWindow(&_build_bridge_desc, start, end, type, bl); } else { delete bl; diff --git a/src/bridge_map.cpp b/src/bridge_map.cpp index b738895065..eb28673867 100644 --- a/src/bridge_map.cpp +++ b/src/bridge_map.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. diff --git a/src/bridge_map.h b/src/bridge_map.h index 75b20498d1..575af60470 100644 --- a/src/bridge_map.h +++ b/src/bridge_map.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. @@ -12,8 +10,10 @@ #ifndef BRIDGE_MAP_H #define BRIDGE_MAP_H +#include "rail_map.h" #include "road_map.h" #include "bridge.h" +#include "water_map.h" /** * Checks if this is a bridge, instead of a tunnel @@ -123,20 +123,20 @@ static inline void SetBridgeMiddle(TileIndex t, Axis a) * @param bridgetype the type of bridge this bridge ramp belongs to * @param d the direction this ramp must be facing * @param tt the transport type of the bridge - * @param rt the road or rail type * @note this function should not be called directly. */ -static inline void MakeBridgeRamp(TileIndex t, Owner o, BridgeType bridgetype, DiagDirection d, TransportType tt, uint rt) +static inline void MakeBridgeRamp(TileIndex 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 = 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 = rt; + _me[t].m8 = INVALID_ROADTYPE << 6; } /** @@ -147,14 +147,15 @@ static inline void MakeBridgeRamp(TileIndex t, Owner o, BridgeType bridgetype, D * @param owner_tram the new owner of the tram on the bridge * @param bridgetype the type of bridge this bridge ramp belongs to * @param d the direction this ramp must be facing - * @param r the road type of the bridge + * @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, RoadTypes r) +static inline void MakeRoadBridgeRamp(TileIndex 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, 0); - SetRoadOwner(t, ROADTYPE_ROAD, owner_road); - if (owner_tram != OWNER_TOWN) SetRoadOwner(t, ROADTYPE_TRAM, owner_tram); - SetRoadTypes(t, r); + MakeBridgeRamp(t, o, bridgetype, d, TRANSPORT_ROAD); + SetRoadOwner(t, RTT_ROAD, owner_road); + if (owner_tram != OWNER_TOWN) SetRoadOwner(t, RTT_TRAM, owner_tram); + SetRoadTypes(t, road_rt, tram_rt); } /** @@ -163,11 +164,12 @@ static inline void MakeRoadBridgeRamp(TileIndex t, Owner o, Owner owner_road, Ow * @param o the new owner of the bridge ramp * @param bridgetype the type of bridge this bridge ramp belongs to * @param d the direction this ramp must be facing - * @param r the rail type of the bridge + * @param rt the rail type of the bridge */ -static inline void MakeRailBridgeRamp(TileIndex t, Owner o, BridgeType bridgetype, DiagDirection d, RailType r) +static inline void MakeRailBridgeRamp(TileIndex t, Owner o, BridgeType bridgetype, DiagDirection d, RailType rt) { - MakeBridgeRamp(t, o, bridgetype, d, TRANSPORT_RAIL, r); + MakeBridgeRamp(t, o, bridgetype, d, TRANSPORT_RAIL); + SetRailType(t, rt); } /** @@ -178,7 +180,7 @@ static inline void MakeRailBridgeRamp(TileIndex t, Owner o, BridgeType bridgetyp */ static inline void MakeAqueductBridgeRamp(TileIndex t, Owner o, DiagDirection d) { - MakeBridgeRamp(t, o, 0, d, TRANSPORT_WATER, 0); + MakeBridgeRamp(t, o, 0, d, TRANSPORT_WATER); } #endif /* BRIDGE_MAP_H */ diff --git a/src/build_vehicle_gui.cpp b/src/build_vehicle_gui.cpp index 631dff67ce..66091a676e 100644 --- a/src/build_vehicle_gui.cpp +++ b/src/build_vehicle_gui.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. @@ -105,57 +103,54 @@ static CargoID _engine_sort_last_cargo_criteria[] = {CF_ANY, CF_ANY, CF_ANY, CF_ /** * Determines order of engines by engineID - * @param *a first engine to compare - * @param *b second engine to compare - * @return for descending order: returns < 0 if a < b and > 0 for a > b. Vice versa for ascending order and 0 for equal + * @param a first engine to compare + * @param b second engine to compare + * @return for descending order: returns true if a < b. Vice versa for ascending order */ -static int CDECL EngineNumberSorter(const EngineID *a, const EngineID *b) +static bool EngineNumberSorter(const EngineID &a, const EngineID &b) { - int r = Engine::Get(*a)->list_position - Engine::Get(*b)->list_position; + int r = Engine::Get(a)->list_position - Engine::Get(b)->list_position; - return _engine_sort_direction ? -r : r; + return _engine_sort_direction ? r > 0 : r < 0; } /** * Determines order of engines by introduction date - * @param *a first engine to compare - * @param *b second engine to compare - * @return for descending order: returns < 0 if a < b and > 0 for a > b. Vice versa for ascending order and 0 for equal + * @param a first engine to compare + * @param b second engine to compare + * @return for descending order: returns true if a < b. Vice versa for ascending order */ -static int CDECL EngineIntroDateSorter(const EngineID *a, const EngineID *b) +static bool EngineIntroDateSorter(const EngineID &a, const EngineID &b) { - const int va = Engine::Get(*a)->intro_date; - const int vb = Engine::Get(*b)->intro_date; + const int va = Engine::Get(a)->intro_date; + const int vb = Engine::Get(b)->intro_date; const int r = va - vb; /* Use EngineID to sort instead since we want consistent sorting */ if (r == 0) return EngineNumberSorter(a, b); - return _engine_sort_direction ? -r : r; + return _engine_sort_direction ? r > 0 : r < 0; } /** * Determines order of engines by name - * @param *a first engine to compare - * @param *b second engine to compare - * @return for descending order: returns < 0 if a < b and > 0 for a > b. Vice versa for ascending order and 0 for equal + * @param a first engine to compare + * @param b second engine to compare + * @return for descending order: returns true if a < b. Vice versa for ascending order */ -static int CDECL EngineNameSorter(const EngineID *a, const EngineID *b) +static bool EngineNameSorter(const EngineID &a, const EngineID &b) { static EngineID last_engine[2] = { INVALID_ENGINE, INVALID_ENGINE }; static char last_name[2][64] = { "\0", "\0" }; - const EngineID va = *a; - const EngineID vb = *b; - - if (va != last_engine[0]) { - last_engine[0] = va; - SetDParam(0, va); + if (a != last_engine[0]) { + last_engine[0] = a; + SetDParam(0, a); GetString(last_name[0], STR_ENGINE_NAME, lastof(last_name[0])); } - if (vb != last_engine[1]) { - last_engine[1] = vb; - SetDParam(0, vb); + if (b != last_engine[1]) { + last_engine[1] = b; + SetDParam(0, b); GetString(last_name[1], STR_ENGINE_NAME, lastof(last_name[1])); } @@ -163,207 +158,221 @@ static int CDECL EngineNameSorter(const EngineID *a, const EngineID *b) /* Use EngineID to sort instead since we want consistent sorting */ if (r == 0) return EngineNumberSorter(a, b); - return _engine_sort_direction ? -r : r; + return _engine_sort_direction ? r > 0 : r < 0; } /** * Determines order of engines by reliability - * @param *a first engine to compare - * @param *b second engine to compare - * @return for descending order: returns < 0 if a < b and > 0 for a > b. Vice versa for ascending order and 0 for equal + * @param a first engine to compare + * @param b second engine to compare + * @return for descending order: returns true if a < b. Vice versa for ascending order */ -static int CDECL EngineReliabilitySorter(const EngineID *a, const EngineID *b) +static bool EngineReliabilitySorter(const EngineID &a, const EngineID &b) { - const int va = Engine::Get(*a)->reliability; - const int vb = Engine::Get(*b)->reliability; + const int va = Engine::Get(a)->reliability; + const int vb = Engine::Get(b)->reliability; const int r = va - vb; /* Use EngineID to sort instead since we want consistent sorting */ if (r == 0) return EngineNumberSorter(a, b); - return _engine_sort_direction ? -r : r; + return _engine_sort_direction ? r > 0 : r < 0; } /** * Determines order of engines by purchase cost - * @param *a first engine to compare - * @param *b second engine to compare - * @return for descending order: returns < 0 if a < b and > 0 for a > b. Vice versa for ascending order and 0 for equal + * @param a first engine to compare + * @param b second engine to compare + * @return for descending order: returns true if a < b. Vice versa for ascending order */ -static int CDECL EngineCostSorter(const EngineID *a, const EngineID *b) +static bool EngineCostSorter(const EngineID &a, const EngineID &b) { - Money va = Engine::Get(*a)->GetCost(); - Money vb = Engine::Get(*b)->GetCost(); + Money va = Engine::Get(a)->GetCost(); + Money vb = Engine::Get(b)->GetCost(); int r = ClampToI32(va - vb); /* Use EngineID to sort instead since we want consistent sorting */ if (r == 0) return EngineNumberSorter(a, b); - return _engine_sort_direction ? -r : r; + return _engine_sort_direction ? r > 0 : r < 0; } /** * Determines order of engines by speed - * @param *a first engine to compare - * @param *b second engine to compare - * @return for descending order: returns < 0 if a < b and > 0 for a > b. Vice versa for ascending order and 0 for equal + * @param a first engine to compare + * @param b second engine to compare + * @return for descending order: returns true if a < b. Vice versa for ascending order */ -static int CDECL EngineSpeedSorter(const EngineID *a, const EngineID *b) +static bool EngineSpeedSorter(const EngineID &a, const EngineID &b) { - int va = Engine::Get(*a)->GetDisplayMaxSpeed(); - int vb = Engine::Get(*b)->GetDisplayMaxSpeed(); + int va = Engine::Get(a)->GetDisplayMaxSpeed(); + int vb = Engine::Get(b)->GetDisplayMaxSpeed(); int r = va - vb; /* Use EngineID to sort instead since we want consistent sorting */ if (r == 0) return EngineNumberSorter(a, b); - return _engine_sort_direction ? -r : r; + return _engine_sort_direction ? r > 0 : r < 0; } /** * Determines order of engines by power - * @param *a first engine to compare - * @param *b second engine to compare - * @return for descending order: returns < 0 if a < b and > 0 for a > b. Vice versa for ascending order and 0 for equal + * @param a first engine to compare + * @param b second engine to compare + * @return for descending order: returns true if a < b. Vice versa for ascending order */ -static int CDECL EnginePowerSorter(const EngineID *a, const EngineID *b) +static bool EnginePowerSorter(const EngineID &a, const EngineID &b) { - int va = Engine::Get(*a)->GetPower(); - int vb = Engine::Get(*b)->GetPower(); + int va = Engine::Get(a)->GetPower(); + int vb = Engine::Get(b)->GetPower(); int r = va - vb; /* Use EngineID to sort instead since we want consistent sorting */ if (r == 0) return EngineNumberSorter(a, b); - return _engine_sort_direction ? -r : r; + return _engine_sort_direction ? r > 0 : r < 0; } /** * Determines order of engines by tractive effort - * @param *a first engine to compare - * @param *b second engine to compare - * @return for descending order: returns < 0 if a < b and > 0 for a > b. Vice versa for ascending order and 0 for equal + * @param a first engine to compare + * @param b second engine to compare + * @return for descending order: returns true if a < b. Vice versa for ascending order */ -static int CDECL EngineTractiveEffortSorter(const EngineID *a, const EngineID *b) +static bool EngineTractiveEffortSorter(const EngineID &a, const EngineID &b) { - int va = Engine::Get(*a)->GetDisplayMaxTractiveEffort(); - int vb = Engine::Get(*b)->GetDisplayMaxTractiveEffort(); + int va = Engine::Get(a)->GetDisplayMaxTractiveEffort(); + int vb = Engine::Get(b)->GetDisplayMaxTractiveEffort(); int r = va - vb; /* Use EngineID to sort instead since we want consistent sorting */ if (r == 0) return EngineNumberSorter(a, b); - return _engine_sort_direction ? -r : r; + return _engine_sort_direction ? r > 0 : r < 0; } /** * Determines order of engines by running costs - * @param *a first engine to compare - * @param *b second engine to compare - * @return for descending order: returns < 0 if a < b and > 0 for a > b. Vice versa for ascending order and 0 for equal + * @param a first engine to compare + * @param b second engine to compare + * @return for descending order: returns true if a < b. Vice versa for ascending order */ -static int CDECL EngineRunningCostSorter(const EngineID *a, const EngineID *b) +static bool EngineRunningCostSorter(const EngineID &a, const EngineID &b) { - Money va = Engine::Get(*a)->GetRunningCost(); - Money vb = Engine::Get(*b)->GetRunningCost(); + Money va = Engine::Get(a)->GetRunningCost(); + Money vb = Engine::Get(b)->GetRunningCost(); int r = ClampToI32(va - vb); /* Use EngineID to sort instead since we want consistent sorting */ if (r == 0) return EngineNumberSorter(a, b); - return _engine_sort_direction ? -r : r; + return _engine_sort_direction ? r > 0 : r < 0; } /** * Determines order of engines by running costs - * @param *a first engine to compare - * @param *b second engine to compare - * @return for descending order: returns < 0 if a < b and > 0 for a > b. Vice versa for ascending order and 0 for equal + * @param a first engine to compare + * @param b second engine to compare + * @return for descending order: returns true if a < b. Vice versa for ascending order */ -static int CDECL EnginePowerVsRunningCostSorter(const EngineID *a, const EngineID *b) +static bool EnginePowerVsRunningCostSorter(const EngineID &a, const EngineID &b) { - const Engine *e_a = Engine::Get(*a); - const Engine *e_b = Engine::Get(*b); - - /* Here we are using a few tricks to get the right sort. - * We want power/running cost, but since we usually got higher running cost than power and we store the result in an int, - * we will actually calculate cunning cost/power (to make it more than 1). - * Because of this, the return value have to be reversed as well and we return b - a instead of a - b. - * Another thing is that both power and running costs should be doubled for multiheaded engines. - * Since it would be multiplying with 2 in both numerator and denominator, it will even themselves out and we skip checking for multiheaded. */ - Money va = (e_a->GetRunningCost()) / max(1U, (uint)e_a->GetPower()); - Money vb = (e_b->GetRunningCost()) / max(1U, (uint)e_b->GetPower()); - int r = ClampToI32(vb - va); - - /* Use EngineID to sort instead since we want consistent sorting */ - if (r == 0) return EngineNumberSorter(a, b); - return _engine_sort_direction ? -r : r; + const Engine *e_a = Engine::Get(a); + const Engine *e_b = Engine::Get(b); + uint p_a = e_a->GetPower(); + uint p_b = e_b->GetPower(); + Money r_a = e_a->GetRunningCost(); + Money r_b = e_b->GetRunningCost(); + /* Check if running cost is zero in one or both engines. + * If only one of them is zero then that one has higher value, + * else if both have zero cost then compare powers. */ + if (r_a == 0) { + if (r_b == 0) { + /* If it is ambiguous which to return go with their ID */ + if (p_a == p_b) return EngineNumberSorter(a, b); + return _engine_sort_direction != (p_a < p_b); + } + return !_engine_sort_direction; + } + if (r_b == 0) return _engine_sort_direction; + /* Using double for more precision when comparing close values. + * This shouldn't have any major effects in performance nor in keeping + * the game in sync between players since it's used in GUI only in client side */ + double v_a = (double)p_a / (double)r_a; + double v_b = (double)p_b / (double)r_b; + /* Use EngineID to sort if both have same power/running cost, + * since we want consistent sorting. + * Also if both have no power then sort with reverse of running cost to simulate + * previous sorting behaviour for wagons. */ + if (v_a == 0 && v_b == 0) return !EngineRunningCostSorter(a, b); + if (v_a == v_b) return EngineNumberSorter(a, b); + return _engine_sort_direction != (v_a < v_b); } /* Train sorting functions */ /** * Determines order of train engines by capacity - * @param *a first engine to compare - * @param *b second engine to compare - * @return for descending order: returns < 0 if a < b and > 0 for a > b. Vice versa for ascending order and 0 for equal + * @param a first engine to compare + * @param b second engine to compare + * @return for descending order: returns true if a < b. Vice versa for ascending order */ -static int CDECL TrainEngineCapacitySorter(const EngineID *a, const EngineID *b) +static bool TrainEngineCapacitySorter(const EngineID &a, const EngineID &b) { - const RailVehicleInfo *rvi_a = RailVehInfo(*a); - const RailVehicleInfo *rvi_b = RailVehInfo(*b); + const RailVehicleInfo *rvi_a = RailVehInfo(a); + const RailVehicleInfo *rvi_b = RailVehInfo(b); - 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) * (rvi_a->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1); + int vb = GetTotalCapacityOfArticulatedParts(b) * (rvi_b->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1); int r = va - vb; /* Use EngineID to sort instead since we want consistent sorting */ if (r == 0) return EngineNumberSorter(a, b); - return _engine_sort_direction ? -r : r; + return _engine_sort_direction ? r > 0 : r < 0; } /** * Determines order of train engines by engine / wagon - * @param *a first engine to compare - * @param *b second engine to compare - * @return for descending order: returns < 0 if a < b and > 0 for a > b. Vice versa for ascending order and 0 for equal + * @param a first engine to compare + * @param b second engine to compare + * @return for descending order: returns true if a < b. Vice versa for ascending order */ -static int CDECL TrainEnginesThenWagonsSorter(const EngineID *a, const EngineID *b) +static bool TrainEnginesThenWagonsSorter(const EngineID &a, const EngineID &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)->railveh_type == RAILVEH_WAGON ? 1 : 0); + int val_b = (RailVehInfo(b)->railveh_type == RAILVEH_WAGON ? 1 : 0); int r = val_a - val_b; /* Use EngineID to sort instead since we want consistent sorting */ if (r == 0) return EngineNumberSorter(a, b); - return _engine_sort_direction ? -r : r; + return _engine_sort_direction ? r > 0 : r < 0; } /* Road vehicle sorting functions */ /** * Determines order of road vehicles by capacity - * @param *a first engine to compare - * @param *b second engine to compare - * @return for descending order: returns < 0 if a < b and > 0 for a > b. Vice versa for ascending order and 0 for equal + * @param a first engine to compare + * @param b second engine to compare + * @return for descending order: returns true if a < b. Vice versa for ascending order */ -static int CDECL RoadVehEngineCapacitySorter(const EngineID *a, const EngineID *b) +static bool RoadVehEngineCapacitySorter(const EngineID &a, const EngineID &b) { - int va = GetTotalCapacityOfArticulatedParts(*a); - int vb = GetTotalCapacityOfArticulatedParts(*b); + int va = GetTotalCapacityOfArticulatedParts(a); + int vb = GetTotalCapacityOfArticulatedParts(b); int r = va - vb; /* Use EngineID to sort instead since we want consistent sorting */ if (r == 0) return EngineNumberSorter(a, b); - return _engine_sort_direction ? -r : r; + return _engine_sort_direction ? r > 0 : r < 0; } /* Ship vehicle sorting functions */ /** * Determines order of ships by capacity - * @param *a first engine to compare - * @param *b second engine to compare - * @return for descending order: returns < 0 if a < b and > 0 for a > b. Vice versa for ascending order and 0 for equal + * @param a first engine to compare + * @param b second engine to compare + * @return for descending order: returns true if a < b. Vice versa for ascending order */ -static int CDECL ShipEngineCapacitySorter(const EngineID *a, const EngineID *b) +static bool ShipEngineCapacitySorter(const EngineID &a, const EngineID &b) { - const Engine *e_a = Engine::Get(*a); - const Engine *e_b = Engine::Get(*b); + const Engine *e_a = Engine::Get(a); + const Engine *e_b = Engine::Get(b); int va = e_a->GetDisplayDefaultCapacity(); int vb = e_b->GetDisplayDefaultCapacity(); @@ -371,21 +380,21 @@ static int CDECL ShipEngineCapacitySorter(const EngineID *a, const EngineID *b) /* Use EngineID to sort instead since we want consistent sorting */ if (r == 0) return EngineNumberSorter(a, b); - return _engine_sort_direction ? -r : r; + return _engine_sort_direction ? r > 0 : r < 0; } /* Aircraft sorting functions */ /** * Determines order of aircraft by cargo - * @param *a first engine to compare - * @param *b second engine to compare - * @return for descending order: returns < 0 if a < b and > 0 for a > b. Vice versa for ascending order and 0 for equal + * @param a first engine to compare + * @param b second engine to compare + * @return for descending order: returns true if a < b. Vice versa for ascending order */ -static int CDECL AircraftEngineCargoSorter(const EngineID *a, const EngineID *b) +static bool AircraftEngineCargoSorter(const EngineID &a, const EngineID &b) { - const Engine *e_a = Engine::Get(*a); - const Engine *e_b = Engine::Get(*b); + const Engine *e_a = Engine::Get(a); + const Engine *e_b = Engine::Get(b); uint16 mail_a, mail_b; int va = e_a->GetDisplayDefaultCapacity(&mail_a); @@ -401,25 +410,25 @@ static int CDECL AircraftEngineCargoSorter(const EngineID *a, const EngineID *b) return EngineNumberSorter(a, b); } } - return _engine_sort_direction ? -r : r; + return _engine_sort_direction ? r > 0 : r < 0; } /** * Determines order of aircraft by range. - * @param *a first engine to compare. - * @param *b second engine to compare. - * @return for descending order: returns < 0 if a < b and > 0 for a > b. Vice versa for ascending order and 0 for equal. + * @param a first engine to compare + * @param b second engine to compare + * @return for descending order: returns true if a < b. Vice versa for ascending order */ -static int CDECL AircraftRangeSorter(const EngineID *a, const EngineID *b) +static bool AircraftRangeSorter(const EngineID &a, const EngineID &b) { - uint16 r_a = Engine::Get(*a)->GetRange(); - uint16 r_b = Engine::Get(*b)->GetRange(); + uint16 r_a = Engine::Get(a)->GetRange(); + uint16 r_b = Engine::Get(b)->GetRange(); int r = r_a - r_b; /* Use EngineID to sort instead since we want consistent sorting */ if (r == 0) return EngineNumberSorter(a, b); - return _engine_sort_direction ? -r : r; + return _engine_sort_direction ? r > 0 : r < 0; } /** Sort functions for the vehicle sort criteria, for each vehicle type. */ @@ -538,11 +547,11 @@ static GUIEngineList::FilterFunction * const _filter_funcs[] = { &CargoFilter, }; -static int DrawCargoCapacityInfo(int left, int right, int y, EngineID engine) +static int DrawCargoCapacityInfo(int left, int right, int y, EngineID engine, TestedEngineDetails &te) { CargoArray cap; CargoTypes refits; - GetArticulatedVehicleCargoesAndRefits(engine, &cap, &refits); + GetArticulatedVehicleCargoesAndRefits(engine, &cap, &refits, te.cargo, te.capacity); for (CargoID c = 0; c < NUM_CARGO; c++) { if (cap[c] == 0) continue; @@ -558,19 +567,25 @@ static int DrawCargoCapacityInfo(int left, int right, int y, EngineID engine) } /* Draw rail wagon specific details */ -static int DrawRailWagonPurchaseInfo(int left, int right, int y, EngineID engine_number, const RailVehicleInfo *rvi) +static int DrawRailWagonPurchaseInfo(int left, int right, int y, EngineID engine_number, const RailVehicleInfo *rvi, TestedEngineDetails &te) { const Engine *e = Engine::Get(engine_number); /* Purchase cost */ - SetDParam(0, e->GetCost()); - DrawString(left, right, y, STR_PURCHASE_INFO_COST); + if (te.cost != 0) { + SetDParam(0, e->GetCost() + te.cost); + SetDParam(1, te.cost); + DrawString(left, right, y, STR_PURCHASE_INFO_COST_REFIT); + } else { + SetDParam(0, e->GetCost()); + DrawString(left, right, y, STR_PURCHASE_INFO_COST); + } y += FONT_HEIGHT_NORMAL; /* Wagon weight - (including cargo) */ uint weight = e->GetDisplayWeight(); SetDParam(0, weight); - uint cargo_weight = (e->CanCarryCargo() ? CargoSpec::Get(e->GetDefaultCargoType())->weight * GetTotalCapacityOfArticulatedParts(engine_number) / 16 : 0); + uint cargo_weight = (e->CanCarryCargo() ? CargoSpec::Get(te.cargo)->weight * te.capacity / 16 : 0); SetDParam(1, cargo_weight + weight); DrawString(left, right, y, STR_PURCHASE_INFO_WEIGHT_CWEIGHT); y += FONT_HEIGHT_NORMAL; @@ -596,14 +611,21 @@ static int DrawRailWagonPurchaseInfo(int left, int right, int y, EngineID engine } /* Draw locomotive specific details */ -static int DrawRailEnginePurchaseInfo(int left, int right, int y, EngineID engine_number, const RailVehicleInfo *rvi) +static int DrawRailEnginePurchaseInfo(int left, int right, int y, EngineID engine_number, const RailVehicleInfo *rvi, TestedEngineDetails &te) { const Engine *e = Engine::Get(engine_number); /* Purchase Cost - Engine weight */ - SetDParam(0, e->GetCost()); - SetDParam(1, e->GetDisplayWeight()); - DrawString(left, right, y, STR_PURCHASE_INFO_COST_WEIGHT); + if (te.cost != 0) { + SetDParam(0, e->GetCost() + te.cost); + SetDParam(1, te.cost); + SetDParam(2, e->GetDisplayWeight()); + DrawString(left, right, y, STR_PURCHASE_INFO_COST_REFIT_WEIGHT); + } else { + SetDParam(0, e->GetCost()); + SetDParam(1, e->GetDisplayWeight()); + DrawString(left, right, y, STR_PURCHASE_INFO_COST_WEIGHT); + } y += FONT_HEIGHT_NORMAL; /* Max speed - Engine power */ @@ -638,20 +660,26 @@ static int DrawRailEnginePurchaseInfo(int left, int right, int y, EngineID engin } /* Draw road vehicle specific details */ -static int DrawRoadVehPurchaseInfo(int left, int right, int y, EngineID engine_number) +static int DrawRoadVehPurchaseInfo(int left, int right, int y, EngineID engine_number, TestedEngineDetails &te) { const Engine *e = Engine::Get(engine_number); if (_settings_game.vehicle.roadveh_acceleration_model != AM_ORIGINAL) { /* Purchase Cost */ - SetDParam(0, e->GetCost()); - DrawString(left, right, y, STR_PURCHASE_INFO_COST); + if (te.cost != 0) { + SetDParam(0, e->GetCost() + te.cost); + SetDParam(1, te.cost); + DrawString(left, right, y, STR_PURCHASE_INFO_COST_REFIT); + } else { + SetDParam(0, e->GetCost()); + DrawString(left, right, y, STR_PURCHASE_INFO_COST); + } y += FONT_HEIGHT_NORMAL; /* Road vehicle weight - (including cargo) */ int16 weight = e->GetDisplayWeight(); SetDParam(0, weight); - uint cargo_weight = (e->CanCarryCargo() ? CargoSpec::Get(e->GetDefaultCargoType())->weight * GetTotalCapacityOfArticulatedParts(engine_number) / 16 : 0); + uint cargo_weight = (e->CanCarryCargo() ? CargoSpec::Get(te.cargo)->weight * te.capacity / 16 : 0); SetDParam(1, cargo_weight + weight); DrawString(left, right, y, STR_PURCHASE_INFO_WEIGHT_CWEIGHT); y += FONT_HEIGHT_NORMAL; @@ -668,9 +696,16 @@ static int DrawRoadVehPurchaseInfo(int left, int right, int y, EngineID engine_n y += FONT_HEIGHT_NORMAL; } else { /* Purchase cost - Max speed */ - SetDParam(0, e->GetCost()); - SetDParam(1, e->GetDisplayMaxSpeed()); - DrawString(left, right, y, STR_PURCHASE_INFO_COST_SPEED); + if (te.cost != 0) { + SetDParam(0, e->GetCost() + te.cost); + SetDParam(1, te.cost); + SetDParam(2, e->GetDisplayMaxSpeed()); + DrawString(left, right, y, STR_PURCHASE_INFO_COST_REFIT_SPEED); + } else { + SetDParam(0, e->GetCost()); + SetDParam(1, e->GetDisplayMaxSpeed()); + DrawString(left, right, y, STR_PURCHASE_INFO_COST_SPEED); + } y += FONT_HEIGHT_NORMAL; } @@ -683,7 +718,7 @@ static int DrawRoadVehPurchaseInfo(int left, int right, int y, EngineID engine_n } /* Draw ship specific details */ -static int DrawShipPurchaseInfo(int left, int right, int y, EngineID engine_number, bool refittable) +static int DrawShipPurchaseInfo(int left, int right, int y, EngineID engine_number, bool refittable, TestedEngineDetails &te) { const Engine *e = Engine::Get(engine_number); @@ -692,13 +727,27 @@ static int DrawShipPurchaseInfo(int left, int right, int y, EngineID engine_numb uint ocean_speed = e->u.ship.ApplyWaterClassSpeedFrac(raw_speed, true); uint canal_speed = e->u.ship.ApplyWaterClassSpeedFrac(raw_speed, false); - SetDParam(0, e->GetCost()); if (ocean_speed == canal_speed) { - SetDParam(1, ocean_speed); - DrawString(left, right, y, STR_PURCHASE_INFO_COST_SPEED); + if (te.cost != 0) { + SetDParam(0, e->GetCost() + te.cost); + SetDParam(1, te.cost); + SetDParam(2, ocean_speed); + DrawString(left, right, y, STR_PURCHASE_INFO_COST_REFIT_SPEED); + } else { + SetDParam(0, e->GetCost()); + SetDParam(1, ocean_speed); + DrawString(left, right, y, STR_PURCHASE_INFO_COST_SPEED); + } y += FONT_HEIGHT_NORMAL; } else { - DrawString(left, right, y, STR_PURCHASE_INFO_COST); + if (te.cost != 0) { + SetDParam(0, e->GetCost() + te.cost); + SetDParam(1, te.cost); + DrawString(left, right, y, STR_PURCHASE_INFO_COST_REFIT); + } else { + SetDParam(0, e->GetCost()); + DrawString(left, right, y, STR_PURCHASE_INFO_COST); + } y += FONT_HEIGHT_NORMAL; SetDParam(0, ocean_speed); @@ -711,8 +760,8 @@ static int DrawShipPurchaseInfo(int left, int right, int y, EngineID engine_numb } /* Cargo type + capacity */ - SetDParam(0, e->GetDefaultCargoType()); - SetDParam(1, e->GetDisplayDefaultCapacity()); + SetDParam(0, te.cargo); + SetDParam(1, te.capacity); SetDParam(2, refittable ? STR_PURCHASE_INFO_REFITTABLE : STR_EMPTY); DrawString(left, right, y, STR_PURCHASE_INFO_CAPACITY); y += FONT_HEIGHT_NORMAL; @@ -734,31 +783,35 @@ static int DrawShipPurchaseInfo(int left, int right, int y, EngineID engine_numb * @param refittable If set, the aircraft can be refitted. * @return Bottom of the used area. */ -static int DrawAircraftPurchaseInfo(int left, int right, int y, EngineID engine_number, bool refittable) +static int DrawAircraftPurchaseInfo(int left, int right, int y, EngineID engine_number, bool refittable, TestedEngineDetails &te) { const Engine *e = Engine::Get(engine_number); - CargoID cargo = e->GetDefaultCargoType(); /* Purchase cost - Max speed */ - SetDParam(0, e->GetCost()); - SetDParam(1, e->GetDisplayMaxSpeed()); - DrawString(left, right, y, STR_PURCHASE_INFO_COST_SPEED); + if (te.cost != 0) { + SetDParam(0, e->GetCost() + te.cost); + SetDParam(1, te.cost); + SetDParam(2, e->GetDisplayMaxSpeed()); + DrawString(left, right, y, STR_PURCHASE_INFO_COST_REFIT_SPEED); + } else { + SetDParam(0, e->GetCost()); + SetDParam(1, e->GetDisplayMaxSpeed()); + DrawString(left, right, y, STR_PURCHASE_INFO_COST_SPEED); + } y += FONT_HEIGHT_NORMAL; /* Cargo capacity */ - uint16 mail_capacity; - uint capacity = e->GetDisplayDefaultCapacity(&mail_capacity); - if (mail_capacity > 0) { - SetDParam(0, cargo); - SetDParam(1, capacity); + if (te.mail_capacity > 0) { + SetDParam(0, te.cargo); + SetDParam(1, te.capacity); SetDParam(2, CT_MAIL); - SetDParam(3, mail_capacity); + SetDParam(3, te.mail_capacity); DrawString(left, right, y, STR_PURCHASE_INFO_AIRCRAFT_CAPACITY); } else { /* Note, if the default capacity is selected by the refit capacity * callback, then the capacity shown is likely to be incorrect. */ - SetDParam(0, cargo); - SetDParam(1, capacity); + SetDParam(0, te.cargo); + SetDParam(1, te.capacity); SetDParam(2, refittable ? STR_PURCHASE_INFO_REFITTABLE : STR_EMPTY); DrawString(left, right, y, STR_PURCHASE_INFO_CAPACITY); } @@ -795,7 +848,7 @@ static int DrawAircraftPurchaseInfo(int left, int right, int y, EngineID engine_ */ static uint ShowAdditionalText(int left, int right, int y, EngineID engine) { - uint16 callback = GetVehicleCallback(CBID_VEHICLE_ADDITIONAL_TEXT, 0, 0, engine, NULL); + 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(); if (callback > 0x400) { @@ -815,7 +868,7 @@ static uint ShowAdditionalText(int left, int right, int y, EngineID engine) * @param engine_number the engine of which to draw the info of * @return y after drawing all the text */ -int DrawVehiclePurchaseInfo(int left, int right, int y, EngineID engine_number) +int DrawVehiclePurchaseInfo(int left, int right, int y, EngineID engine_number, TestedEngineDetails &te) { const Engine *e = Engine::Get(engine_number); YearMonthDay ymd; @@ -827,30 +880,30 @@ int DrawVehiclePurchaseInfo(int left, int right, int y, EngineID engine_number) default: NOT_REACHED(); case VEH_TRAIN: if (e->u.rail.railveh_type == RAILVEH_WAGON) { - y = DrawRailWagonPurchaseInfo(left, right, y, engine_number, &e->u.rail); + y = DrawRailWagonPurchaseInfo(left, right, y, engine_number, &e->u.rail, te); } else { - y = DrawRailEnginePurchaseInfo(left, right, y, engine_number, &e->u.rail); + y = DrawRailEnginePurchaseInfo(left, right, y, engine_number, &e->u.rail, te); } articulated_cargo = true; break; case VEH_ROAD: - y = DrawRoadVehPurchaseInfo(left, right, y, engine_number); + y = DrawRoadVehPurchaseInfo(left, right, y, engine_number, te); articulated_cargo = true; break; case VEH_SHIP: - y = DrawShipPurchaseInfo(left, right, y, engine_number, refittable); + y = DrawShipPurchaseInfo(left, right, y, engine_number, refittable, te); break; case VEH_AIRCRAFT: - y = DrawAircraftPurchaseInfo(left, right, y, engine_number, refittable); + y = DrawAircraftPurchaseInfo(left, right, y, engine_number, refittable, te); break; } if (articulated_cargo) { /* Cargo type + capacity, or N/A */ - int new_y = DrawCargoCapacityInfo(left, right, y, engine_number); + int new_y = DrawCargoCapacityInfo(left, right, y, engine_number, te); if (new_y == y) { SetDParam(0, CT_INVALID); @@ -881,6 +934,14 @@ int DrawVehiclePurchaseInfo(int left, int right, int y, EngineID engine_number) /* Additional text from NewGRF */ y = ShowAdditionalText(left, right, y, engine_number); + /* The NewGRF's name which the vehicle comes from */ + const GRFConfig *config = GetGRFConfig(e->GetGRFID()); + if (_settings_client.gui.show_newgrf_name && config != nullptr) + { + DrawString(left, right, y, config->GetName(), TC_BLACK); + y += FONT_HEIGHT_NORMAL; + } + return y; } @@ -902,7 +963,7 @@ void DrawEngineList(VehicleType type, int l, int r, int y, const GUIEngineList * static const int sprite_y_offsets[] = { -1, -1, -2, -2 }; /* Obligatory sanity checks! */ - assert(max <= eng_list->Length()); + assert(max <= eng_list->size()); bool rtl = _current_text_dir == TD_RTL; int step_size = GetEngineListHeight(type); @@ -979,8 +1040,8 @@ void DisplayVehicleSortDropDown(Window *w, VehicleType vehicle_type, int selecte struct BuildVehicleWindow : Window { VehicleType vehicle_type; ///< Type of vehicles shown in the window. union { - RailTypeByte railtype; ///< Rail type to show, or #RAILTYPE_END. - RoadTypes roadtypes; ///< Road type to show, or #ROADTYPES_ALL. + RailType railtype; ///< Rail type to show, or #INVALID_RAILTYPE. + RoadType roadtype; ///< Road type to show, or #INVALID_ROADTYPE. } filter; ///< Filter to apply. bool descending_sort_order; ///< Sort direction, @see _engine_sort_direction byte sort_criteria; ///< Current sort criterium. @@ -994,11 +1055,29 @@ struct BuildVehicleWindow : Window { byte cargo_filter_criteria; ///< Selected cargo filter int details_height; ///< Minimal needed height of the details panels (found so far). Scrollbar *vscroll; + TestedEngineDetails te; ///< Tested cost and capacity after refit. + + void SetBuyVehicleText() + { + NWidgetCore *widget = this->GetWidget(WID_BV_BUILD); + + bool refit = this->sel_engine != INVALID_ENGINE && this->cargo_filter[this->cargo_filter_criteria] != CF_ANY && this->cargo_filter[this->cargo_filter_criteria] != CF_NONE; + if (refit) refit = Engine::Get(this->sel_engine)->GetDefaultCargoType() != this->cargo_filter[this->cargo_filter_criteria]; + + if (refit) { + widget->widget_data = STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_BUTTON + this->vehicle_type; + widget->tool_tip = STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_TOOLTIP + this->vehicle_type; + } else { + widget->widget_data = STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_BUTTON + this->vehicle_type; + widget->tool_tip = STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP + this->vehicle_type; + } + } BuildVehicleWindow(WindowDesc *desc, TileIndex tile, VehicleType type) : Window(desc) { this->vehicle_type = type; - this->window_number = tile == INVALID_TILE ? (int)type : tile; + this->listview_mode = tile == INVALID_TILE; + this->window_number = this->listview_mode ? (int)type : tile; this->sel_engine = INVALID_ENGINE; @@ -1006,19 +1085,7 @@ struct BuildVehicleWindow : Window { this->descending_sort_order = _engine_sort_last_order[type]; this->show_hidden_engines = _engine_sort_show_hidden_engines[type]; - switch (type) { - default: NOT_REACHED(); - case VEH_TRAIN: - this->filter.railtype = (tile == INVALID_TILE) ? RAILTYPE_END : GetRailType(tile); - break; - case VEH_ROAD: - this->filter.roadtypes = (tile == INVALID_TILE) ? ROADTYPES_ALL : GetRoadTypes(tile); - case VEH_SHIP: - case VEH_AIRCRAFT: - break; - } - - this->listview_mode = (this->window_number <= VEH_END); + this->UpdateFilterByTile(); this->CreateNestedTree(); @@ -1037,10 +1104,6 @@ struct BuildVehicleWindow : Window { widget = this->GetWidget(WID_BV_SHOW_HIDE); widget->tool_tip = STR_BUY_VEHICLE_TRAIN_HIDE_SHOW_TOGGLE_TOOLTIP + type; - widget = this->GetWidget(WID_BV_BUILD); - widget->widget_data = STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_BUTTON + type; - widget->tool_tip = STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP + type; - widget = this->GetWidget(WID_BV_RENAME); widget->widget_data = STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON + type; widget->tool_tip = STR_BUY_VEHICLE_TRAIN_RENAME_TOOLTIP + type; @@ -1059,7 +1122,41 @@ 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.Length() > 0) this->sel_engine = this->eng_list[0]; + if (this->eng_list.size() > 0) { + this->SelectEngine(this->eng_list[0]); + } else { + this->SelectEngine(INVALID_ENGINE); + } + } + + /** Set the filter type according to the depot type */ + void UpdateFilterByTile() + { + switch (this->vehicle_type) { + default: NOT_REACHED(); + case VEH_TRAIN: + if (this->listview_mode) { + this->filter.railtype = INVALID_RAILTYPE; + } else { + this->filter.railtype = GetRailType(this->window_number); + } + break; + + case VEH_ROAD: + if (this->listview_mode) { + this->filter.roadtype = INVALID_ROADTYPE; + } else { + this->filter.roadtype = GetRoadTypeRoad(this->window_number); + if (this->filter.roadtype == INVALID_ROADTYPE) { + this->filter.roadtype = GetRoadTypeTram(this->window_number); + } + } + break; + + case VEH_SHIP: + case VEH_AIRCRAFT: + break; + } } /** Populate the filter list and set the cargo filter criteria. */ @@ -1106,7 +1203,42 @@ struct BuildVehicleWindow : Window { this->eng_list.SetFilterState(this->cargo_filter[this->cargo_filter_criteria] != CF_ANY); } - void OnInit() + void SelectEngine(EngineID engine) + { + CargoID cargo = this->cargo_filter[this->cargo_filter_criteria]; + if (cargo == CF_ANY) cargo = CF_NONE; + + this->sel_engine = engine; + this->SetBuyVehicleText(); + + 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 */ + CommandCost ret = DoCommand(this->window_number, this->sel_engine | (cargo << 24), 0, DC_QUERY_COST, GetCmdBuildVeh(this->vehicle_type), nullptr); + if (ret.Succeeded()) { + this->te.cost = ret.GetCost() - e->GetCost(); + this->te.capacity = _returned_refit_capacity; + this->te.mail_capacity = _returned_mail_refit_capacity; + this->te.cargo = (cargo == CT_INVALID) ? e->GetDefaultCargoType() : cargo; + 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(); + } + + void OnInit() override { this->SetCargoFilterArray(); } @@ -1115,10 +1247,10 @@ struct BuildVehicleWindow : Window { void FilterEngineList() { this->eng_list.Filter(this->cargo_filter[this->cargo_filter_criteria]); - if (0 == this->eng_list.Length()) { // no engine passed through the filter, invalidate the previously selected engine - this->sel_engine = INVALID_ENGINE; - } else if (!this->eng_list.Contains(this->sel_engine)) { // previously selected engine didn't pass the filter, select the first engine of the list - this->sel_engine = this->eng_list[0]; + 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]); } } @@ -1136,27 +1268,24 @@ struct BuildVehicleWindow : Window { int num_engines = 0; int num_wagons = 0; - this->filter.railtype = (this->listview_mode) ? RAILTYPE_END : GetRailType(this->window_number); - - this->eng_list.Clear(); + this->eng_list.clear(); /* Make list of all available train engines and wagons. * Also check to see if the previously selected engine is still available, * and if not, reset selection to INVALID_ENGINE. This could be the case * when engines become obsolete and are removed */ - const Engine *e; - FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) { + for (const Engine *e : Engine::IterateType(VEH_TRAIN)) { if (!this->show_hidden_engines && e->IsHidden(_local_company)) continue; EngineID eid = e->index; const RailVehicleInfo *rvi = &e->u.rail; - if (this->filter.railtype != RAILTYPE_END && !HasPowerOnRail(rvi->railtype, this->filter.railtype)) continue; + if (this->filter.railtype != INVALID_RAILTYPE && !HasPowerOnRail(rvi->railtype, this->filter.railtype)) continue; if (!IsEngineBuildable(eid, VEH_TRAIN, _local_company)) continue; /* Filter now! So num_engines and num_wagons is valid */ if (!FilterSingleEngine(eid)) continue; - *this->eng_list.Append() = eid; + this->eng_list.push_back(eid); if (rvi->railveh_type != RAILVEH_WAGON) { num_engines++; @@ -1167,7 +1296,7 @@ struct BuildVehicleWindow : Window { if (eid == this->sel_engine) sel_id = eid; } - this->sel_engine = sel_id; + this->SelectEngine(sel_id); /* make engines first, and then wagons, sorted by selected sort_criteria */ _engine_sort_direction = false; @@ -1186,37 +1315,36 @@ struct BuildVehicleWindow : Window { { EngineID sel_id = INVALID_ENGINE; - this->eng_list.Clear(); + this->eng_list.clear(); - const Engine *e; - FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) { + for (const Engine *e : Engine::IterateType(VEH_ROAD)) { if (!this->show_hidden_engines && e->IsHidden(_local_company)) continue; EngineID eid = e->index; if (!IsEngineBuildable(eid, VEH_ROAD, _local_company)) continue; - if (!HasBit(this->filter.roadtypes, HasBit(EngInfo(eid)->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD)) continue; - *this->eng_list.Append() = eid; + if (this->filter.roadtype != INVALID_ROADTYPE && !HasPowerOnRoad(e->u.road.roadtype, this->filter.roadtype)) continue; + + this->eng_list.push_back(eid); if (eid == this->sel_engine) sel_id = eid; } - this->sel_engine = sel_id; + this->SelectEngine(sel_id); } /* Figure out what ship EngineIDs to put in the list */ void GenerateBuildShipList() { EngineID sel_id = INVALID_ENGINE; - this->eng_list.Clear(); + this->eng_list.clear(); - const Engine *e; - FOR_ALL_ENGINES_OF_TYPE(e, VEH_SHIP) { + for (const Engine *e : Engine::IterateType(VEH_SHIP)) { 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.Append() = eid; + this->eng_list.push_back(eid); if (eid == this->sel_engine) sel_id = eid; } - this->sel_engine = sel_id; + this->SelectEngine(sel_id); } /* Figure out what aircraft EngineIDs to put in the list */ @@ -1224,38 +1352,41 @@ struct BuildVehicleWindow : Window { { EngineID sel_id = INVALID_ENGINE; - this->eng_list.Clear(); + this->eng_list.clear(); - const Station *st = this->listview_mode ? NULL : Station::GetByTile(this->window_number); + const Station *st = this->listview_mode ? nullptr : Station::GetByTile(this->window_number); /* Make list of all available planes. * Also check to see if the previously selected plane is still available, * and if not, reset selection to INVALID_ENGINE. This could be the case * when planes become obsolete and are removed */ - const Engine *e; - FOR_ALL_ENGINES_OF_TYPE(e, VEH_AIRCRAFT) { + for (const Engine *e : Engine::IterateType(VEH_AIRCRAFT)) { if (!this->show_hidden_engines && e->IsHidden(_local_company)) continue; EngineID eid = e->index; if (!IsEngineBuildable(eid, VEH_AIRCRAFT, _local_company)) continue; /* 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.Append() = eid; + this->eng_list.push_back(eid); if (eid == this->sel_engine) sel_id = eid; } - this->sel_engine = sel_id; + this->SelectEngine(sel_id); } /* Generate the list of vehicles */ void GenerateBuildList() { if (!this->eng_list.NeedRebuild()) return; + + /* Update filter type in case the road/railtype of the depot got converted */ + this->UpdateFilterByTile(); + switch (this->vehicle_type) { default: NOT_REACHED(); case VEH_TRAIN: this->GenerateBuildTrainList(); - this->eng_list.Compact(); + this->eng_list.shrink_to_fit(); this->eng_list.RebuildDone(); return; // trains should not reach the last sorting case VEH_ROAD: @@ -1274,11 +1405,11 @@ struct BuildVehicleWindow : Window { _engine_sort_direction = this->descending_sort_order; EngList_Sort(&this->eng_list, _engine_sort_functions[this->vehicle_type][this->sort_criteria]); - this->eng_list.Compact(); + this->eng_list.shrink_to_fit(); this->eng_list.RebuildDone(); } - void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_BV_SORT_ASCENDING_DESCENDING: @@ -1298,8 +1429,8 @@ 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.Length(); - this->sel_engine = (i < num_items) ? this->eng_list[i] : INVALID_ENGINE; + size_t num_items = this->eng_list.size(); + this->SelectEngine((i < num_items) ? this->eng_list[i] : INVALID_ENGINE); this->SetDirty(); if (_ctrl_pressed) { this->OnClick(pt, WID_BV_SHOW_HIDE, 1); @@ -1318,8 +1449,8 @@ struct BuildVehicleWindow : Window { break; case WID_BV_SHOW_HIDE: { - const Engine *e = (this->sel_engine == INVALID_ENGINE) ? NULL : Engine::Get(this->sel_engine); - if (e != NULL) { + const Engine *e = (this->sel_engine == INVALID_ENGINE) ? nullptr : Engine::Get(this->sel_engine); + if (e != nullptr) { DoCommandP(0, 0, this->sel_engine | (e->IsHidden(_current_company) ? 0 : (1u << 31)), CMD_SET_VEHICLE_VISIBILITY); } break; @@ -1329,7 +1460,9 @@ struct BuildVehicleWindow : Window { EngineID sel_eng = this->sel_engine; if (sel_eng != INVALID_ENGINE) { CommandCallback *callback = (this->vehicle_type == VEH_TRAIN && RailVehInfo(sel_eng)->railveh_type == RAILVEH_WAGON) ? CcBuildWagon : CcBuildPrimaryVehicle; - DoCommandP(this->window_number, sel_eng, 0, GetCmdBuildVeh(this->vehicle_type), callback); + CargoID cargo = this->cargo_filter[this->cargo_filter_criteria]; + if (cargo == CF_ANY) cargo = CF_NONE; + DoCommandP(this->window_number, sel_eng | (cargo << 24), 0, GetCmdBuildVeh(this->vehicle_type), callback); } break; } @@ -1351,7 +1484,7 @@ struct BuildVehicleWindow : Window { * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; /* When switching to original acceleration model for road vehicles, clear the selected sort criteria if it is not available now. */ @@ -1364,13 +1497,16 @@ struct BuildVehicleWindow : Window { this->eng_list.ForceRebuild(); } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { switch (widget) { case WID_BV_CAPTION: if (this->vehicle_type == VEH_TRAIN && !this->listview_mode) { const RailtypeInfo *rti = GetRailTypeInfo(this->filter.railtype); SetDParam(0, rti->strings.build_caption); + } else if (this->vehicle_type == VEH_ROAD && !this->listview_mode) { + const RoadTypeInfo *rti = GetRoadTypeInfo(this->filter.roadtype); + SetDParam(0, rti->strings.build_caption); } else { SetDParam(0, (this->listview_mode ? STR_VEHICLE_LIST_AVAILABLE_TRAINS : STR_BUY_VEHICLE_TRAIN_ALL_CAPTION) + this->vehicle_type); } @@ -1385,8 +1521,8 @@ struct BuildVehicleWindow : Window { break; case WID_BV_SHOW_HIDE: { - const Engine *e = (this->sel_engine == INVALID_ENGINE) ? NULL : Engine::Get(this->sel_engine); - if (e != NULL && e->IsHidden(_local_company)) { + const Engine *e = (this->sel_engine == INVALID_ENGINE) ? nullptr : Engine::Get(this->sel_engine); + if (e != nullptr && e->IsHidden(_local_company)) { SetDParam(0, STR_BUY_VEHICLE_TRAIN_SHOW_TOGGLE_BUTTON + this->vehicle_type); } else { SetDParam(0, STR_BUY_VEHICLE_TRAIN_HIDE_TOGGLE_BUTTON + this->vehicle_type); @@ -1396,7 +1532,7 @@ struct BuildVehicleWindow : Window { } } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_BV_LIST: @@ -1418,6 +1554,13 @@ struct BuildVehicleWindow : Window { break; } + case WID_BV_BUILD: + *size = GetStringBoundingBox(STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_BUTTON + this->vehicle_type); + *size = maxdim(*size, GetStringBoundingBox(STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_BUTTON + this->vehicle_type)); + size->width += padding.width; + size->height += padding.height; + break; + case WID_BV_SHOW_HIDE: *size = GetStringBoundingBox(STR_BUY_VEHICLE_TRAIN_HIDE_TOGGLE_BUTTON + this->vehicle_type); *size = maxdim(*size, GetStringBoundingBox(STR_BUY_VEHICLE_TRAIN_SHOW_TOGGLE_BUTTON + this->vehicle_type)); @@ -1427,11 +1570,11 @@ struct BuildVehicleWindow : Window { } } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { switch (widget) { 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, this->vscroll->GetPosition(), min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->eng_list.Length()), this->sel_engine, false, DEFAULT_GROUP); + DrawEngineList(this->vehicle_type, r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, &this->eng_list, this->vscroll->GetPosition(), min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), (uint)this->eng_list.size()), this->sel_engine, false, DEFAULT_GROUP); break; case WID_BV_SORT_ASCENDING_DESCENDING: @@ -1440,10 +1583,10 @@ struct BuildVehicleWindow : Window { } } - virtual void OnPaint() + void OnPaint() override { this->GenerateBuildList(); - this->vscroll->SetCount(this->eng_list.Length()); + this->vscroll->SetCount((uint)this->eng_list.size()); this->SetWidgetsDisabledState(this->sel_engine == INVALID_ENGINE, WID_BV_SHOW_HIDE, WID_BV_BUILD, WID_BV_RENAME, WIDGET_LIST_END); @@ -1455,7 +1598,7 @@ struct BuildVehicleWindow : Window { 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); + nwi->pos_y + WD_FRAMERECT_TOP, this->sel_engine, this->te); needed_height = max(needed_height, text_end - (int)nwi->pos_y + WD_FRAMERECT_BOTTOM); } if (needed_height != this->details_height) { // Details window are not high enough, enlarge them. @@ -1467,14 +1610,14 @@ struct BuildVehicleWindow : Window { } } - virtual void OnQueryTextFinished(char *str) + void OnQueryTextFinished(char *str) override { - if (str == NULL) return; + if (str == nullptr) return; - DoCommandP(0, this->rename_engine, 0, CMD_RENAME_ENGINE | CMD_MSG(STR_ERROR_CAN_T_RENAME_TRAIN_TYPE + this->vehicle_type), NULL, str); + DoCommandP(0, this->rename_engine, 0, CMD_RENAME_ENGINE | CMD_MSG(STR_ERROR_CAN_T_RENAME_TRAIN_TYPE + this->vehicle_type), nullptr, str); } - virtual void OnDropdownSelect(int widget, int index) + void OnDropdownSelect(int widget, int index) override { switch (widget) { case WID_BV_SORT_DROPDOWN: @@ -1492,13 +1635,14 @@ struct BuildVehicleWindow : Window { /* deactivate filter if criteria is 'Show All', activate it otherwise */ this->eng_list.SetFilterState(this->cargo_filter[this->cargo_filter_criteria] != CF_ANY); this->eng_list.ForceRebuild(); + this->SelectEngine(this->sel_engine); } break; } this->SetDirty(); } - virtual void OnResize() + void OnResize() override { this->vscroll->SetCapacityFromWidget(this, WID_BV_LIST); } diff --git a/src/cargo_type.h b/src/cargo_type.h index 79d1c84f46..89e6f13808 100644 --- a/src/cargo_type.h +++ b/src/cargo_type.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. @@ -145,12 +143,11 @@ public: /** Types of cargo source and destination */ -enum SourceType { +enum SourceType : byte { ST_INDUSTRY, ///< Source/destination is an industry ST_TOWN, ///< Source/destination is a town ST_HEADQUARTERS, ///< Source/destination are company headquarters }; -typedef SimpleTinyEnumT SourceTypeByte; ///< The SourceType packed into a byte for savegame purposes. typedef uint16 SourceID; ///< Contains either industry ID, town ID or company ID (or INVALID_SOURCE) static const SourceID INVALID_SOURCE = 0xFFFF; ///< Invalid/unknown index of source diff --git a/src/cargoaction.cpp b/src/cargoaction.cpp index 96ddc3708e..5853b87da9 100644 --- a/src/cargoaction.cpp +++ b/src/cargoaction.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. @@ -121,7 +119,7 @@ bool CargoDelivery::operator()(CargoPacket *cp) bool CargoLoad::operator()(CargoPacket *cp) { CargoPacket *cp_new = this->Preprocess(cp); - if (cp_new == NULL) return false; + if (cp_new == nullptr) return false; cp_new->SetLoadPlace(this->load_place); this->source->RemoveFromCache(cp_new, cp_new->Count()); this->destination->Append(cp_new, VehicleCargoList::MTA_KEEP); @@ -136,7 +134,7 @@ bool CargoLoad::operator()(CargoPacket *cp) bool CargoReservation::operator()(CargoPacket *cp) { CargoPacket *cp_new = this->Preprocess(cp); - if (cp_new == NULL) return false; + if (cp_new == nullptr) return false; cp_new->SetLoadPlace(this->load_place); this->source->reserved_count += cp_new->Count(); this->source->RemoveFromCache(cp_new, cp_new->Count()); @@ -152,7 +150,7 @@ bool CargoReservation::operator()(CargoPacket *cp) bool CargoReturn::operator()(CargoPacket *cp) { CargoPacket *cp_new = this->Preprocess(cp); - if (cp_new == NULL) cp_new = cp; + if (cp_new == nullptr) cp_new = cp; assert(cp_new->Count() <= this->destination->reserved_count); this->source->RemoveFromMeta(cp_new, VehicleCargoList::MTA_LOAD, cp_new->Count()); this->destination->reserved_count -= cp_new->Count(); @@ -162,13 +160,13 @@ bool CargoReturn::operator()(CargoPacket *cp) /** * Transfers some cargo from a vehicle to a station. - * @param cp Packet to be transfered. + * @param cp Packet to be transferred. * @return True if the packet was completely reserved, false if part of it was. */ bool CargoTransfer::operator()(CargoPacket *cp) { CargoPacket *cp_new = this->Preprocess(cp); - if (cp_new == NULL) return false; + if (cp_new == nullptr) return false; this->source->RemoveFromMeta(cp_new, VehicleCargoList::MTA_TRANSFER, cp_new->Count()); /* No transfer credits here as they were already granted during Stage(). */ this->destination->Append(cp_new, cp_new->NextStation()); @@ -183,7 +181,7 @@ bool CargoTransfer::operator()(CargoPacket *cp) bool CargoShift::operator()(CargoPacket *cp) { CargoPacket *cp_new = this->Preprocess(cp); - if (cp_new == NULL) cp_new = cp; + if (cp_new == nullptr) cp_new = cp; this->source->RemoveFromMeta(cp_new, VehicleCargoList::MTA_KEEP, cp_new->Count()); this->destination->Append(cp_new, VehicleCargoList::MTA_KEEP); return cp_new == cp; @@ -197,7 +195,7 @@ bool CargoShift::operator()(CargoPacket *cp) bool StationCargoReroute::operator()(CargoPacket *cp) { CargoPacket *cp_new = this->Preprocess(cp); - if (cp_new == NULL) cp_new = cp; + if (cp_new == nullptr) cp_new = cp; StationID next = this->ge->GetVia(cp_new->SourceStation(), this->avoid, this->avoid2); assert(next != this->avoid && next != this->avoid2); if (this->source != this->destination) { @@ -220,7 +218,7 @@ bool StationCargoReroute::operator()(CargoPacket *cp) bool VehicleCargoReroute::operator()(CargoPacket *cp) { CargoPacket *cp_new = this->Preprocess(cp); - if (cp_new == NULL) cp_new = cp; + if (cp_new == nullptr) cp_new = cp; if (cp_new->NextStation() == this->avoid || cp_new->NextStation() == this->avoid2) { cp->SetNextStation(this->ge->GetVia(cp_new->SourceStation(), this->avoid, this->avoid2)); } diff --git a/src/cargoaction.h b/src/cargoaction.h index 0311efcae1..58c866ef65 100644 --- a/src/cargoaction.h +++ b/src/cargoaction.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/cargomonitor.cpp b/src/cargomonitor.cpp index 40a029ac53..2941a29556 100644 --- a/src/cargomonitor.cpp +++ b/src/cargomonitor.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. @@ -151,9 +149,9 @@ void AddCargoDelivery(CargoID cargo_type, CompanyID company, uint32 amount, Sour if (iter != _cargo_deliveries.end()) iter->second += amount; /* Industry delivery. */ - for (const Industry * const *ip = st->industries_near.Begin(); ip != st->industries_near.End(); ip++) { - if ((*ip)->index != dest) continue; - CargoMonitorID num = EncodeCargoIndustryMonitor(company, cargo_type, (*ip)->index); + for (Industry *ind : st->industries_near) { + if (ind->index != dest) continue; + CargoMonitorID num = EncodeCargoIndustryMonitor(company, cargo_type, ind->index); CargoMonitorMap::iterator iter = _cargo_deliveries.find(num); if (iter != _cargo_deliveries.end()) iter->second += amount; } diff --git a/src/cargomonitor.h b/src/cargomonitor.h index c7e5da135b..9a6a0c44d8 100644 --- a/src/cargomonitor.h +++ b/src/cargomonitor.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/cargopacket.cpp b/src/cargopacket.cpp index 9e699d6f42..f5f7c0c033 100644 --- a/src/cargopacket.cpp +++ b/src/cargopacket.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. @@ -86,11 +84,11 @@ CargoPacket::CargoPacket(uint16 count, byte days_in_transit, StationID source, T /** * Split this packet in two and return the split off part. * @param new_size Size of the split part. - * @return Split off part, or NULL if no packet could be allocated! + * @return Split off part, or nullptr if no packet could be allocated! */ CargoPacket *CargoPacket::Split(uint new_size) { - if (!CargoPacket::CanAllocateItem()) return NULL; + if (!CargoPacket::CanAllocateItem()) return nullptr; Money fs = this->FeederShare(new_size); CargoPacket *cp_new = new CargoPacket(new_size, this->days_in_transit, this->source, this->source_xy, this->loaded_at_xy, fs, this->source_type, this->source_id); @@ -128,8 +126,7 @@ void CargoPacket::Reduce(uint count) */ /* static */ void CargoPacket::InvalidateAllFrom(SourceType src_type, SourceID src) { - CargoPacket *cp; - FOR_ALL_CARGOPACKETS(cp) { + for (CargoPacket *cp : CargoPacket::Iterate()) { if (cp->source_type == src_type && cp->source_id == src) cp->source_id = INVALID_SOURCE; } } @@ -140,8 +137,7 @@ void CargoPacket::Reduce(uint count) */ /* static */ void CargoPacket::InvalidateAllFrom(StationID sid) { - CargoPacket *cp; - FOR_ALL_CARGOPACKETS(cp) { + for (CargoPacket *cp : CargoPacket::Iterate()) { if (cp->source == sid) cp->source = INVALID_STATION; } } @@ -248,12 +244,12 @@ template * @param cp Cargo packet to add. * @param action Either MTA_KEEP if you want to add the packet directly or MTA_LOAD * if you want to reserve it first. - * @pre cp != NULL + * @pre cp != nullptr * @pre action == MTA_LOAD || (action == MTA_KEEP && this->designation_counts[MTA_LOAD] == 0) */ void VehicleCargoList::Append(CargoPacket *cp, MoveToAction action) { - assert(cp != NULL); + assert(cp != nullptr); assert(action == MTA_LOAD || (action == MTA_KEEP && this->action_counts[MTA_LOAD] == 0)); this->AddToMeta(cp, action); @@ -395,7 +391,7 @@ void VehicleCargoList::AgeCargo() } /** - * Sets loaded_at_xy to the current station for all cargo to be transfered. + * Sets loaded_at_xy to the current station for all cargo to be transferred. * This is done when stopping or skipping while the vehicle is unloading. In * that case the vehicle will get part of its transfer credits early and it may * get more transfer credits than it's entitled to. @@ -689,11 +685,11 @@ uint VehicleCargoList::Reroute(uint max_move, VehicleCargoList *dest, StationID * @note Do not use the cargo packet anymore after it has been appended to this CargoList! * @param next the next hop * @param cp the cargo packet to add - * @pre cp != NULL + * @pre cp != nullptr */ void StationCargoList::Append(CargoPacket *cp, StationID next) { - assert(cp != NULL); + assert(cp != nullptr); this->AddToCache(cp); StationCargoPacketMap::List &list = this->packets[next]; @@ -776,7 +772,7 @@ uint StationCargoList::Truncate(uint max_move, StationCargoAmountMap *cargo_per_ uint prev_count = this->count; uint moved = 0; uint loop = 0; - bool do_count = cargo_per_source != NULL; + bool do_count = cargo_per_source != nullptr; while (max_move > moved) { for (Iterator it(this->packets.begin()); it != this->packets.end();) { CargoPacket *cp = *it; diff --git a/src/cargopacket.h b/src/cargopacket.h index 0ed4fd9bbc..c058bafdbb 100644 --- a/src/cargopacket.h +++ b/src/cargopacket.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. @@ -43,13 +41,13 @@ typedef uint32 TileOrStationID; */ struct CargoPacket : CargoPacketPool::PoolItem<&_cargopacket_pool> { private: - Money feeder_share; ///< Value of feeder pickup to be paid for on delivery of cargo. - uint16 count; ///< The amount of cargo in this packet. - byte days_in_transit; ///< Amount of days this packet has been in transit. - SourceTypeByte source_type; ///< Type of \c source_id. - SourceID source_id; ///< Index of source, INVALID_SOURCE if unknown/invalid. - StationID source; ///< The station where the cargo came from first. - TileIndex source_xy; ///< The origin of the cargo (first station in feeder chain). + Money feeder_share; ///< Value of feeder pickup to be paid for on delivery of cargo. + uint16 count; ///< The amount of cargo in this packet. + byte days_in_transit; ///< Amount of days this packet has been in transit. + SourceType source_type; ///< Type of \c source_id. + SourceID source_id; ///< Index of source, INVALID_SOURCE if unknown/invalid. + StationID source; ///< The station where the cargo came from first. + TileIndex source_xy; ///< The origin of the cargo (first station in feeder chain). union { TileOrStationID loaded_at_xy; ///< Location where this cargo has been loaded into the vehicle. TileOrStationID next_station; ///< Station where the cargo wants to go next. @@ -194,19 +192,6 @@ public: static void AfterLoad(); }; -/** - * Iterate over all _valid_ cargo packets from the given start. - * @param var Variable used as "iterator". - * @param start Cargo packet ID of the first packet to iterate over. - */ -#define FOR_ALL_CARGOPACKETS_FROM(var, start) FOR_ALL_ITEMS_FROM(CargoPacket, cargopacket_index, var, start) - -/** - * Iterate over all _valid_ cargo packets from the begin of the pool. - * @param var Variable used as "iterator". - */ -#define FOR_ALL_CARGOPACKETS(var) FOR_ALL_CARGOPACKETS_FROM(var, 0) - /** * Simple collection class for a list of cargo packets. * @tparam Tinst Actual instantiation of this cargo list. @@ -286,7 +271,7 @@ protected: typedef CargoList Parent; Money feeder_share; ///< Cache for the feeder share. - uint action_counts[NUM_MOVE_TO_ACTION]; ///< Counts of cargo to be transfered, delivered, kept and loaded. + uint action_counts[NUM_MOVE_TO_ACTION]; ///< Counts of cargo to be transferred, delivered, kept and loaded. template void ShiftCargo(Taction action); @@ -549,7 +534,7 @@ public: uint Reserve(uint max_move, VehicleCargoList *dest, TileIndex load_place, StationIDStack next); uint Load(uint max_move, VehicleCargoList *dest, TileIndex load_place, StationIDStack next); - uint Truncate(uint max_move = UINT_MAX, StationCargoAmountMap *cargo_per_source = NULL); + uint Truncate(uint max_move = UINT_MAX, StationCargoAmountMap *cargo_per_source = nullptr); uint Reroute(uint max_move, StationCargoList *dest, StationID avoid, StationID avoid2, const GoodsEntry *ge); /** diff --git a/src/cargotype.cpp b/src/cargotype.cpp index 6cc02f63a3..52dd196c84 100644 --- a/src/cargotype.cpp +++ b/src/cargotype.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. @@ -14,7 +12,7 @@ #include "newgrf_cargo.h" #include "string_func.h" #include "strings_func.h" -#include "core/sort_func.hpp" +#include #include "table/sprites.h" #include "table/strings.h" @@ -132,56 +130,54 @@ SpriteID CargoSpec::GetCargoIcon() const return sprite; } -const CargoSpec *_sorted_cargo_specs[NUM_CARGO]; ///< Cargo specifications sorted alphabetically by name. -uint8 _sorted_cargo_specs_size; ///< Number of cargo specifications stored at the _sorted_cargo_specs array (including special cargoes). -uint8 _sorted_standard_cargo_specs_size; ///< Number of standard cargo specifications stored at the _sorted_cargo_specs array. +std::vector _sorted_cargo_specs; ///< Cargo specifications sorted alphabetically by name. +uint8 _sorted_standard_cargo_specs_size; ///< Number of standard cargo specifications stored in the _sorted_cargo_specs array. /** Sort cargo specifications by their name. */ -static int CDECL CargoSpecNameSorter(const CargoSpec * const *a, const CargoSpec * const *b) +static bool CargoSpecNameSorter(const CargoSpec * const &a, const CargoSpec * const &b) { static char a_name[64]; static char b_name[64]; - GetString(a_name, (*a)->name, lastof(a_name)); - GetString(b_name, (*b)->name, lastof(b_name)); + GetString(a_name, a->name, lastof(a_name)); + GetString(b_name, b->name, lastof(b_name)); int res = strnatcmp(a_name, b_name); // Sort by name (natural sorting). /* If the names are equal, sort by cargo bitnum. */ - return (res != 0) ? res : ((*a)->bitnum - (*b)->bitnum); + return (res != 0) ? res < 0 : (a->bitnum < b->bitnum); } /** Sort cargo specifications by their cargo class. */ -static int CDECL CargoSpecClassSorter(const CargoSpec * const *a, const CargoSpec * const *b) +static bool CargoSpecClassSorter(const CargoSpec * const &a, const CargoSpec * const &b) { - int res = ((*b)->classes & CC_PASSENGERS) - ((*a)->classes & CC_PASSENGERS); + int res = (b->classes & CC_PASSENGERS) - (a->classes & CC_PASSENGERS); if (res == 0) { - res = ((*b)->classes & CC_MAIL) - ((*a)->classes & CC_MAIL); + res = (b->classes & CC_MAIL) - (a->classes & CC_MAIL); if (res == 0) { - res = ((*a)->classes & CC_SPECIAL) - ((*b)->classes & CC_SPECIAL); + res = (a->classes & CC_SPECIAL) - (b->classes & CC_SPECIAL); if (res == 0) { return CargoSpecNameSorter(a, b); } } } - return res; + return res < 0; } /** Initialize the list of sorted cargo specifications. */ void InitializeSortedCargoSpecs() { - _sorted_cargo_specs_size = 0; + _sorted_cargo_specs.clear(); const CargoSpec *cargo; /* Add each cargo spec to the list. */ FOR_ALL_CARGOSPECS(cargo) { - _sorted_cargo_specs[_sorted_cargo_specs_size] = cargo; - _sorted_cargo_specs_size++; + _sorted_cargo_specs.push_back(cargo); } /* Sort cargo specifications by cargo class and name. */ - QSortT(_sorted_cargo_specs, _sorted_cargo_specs_size, &CargoSpecClassSorter); + std::sort(_sorted_cargo_specs.begin(), _sorted_cargo_specs.end(), &CargoSpecClassSorter); _standard_cargo_mask = 0; diff --git a/src/cargotype.h b/src/cargotype.h index 71cd932bbf..9645bf7c59 100644 --- a/src/cargotype.h +++ b/src/cargotype.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. @@ -17,6 +15,7 @@ #include "gfx_type.h" #include "strings_type.h" #include "landscape_type.h" +#include /** Globally unique label of a cargo type. */ typedef uint32 CargoLabel; @@ -137,8 +136,7 @@ CargoID GetCargoIDByLabel(CargoLabel cl); CargoID GetCargoIDByBitnum(uint8 bitnum); void InitializeSortedCargoSpecs(); -extern const CargoSpec *_sorted_cargo_specs[NUM_CARGO]; -extern uint8 _sorted_cargo_specs_size; +extern std::vector _sorted_cargo_specs; extern uint8 _sorted_standard_cargo_specs_size; /** @@ -152,7 +150,7 @@ static inline bool IsCargoInClass(CargoID c, CargoClass cc) return (CargoSpec::Get(c)->classes & cc) != 0; } -#define FOR_ALL_CARGOSPECS_FROM(var, start) for (size_t cargospec_index = start; var = NULL, cargospec_index < CargoSpec::GetArraySize(); cargospec_index++) \ +#define FOR_ALL_CARGOSPECS_FROM(var, start) for (size_t cargospec_index = start; var = nullptr, cargospec_index < CargoSpec::GetArraySize(); cargospec_index++) \ if ((var = CargoSpec::Get(cargospec_index))->IsValid()) #define FOR_ALL_CARGOSPECS(var) FOR_ALL_CARGOSPECS_FROM(var, 0) @@ -163,7 +161,7 @@ static inline bool IsCargoInClass(CargoID c, CargoClass cc) * @param var Reference getting the cargospec. * @see CargoSpec */ -#define FOR_ALL_SORTED_CARGOSPECS(var) for (uint8 index = 0; index < _sorted_cargo_specs_size && (var = _sorted_cargo_specs[index], true) ; index++) +#define FOR_ALL_SORTED_CARGOSPECS(var) for (uint8 index = 0; index < _sorted_cargo_specs.size() && (var = _sorted_cargo_specs[index], true) ; index++) /** * Loop header for iterating over 'real' cargoes, sorted by name. Phony cargoes like regearing cargoes are skipped. diff --git a/src/cheat.cpp b/src/cheat.cpp index 8b300c9668..9fba889da0 100644 --- a/src/cheat.cpp +++ b/src/cheat.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. diff --git a/src/cheat_func.h b/src/cheat_func.h index e774abc686..6d26e71c4a 100644 --- a/src/cheat_func.h +++ b/src/cheat_func.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/cheat_gui.cpp b/src/cheat_gui.cpp index fda2b246e4..7290414c00 100644 --- a/src/cheat_gui.cpp +++ b/src/cheat_gui.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. @@ -186,9 +184,9 @@ struct CheatEntry { static const CheatEntry _cheats_ui[] = { {SLE_INT32, STR_CHEAT_MONEY, &_money_cheat_amount, &_cheats.money.been_used, &ClickMoneyCheat }, {SLE_UINT8, STR_CHEAT_CHANGE_COMPANY, &_local_company, &_cheats.switch_company.been_used, &ClickChangeCompanyCheat }, - {SLE_BOOL, STR_CHEAT_EXTRA_DYNAMITE, &_cheats.magic_bulldozer.value, &_cheats.magic_bulldozer.been_used, NULL }, - {SLE_BOOL, STR_CHEAT_CROSSINGTUNNELS, &_cheats.crossing_tunnels.value, &_cheats.crossing_tunnels.been_used, NULL }, - {SLE_BOOL, STR_CHEAT_NO_JETCRASH, &_cheats.no_jetcrash.value, &_cheats.no_jetcrash.been_used, NULL }, + {SLE_BOOL, STR_CHEAT_EXTRA_DYNAMITE, &_cheats.magic_bulldozer.value, &_cheats.magic_bulldozer.been_used, nullptr }, + {SLE_BOOL, STR_CHEAT_CROSSINGTUNNELS, &_cheats.crossing_tunnels.value, &_cheats.crossing_tunnels.been_used, nullptr }, + {SLE_BOOL, STR_CHEAT_NO_JETCRASH, &_cheats.no_jetcrash.value, &_cheats.no_jetcrash.been_used, nullptr }, {SLE_BOOL, STR_CHEAT_SETUP_PROD, &_cheats.setup_prod.value, &_cheats.setup_prod.been_used, &ClickSetProdCheat }, {SLE_UINT8, STR_CHEAT_EDIT_MAX_HL, &_settings_game.construction.max_heightlevel, &_cheats.edit_max_hl.been_used, &ClickChangeMaxHlCheat }, {SLE_INT32, STR_CHEAT_CHANGE_DATE, &_cur_year, &_cheats.change_date.been_used, &ClickChangeDateCheat }, @@ -221,7 +219,7 @@ struct CheatWindow : Window { this->InitNested(); } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { if (widget != WID_C_PANEL) return; @@ -283,7 +281,7 @@ struct CheatWindow : Window { } } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { if (widget != WID_C_PANEL) return; @@ -330,7 +328,7 @@ struct CheatWindow : Window { size->height = this->header_height + WD_FRAMERECT_TOP + WD_PAR_VSEP_NORMAL + WD_FRAMERECT_BOTTOM + this->line_height * lengthof(_cheats_ui); } - virtual void OnClick(Point pt, int widget, int click_count) + 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 - this->header_height) / this->line_height; @@ -365,12 +363,12 @@ struct CheatWindow : Window { switch (ce->type) { case SLE_BOOL: value ^= 1; - if (ce->proc != NULL) ce->proc(value, 0); + if (ce->proc != nullptr) ce->proc(value, 0); break; default: /* Take whatever the function returns */ - value = ce->proc(value + ((x >= 20 + SETTING_BUTTON_WIDTH / 2) ? 1 : -1), (x >= 10 + this->box_width + SETTING_BUTTON_WIDTH / 2) ? 1 : -1); + 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); /* 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); @@ -384,16 +382,16 @@ struct CheatWindow : Window { this->SetDirty(); } - virtual void OnTimeout() + void OnTimeout() override { this->clicked = 0; this->SetDirty(); } - virtual void OnQueryTextFinished(char *str) + void OnQueryTextFinished(char *str) override { /* Was 'cancel' pressed or nothing entered? */ - if (str == NULL || StrEmpty(str)) return; + if (str == nullptr || StrEmpty(str)) return; const CheatEntry *ce = &_cheats_ui[clicked_widget]; int oldvalue = (int32)ReadValue(ce->variable, ce->type); diff --git a/src/cheat_type.h b/src/cheat_type.h index a75acf35e3..3d70d527f9 100644 --- a/src/cheat_type.h +++ b/src/cheat_type.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/clear_cmd.cpp b/src/clear_cmd.cpp index c4aeb3a52e..06953884e1 100644 --- a/src/clear_cmd.cpp +++ b/src/clear_cmd.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. @@ -389,15 +387,15 @@ extern const TileTypeProcs _tile_type_clear_procs = { DrawTile_Clear, ///< draw_tile_proc GetSlopePixelZ_Clear, ///< get_slope_z_proc ClearTile_Clear, ///< clear_tile_proc - NULL, ///< add_accepted_cargo_proc + nullptr, ///< add_accepted_cargo_proc GetTileDesc_Clear, ///< get_tile_desc_proc GetTileTrackStatus_Clear, ///< get_tile_track_status_proc - NULL, ///< click_tile_proc - NULL, ///< animate_tile_proc + nullptr, ///< click_tile_proc + nullptr, ///< animate_tile_proc TileLoop_Clear, ///< tile_loop_proc ChangeTileOwner_Clear, ///< change_tile_owner_proc - NULL, ///< add_produced_cargo_proc - NULL, ///< vehicle_enter_tile_proc + nullptr, ///< add_produced_cargo_proc + nullptr, ///< vehicle_enter_tile_proc GetFoundation_Clear, ///< get_foundation_proc TerraformTile_Clear, ///< terraform_tile_proc }; diff --git a/src/clear_func.h b/src/clear_func.h index b128288d1b..2232b56747 100644 --- a/src/clear_func.h +++ b/src/clear_func.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/clear_map.h b/src/clear_map.h index d24916de35..159f5c6a40 100644 --- a/src/clear_map.h +++ b/src/clear_map.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/cmd_helper.h b/src/cmd_helper.h index 569708dfc5..ee5d445c28 100644 --- a/src/cmd_helper.h +++ b/src/cmd_helper.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/command.cpp b/src/command.cpp index 904353175d..5dc7f2598e 100644 --- a/src/command.cpp +++ b/src/command.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. @@ -71,6 +69,8 @@ CommandProc CmdBuildRoad; CommandProc CmdBuildRoadDepot; +CommandProc CmdConvertRoad; + CommandProc CmdBuildAirport; CommandProc CmdBuildDock; @@ -108,6 +108,7 @@ CommandProc CmdIncreaseLoan; CommandProc CmdDecreaseLoan; CommandProc CmdWantEnginePreview; +CommandProc CmdEngineCtrl; CommandProc CmdRenameVehicle; CommandProc CmdRenameEngine; @@ -133,6 +134,7 @@ CommandProc CmdFoundTown; CommandProc CmdRenameTown; CommandProc CmdDoTownAction; CommandProc CmdTownGrowthRate; +CommandProc CmdTownRating; CommandProc CmdTownCargoGoal; CommandProc CmdTownSetText; CommandProc CmdExpandTown; @@ -217,7 +219,7 @@ static const Command _command_proc_table[] = { DEF_CMD(CmdRemoveRailroadTrack, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_REMOVE_RAILROAD_TRACK DEF_CMD(CmdBuildSingleRail, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_SINGLE_RAIL DEF_CMD(CmdRemoveSingleRail, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_REMOVE_SINGLE_RAIL - DEF_CMD(CmdLandscapeClear, 0, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_LANDSCAPE_CLEAR + DEF_CMD(CmdLandscapeClear, CMD_DEITY, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_LANDSCAPE_CLEAR DEF_CMD(CmdBuildBridge, CMD_DEITY | CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_BRIDGE DEF_CMD(CmdBuildRailStation, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_RAIL_STATION DEF_CMD(CmdBuildTrainDepot, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_TRAIN_DEPOT @@ -238,6 +240,7 @@ static const Command _command_proc_table[] = { DEF_CMD(CmdRemoveLongRoad, CMD_NO_TEST | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_REMOVE_LONG_ROAD; towns may disallow removing road bits (as they are connected) in test, but in exec they're removed and thus removing is allowed. DEF_CMD(CmdBuildRoad, CMD_DEITY | CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_ROAD DEF_CMD(CmdBuildRoadDepot, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_ROAD_DEPOT + DEF_CMD(CmdConvertRoad, 0, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_CONVERT_ROAD DEF_CMD(CmdBuildAirport, CMD_NO_WATER | CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_AIRPORT DEF_CMD(CmdBuildDock, CMD_AUTO, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_BUILD_DOCK @@ -271,6 +274,7 @@ static const Command _command_proc_table[] = { DEF_CMD(CmdDecreaseLoan, 0, CMDT_MONEY_MANAGEMENT ), // CMD_DECREASE_LOAN DEF_CMD(CmdWantEnginePreview, 0, CMDT_VEHICLE_MANAGEMENT ), // CMD_WANT_ENGINE_PREVIEW + DEF_CMD(CmdEngineCtrl, CMD_DEITY, CMDT_VEHICLE_MANAGEMENT ), // CMD_ENGINE_CTRL DEF_CMD(CmdRenameVehicle, 0, CMDT_OTHER_MANAGEMENT ), // CMD_RENAME_VEHICLE DEF_CMD(CmdRenameEngine, CMD_SERVER, CMDT_OTHER_MANAGEMENT ), // CMD_RENAME_ENGINE @@ -297,6 +301,7 @@ static const Command _command_proc_table[] = { DEF_CMD(CmdDoTownAction, 0, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_DO_TOWN_ACTION DEF_CMD(CmdTownCargoGoal, CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_TOWN_CARGO_GOAL DEF_CMD(CmdTownGrowthRate, CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_TOWN_GROWTH_RATE + DEF_CMD(CmdTownRating, CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_TOWN_RATING DEF_CMD(CmdTownSetText, CMD_STR_CTRL | CMD_DEITY, CMDT_OTHER_MANAGEMENT ), // CMD_TOWN_SET_TEXT DEF_CMD(CmdExpandTown, CMD_DEITY, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_EXPAND_TOWN DEF_CMD(CmdDeleteTown, CMD_OFFLINE, CMDT_LANDSCAPE_CONSTRUCTION), // CMD_DELETE_TOWN @@ -364,7 +369,7 @@ static const Command _command_proc_table[] = { }; /*! - * This function range-checks a cmd, and checks if the cmd is not NULL + * This function range-checks a cmd, and checks if the cmd is not nullptr * * @param cmd The integer value of a command * @return true if the command is valid (and got a CommandProc function) @@ -373,7 +378,7 @@ bool IsValidCommand(uint32 cmd) { cmd &= CMD_ID_MASK; - return cmd < lengthof(_command_proc_table) && _command_proc_table[cmd].proc != NULL; + return cmd < lengthof(_command_proc_table) && _command_proc_table[cmd].proc != nullptr; } /*! @@ -472,7 +477,7 @@ CommandCost DoCommand(TileIndex tile, uint32 p1, uint32 p2, DoCommandFlag flags, /* only execute the test call if it's toplevel, or we're not execing. */ if (_docommand_recursive == 1 || !(flags & DC_EXEC) ) { - if (_docommand_recursive == 1) _cleared_object_areas.Clear(); + if (_docommand_recursive == 1) _cleared_object_areas.clear(); SetTownRatingTestMode(true); res = proc(tile, flags & ~DC_EXEC, p1, p2, text); SetTownRatingTestMode(false); @@ -495,7 +500,7 @@ CommandCost DoCommand(TileIndex tile, uint32 p1, uint32 p2, DoCommandFlag flags, /* Execute the command here. All cost-relevant functions set the expenses type * themselves to the cost object at some point */ - if (_docommand_recursive == 1) _cleared_object_areas.Clear(); + if (_docommand_recursive == 1) _cleared_object_areas.clear(); res = proc(tile, flags, p1, p2, text); if (res.Failed()) { error: @@ -554,7 +559,7 @@ bool DoCommandP(const CommandContainer *container, bool my_cmd) bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const char *text, bool my_cmd) { /* Cost estimation is generally only done when the - * local user presses shift while doing somthing. + * local user presses shift while doing something. * However, in case of incoming network commands, * map generation or the pause button we do want * to execute. */ @@ -583,10 +588,8 @@ bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallbac return false; } -#ifdef ENABLE_NETWORK /* Only set p2 when the command does not come from the network. */ if (!(cmd & CMD_NETWORK_COMMAND) && GetCommandFlags(cmd) & CMD_CLIENT_ID && p2 == 0) p2 = CLIENT_ID_SERVER; -#endif CommandCost res = DoCommandPInternal(tile, p1, p2, cmd, callback, text, my_cmd, estimate_only); if (res.Failed()) { @@ -606,8 +609,8 @@ bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallbac ShowCostOrIncomeAnimation(x, y, GetSlopePixelZ(x, y), res.GetCost()); } - if (!estimate_only && !only_sending && callback != NULL) { - callback(res, tile, p1, p2); + if (!estimate_only && !only_sending && callback != nullptr) { + callback(res, tile, p1, p2, cmd); } return res.Succeeded(); @@ -649,17 +652,15 @@ CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandProc *proc = _command_proc_table[cmd_id].proc; /* Shouldn't happen, but you never know when someone adds * NULLs to the _command_proc_table. */ - assert(proc != NULL); + assert(proc != nullptr); /* Command flags are used internally */ CommandFlags cmd_flags = GetCommandFlags(cmd); /* Flags get send to the DoCommand */ DoCommandFlag flags = CommandFlagsToDCFlags(cmd_flags); -#ifdef ENABLE_NETWORK /* Make sure p2 is properly set to a ClientID. */ assert(!(cmd_flags & CMD_CLIENT_ID) || p2 != 0); -#endif /* Do not even think about executing out-of-bounds tile-commands */ if (tile != 0 && (tile >= MapSize() || (!IsValidTile(tile) && (cmd_flags & CMD_ALL_TILES) == 0))) return_dcpi(CMD_ERROR); @@ -674,13 +675,13 @@ CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, return_dcpi(CMD_ERROR); } - Backup cur_company(_current_company, FILE_LINE); + Backup cur_company(_current_company, FILE_LINE); if (exec_as_spectator) cur_company.Change(COMPANY_SPECTATOR); bool test_and_exec_can_differ = (cmd_flags & CMD_NO_TEST) != 0; /* Test the command. */ - _cleared_object_areas.Clear(); + _cleared_object_areas.clear(); SetTownRatingTestMode(true); BasePersistentStorageArray::SwitchMode(PSM_ENTER_TESTMODE); CommandCost res = proc(tile, flags, p1, p2, text); @@ -706,7 +707,6 @@ CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, return_dcpi(res); } -#ifdef ENABLE_NETWORK /* * If we are in network, and the command is not from the network * send it to the command-queue and abort execution @@ -721,12 +721,11 @@ CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, * reset the storages as we've not executed the command. */ return_dcpi(CommandCost()); } -#endif /* ENABLE_NETWORK */ DEBUG(desync, 1, "cmd: %08x; %02x; %02x; %06x; %08x; %08x; %08x; \"%s\" (%s)", _date, _date_fract, (int)_current_company, tile, p1, p2, cmd & ~CMD_NETWORK_COMMAND, text, GetCommandName(cmd)); /* Actually try and execute the command. If no cost-type is given * use the construction one */ - _cleared_object_areas.Clear(); + _cleared_object_areas.clear(); BasePersistentStorageArray::SwitchMode(PSM_ENTER_COMMAND); CommandCost res2 = proc(tile, flags | DC_EXEC, p1, p2, text); BasePersistentStorageArray::SwitchMode(PSM_LEAVE_COMMAND); @@ -766,7 +765,7 @@ CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, /* update last build coordinate of company. */ if (tile != 0) { Company *c = Company::GetIfValid(_current_company); - if (c != NULL) c->last_build_coordinate = tile; + if (c != nullptr) c->last_build_coordinate = tile; } SubtractMoneyFromCompany(res2); diff --git a/src/command_func.h b/src/command_func.h index 3369475675..7a0a77e8d8 100644 --- a/src/command_func.h +++ b/src/command_func.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. @@ -34,17 +32,15 @@ static const CommandCost CMD_ERROR = CommandCost(INVALID_STRING_ID); */ #define return_cmd_error(errcode) return CommandCost(errcode); -CommandCost DoCommand(TileIndex tile, uint32 p1, uint32 p2, DoCommandFlag flags, uint32 cmd, const char *text = NULL); +CommandCost DoCommand(TileIndex tile, uint32 p1, uint32 p2, DoCommandFlag flags, uint32 cmd, const char *text = nullptr); CommandCost DoCommand(const CommandContainer *container, DoCommandFlag flags); -bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback = NULL, const char *text = NULL, bool my_cmd = true); +bool DoCommandP(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback = nullptr, const char *text = nullptr, bool my_cmd = true); bool DoCommandP(const CommandContainer *container, bool my_cmd = true); CommandCost DoCommandPInternal(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const char *text, bool my_cmd, bool estimate_only); -#ifdef ENABLE_NETWORK void NetworkSendCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, CommandCallback *callback, const char *text, CompanyID company); -#endif /* ENABLE_NETWORK */ extern Money _additional_cash_required; diff --git a/src/command_type.h b/src/command_type.h index e7512f11d2..98ba3a7053 100644 --- a/src/command_type.h +++ b/src/command_type.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. @@ -36,25 +34,25 @@ public: /** * Creates a command cost return with no cost and no error */ - CommandCost() : expense_type(INVALID_EXPENSES), cost(0), message(INVALID_STRING_ID), success(true), textref_stack_grffile(NULL), textref_stack_size(0) {} + 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 */ - explicit CommandCost(StringID msg) : expense_type(INVALID_EXPENSES), cost(0), message(msg), success(false), textref_stack_grffile(NULL), textref_stack_size(0) {} + explicit CommandCost(StringID msg) : expense_type(INVALID_EXPENSES), cost(0), message(msg), success(false), textref_stack_grffile(nullptr), textref_stack_size(0) {} /** * Creates a command cost with given expense type and start cost of 0 * @param ex_t the expense type */ - explicit CommandCost(ExpensesType ex_t) : expense_type(ex_t), cost(0), message(INVALID_STRING_ID), success(true), textref_stack_grffile(NULL), textref_stack_size(0) {} + explicit CommandCost(ExpensesType ex_t) : expense_type(ex_t), cost(0), message(INVALID_STRING_ID), success(true), textref_stack_grffile(nullptr), textref_stack_size(0) {} /** * Creates a command return value with the given start cost and expense type * @param ex_t the expense type * @param cst the initial cost of this command */ - CommandCost(ExpensesType ex_t, const Money &cst) : expense_type(ex_t), cost(cst), message(INVALID_STRING_ID), success(true), textref_stack_grffile(NULL), textref_stack_size(0) {} + CommandCost(ExpensesType ex_t, const Money &cst) : expense_type(ex_t), cost(cst), message(INVALID_STRING_ID), success(true), textref_stack_grffile(nullptr), textref_stack_size(0) {} /** @@ -202,6 +200,7 @@ enum Commands { CMD_REMOVE_LONG_ROAD, ///< remove a complete road (not a "half" one) CMD_BUILD_ROAD, ///< build a "half" road CMD_BUILD_ROAD_DEPOT, ///< build a road depot + CMD_CONVERT_ROAD, ///< convert a road type CMD_BUILD_AIRPORT, ///< build an airport @@ -239,6 +238,7 @@ enum Commands { CMD_DECREASE_LOAN, ///< decrease the loan from the bank CMD_WANT_ENGINE_PREVIEW, ///< confirm the preview of an engine + CMD_ENGINE_CTRL, ///< control availability of the engine for companies CMD_RENAME_VEHICLE, ///< rename a whole vehicle CMD_RENAME_ENGINE, ///< rename a engine (in the engine list) @@ -263,6 +263,7 @@ enum Commands { CMD_DO_TOWN_ACTION, ///< do a action from the town detail window (like advertises or bribe) CMD_TOWN_CARGO_GOAL, ///< set the goal of a cargo for a town CMD_TOWN_GROWTH_RATE, ///< set the town growth rate + CMD_TOWN_RATING, ///< set rating of a company in a town CMD_TOWN_SET_TEXT, ///< set the custom text of a town CMD_EXPAND_TOWN, ///< expand a town CMD_DELETE_TOWN, ///< delete a town @@ -467,7 +468,7 @@ struct Command { * @param p1 Additional data of the command * @see CommandProc */ -typedef void CommandCallback(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2); +typedef void CommandCallback(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd); /** * Structure for buffering the build command when selecting a station to join. diff --git a/src/company_base.h b/src/company_base.h index 9d2bc90009..095f7d9e6c 100644 --- a/src/company_base.h +++ b/src/company_base.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. @@ -43,6 +41,9 @@ struct CompanyInfrastructure { for (RailType rt = RAILTYPE_BEGIN; rt < RAILTYPE_END; rt++) total += this->rail[rt]; return total; } + + uint32 GetRoadTotal() const; + uint32 GetTramTotal() const; }; typedef Pool CompanyPool; @@ -72,7 +73,7 @@ struct CompanyProperties { TileIndex location_of_HQ; ///< Northern tile of HQ; #INVALID_TILE when there is none. TileIndex last_build_coordinate; ///< Coordinate of the last build thing by this company. - OwnerByte share_owners[4]; ///< Owners of the 4 shares of the company. #INVALID_OWNER if nobody has bought them yet. + Owner share_owners[4]; ///< Owners of the 4 shares of the company. #INVALID_OWNER if nobody has bought them yet. Year inaugurated_year; ///< Year of starting the company. @@ -98,7 +99,7 @@ struct CompanyProperties { // TODO: Change some of these member variables to use relevant INVALID_xxx constants CompanyProperties() - : name_2(0), name_1(0), name(NULL), president_name_1(0), president_name_2(0), president_name(NULL), + : name_2(0), name_1(0), name(nullptr), president_name_1(0), president_name_2(0), president_name(nullptr), 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), @@ -137,7 +138,7 @@ struct Company : CompanyPool::PoolItem<&_company_pool>, CompanyProperties { static inline bool IsValidAiID(size_t index) { const Company *c = Company::GetIfValid(index); - return c != NULL && c->is_ai; + return c != nullptr && c->is_ai; } /** @@ -149,7 +150,7 @@ struct Company : CompanyPool::PoolItem<&_company_pool>, CompanyProperties { static inline bool IsValidHumanID(size_t index) { const Company *c = Company::GetIfValid(index); - return c != NULL && !c->is_ai; + return c != nullptr && !c->is_ai; } /** @@ -167,9 +168,6 @@ struct Company : CompanyPool::PoolItem<&_company_pool>, CompanyProperties { static void PostDestructor(size_t index); }; -#define FOR_ALL_COMPANIES_FROM(var, start) FOR_ALL_ITEMS_FROM(Company, company_index, var, start) -#define FOR_ALL_COMPANIES(var) FOR_ALL_COMPANIES_FROM(var, 0) - Money CalculateCompanyValue(const Company *c, bool including_loan = true); extern uint _next_competitor_start; diff --git a/src/company_cmd.cpp b/src/company_cmd.cpp index 3426451f58..ca8cee031d 100644 --- a/src/company_cmd.cpp +++ b/src/company_cmd.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. @@ -43,8 +41,8 @@ void ClearEnginesHiddenFlagOfCompany(CompanyID cid); -CompanyByte _local_company; ///< Company controlled by the human player at this client. Can also be #COMPANY_SPECTATOR. -CompanyByte _current_company; ///< Company currently doing an action. +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. Colours _company_colours[MAX_COMPANIES]; ///< NOSAVE: can be determined from company structs. CompanyManagerFace _company_manager_face; ///< for company manager face storage in openttd.cfg uint _next_competitor_start; ///< the number of ticks before the next AI is started @@ -104,17 +102,18 @@ void SetLocalCompany(CompanyID new_company) /* company could also be COMPANY_SPECTATOR or OWNER_NONE */ assert(Company::IsValidID(new_company) || new_company == COMPANY_SPECTATOR || new_company == OWNER_NONE); -#ifdef ENABLE_NETWORK + /* If actually changing to another company, several windows need closing */ + bool switching_company = _local_company != new_company; + /* Delete the chat window, if you were team chatting. */ - InvalidateWindowData(WC_SEND_NETWORK_MSG, DESTTYPE_TEAM, _local_company); -#endif + if (switching_company) InvalidateWindowData(WC_SEND_NETWORK_MSG, DESTTYPE_TEAM, _local_company); assert(IsLocalCompany()); _current_company = _local_company = new_company; /* Delete any construction windows... */ - DeleteConstructionWindows(); + if (switching_company) DeleteConstructionWindows(); /* ... and redraw the whole screen. */ MarkWholeScreenDirty(); @@ -195,7 +194,7 @@ bool CheckCompanyHasMoney(CommandCost &cost) { if (cost.GetCost() > 0) { const Company *c = Company::GetIfValid(_current_company); - if (c != NULL && cost.GetCost() > c->money) { + if (c != nullptr && cost.GetCost() > c->money) { SetDParam(0, cost.GetCost()); cost.MakeError(STR_ERROR_NOT_ENOUGH_CASH_REQUIRES_CURRENCY); return false; @@ -241,7 +240,7 @@ static void SubtractMoneyFromAnyCompany(Company *c, CommandCost cost) void SubtractMoneyFromCompany(CommandCost cost) { Company *c = Company::GetIfValid(_current_company); - if (c != NULL) SubtractMoneyFromAnyCompany(c, cost); + if (c != nullptr) SubtractMoneyFromAnyCompany(c, cost); } /** @@ -264,8 +263,7 @@ void SubtractMoneyFromCompanyFract(CompanyID company, CommandCost cst) /** Update the landscaping limits per company. */ void UpdateLandscapingLimits() { - Company *c; - FOR_ALL_COMPANIES(c) { + for (Company *c : Company::Iterate()) { c->terraform_limit = min(c->terraform_limit + _settings_game.construction.terraform_per_64k_frames, (uint32)_settings_game.construction.terraform_frame_burst << 16); c->clear_limit = min(c->clear_limit + _settings_game.construction.clear_per_64k_frames, (uint32)_settings_game.construction.clear_frame_burst << 16); c->tree_limit = min(c->tree_limit + _settings_game.construction.tree_per_64k_frames, (uint32)_settings_game.construction.tree_frame_burst << 16); @@ -355,14 +353,13 @@ static void GenerateCompanyName(Company *c) StringID str; uint32 strp; - if (t->name == NULL && IsInsideMM(t->townnametype, SPECSTR_TOWNNAME_START, SPECSTR_TOWNNAME_LAST + 1)) { + if (t->name == nullptr && IsInsideMM(t->townnametype, SPECSTR_TOWNNAME_START, SPECSTR_TOWNNAME_LAST + 1)) { str = t->townnametype - SPECSTR_TOWNNAME_START + SPECSTR_COMPANY_NAME_START; strp = t->townnameparts; verify_name:; /* No companies must have this name already */ - Company *cc; - FOR_ALL_COMPANIES(cc) { + for (const Company *cc : Company::Iterate()) { if (cc->name_1 == str && cc->name_2 == strp) goto bad_town_name; } @@ -448,8 +445,7 @@ static Colours GenerateCompanyColour() } /* Move the colours that look similar to each company's colour to the side */ - Company *c; - FOR_ALL_COMPANIES(c) { + for (const Company *c : Company::Iterate()) { Colours pcolour = (Colours)c->colour; for (uint i = 0; i < COLOUR_END; i++) { @@ -495,8 +491,7 @@ restart:; GetString(buffer, STR_PRESIDENT_NAME, lastof(buffer)); if (Utf8StringLength(buffer) >= MAX_LENGTH_PRESIDENT_NAME_CHARS) continue; - Company *cc; - FOR_ALL_COMPANIES(cc) { + for (const Company *cc : Company::Iterate()) { if (c != cc) { /* Reserve extra space so even overlength president names can be compared. */ char buffer2[(MAX_LENGTH_PRESIDENT_NAME_CHARS + 1) * MAX_CHAR_LENGTH]; @@ -522,8 +517,7 @@ void ResetCompanyLivery(Company *c) c->livery[scheme].colour2 = c->colour; } - Group *g; - FOR_ALL_GROUPS(g) { + for (Group *g : Group::Iterate()) { if (g->owner == c->index) { g->livery.in_use = 0; g->livery.colour1 = c->colour; @@ -541,7 +535,7 @@ void ResetCompanyLivery(Company *c) */ Company *DoStartupNewCompany(bool is_ai, CompanyID company = INVALID_COMPANY) { - if (!Company::CanAllocateItem()) return NULL; + if (!Company::CanAllocateItem()) return nullptr; /* we have to generate colour before this company is valid */ Colours colour = GenerateCompanyColour(); @@ -550,7 +544,7 @@ Company *DoStartupNewCompany(bool is_ai, CompanyID company = INVALID_COMPANY) if (company == INVALID_COMPANY) { c = new Company(STR_SV_UNNAMED, is_ai); } else { - if (Company::IsValidID(company)) return NULL; + if (Company::IsValidID(company)) return nullptr; c = new (company) Company(STR_SV_UNNAMED, is_ai); } @@ -564,7 +558,7 @@ Company *DoStartupNewCompany(bool is_ai, CompanyID company = INVALID_COMPANY) c->share_owners[0] = c->share_owners[1] = c->share_owners[2] = c->share_owners[3] = INVALID_OWNER; c->avail_railtypes = GetCompanyRailtypes(c->index); - c->avail_roadtypes = GetCompanyRoadtypes(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 @@ -597,15 +591,11 @@ void StartupCompanies() /** Start a new competitor company if possible. */ static void MaybeStartNewCompany() { -#ifdef ENABLE_NETWORK - if (_networking && Company::GetNumItems() >= _settings_client.network.max_companies) return; -#endif /* ENABLE_NETWORK */ - - Company *c; + if (_networking && Company::GetNumItems() >= _settings_client.network.max_companies) return false; /* count number of competitors */ uint n = 0; - FOR_ALL_COMPANIES(c) { + for (const Company *c : Company::Iterate()) { if (c->is_ai) n++; } @@ -672,11 +662,11 @@ static void HandleBankruptcyTakeover(Company *c) /* Did we ask everyone for bankruptcy? If so, bail out. */ if (c->bankrupt_asked == MAX_UVALUE(CompanyMask)) return; - Company *c2, *best = NULL; + Company *best = nullptr; int32 best_performance = -1; /* Ask the company with the highest performance history first */ - FOR_ALL_COMPANIES(c2) { + for (Company *c2 : Company::Iterate()) { if (c2->bankrupt_asked == 0 && // Don't ask companies going bankrupt themselves !HasBit(c->bankrupt_asked, c2->index) && best_performance < c2->old_economy[1].performance_history && @@ -708,7 +698,7 @@ void OnTick_Companies() if (_game_mode == GM_EDITOR) return; Company *c = Company::GetIfValid(_cur_company_tick_index); - if (c != NULL) { + if (c != nullptr) { if (c->name_1 != 0) GenerateCompanyName(c); if (c->bankrupt_asked != 0) HandleBankruptcyTakeover(c); } @@ -730,10 +720,8 @@ void OnTick_Companies() */ void CompaniesYearlyLoop() { - Company *c; - /* Copy statistics */ - FOR_ALL_COMPANIES(c) { + for (Company *c : Company::Iterate()) { memmove(&c->yearly_expenses[1], &c->yearly_expenses[0], sizeof(c->yearly_expenses) - sizeof(c->yearly_expenses[0])); memset(&c->yearly_expenses[0], 0, sizeof(c->yearly_expenses[0])); SetWindowDirty(WC_FINANCES, c->index); @@ -741,7 +729,7 @@ void CompaniesYearlyLoop() if (_settings_client.gui.show_finances && _local_company != COMPANY_SPECTATOR) { ShowCompanyFinances(_local_company); - c = Company::Get(_local_company); + Company *c = Company::Get(_local_company); if (c->num_valid_stat_ent > 5 && c->old_economy[0].performance_history < c->old_economy[4].performance_history) { if (_settings_client.sound.new_year) SndPlayFx(SND_01_BAD_YEAR); } else { @@ -753,14 +741,14 @@ void CompaniesYearlyLoop() /** * Fill the CompanyNewsInformation struct with the required data. * @param c the current company. - * @param other the other company (use \c NULL if not relevant). + * @param other the other company (use \c nullptr if not relevant). */ void CompanyNewsInformation::FillData(const Company *c, const Company *other) { SetDParam(0, c->index); GetString(this->company_name, STR_COMPANY_NAME, lastof(this->company_name)); - if (other == NULL) { + if (other == nullptr) { *this->other_company_name = '\0'; } else { SetDParam(0, other->index); @@ -782,9 +770,7 @@ void CompanyNewsInformation::FillData(const Company *c, const Company *other) */ void CompanyAdminUpdate(const Company *company) { -#ifdef ENABLE_NETWORK if (_network_server) NetworkAdminCompanyUpdate(company); -#endif /* ENABLE_NETWORK */ } /** @@ -794,9 +780,7 @@ void CompanyAdminUpdate(const Company *company) */ void CompanyAdminRemove(CompanyID company_id, CompanyRemoveReason reason) { -#ifdef ENABLE_NETWORK if (_network_server) NetworkAdminCompanyRemove(company_id, (AdminCompanyRemoveReason)reason); -#endif /* ENABLE_NETWORK */ } /** @@ -805,10 +789,9 @@ void CompanyAdminRemove(CompanyID company_id, CompanyRemoveReason reason) * @param flags operation to perform * @param p1 various functionality * - bits 0..15: CompanyCtrlAction - * - bits 16..24: CompanyID - * @param p2 various depending on CompanyCtrlAction - * - bits 0..31: ClientID (with CCA_NEW) - * - bits 0..1: CompanyRemoveReason (with CCA_DELETE) + * - bits 16..23: CompanyID + * - bits 24..31: CompanyRemoveReason (with CCA_DELETE) + * @param p2 ClientID * @param text unused * @return the cost of this operation or an error */ @@ -822,7 +805,6 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 /* This command is only executed in a multiplayer game */ if (!_networking) return CMD_ERROR; -#ifdef ENABLE_NETWORK /* Has the network client a correct ClientIndex? */ if (!(flags & DC_EXEC)) return CommandCost(); @@ -832,8 +814,8 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 /* When replaying the client ID is not a valid client; there * are actually no clients at all. However, the company has to * be created, otherwise we cannot rerun the game properly. - * So only allow a NULL client info in that case. */ - if (ci == NULL) return CommandCost(); + * So only allow a nullptr client info in that case. */ + if (ci == nullptr) return CommandCost(); #endif /* NOT DEBUG_DUMP_COMMANDS */ /* Delete multiplayer progress bar */ @@ -842,7 +824,7 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 Company *c = DoStartupNewCompany(false); /* A new company could not be created, revert to being a spectator */ - if (c == NULL) { + if (c == nullptr) { if (_network_server) { ci->client_playas = COMPANY_SPECTATOR; NetworkUpdateClientInfo(ci->client_id); @@ -866,7 +848,6 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 } NetworkServerNewCompany(c, ci); -#endif /* ENABLE_NETWORK */ break; } @@ -875,18 +856,16 @@ CommandCost CmdCompanyCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 if (company_id != INVALID_COMPANY && (company_id >= MAX_COMPANIES || Company::IsValidID(company_id))) return CMD_ERROR; Company *c = DoStartupNewCompany(true, company_id); -#ifdef ENABLE_NETWORK - if (c != NULL) NetworkServerNewCompany(c, NULL); -#endif /* ENABLE_NETWORK */ + if (c != nullptr) NetworkServerNewCompany(c, nullptr); break; } case CCA_DELETE: { // Delete a company - CompanyRemoveReason reason = (CompanyRemoveReason)GB(p2, 0, 2); + CompanyRemoveReason reason = (CompanyRemoveReason)GB(p1, 24, 8); if (reason >= CRR_END) return CMD_ERROR; Company *c = Company::GetIfValid(company_id); - if (c == NULL) return CMD_ERROR; + if (c == nullptr) return CMD_ERROR; if (!(flags & DC_EXEC)) return CommandCost(); @@ -976,8 +955,7 @@ CommandCost CmdSetCompanyColour(TileIndex tile, DoCommandFlag flags, uint32 p1, /* Ensure no two companies have the same primary colour */ if (scheme == LS_DEFAULT && !second) { - const Company *cc; - FOR_ALL_COMPANIES(cc) { + for (const Company *cc : Company::Iterate()) { if (cc != c && cc->colour == colour) return CMD_ERROR; } } @@ -1040,8 +1018,7 @@ CommandCost CmdSetCompanyColour(TileIndex tile, DoCommandFlag flags, uint32 p1, InvalidateWindowData(WC_SMALLMAP, 0, 1); /* Company colour data is indirectly cached. */ - Vehicle *v; - FOR_ALL_VEHICLES(v) { + for (Vehicle *v : Vehicle::Iterate()) { if (v->owner == _current_company) v->InvalidateNewGRFCache(); } @@ -1058,10 +1035,8 @@ CommandCost CmdSetCompanyColour(TileIndex tile, DoCommandFlag flags, uint32 p1, */ static bool IsUniqueCompanyName(const char *name) { - const Company *c; - - FOR_ALL_COMPANIES(c) { - if (c->name != NULL && strcmp(c->name, name) == 0) return false; + for (const Company *c : Company::Iterate()) { + if (c->name != nullptr && strcmp(c->name, name) == 0) return false; } return true; @@ -1088,7 +1063,7 @@ CommandCost CmdRenameCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uin if (flags & DC_EXEC) { Company *c = Company::Get(_current_company); free(c->name); - c->name = reset ? NULL : stredup(text); + c->name = reset ? nullptr : stredup(text); MarkWholeScreenDirty(); CompanyAdminUpdate(c); } @@ -1103,10 +1078,8 @@ CommandCost CmdRenameCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uin */ static bool IsUniquePresidentName(const char *name) { - const Company *c; - - FOR_ALL_COMPANIES(c) { - if (c->president_name != NULL && strcmp(c->president_name, name) == 0) return false; + for (const Company *c : Company::Iterate()) { + if (c->president_name != nullptr && strcmp(c->president_name, name) == 0) return false; } return true; @@ -1135,11 +1108,11 @@ CommandCost CmdRenamePresident(TileIndex tile, DoCommandFlag flags, uint32 p1, u free(c->president_name); if (reset) { - c->president_name = NULL; + c->president_name = nullptr; } else { c->president_name = stredup(text); - if (c->name_1 == STR_SV_UNNAMED && c->name == NULL) { + if (c->name_1 == STR_SV_UNNAMED && c->name == nullptr) { char buf[80]; seprintf(buf, lastof(buf), "%s Transport", text); @@ -1156,13 +1129,13 @@ CommandCost CmdRenamePresident(TileIndex tile, DoCommandFlag flags, uint32 p1, u /** * Get the service interval for the given company and vehicle type. - * @param c The company, or NULL for client-default settings. + * @param c The company, or nullptr for client-default settings. * @param type The vehicle type to get the interval for. * @return The service interval. */ int CompanyServiceInterval(const Company *c, VehicleType type) { - const VehicleDefaultSettings *vds = (c == NULL) ? &_settings_client.company.vehicle : &c->settings.vehicle; + const VehicleDefaultSettings *vds = (c == nullptr) ? &_settings_client.company.vehicle : &c->settings.vehicle; switch (type) { default: NOT_REACHED(); case VEH_TRAIN: return vds->servint_trains; @@ -1171,3 +1144,29 @@ int CompanyServiceInterval(const Company *c, VehicleType type) case VEH_SHIP: return vds->servint_ships; } } + +/** + * Get total sum of all owned road bits. + * @return Combined total road road bits. + */ +uint32 CompanyInfrastructure::GetRoadTotal() const +{ + uint32 total = 0; + for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) { + if (RoadTypeIsRoad(rt)) total += this->road[rt]; + } + return total; +} + +/** + * Get total sum of all owned tram bits. + * @return Combined total of tram road bits. + */ +uint32 CompanyInfrastructure::GetTramTotal() const +{ + uint32 total = 0; + for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) { + if (RoadTypeIsTram(rt)) total += this->road[rt]; + } + return total; +} diff --git a/src/company_func.h b/src/company_func.h index 29650d78cd..cec6110044 100644 --- a/src/company_func.h +++ b/src/company_func.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. @@ -32,8 +30,8 @@ void SubtractMoneyFromCompanyFract(CompanyID company, CommandCost cost); CommandCost CheckOwnership(Owner owner, TileIndex tile = 0); CommandCost CheckTileOwnership(TileIndex tile); -extern CompanyByte _local_company; -extern CompanyByte _current_company; +extern CompanyID _local_company; +extern CompanyID _current_company; extern Colours _company_colours[MAX_COMPANIES]; extern CompanyManagerFace _company_manager_face; diff --git a/src/company_gui.cpp b/src/company_gui.cpp index e526acb3e7..18cacaf4bc 100644 --- a/src/company_gui.cpp +++ b/src/company_gui.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. @@ -30,6 +28,7 @@ #include "core/geometry_func.hpp" #include "object_type.h" #include "rail.h" +#include "road.h" #include "engine_base.h" #include "window_func.h" #include "road_func.h" @@ -285,7 +284,7 @@ struct CompanyFinancesWindow : Window { this->owner = (Owner)this->window_number; } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { switch (widget) { case WID_CF_CAPTION: @@ -304,7 +303,7 @@ struct CompanyFinancesWindow : Window { } } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { int type = _settings_client.gui.expenses_layout; switch (widget) { @@ -332,7 +331,7 @@ struct CompanyFinancesWindow : Window { } } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { switch (widget) { case WID_CF_EXPS_CATEGORY: @@ -393,7 +392,7 @@ struct CompanyFinancesWindow : Window { this->GetWidget(WID_CF_SEL_BUTTONS)->SetDisplayedPlane(plane); } - virtual void OnPaint() + void OnPaint() override { if (!this->IsShaded()) { if (!this->small) { @@ -423,7 +422,7 @@ struct CompanyFinancesWindow : Window { this->DrawWidgets(); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_CF_TOGGLE_SIZE: // toggle size @@ -452,7 +451,7 @@ struct CompanyFinancesWindow : Window { } } - virtual void OnHundredthTick() + void OnHundredthTick() override { const Company *c = Company::Get((CompanyID)this->window_number); if (c->money > CompanyFinancesWindow::max_money) { @@ -520,24 +519,22 @@ class DropDownListColourItem : public DropDownListItem { public: DropDownListColourItem(int result, bool masked) : DropDownListItem(result, masked) {} - virtual ~DropDownListColourItem() {} - StringID String() const { return this->result >= COLOUR_END ? STR_COLOUR_DEFAULT : _colour_dropdown[this->result]; } - uint Height(uint width) const + uint Height(uint width) const override { return GetMinSizing(NWST_STEP, max(FONT_HEIGHT_NORMAL, ScaleGUITrad(12) + 2)); } - bool Selectable() const + bool Selectable() const override { return true; } - void Draw(int left, int right, int top, int bottom, bool sel, int bg_colour) const + void Draw(int left, int right, int top, int bottom, bool sel, Colours bg_colour) const override { bool rtl = _current_text_dir == TD_RTL; int height = bottom - top; @@ -565,20 +562,20 @@ private: uint rows; uint line_height; GUIGroupList groups; - SmallVector indents; + std::vector indents; Scrollbar *vscroll; void ShowColourDropDownMenu(uint32 widget) { uint32 used_colours = 0; const Company *c; - const Livery *livery, *default_livery = NULL; + const Livery *livery, *default_livery = nullptr; bool primary = widget == WID_SCL_PRI_COL_DROPDOWN; byte default_col; /* Disallow other company colours for the primary colour */ if (this->livery_class < LC_GROUP_RAIL && HasBit(this->sel, LS_DEFAULT) && primary) { - FOR_ALL_COMPANIES(c) { + for (const Company *c : Company::Iterate()) { if (c->index != _local_company) SetBit(used_colours, c->colour); } } @@ -605,49 +602,49 @@ private: } } - DropDownList *list = new DropDownList(); - if (default_livery != NULL) { + DropDownList list; + if (default_livery != nullptr) { /* Add COLOUR_END to put the colour out of range, but also allow us to show what the default is */ default_col = (primary ? default_livery->colour1 : default_livery->colour2) + COLOUR_END; - *list->Append() = new DropDownListColourItem(default_col, false); + list.emplace_back(new DropDownListColourItem(default_col, false)); } for (uint i = 0; i < lengthof(_colour_dropdown); i++) { - *list->Append() = new DropDownListColourItem(i, HasBit(used_colours, i)); + list.emplace_back(new DropDownListColourItem(i, HasBit(used_colours, i))); } - byte sel = (default_livery == NULL || HasBit(livery->in_use, primary ? 0 : 1)) ? (primary ? livery->colour1 : livery->colour2) : default_col; - ShowDropDownList(this, list, sel, widget); + byte sel = (default_livery == nullptr || HasBit(livery->in_use, primary ? 0 : 1)) ? (primary ? livery->colour1 : livery->colour2) : default_col; + ShowDropDownList(this, std::move(list), sel, widget); } - static int CDECL GroupNameSorter(const Group * const *a, const Group * const *b) + static bool GroupNameSorter(const Group * const &a, const Group * const &b) { - static const Group *last_group[2] = { NULL, NULL }; + static const Group *last_group[2] = { nullptr, nullptr }; static char last_name[2][64] = { "", "" }; - if (*a != last_group[0]) { - last_group[0] = *a; - SetDParam(0, (*a)->index); + if (a != last_group[0]) { + last_group[0] = a; + SetDParam(0, a->index); GetString(last_name[0], STR_GROUP_NAME, lastof(last_name[0])); } - if (*b != last_group[1]) { - last_group[1] = *b; - SetDParam(0, (*b)->index); + if (b != last_group[1]) { + last_group[1] = b; + SetDParam(0, b->index); GetString(last_name[1], STR_GROUP_NAME, lastof(last_name[1])); } int r = strnatcmp(last_name[0], last_name[1]); // Sort by name (natural sorting). - if (r == 0) return (*a)->index - (*b)->index; - return r; + if (r == 0) return a->index < b->index; + return r < 0; } void AddChildren(GUIGroupList *source, GroupID parent, int indent) { - for (const Group **g = source->Begin(); g != source->End(); g++) { - if ((*g)->parent != parent) continue; - *this->groups.Append() = *g; - *this->indents.Append() = indent; - AddChildren(source, (*g)->index, indent + 1); + for (const Group *g : *source) { + if (g->parent != parent) continue; + this->groups.push_back(g); + this->indents.push_back(indent); + AddChildren(source, g->index, indent + 1); } } @@ -655,17 +652,16 @@ private: { if (!this->groups.NeedRebuild()) return; - this->groups.Clear(); - this->indents.Clear(); + this->groups.clear(); + this->indents.clear(); if (this->livery_class >= LC_GROUP_RAIL) { GUIGroupList list; VehicleType vtype = (VehicleType)(this->livery_class - LC_GROUP_RAIL); - const Group *g; - FOR_ALL_GROUPS(g) { + for (const Group *g : Group::Iterate()) { if (g->owner == owner && g->vehicle_type == vtype) { - *list.Append() = g; + list.push_back(g); } } @@ -675,7 +671,7 @@ private: AddChildren(&list, INVALID_GROUP, 0); } - this->groups.Compact(); + this->groups.shrink_to_fit(); this->groups.RebuildDone(); } @@ -689,7 +685,7 @@ private: } } } else { - this->rows = this->groups.Length(); + this->rows = (uint)this->groups.size(); } this->vscroll->SetCount(this->rows); @@ -743,7 +739,7 @@ public: } } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_SCL_SPACER_DROPDOWN: { @@ -754,8 +750,7 @@ public: } /* And group names */ - const Group *g; - FOR_ALL_GROUPS(g) { + for (const Group *g : Group::Iterate()) { if (g->owner == (CompanyID)this->window_number) { SetDParam(0, g->index); d = maxdim(d, GetStringBoundingBox(STR_GROUP_NAME)); @@ -796,7 +791,7 @@ public: } } - virtual void OnPaint() + void OnPaint() override { bool local = (CompanyID)this->window_number == _local_company; @@ -810,7 +805,7 @@ public: this->DrawWidgets(); } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { switch (widget) { case WID_SCL_CAPTION: @@ -850,7 +845,7 @@ public: } } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { if (widget != WID_SCL_MATRIX) return; @@ -905,7 +900,7 @@ public: } } } else { - uint max = min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->groups.Length()); + uint max = min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), (uint)this->groups.size()); for (uint i = this->vscroll->GetPosition(); i < max; ++i) { const Group *g = this->groups[i]; SetDParam(0, g->index); @@ -914,7 +909,7 @@ public: } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { /* Livery Class buttons */ @@ -945,7 +940,7 @@ public: this->groups.ForceRebuild(); this->BuildGroupList((CompanyID)this->window_number); - if (this->groups.Length() > 0) { + if (this->groups.size() > 0) { this->sel = this->groups[0]->index; } } @@ -988,12 +983,12 @@ public: } } - virtual void OnResize() + void OnResize() override { this->vscroll->SetCapacityFromWidget(this, WID_SCL_MATRIX); } - virtual void OnDropdownSelect(int widget, int index) + void OnDropdownSelect(int widget, int index) override { bool local = (CompanyID)this->window_number == _local_company; if (!local) return; @@ -1019,7 +1014,7 @@ public: * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; @@ -1032,7 +1027,7 @@ public: if (!Group::IsValidID(this->sel)) { this->sel = INVALID_GROUP; - if (this->groups.Length() > 0) this->sel = this->groups[0]->index; + if (this->groups.size() > 0) this->sel = this->groups[0]->index; } this->SetDirty(); @@ -1103,7 +1098,7 @@ static WindowDesc _select_company_livery_desc( void ShowCompanyLiveryWindow(CompanyID company, GroupID group) { SelectCompanyLiveryWindow *w = (SelectCompanyLiveryWindow *)BringWindowToFrontById(WC_COMPANY_COLOUR, company); - if (w == NULL) { + if (w == nullptr) { new SelectCompanyLiveryWindow(&_select_company_livery_desc, company, group); } else if (group != INVALID_GROUP) { w->SetSelectedGroup(company, group); @@ -1381,7 +1376,7 @@ public: } } - virtual void OnInit() + void OnInit() override { /* Size of the boolean yes/no button. */ Dimension yesno_dim = maxdim(GetStringBoundingBox(STR_FACE_YES), GetStringBoundingBox(STR_FACE_NO)); @@ -1408,7 +1403,7 @@ public: this->number_dim = number_dim; } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_SCMF_FACE: { @@ -1467,7 +1462,7 @@ public: } } - virtual void OnPaint() + void OnPaint() override { /* lower the non-selected gender button */ this->SetWidgetsLoweredState(!this->is_female, WID_SCMF_MALE, WID_SCMF_MALE2, WIDGET_LIST_END); @@ -1528,7 +1523,7 @@ public: this->DrawWidgets(); } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { switch (widget) { case WID_SCMF_HAS_MOUSTACHE_EARRING_TEXT: @@ -1617,7 +1612,7 @@ public: } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { /* Toggle size, advanced/simple face selection */ @@ -1726,12 +1721,12 @@ public: } } - virtual void OnQueryTextFinished(char *str) + void OnQueryTextFinished(char *str) override { - if (str == NULL) return; + if (str == nullptr) return; /* Set a new company manager face number */ if (!StrEmpty(str)) { - this->face = strtoul(str, NULL, 10); + this->face = strtoul(str, nullptr, 10); ScaleAllCompanyManagerFaceBits(this->face); ShowErrorMessage(STR_FACE_FACECODE_SET, INVALID_STRING_ID, WL_INFO); this->UpdateData(); @@ -1799,6 +1794,10 @@ static const NWidgetPart _nested_company_infrastructure_widgets[] = { 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(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(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), @@ -1836,11 +1835,10 @@ struct CompanyInfrastructureWindow : Window void UpdateRailRoadTypes() { this->railtypes = RAILTYPES_NONE; - this->roadtypes = ROADTYPES_ROAD; // Road is always available. + this->roadtypes = ROADTYPES_NONE; /* Find the used railtypes. */ - Engine *e; - FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) { + for (const Engine *e : Engine::IterateType(VEH_TRAIN)) { if (!HasBit(e->info.climates, _settings_game.game_creation.landscape)) continue; this->railtypes |= GetRailTypeInfo(e->u.rail.railtype)->introduces_railtypes; @@ -1849,14 +1847,16 @@ struct CompanyInfrastructureWindow : Window /* Get the date introduced railtypes as well. */ this->railtypes = AddDateIntroducedRailTypes(this->railtypes, MAX_DAY); - /* Tram is only visible when there will be a tram. */ - FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) { + /* Find the used roadtypes. */ + for (const Engine *e : Engine::IterateType(VEH_ROAD)) { if (!HasBit(e->info.climates, _settings_game.game_creation.landscape)) continue; - if (!HasBit(e->info.misc_flags, EF_ROAD_TRAM)) continue; - this->roadtypes |= ROADTYPES_TRAM; - break; + this->roadtypes |= GetRoadTypeInfo(e->u.road.roadtype)->introduces_roadtypes; } + + /* Get the date introduced roadtypes as well. */ + this->roadtypes = AddDateIntroducedRoadTypes(this->roadtypes, MAX_DAY); + this->roadtypes &= ~_roadtypes_hidden_mask; } /** Get total infrastructure maintenance cost. */ @@ -1871,8 +1871,11 @@ struct CompanyInfrastructureWindow : Window } total += SignalMaintenanceCost(c->infrastructure.signal); - if (HasBit(this->roadtypes, ROADTYPE_ROAD)) total += RoadMaintenanceCost(ROADTYPE_ROAD, c->infrastructure.road[ROADTYPE_ROAD]); - if (HasBit(this->roadtypes, ROADTYPE_TRAM)) total += RoadMaintenanceCost(ROADTYPE_TRAM, c->infrastructure.road[ROADTYPE_TRAM]); + uint32 road_total = c->infrastructure.GetRoadTotal(); + uint32 tram_total = c->infrastructure.GetTramTotal(); + for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) { + if (HasBit(this->roadtypes, rt)) total += RoadMaintenanceCost(rt, c->infrastructure.road[rt], RoadTypeIsRoad(rt) ? road_total : tram_total); + } total += CanalMaintenanceCost(c->infrastructure.water); total += StationMaintenanceCost(c->infrastructure.station); @@ -1881,7 +1884,7 @@ struct CompanyInfrastructureWindow : Window return total; } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { switch (widget) { case WID_CI_CAPTION: @@ -1890,7 +1893,7 @@ struct CompanyInfrastructureWindow : Window } } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { const Company *c = Company::Get((CompanyID)this->window_number); @@ -1900,7 +1903,8 @@ struct CompanyInfrastructureWindow : Window size->width = max(size->width, GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT).width); - for (RailType rt = RAILTYPE_BEGIN; rt < RAILTYPE_END; rt++) { + RailType rt; + FOR_ALL_SORTED_RAILTYPES(rt) { if (HasBit(this->railtypes, rt)) { lines++; SetDParam(0, GetRailTypeInfo(rt)->strings.name); @@ -1916,18 +1920,19 @@ struct CompanyInfrastructureWindow : Window break; } - case WID_CI_ROAD_DESC: { - uint lines = 1; + case WID_CI_ROAD_DESC: + case WID_CI_TRAM_DESC: { + uint lines = 0; - size->width = max(size->width, GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT).width); + size->width = max(size->width, GetStringBoundingBox(widget == WID_CI_ROAD_DESC ? STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT : STR_COMPANY_INFRASTRUCTURE_VIEW_TRAM_SECT).width); - if (HasBit(this->roadtypes, ROADTYPE_ROAD)) { - lines++; - size->width = max(size->width, GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD).width + WD_FRAMERECT_LEFT); - } - if (HasBit(this->roadtypes, ROADTYPE_TRAM)) { - lines++; - size->width = max(size->width, GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY).width + WD_FRAMERECT_LEFT); + RoadType rt; + FOR_ALL_SORTED_ROADTYPES(rt) { + if (HasBit(this->roadtypes, rt) && RoadTypeIsRoad(rt) == (widget == WID_CI_ROAD_DESC)) { + lines++; + SetDParam(0, GetRoadTypeInfo(rt)->strings.name); + size->width = max(size->width, GetStringBoundingBox(STR_WHITE_STRING).width + WD_FRAMERECT_LEFT); + } } size->height = max(size->height, lines * FONT_HEIGHT_NORMAL); @@ -1947,6 +1952,7 @@ struct CompanyInfrastructureWindow : Window case WID_CI_RAIL_COUNT: case WID_CI_ROAD_COUNT: + case WID_CI_TRAM_COUNT: case WID_CI_WATER_COUNT: case WID_CI_STATION_COUNT: case WID_CI_TOTAL: { @@ -1960,9 +1966,12 @@ struct CompanyInfrastructureWindow : Window } max_val = max(max_val, c->infrastructure.signal); max_cost = max(max_cost, SignalMaintenanceCost(c->infrastructure.signal)); + uint32 road_total = c->infrastructure.GetRoadTotal(); + uint32 tram_total = c->infrastructure.GetTramTotal(); for (RoadType rt = ROADTYPE_BEGIN; rt < ROADTYPE_END; rt++) { max_val = max(max_val, c->infrastructure.road[rt]); - max_cost = max(max_cost, RoadMaintenanceCost(rt, c->infrastructure.road[rt])); + max_cost = max(max_cost, RoadMaintenanceCost(rt, c->infrastructure.road[rt], RoadTypeIsRoad(rt) ? road_total : tram_total)); + } max_val = max(max_val, c->infrastructure.water); max_cost = max(max_cost, CanalMaintenanceCost(c->infrastructure.water)); @@ -2013,7 +2022,7 @@ struct CompanyInfrastructureWindow : Window } } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { const Company *c = Company::Get((CompanyID)this->window_number); int y = r.top; @@ -2058,26 +2067,32 @@ struct CompanyInfrastructureWindow : Window } case WID_CI_ROAD_DESC: - DrawString(r.left, r.right, y, STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT); + case WID_CI_TRAM_DESC: { + DrawString(r.left, r.right, y, widget == WID_CI_ROAD_DESC ? STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT : STR_COMPANY_INFRASTRUCTURE_VIEW_TRAM_SECT); - if (this->roadtypes != ROADTYPES_NONE) { - if (HasBit(this->roadtypes, ROADTYPE_ROAD)) DrawString(r.left + offs_left, r.right - offs_right, y += FONT_HEIGHT_NORMAL, STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD); - if (HasBit(this->roadtypes, ROADTYPE_TRAM)) DrawString(r.left + offs_left, r.right - offs_right, y += FONT_HEIGHT_NORMAL, STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY); - } else { - /* No valid roadtypes. */ - DrawString(r.left + offs_left, r.right - offs_right, y += FONT_HEIGHT_NORMAL, STR_COMPANY_VIEW_INFRASTRUCTURE_NONE); + /* Draw name of each valid roadtype. */ + RoadType rt; + FOR_ALL_SORTED_ROADTYPES(rt) { + 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); + } } break; + } case WID_CI_ROAD_COUNT: - if (HasBit(this->roadtypes, ROADTYPE_ROAD)) { - this->DrawCountLine(r, y, c->infrastructure.road[ROADTYPE_ROAD], RoadMaintenanceCost(ROADTYPE_ROAD, c->infrastructure.road[ROADTYPE_ROAD])); - } - if (HasBit(this->roadtypes, ROADTYPE_TRAM)) { - this->DrawCountLine(r, y, c->infrastructure.road[ROADTYPE_TRAM], RoadMaintenanceCost(ROADTYPE_TRAM, c->infrastructure.road[ROADTYPE_TRAM])); + case WID_CI_TRAM_COUNT: { + uint32 road_tram_total = widget == WID_CI_ROAD_COUNT ? c->infrastructure.GetRoadTotal() : c->infrastructure.GetTramTotal(); + RoadType rt; + FOR_ALL_SORTED_ROADTYPES(rt) { + if (HasBit(this->roadtypes, rt) && RoadTypeIsRoad(rt) == (widget == WID_CI_ROAD_COUNT)) { + this->DrawCountLine(r, y, c->infrastructure.road[rt], RoadMaintenanceCost(rt, c->infrastructure.road[rt], road_tram_total)); + } } break; + } case WID_CI_WATER_DESC: DrawString(r.left, r.right, y, STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT); @@ -2116,7 +2131,7 @@ struct CompanyInfrastructureWindow : Window * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; @@ -2282,7 +2297,7 @@ struct CompanyWindow : Window this->OnInvalidateData(); } - virtual void OnPaint() + void OnPaint() override { const Company *c = Company::Get((CompanyID)this->window_number); bool local = this->window_number == _local_company; @@ -2351,7 +2366,7 @@ struct CompanyWindow : Window this->DrawWidgets(); } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_C_FACE: { @@ -2393,9 +2408,7 @@ struct CompanyWindow : Window break; case WID_C_DESC_OWNERS: { - const Company *c2; - - FOR_ALL_COMPANIES(c2) { + for (const Company *c2 : Company::Iterate()) { SetDParamMaxValue(0, 75); SetDParam(1, c2->index); @@ -2404,15 +2417,13 @@ struct CompanyWindow : Window break; } -#ifdef ENABLE_NETWORK case WID_C_HAS_PASSWORD: *size = maxdim(*size, GetSpriteSize(SPR_LOCK)); break; -#endif /* ENABLE_NETWORK */ } } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { const Company *c = Company::Get((CompanyID)this->window_number); switch (widget) { @@ -2499,10 +2510,9 @@ struct CompanyWindow : Window } case WID_C_DESC_OWNERS: { - const Company *c2; uint y = r.top; - FOR_ALL_COMPANIES(c2) { + for (const Company *c2 : Company::Iterate()) { uint amt = GetAmountOwnedBy(c, c2->index); if (amt != 0) { SetDParam(0, amt * 25); @@ -2515,17 +2525,15 @@ struct CompanyWindow : Window break; } -#ifdef ENABLE_NETWORK case WID_C_HAS_PASSWORD: if (_networking && NetworkCompanyIsPassworded(c->index)) { DrawSprite(SPR_LOCK, PAL_NONE, r.left, r.top); } break; -#endif /* ENABLE_NETWORK */ } } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { switch (widget) { case WID_C_CAPTION: @@ -2543,7 +2551,7 @@ struct CompanyWindow : Window } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_C_NEW_FACE: DoSelectCompanyManagerFace(this); break; @@ -2611,7 +2619,6 @@ struct CompanyWindow : Window DoCommandP(0, this->window_number, 0, CMD_SELL_SHARE_IN_COMPANY | CMD_MSG(STR_ERROR_CAN_T_SELL_25_SHARE_IN)); break; -#ifdef ENABLE_NETWORK case WID_C_COMPANY_PASSWORD: if (this->window_number == _local_company) ShowNetworkCompanyPasswordWindow(this); break; @@ -2624,24 +2631,23 @@ struct CompanyWindow : Window MarkWholeScreenDirty(); } else if (NetworkCompanyIsPassworded(company)) { /* ask for the password */ - ShowQueryString(STR_EMPTY, STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION, NETWORK_PASSWORD_LENGTH, this, CS_ALPHANUMERAL, QSF_NONE); + ShowQueryString(STR_EMPTY, STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION, NETWORK_PASSWORD_LENGTH, this, CS_ALPHANUMERAL, QSF_PASSWORD); } else { /* just send the join command */ NetworkClientRequestMove(company); } break; } -#endif /* ENABLE_NETWORK */ } } - virtual void OnHundredthTick() + void OnHundredthTick() override { /* redraw the window every now and then */ this->SetDirty(); } - virtual void OnPlaceObject(Point pt, TileIndex tile) + void OnPlaceObject(Point pt, TileIndex tile) override { if (DoCommandP(tile, OBJECT_HQ, 0, CMD_BUILD_OBJECT | CMD_MSG(STR_ERROR_CAN_T_BUILD_COMPANY_HEADQUARTERS)) && !_shift_pressed) { ResetObjectToPlace(); @@ -2649,31 +2655,29 @@ struct CompanyWindow : Window } } - virtual void OnPlaceObjectAbort() + void OnPlaceObjectAbort() override { this->RaiseButtons(); } - virtual void OnQueryTextFinished(char *str) + void OnQueryTextFinished(char *str) override { - if (str == NULL) return; + if (str == nullptr) return; switch (this->query_widget) { default: NOT_REACHED(); case WID_C_PRESIDENT_NAME: - DoCommandP(0, 0, 0, CMD_RENAME_PRESIDENT | CMD_MSG(STR_ERROR_CAN_T_CHANGE_PRESIDENT), NULL, str); + DoCommandP(0, 0, 0, CMD_RENAME_PRESIDENT | CMD_MSG(STR_ERROR_CAN_T_CHANGE_PRESIDENT), nullptr, str); break; case WID_C_COMPANY_NAME: - DoCommandP(0, 0, 0, CMD_RENAME_COMPANY | CMD_MSG(STR_ERROR_CAN_T_CHANGE_COMPANY_NAME), NULL, str); + DoCommandP(0, 0, 0, CMD_RENAME_COMPANY | CMD_MSG(STR_ERROR_CAN_T_CHANGE_COMPANY_NAME), nullptr, str); break; -#ifdef ENABLE_NETWORK case WID_C_COMPANY_JOIN: NetworkClientRequestMove((CompanyID)this->window_number, str); break; -#endif /* ENABLE_NETWORK */ } } @@ -2683,7 +2687,7 @@ struct CompanyWindow : Window * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (this->window_number == _local_company) return; @@ -2742,7 +2746,7 @@ struct BuyCompanyWindow : Window { this->InitNested(window_number); } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_BC_FACE: @@ -2758,7 +2762,7 @@ struct BuyCompanyWindow : Window { } } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { switch (widget) { case WID_BC_CAPTION: @@ -2768,7 +2772,7 @@ struct BuyCompanyWindow : Window { } } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { switch (widget) { case WID_BC_FACE: { @@ -2787,7 +2791,7 @@ struct BuyCompanyWindow : Window { } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_BC_NO: @@ -2821,7 +2825,7 @@ static const NWidgetPart _nested_buy_company_widgets[] = { }; static WindowDesc _buy_company_desc( - WDP_AUTO, NULL, 0, 0, + WDP_AUTO, nullptr, 0, 0, WC_BUY_COMPANY, WC_NONE, WDF_CONSTRUCTION, _nested_buy_company_widgets, lengthof(_nested_buy_company_widgets) diff --git a/src/company_gui.h b/src/company_gui.h index c5593d15d3..d5c69f6964 100644 --- a/src/company_gui.h +++ b/src/company_gui.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/company_manager_face.h b/src/company_manager_face.h index 511f85b7d5..2f16656d56 100644 --- a/src/company_manager_face.h +++ b/src/company_manager_face.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/company_type.h b/src/company_type.h index 771e6d8b93..de2556b914 100644 --- a/src/company_type.h +++ b/src/company_type.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. @@ -17,7 +15,7 @@ /** * Enum for all companies/owners. */ -enum Owner { +enum Owner : byte { /* All companies below MAX_COMPANIES are playable * companies, above, they are special, computer controlled 'companies' */ OWNER_BEGIN = 0x00, ///< First owner @@ -45,10 +43,8 @@ static const uint MAX_HISTORY_QUARTERS = 24; ///< The maximum number /** Define basic enum properties */ template <> struct EnumPropsT : MakeEnumPropsT {}; -typedef TinyEnumT OwnerByte; typedef Owner CompanyID; -typedef OwnerByte CompanyByte; typedef uint16 CompanyMask; diff --git a/src/console.cpp b/src/console.cpp index 2cf9d96958..3c782357d2 100644 --- a/src/console.cpp +++ b/src/console.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. @@ -23,6 +21,7 @@ #include "safeguards.h" static const uint ICON_TOKEN_COUNT = 20; ///< Maximum number of tokens in one command +static const uint ICON_MAX_RECURSE = 10; ///< Maximum number of recursion /* console parser */ IConsoleCmd *_iconsole_cmds; ///< list of registered commands @@ -32,11 +31,9 @@ FILE *_iconsole_output_file; void IConsoleInit() { - _iconsole_output_file = NULL; -#ifdef ENABLE_NETWORK /* Initialize network only variables */ + _iconsole_output_file = nullptr; _redirect_console_to_client = INVALID_CLIENT_ID; _redirect_console_to_admin = INVALID_ADMIN_ID; -#endif IConsoleGUIInit(); @@ -45,14 +42,14 @@ void IConsoleInit() static void IConsoleWriteToLogFile(const char *string) { - if (_iconsole_output_file != NULL) { + if (_iconsole_output_file != nullptr) { /* if there is an console output file ... also print it there */ const char *header = GetLogPrefix(); if ((strlen(header) != 0 && fwrite(header, strlen(header), 1, _iconsole_output_file) != 1) || fwrite(string, strlen(string), 1, _iconsole_output_file) != 1 || fwrite("\n", 1, 1, _iconsole_output_file) != 1) { fclose(_iconsole_output_file); - _iconsole_output_file = NULL; + _iconsole_output_file = nullptr; IConsolePrintF(CC_DEFAULT, "cannot write to log file"); } } @@ -60,10 +57,10 @@ static void IConsoleWriteToLogFile(const char *string) bool CloseConsoleLogIfActive() { - if (_iconsole_output_file != NULL) { + if (_iconsole_output_file != nullptr) { IConsolePrintF(CC_DEFAULT, "file output complete"); fclose(_iconsole_output_file); - _iconsole_output_file = NULL; + _iconsole_output_file = nullptr; return true; } @@ -90,7 +87,6 @@ void IConsolePrint(TextColour colour_code, const char *string) assert(IsValidConsoleColour(colour_code)); char *str; -#ifdef ENABLE_NETWORK if (_redirect_console_to_client != INVALID_CLIENT_ID) { /* Redirect the string to the client */ NetworkServerSendRcon(_redirect_console_to_client, colour_code, string); @@ -101,7 +97,6 @@ void IConsolePrint(TextColour colour_code, const char *string) NetworkServerSendAdminRcon(_redirect_console_to_admin, colour_code, string); return; } -#endif /* Create a copy of the string, strip if of colours and invalid * characters and (when applicable) assign it to the console buffer */ @@ -110,9 +105,7 @@ void IConsolePrint(TextColour colour_code, const char *string) str_validate(str, str + strlen(str)); if (_network_dedicated) { -#ifdef ENABLE_NETWORK NetworkAdminConsole("console", str); -#endif /* ENABLE_NETWORK */ fprintf(stdout, "%s%s\n", GetLogPrefix(), str); fflush(stdout); IConsoleWriteToLogFile(str); @@ -209,22 +202,22 @@ bool GetArgumentInteger(uint32 *value, const char *arg) template void IConsoleAddSorted(T **base, T *item_new) { - if (*base == NULL) { + if (*base == nullptr) { *base = item_new; return; } - T *item_before = NULL; + T *item_before = nullptr; T *item = *base; /* The list is alphabetically sorted, insert the new item at the correct location */ - while (item != NULL) { + while (item != nullptr) { if (strcmp(item->name, item_new->name) > 0) break; // insert here item_before = item; item = item->next; } - if (item_before == NULL) { + if (item_before == nullptr) { *base = item_new; } else { item_before->next = item_new; @@ -257,7 +250,7 @@ void IConsoleCmdRegister(const char *name, IConsoleCmdProc *proc, IConsoleHook * { IConsoleCmd *item_new = MallocT(1); item_new->name = RemoveUnderscores(stredup(name)); - item_new->next = NULL; + item_new->next = nullptr; item_new->proc = proc; item_new->hook = hook; @@ -267,16 +260,16 @@ void IConsoleCmdRegister(const char *name, IConsoleCmdProc *proc, IConsoleHook * /** * Find the command pointed to by its string * @param name command to be found - * @return return Cmdstruct of the found command, or NULL on failure + * @return return Cmdstruct of the found command, or nullptr on failure */ IConsoleCmd *IConsoleCmdGet(const char *name) { IConsoleCmd *item; - for (item = _iconsole_cmds; item != NULL; item = item->next) { + for (item = _iconsole_cmds; item != nullptr; item = item->next) { if (strcmp(item->name, name) == 0) return item; } - return NULL; + return nullptr; } /** @@ -286,7 +279,7 @@ IConsoleCmd *IConsoleCmdGet(const char *name) */ void IConsoleAliasRegister(const char *name, const char *cmd) { - if (IConsoleAliasGet(name) != NULL) { + if (IConsoleAliasGet(name) != nullptr) { IConsoleError("an alias with this name already exists; insertion aborted"); return; } @@ -295,7 +288,7 @@ void IConsoleAliasRegister(const char *name, const char *cmd) char *cmd_aliased = stredup(cmd); IConsoleAlias *item_new = MallocT(1); - item_new->next = NULL; + item_new->next = nullptr; item_new->cmdline = cmd_aliased; item_new->name = new_alias; @@ -305,17 +298,17 @@ void IConsoleAliasRegister(const char *name, const char *cmd) /** * Find the alias pointed to by its string * @param name alias to be found - * @return return Aliasstruct of the found alias, or NULL on failure + * @return return Aliasstruct of the found alias, or nullptr on failure */ IConsoleAlias *IConsoleAliasGet(const char *name) { IConsoleAlias *item; - for (item = _iconsole_aliases; item != NULL; item = item->next) { + for (item = _iconsole_aliases; item != nullptr; item = item->next) { if (strcmp(item->name, name) == 0) return item; } - return NULL; + return nullptr; } /** * An alias is just another name for a command, or for more commands @@ -324,13 +317,18 @@ IConsoleAlias *IConsoleAliasGet(const char *name) * @param tokencount the number of parameters passed * @param *tokens are the parameters given to the original command (0 is the first param) */ -static void IConsoleAliasExec(const IConsoleAlias *alias, byte tokencount, char *tokens[ICON_TOKEN_COUNT]) +static void IConsoleAliasExec(const IConsoleAlias *alias, byte tokencount, char *tokens[ICON_TOKEN_COUNT], const uint recurse_count) { char alias_buffer[ICON_MAX_STREAMSIZE] = { '\0' }; char *alias_stream = alias_buffer; DEBUG(console, 6, "Requested command is an alias; parsing..."); + if (recurse_count > ICON_MAX_RECURSE) { + IConsoleError("Too many alias expansions, recursion limit reached. Aborting"); + return; + } + for (const char *cmdptr = alias->cmdline; *cmdptr != '\0'; cmdptr++) { switch (*cmdptr) { case '\'': // ' will double for "" @@ -338,7 +336,7 @@ static void IConsoleAliasExec(const IConsoleAlias *alias, byte tokencount, char break; case ';': // Cmd separator; execute previous and start new command - IConsoleCmdExec(alias_buffer); + IConsoleCmdExec(alias_buffer, recurse_count); alias_stream = alias_buffer; *alias_stream = '\0'; // Make sure the new command is terminated. @@ -398,7 +396,7 @@ static void IConsoleAliasExec(const IConsoleAlias *alias, byte tokencount, char } } - IConsoleCmdExec(alias_buffer); + IConsoleCmdExec(alias_buffer, recurse_count); } /** @@ -406,7 +404,7 @@ static void IConsoleAliasExec(const IConsoleAlias *alias, byte tokencount, char * individual tokens (separated by spaces), then execute it if possible * @param cmdstr string to be parsed and executed */ -void IConsoleCmdExec(const char *cmdstr) +void IConsoleCmdExec(const char *cmdstr, const uint recurse_count) { const char *cmdptr; char *tokens[ICON_TOKEN_COUNT], tokenstream[ICON_MAX_STREAMSIZE]; @@ -484,7 +482,7 @@ void IConsoleCmdExec(const char *cmdstr) } } - for (uint i = 0; i < lengthof(tokens) && tokens[i] != NULL; i++) { + for (uint i = 0; i < lengthof(tokens) && tokens[i] != nullptr; i++) { DEBUG(console, 8, "Token %d is: '%s'", i, tokens[i]); } @@ -495,12 +493,12 @@ void IConsoleCmdExec(const char *cmdstr) */ RemoveUnderscores(tokens[0]); IConsoleCmd *cmd = IConsoleCmdGet(tokens[0]); - if (cmd != NULL) { - ConsoleHookResult chr = (cmd->hook == NULL ? CHR_ALLOW : cmd->hook(true)); + if (cmd != nullptr) { + ConsoleHookResult chr = (cmd->hook == nullptr ? CHR_ALLOW : cmd->hook(true)); switch (chr) { case CHR_ALLOW: if (!cmd->proc(t_index, tokens)) { // index started with 0 - cmd->proc(0, NULL); // if command failed, give help + cmd->proc(0, nullptr); // if command failed, give help } return; @@ -511,8 +509,8 @@ void IConsoleCmdExec(const char *cmdstr) t_index--; IConsoleAlias *alias = IConsoleAliasGet(tokens[0]); - if (alias != NULL) { - IConsoleAliasExec(alias, t_index, &tokens[1]); + if (alias != nullptr) { + IConsoleAliasExec(alias, t_index, &tokens[1], recurse_count + 1); return; } diff --git a/src/console_cmds.cpp b/src/console_cmds.cpp index 3edf53b433..016027d356 100644 --- a/src/console_cmds.cpp +++ b/src/console_cmds.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. @@ -35,10 +33,12 @@ #include "ai/ai.hpp" #include "ai/ai_config.hpp" #include "newgrf.h" +#include "newgrf_profiling.h" #include "console_func.h" #include "engine_base.h" #include "game/game.hpp" #include "table/strings.h" +#include #include "safeguards.h" @@ -86,8 +86,6 @@ static ConsoleFileList _console_file_list; ///< File storage cache for the conso * command hooks ****************/ -#ifdef ENABLE_NETWORK - /** * Check network availability and inform in console about failure of detection. * @return Network availability. @@ -159,10 +157,6 @@ DEF_CONSOLE_HOOK(ConHookNoNetwork) return CHR_ALLOW; } -#else -# define ConHookNoNetwork NULL -#endif /* ENABLE_NETWORK */ - DEF_CONSOLE_HOOK(ConHookNewGRFDeveloperTool) { if (_settings_client.gui.newgrf_developer_tools) { @@ -170,11 +164,7 @@ DEF_CONSOLE_HOOK(ConHookNewGRFDeveloperTool) if (echo) IConsoleError("This command is only available in game and editor."); return CHR_DISALLOW; } -#ifdef ENABLE_NETWORK return ConHookNoNetwork(echo); -#else - return CHR_ALLOW; -#endif } return CHR_HIDE; } @@ -258,7 +248,7 @@ DEF_CONSOLE_CMD(ConResetTile) * Scroll to a tile on the map. * param x tile number or tile x coordinate. * param y optional y coordinate. - * @note When only one argument is given it is intepreted as the tile number. + * @note When only one argument is given it is interpreted as the tile number. * When two arguments are given, they are interpreted as the tile's x * and y coordinates. * @return True when either console help was shown or a proper amount of parameters given. @@ -359,7 +349,7 @@ DEF_CONSOLE_CMD(ConLoad) const char *file = argv[1]; _console_file_list.ValidateFileList(); const FiosItem *item = _console_file_list.FindItem(file); - if (item != NULL) { + if (item != nullptr) { if (GetAbstractFileType(item->type) == FT_SAVEGAME) { _switch_mode = SM_LOAD_GAME; _file_to_saveload.SetMode(item->type); @@ -388,7 +378,7 @@ DEF_CONSOLE_CMD(ConRemove) const char *file = argv[1]; _console_file_list.ValidateFileList(); const FiosItem *item = _console_file_list.FindItem(file); - if (item != NULL) { + if (item != nullptr) { if (!FiosDelete(item->name)) { IConsolePrintF(CC_ERROR, "%s: Failed to delete file", file); } @@ -444,7 +434,7 @@ DEF_CONSOLE_CMD(ConChangeDirectory) const char *file = argv[1]; _console_file_list.ValidateFileList(true); const FiosItem *item = _console_file_list.FindItem(file); - if (item != NULL) { + if (item != nullptr) { switch (item->type) { case FIOS_TYPE_DIR: case FIOS_TYPE_DRIVE: case FIOS_TYPE_PARENT: FiosBrowseTo(item); @@ -472,7 +462,7 @@ DEF_CONSOLE_CMD(ConPrintWorkingDirectory) _console_file_list.ValidateFileList(true); _console_file_list.InvalidateFileList(); - FiosGetDescText(&path, NULL); + FiosGetDescText(&path, nullptr); IConsolePrint(CC_DEFAULT, path); return true; } @@ -493,13 +483,12 @@ DEF_CONSOLE_CMD(ConClearBuffer) /********************************** * Network Core Console Commands **********************************/ -#ifdef ENABLE_NETWORK -static bool ConKickOrBan(const char *argv, bool ban) +static bool ConKickOrBan(const char *argv, bool ban, const char *reason) { uint n; - if (strchr(argv, '.') == NULL && strchr(argv, ':') == NULL) { // banning with ID + if (strchr(argv, '.') == nullptr && strchr(argv, ':') == nullptr) { // banning with ID ClientID client_id = (ClientID)atoi(argv); /* Don't kill the server, or the client doing the rcon. The latter can't be kicked because @@ -512,21 +501,21 @@ static bool ConKickOrBan(const char *argv, bool ban) } NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id); - if (ci == NULL) { + if (ci == nullptr) { IConsoleError("Invalid client"); return true; } if (!ban) { /* Kick only this client, not all clients with that IP */ - NetworkServerKickClient(client_id); + NetworkServerKickClient(client_id, reason); return true; } /* When banning, kick+ban all clients with that IP */ - n = NetworkServerKickOrBanIP(client_id, ban); + n = NetworkServerKickOrBanIP(client_id, ban, reason); } else { - n = NetworkServerKickOrBanIP(argv, ban); + n = NetworkServerKickOrBanIP(argv, ban, reason); } if (n == 0) { @@ -541,28 +530,48 @@ static bool ConKickOrBan(const char *argv, bool ban) DEF_CONSOLE_CMD(ConKick) { if (argc == 0) { - IConsoleHelp("Kick a client from a network game. Usage: 'kick '"); + IConsoleHelp("Kick a client from a network game. Usage: 'kick []'"); IConsoleHelp("For client-id's, see the command 'clients'"); return true; } - if (argc != 2) return false; + if (argc != 2 && argc != 3) return false; - return ConKickOrBan(argv[1], false); + /* No reason supplied for kicking */ + if (argc == 2) return ConKickOrBan(argv[1], false, nullptr); + + /* Reason for kicking supplied */ + size_t kick_message_length = strlen(argv[2]); + if (kick_message_length >= 255) { + IConsolePrintF(CC_ERROR, "ERROR: Maximum kick message length is 254 characters. You entered %d characters.", kick_message_length); + return false; + } else { + return ConKickOrBan(argv[1], false, argv[2]); + } } DEF_CONSOLE_CMD(ConBan) { if (argc == 0) { - IConsoleHelp("Ban a client from a network game. Usage: 'ban '"); + IConsoleHelp("Ban a client from a network game. Usage: 'ban []'"); IConsoleHelp("For client-id's, see the command 'clients'"); IConsoleHelp("If the client is no longer online, you can still ban his/her IP"); return true; } - if (argc != 2) return false; + if (argc != 2 && argc != 3) return false; - return ConKickOrBan(argv[1], true); + /* No reason supplied for kicking */ + if (argc == 2) return ConKickOrBan(argv[1], true, nullptr); + + /* Reason for kicking supplied */ + size_t kick_message_length = strlen(argv[2]); + if (kick_message_length >= 255) { + IConsolePrintF(CC_ERROR, "ERROR: Maximum kick message length is 254 characters. You entered %d characters.", kick_message_length); + return false; + } else { + return ConKickOrBan(argv[1], true, argv[2]); + } } DEF_CONSOLE_CMD(ConUnBan) @@ -577,21 +586,20 @@ DEF_CONSOLE_CMD(ConUnBan) /* Try by IP. */ uint index; - for (index = 0; index < _network_ban_list.Length(); index++) { - if (strcmp(_network_ban_list[index], argv[1]) == 0) break; + for (index = 0; index < _network_ban_list.size(); index++) { + if (_network_ban_list[index] == argv[1]) break; } /* Try by index. */ - if (index >= _network_ban_list.Length()) { + if (index >= _network_ban_list.size()) { index = atoi(argv[1]) - 1U; // let it wrap } - if (index < _network_ban_list.Length()) { + if (index < _network_ban_list.size()) { char msg[64]; - seprintf(msg, lastof(msg), "Unbanned %s", _network_ban_list[index]); + seprintf(msg, lastof(msg), "Unbanned %s", _network_ban_list[index].c_str()); IConsolePrint(CC_DEFAULT, msg); - free(_network_ban_list[index]); - _network_ban_list.Erase(_network_ban_list.Get(index)); + _network_ban_list.erase(_network_ban_list.begin() + index); } else { IConsolePrint(CC_DEFAULT, "Invalid list index or IP not in ban-list."); IConsolePrint(CC_DEFAULT, "For a list of banned IP's, see the command 'banlist'"); @@ -610,8 +618,8 @@ DEF_CONSOLE_CMD(ConBanList) IConsolePrint(CC_DEFAULT, "Banlist: "); uint i = 1; - for (char **iter = _network_ban_list.Begin(); iter != _network_ban_list.End(); iter++, i++) { - IConsolePrintF(CC_DEFAULT, " %d) %s", i, *iter); + for (const auto &entry : _network_ban_list) { + IConsolePrintF(CC_DEFAULT, " %d) %s", i, entry.c_str()); } return true; @@ -714,7 +722,7 @@ DEF_CONSOLE_CMD(ConClientNickChange) return true; } - if (NetworkClientInfo::GetByClientID(client_id) == NULL) { + if (NetworkClientInfo::GetByClientID(client_id) == nullptr) { IConsoleError("Invalid client"); return true; } @@ -785,7 +793,7 @@ DEF_CONSOLE_CMD(ConMoveClient) CompanyID company_id = (CompanyID)(atoi(argv[2]) <= MAX_COMPANIES ? atoi(argv[2]) - 1 : atoi(argv[2])); /* check the client exists */ - if (ci == NULL) { + if (ci == nullptr) { IConsoleError("Invalid client-id, check the command 'clients' for valid client-id's."); return true; } @@ -850,7 +858,7 @@ DEF_CONSOLE_CMD(ConResetCompany) } /* It is safe to remove this company */ - DoCommandP(0, CCA_DELETE | index << 16, CRR_MANUAL, CMD_COMPANY_CTRL); + DoCommandP(0, CCA_DELETE | index << 16 | CRR_MANUAL << 24, 0, CMD_COMPANY_CTRL); IConsolePrint(CC_DEFAULT, "Company deleted."); return true; @@ -884,8 +892,7 @@ DEF_CONSOLE_CMD(ConNetworkReconnect) default: /* From a user pov 0 is a new company, internally it's different and all * companies are offset by one to ease up on users (eg companies 1-8 not 0-7) */ - playas--; - if (playas < COMPANY_FIRST || playas >= MAX_COMPANIES) return false; + if (playas < COMPANY_FIRST + 1 || playas > MAX_COMPANIES + 1) return false; break; } @@ -913,8 +920,8 @@ DEF_CONSOLE_CMD(ConNetworkConnect) if (argc < 2) return false; if (_networking) NetworkDisconnect(); // we are in network-mode, first close it! - const char *port = NULL; - const char *company = NULL; + const char *port = nullptr; + const char *company = nullptr; char *ip = argv[1]; /* Default settings: default port and new company */ uint16 rport = NETWORK_DEFAULT_PORT; @@ -923,7 +930,7 @@ DEF_CONSOLE_CMD(ConNetworkConnect) ParseConnectionString(&company, &port, ip); IConsolePrintF(CC_DEFAULT, "Connecting to %s...", ip); - if (company != NULL) { + if (company != nullptr) { join_as = (CompanyID)atoi(company); IConsolePrintF(CC_DEFAULT, " company-no: %d", join_as); @@ -934,7 +941,7 @@ DEF_CONSOLE_CMD(ConNetworkConnect) join_as--; } } - if (port != NULL) { + if (port != nullptr) { rport = atoi(port); IConsolePrintF(CC_DEFAULT, " port: %s", port); } @@ -944,8 +951,6 @@ DEF_CONSOLE_CMD(ConNetworkConnect) return true; } -#endif /* ENABLE_NETWORK */ - /********************************* * script file console commands *********************************/ @@ -961,7 +966,7 @@ DEF_CONSOLE_CMD(ConExec) FILE *script_file = FioFOpenFile(argv[1], "r", BASE_DIR); - if (script_file == NULL) { + if (script_file == nullptr) { if (argc == 2 || atoi(argv[2]) != 0) IConsoleError("script file not found"); return true; } @@ -969,7 +974,7 @@ DEF_CONSOLE_CMD(ConExec) _script_running = true; char cmdline[ICON_CMDLN_SIZE]; - while (_script_running && fgets(cmdline, sizeof(cmdline), script_file) != NULL) { + while (_script_running && fgets(cmdline, sizeof(cmdline), script_file) != nullptr) { /* Remove newline characters from the executing script */ for (char *cmdptr = cmdline; *cmdptr != '\0'; cmdptr++) { if (*cmdptr == '\n' || *cmdptr == '\r') { @@ -1020,7 +1025,7 @@ DEF_CONSOLE_CMD(ConScript) IConsolePrintF(CC_DEFAULT, "file output started to: %s", argv[1]); _iconsole_output_file = fopen(argv[1], "ab"); - if (_iconsole_output_file == NULL) IConsoleError("could not open file"); + if (_iconsole_output_file == nullptr) IConsoleError("could not open file"); } return true; @@ -1059,7 +1064,7 @@ DEF_CONSOLE_CMD(ConNewGame) return true; } - StartNewGameWithoutGUI((argc == 2) ? strtoul(argv[1], NULL, 10) : GENERATE_NEW_SEED); + StartNewGameWithoutGUI((argc == 2) ? strtoul(argv[1], nullptr, 10) : GENERATE_NEW_SEED); return true; } @@ -1172,9 +1177,8 @@ DEF_CONSOLE_CMD(ConStartAI) } int n = 0; - Company *c; /* Find the next free slot */ - FOR_ALL_COMPANIES(c) { + for (const Company *c : Company::Iterate()) { if (c->index != n) break; n++; } @@ -1227,7 +1231,7 @@ DEF_CONSOLE_CMD(ConReloadAI) } /* First kill the company of the AI, then start a new one. This should start the current AI again */ - DoCommandP(0, CCA_DELETE | company_id << 16, CRR_MANUAL, CMD_COMPANY_CTRL); + DoCommandP(0, CCA_DELETE | company_id << 16 | CRR_MANUAL << 24, 0,CMD_COMPANY_CTRL); DoCommandP(0, CCA_NEW_AI | company_id << 16, 0, CMD_COMPANY_CTRL); IConsolePrint(CC_DEFAULT, "AI reloaded."); @@ -1264,7 +1268,7 @@ DEF_CONSOLE_CMD(ConStopAI) } /* Now kill the company of the AI. */ - DoCommandP(0, CCA_DELETE | company_id << 16, CRR_MANUAL, CMD_COMPANY_CTRL); + DoCommandP(0, CCA_DELETE | company_id << 16 | CRR_MANUAL << 24, 0, CMD_COMPANY_CTRL); IConsolePrint(CC_DEFAULT, "AI stopped, company deleted."); return true; @@ -1311,7 +1315,7 @@ DEF_CONSOLE_CMD(ConRescanNewGRF) return true; } - ScanNewGRFFiles(NULL); + ScanNewGRFFiles(nullptr); return true; } @@ -1331,13 +1335,27 @@ DEF_CONSOLE_CMD(ConGetSeed) DEF_CONSOLE_CMD(ConGetDate) { if (argc == 0) { - IConsoleHelp("Returns the current date (day-month-year) of the game. Usage: 'getdate'"); + IConsoleHelp("Returns the current date (year-month-day) of the game. Usage: 'getdate'"); return true; } YearMonthDay ymd; ConvertDateToYMD(_date, &ymd); - IConsolePrintF(CC_DEFAULT, "Date: %d-%d-%d", ymd.day, ymd.month + 1, ymd.year); + IConsolePrintF(CC_DEFAULT, "Date: %04d-%02d-%02d", ymd.year, ymd.month + 1, ymd.day); + return true; +} + +DEF_CONSOLE_CMD(ConGetSysDate) +{ + if (argc == 0) { + IConsoleHelp("Returns the current date (year-month-day) of your system. Usage: 'getsysdate'"); + return true; + } + + time_t t; + time(&t); + auto timeinfo = localtime(&t); + IConsolePrintF(CC_DEFAULT, "System Date: %04d-%02d-%02d %02d:%02d:%02d", timeinfo->tm_year + 1900, timeinfo->tm_mon + 1, timeinfo->tm_mday, timeinfo->tm_hour, timeinfo->tm_min, timeinfo->tm_sec); return true; } @@ -1354,7 +1372,7 @@ DEF_CONSOLE_CMD(ConAlias) if (argc < 3) return false; alias = IConsoleAliasGet(argv[1]); - if (alias == NULL) { + if (alias == nullptr) { IConsoleAliasRegister(argv[1], argv[2]); } else { free(alias->cmdline); @@ -1366,17 +1384,18 @@ DEF_CONSOLE_CMD(ConAlias) DEF_CONSOLE_CMD(ConScreenShot) { if (argc == 0) { - IConsoleHelp("Create a screenshot of the game. Usage: 'screenshot [big | giant | no_con] [file name]'"); + IConsoleHelp("Create a screenshot of the game. Usage: 'screenshot [big | giant | no_con | minimap] [file name]'"); IConsoleHelp("'big' makes a zoomed-in screenshot of the visible area, 'giant' makes a screenshot of the " "whole map, 'no_con' hides the console to create the screenshot. 'big' or 'giant' " - "screenshots are always drawn without console"); + "screenshots are always drawn without console. " + "'minimap' makes a top-viewed minimap screenshot of whole world which represents one tile by one pixel."); return true; } if (argc > 3) return false; ScreenshotType type = SC_VIEWPORT; - const char *name = NULL; + const char *name = nullptr; if (argc > 1) { if (strcmp(argv[1], "big") == 0) { @@ -1387,6 +1406,10 @@ DEF_CONSOLE_CMD(ConScreenShot) /* screenshot giant [filename] */ type = SC_WORLD; if (argc > 2) name = argv[2]; + } else if (strcmp(argv[1], "minimap") == 0) { + /* screenshot minimap [filename] */ + type = SC_MINIMAP; + if (argc > 2) name = argv[2]; } else if (strcmp(argv[1], "no_con") == 0) { /* screenshot no_con [filename] */ IConsoleClose(); @@ -1414,7 +1437,7 @@ DEF_CONSOLE_CMD(ConInfoCmd) if (argc < 2) return false; const IConsoleCmd *cmd = IConsoleCmdGet(argv[1]); - if (cmd == NULL) { + if (cmd == nullptr) { IConsoleError("the given command was not found"); return true; } @@ -1422,7 +1445,7 @@ DEF_CONSOLE_CMD(ConInfoCmd) IConsolePrintF(CC_DEFAULT, "command name: %s", cmd->name); IConsolePrintF(CC_DEFAULT, "command proc: %p", cmd->proc); - if (cmd->hook != NULL) IConsoleWarning("command is hooked"); + if (cmd->hook != nullptr) IConsoleWarning("command is hooked"); return true; } @@ -1480,16 +1503,16 @@ DEF_CONSOLE_CMD(ConHelp) RemoveUnderscores(argv[1]); cmd = IConsoleCmdGet(argv[1]); - if (cmd != NULL) { - cmd->proc(0, NULL); + if (cmd != nullptr) { + cmd->proc(0, nullptr); return true; } alias = IConsoleAliasGet(argv[1]); - if (alias != NULL) { + if (alias != nullptr) { cmd = IConsoleCmdGet(alias->cmdline); - if (cmd != NULL) { - cmd->proc(0, NULL); + if (cmd != nullptr) { + cmd->proc(0, nullptr); return true; } IConsolePrintF(CC_ERROR, "ERROR: alias is of special type, please see its execution-line: '%s'", alias->cmdline); @@ -1519,9 +1542,9 @@ DEF_CONSOLE_CMD(ConListCommands) return true; } - for (const IConsoleCmd *cmd = _iconsole_cmds; cmd != NULL; cmd = cmd->next) { - if (argv[1] == NULL || strstr(cmd->name, argv[1]) != NULL) { - if (cmd->hook == NULL || cmd->hook(false) != CHR_HIDE) IConsolePrintF(CC_DEFAULT, "%s", cmd->name); + for (const IConsoleCmd *cmd = _iconsole_cmds; cmd != nullptr; cmd = cmd->next) { + if (argv[1] == nullptr || strstr(cmd->name, argv[1]) != nullptr) { + if (cmd->hook == nullptr || cmd->hook(false) != CHR_HIDE) IConsolePrintF(CC_DEFAULT, "%s", cmd->name); } } @@ -1535,8 +1558,8 @@ DEF_CONSOLE_CMD(ConListAliases) return true; } - for (const IConsoleAlias *alias = _iconsole_aliases; alias != NULL; alias = alias->next) { - if (argv[1] == NULL || strstr(alias->name, argv[1]) != NULL) { + for (const IConsoleAlias *alias = _iconsole_aliases; alias != nullptr; alias = alias->next) { + if (argv[1] == nullptr || strstr(alias->name, argv[1]) != nullptr) { IConsolePrintF(CC_DEFAULT, "%s => %s", alias->name, alias->cmdline); } } @@ -1551,8 +1574,7 @@ DEF_CONSOLE_CMD(ConCompanies) return true; } - Company *c; - FOR_ALL_COMPANIES(c) { + for (const Company *c : Company::Iterate()) { /* Grab the company name */ char company_name[512]; SetDParam(0, c->index); @@ -1561,12 +1583,9 @@ DEF_CONSOLE_CMD(ConCompanies) const char *password_state = ""; if (c->is_ai) { password_state = "AI"; - } -#ifdef ENABLE_NETWORK - else if (_network_server) { + } else if (_network_server) { password_state = StrEmpty(_network_company_states[c->index].password) ? "unprotected" : "protected"; } -#endif char colour[512]; GetString(colour, STR_COLOUR_DARK_BLUE + _company_colours[c->index], lastof(colour)); @@ -1583,8 +1602,6 @@ DEF_CONSOLE_CMD(ConCompanies) return true; } -#ifdef ENABLE_NETWORK - DEF_CONSOLE_CMD(ConSay) { if (argc == 0) { @@ -1750,8 +1767,8 @@ static void OutputContentState(const ContentInfo *const ci) DEF_CONSOLE_CMD(ConContent) { - static ContentCallback *cb = NULL; - if (cb == NULL) { + static ContentCallback *cb = nullptr; + if (cb == nullptr) { cb = new ConsoleContentCallback(); _network_content_client.AddCallback(cb); } @@ -1809,7 +1826,7 @@ DEF_CONSOLE_CMD(ConContent) if (strcasecmp(argv[1], "state") == 0) { IConsolePrintF(CC_WHITE, "id, type, state, name"); for (ConstContentIterator iter = _network_content_client.Begin(); iter != _network_content_client.End(); iter++) { - if (argc > 2 && strcasestr((*iter)->name, argv[2]) == NULL) continue; + if (argc > 2 && strcasestr((*iter)->name, argv[2]) == nullptr) continue; OutputContentState(*iter); } return true; @@ -1826,7 +1843,6 @@ DEF_CONSOLE_CMD(ConContent) return false; } #endif /* defined(WITH_ZLIB) */ -#endif /* ENABLE_NETWORK */ DEF_CONSOLE_CMD(ConSetting) { @@ -1875,7 +1891,7 @@ DEF_CONSOLE_CMD(ConListSettings) if (argc > 2) return false; - IConsoleListSettings((argc == 2) ? argv[1] : NULL); + IConsoleListSettings((argc == 2) ? argv[1] : nullptr); return true; } @@ -1896,6 +1912,135 @@ DEF_CONSOLE_CMD(ConNewGRFReload) return true; } +DEF_CONSOLE_CMD(ConNewGRFProfile) +{ + if (argc == 0) { + IConsoleHelp("Collect performance data about NewGRF sprite requests and callbacks. Sub-commands can be abbreviated."); + IConsoleHelp("Usage: newgrf_profile [list]"); + IConsoleHelp(" List all NewGRFs that can be profiled, and their status."); + IConsoleHelp("Usage: newgrf_profile select ..."); + IConsoleHelp(" Select one or more GRFs for profiling."); + IConsoleHelp("Usage: newgrf_profile unselect ..."); + IConsoleHelp(" Unselect one or more GRFs from profiling. Use the keyword \"all\" instead of a GRF number to unselect all. Removing an active profiler aborts data collection."); + IConsoleHelp("Usage: newgrf_profile start []"); + IConsoleHelp(" Begin profiling all selected GRFs. If a number of days is provided, profiling stops after that many in-game days."); + IConsoleHelp("Usage: newgrf_profile stop"); + IConsoleHelp(" End profiling and write the collected data to CSV files."); + IConsoleHelp("Usage: newgrf_profile abort"); + IConsoleHelp(" End profiling and discard all collected data."); + return true; + } + + extern const std::vector &GetAllGRFFiles(); + const std::vector &files = GetAllGRFFiles(); + + /* "list" sub-command */ + if (argc == 1 || strncasecmp(argv[1], "lis", 3) == 0) { + IConsolePrint(CC_INFO, "Loaded GRF files:"); + int i = 1; + for (GRFFile *grf : files) { + auto profiler = std::find_if(_newgrf_profilers.begin(), _newgrf_profilers.end(), [&](NewGRFProfiler &pr) { return pr.grffile == grf; }); + bool selected = profiler != _newgrf_profilers.end(); + bool active = selected && profiler->active; + TextColour tc = active ? TC_LIGHT_BLUE : selected ? TC_GREEN : CC_INFO; + const char *statustext = active ? " (active)" : selected ? " (selected)" : ""; + IConsolePrintF(tc, "%d: [%08X] %s%s", i, BSWAP32(grf->grfid), grf->filename, statustext); + i++; + } + return true; + } + + /* "select" sub-command */ + if (strncasecmp(argv[1], "sel", 3) == 0 && argc >= 3) { + for (size_t argnum = 2; argnum < argc; ++argnum) { + int grfnum = atoi(argv[argnum]); + if (grfnum < 1 || grfnum > (int)files.size()) { // safe cast, files.size() should not be larger than a few hundred in the most extreme cases + IConsolePrintF(CC_WARNING, "GRF number %d out of range, not added.", grfnum); + continue; + } + GRFFile *grf = files[grfnum - 1]; + if (std::any_of(_newgrf_profilers.begin(), _newgrf_profilers.end(), [&](NewGRFProfiler &pr) { return pr.grffile == grf; })) { + IConsolePrintF(CC_WARNING, "GRF number %d [%08X] is already selected for profiling.", grfnum, BSWAP32(grf->grfid)); + continue; + } + _newgrf_profilers.emplace_back(grf); + } + return true; + } + + /* "unselect" sub-command */ + if (strncasecmp(argv[1], "uns", 3) == 0 && argc >= 3) { + for (size_t argnum = 2; argnum < argc; ++argnum) { + if (strcasecmp(argv[argnum], "all") == 0) { + _newgrf_profilers.clear(); + break; + } + int grfnum = atoi(argv[argnum]); + if (grfnum < 1 || grfnum > (int)files.size()) { + IConsolePrintF(CC_WARNING, "GRF number %d out of range, not removing.", grfnum); + continue; + } + GRFFile *grf = files[grfnum - 1]; + auto pos = std::find_if(_newgrf_profilers.begin(), _newgrf_profilers.end(), [&](NewGRFProfiler &pr) { return pr.grffile == grf; }); + if (pos != _newgrf_profilers.end()) _newgrf_profilers.erase(pos); + } + return true; + } + + /* "start" sub-command */ + if (strncasecmp(argv[1], "sta", 3) == 0) { + std::string grfids; + size_t started = 0; + for (NewGRFProfiler &pr : _newgrf_profilers) { + if (!pr.active) { + pr.Start(); + started++; + + if (!grfids.empty()) grfids += ", "; + char grfidstr[12]{ 0 }; + seprintf(grfidstr, lastof(grfidstr), "[%08X]", BSWAP32(pr.grffile->grfid)); + grfids += grfidstr; + } + } + if (started > 0) { + IConsolePrintF(CC_DEBUG, "Started profiling for GRFID%s %s", (started > 1) ? "s" : "", grfids.c_str()); + if (argc >= 3) { + int days = max(atoi(argv[2]), 1); + _newgrf_profile_end_date = _date + days; + + char datestrbuf[32]{ 0 }; + SetDParam(0, _newgrf_profile_end_date); + GetString(datestrbuf, STR_JUST_DATE_ISO, lastof(datestrbuf)); + IConsolePrintF(CC_DEBUG, "Profiling will automatically stop on game date %s", datestrbuf); + } else { + _newgrf_profile_end_date = MAX_DAY; + } + } else if (_newgrf_profilers.empty()) { + IConsolePrintF(CC_WARNING, "No GRFs selected for profiling, did not start."); + } else { + IConsolePrintF(CC_WARNING, "Did not start profiling for any GRFs, all selected GRFs are already profiling."); + } + return true; + } + + /* "stop" sub-command */ + if (strncasecmp(argv[1], "sto", 3) == 0) { + NewGRFProfiler::FinishAll(); + return true; + } + + /* "abort" sub-command */ + if (strncasecmp(argv[1], "abo", 3) == 0) { + for (NewGRFProfiler &pr : _newgrf_profilers) { + pr.Abort(); + } + _newgrf_profile_end_date = MAX_DAY; + return true; + } + + return false; +} + #ifdef _DEBUG /****************** * debug commands @@ -1960,6 +2105,7 @@ void IConsoleStdLibRegister() IConsoleCmdRegister("restart", ConRestart); IConsoleCmdRegister("getseed", ConGetSeed); IConsoleCmdRegister("getdate", ConGetDate); + IConsoleCmdRegister("getsysdate", ConGetSysDate); IConsoleCmdRegister("quit", ConExit); IConsoleCmdRegister("resetengines", ConResetEngines, ConHookNoNetwork); IConsoleCmdRegister("reset_enginepool", ConResetEnginePool, ConHookNoNetwork); @@ -2008,7 +2154,7 @@ void IConsoleStdLibRegister() IConsoleAliasRegister("players", "companies"); /* networking functions */ -#ifdef ENABLE_NETWORK + /* Content downloading is only available with ZLIB */ #if defined(WITH_ZLIB) IConsoleCmdRegister("content", ConContent); @@ -2066,7 +2212,6 @@ void IConsoleStdLibRegister() IConsoleAliasRegister("restart_game_year", "setting restart_game_year %+"); IConsoleAliasRegister("min_players", "setting min_active_clients %+"); IConsoleAliasRegister("reload_cfg", "setting reload_cfg %+"); -#endif /* ENABLE_NETWORK */ /* debugging stuff */ #ifdef _DEBUG @@ -2077,4 +2222,5 @@ void IConsoleStdLibRegister() /* NewGRF development stuff */ IConsoleCmdRegister("reload_newgrfs", ConNewGRFReload, ConHookNewGRFDeveloperTool); + IConsoleCmdRegister("newgrf_profile", ConNewGRFProfile, ConHookNewGRFDeveloperTool); } diff --git a/src/console_func.h b/src/console_func.h index 6f58bdf544..6d634a4553 100644 --- a/src/console_func.h +++ b/src/console_func.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. @@ -30,7 +28,7 @@ void IConsoleWarning(const char *string); void IConsoleError(const char *string); /* Parser */ -void IConsoleCmdExec(const char *cmdstr); +void IConsoleCmdExec(const char *cmdstr, const uint recurse_count = 0); bool IsValidConsoleColour(TextColour c); diff --git a/src/console_gui.cpp b/src/console_gui.cpp index ed84f6fe09..02e5fac376 100644 --- a/src/console_gui.cpp +++ b/src/console_gui.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. @@ -83,7 +81,7 @@ struct IConsoleLine { static const IConsoleLine *Get(uint index) { const IConsoleLine *item = IConsoleLine::front; - while (index != 0 && item != NULL) { + while (index != 0 && item != nullptr) { index--; item = item->previous; } @@ -101,14 +99,14 @@ struct IConsoleLine { static bool Truncate() { IConsoleLine *cur = IConsoleLine::front; - if (cur == NULL) return false; + if (cur == nullptr) return false; int count = 1; - for (IConsoleLine *item = cur->previous; item != NULL; count++, cur = item, item = item->previous) { + 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 = NULL; + cur->previous = nullptr; return true; } @@ -124,12 +122,12 @@ struct IConsoleLine { static void Reset() { delete IConsoleLine::front; - IConsoleLine::front = NULL; + IConsoleLine::front = nullptr; IConsoleLine::size = 0; } }; -/* static */ IConsoleLine *IConsoleLine::front = NULL; +/* static */ IConsoleLine *IConsoleLine::front = nullptr; /* static */ int IConsoleLine::size = 0; @@ -167,7 +165,7 @@ static const struct NWidgetPart _nested_console_window_widgets[] = { }; static WindowDesc _console_window_desc( - WDP_MANUAL, NULL, 0, 0, + WDP_MANUAL, nullptr, 0, 0, WC_CONSOLE, WC_NONE, 0, _nested_console_window_widgets, lengthof(_nested_console_window_widgets) @@ -206,13 +204,13 @@ struct IConsoleWindow : Window this->SetDirty(); } - virtual void OnPaint() + void OnPaint() override { const int right = this->width - 5; 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 != NULL; print = print->previous) { + 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; if (ypos < 0) break; @@ -234,7 +232,7 @@ struct IConsoleWindow : Window } } - virtual void OnQueryTextFinished(char *str) + void OnQueryTextFinished(char *str) override { _focused_window = this; @@ -244,7 +242,7 @@ struct IConsoleWindow : Window this->OnKeyPress(0, WKC_RETURN); } - virtual void OnHundredthTick() + void OnHundredthTick() override { if (IConsoleLine::Truncate() && (IConsoleWindow::scroll > IConsoleLine::size)) { @@ -253,12 +251,12 @@ struct IConsoleWindow : Window } } - virtual void OnMouseLoop() + void OnMouseLoop() override { if (_iconsole_cmdline.HandleCaret()) this->SetDirty(); } - virtual EventState OnKeyPress(WChar key, uint16 keycode) + EventState OnKeyPress(WChar key, uint16 keycode) override { if (_focused_window != this) return ES_NOT_HANDLED; @@ -296,13 +294,13 @@ struct IConsoleWindow : Window case WKC_RETURN: case WKC_NUM_ENTER: { /* We always want the ] at the left side; we always force these strings to be left - * aligned anyway. So enforce this in all cases by addding a left-to-right marker, + * aligned anyway. So enforce this in all cases by adding a left-to-right marker, * otherwise it will be drawn at the wrong side with right-to-left texts. */ IConsolePrintF(CC_COMMAND, LRM "] %s", _iconsole_cmdline.buf); const char *cmd = IConsoleHistoryAdd(_iconsole_cmdline.buf); IConsoleClearCommand(); - if (cmd != NULL) IConsoleCmdExec(cmd); + if (cmd != nullptr) IConsoleCmdExec(cmd); break; } @@ -329,7 +327,7 @@ struct IConsoleWindow : Window return ES_HANDLED; } - virtual void InsertTextString(int wid, const char *str, bool marked, const char *caret, const char *insert_location, const char *replacement_end) + void InsertTextString(int wid, const char *str, bool marked, const char *caret, const char *insert_location, const char *replacement_end) override { if (_iconsole_cmdline.InsertString(str, marked, caret, insert_location, replacement_end)) { IConsoleWindow::scroll = 0; @@ -338,25 +336,25 @@ struct IConsoleWindow : Window } } - virtual const char *GetFocusedText() const + const char *GetFocusedText() const override { return _iconsole_cmdline.buf; } - virtual const char *GetCaret() const + const char *GetCaret() const override { return _iconsole_cmdline.buf + _iconsole_cmdline.caretpos; } - virtual const char *GetMarkedText(size_t *length) const + const char *GetMarkedText(size_t *length) const override { - if (_iconsole_cmdline.markend == 0) return NULL; + if (_iconsole_cmdline.markend == 0) return nullptr; *length = _iconsole_cmdline.markend - _iconsole_cmdline.markpos; return _iconsole_cmdline.buf + _iconsole_cmdline.markpos; } - virtual Point GetCaretPosition() const + Point GetCaretPosition() const override { int delta = min(this->width - this->line_offset - _iconsole_cmdline.pixels - ICON_RIGHT_BORDERWIDTH, 0); Point pt = {this->line_offset + delta + _iconsole_cmdline.caretxoffs, this->height - this->line_height}; @@ -364,7 +362,7 @@ struct IConsoleWindow : Window return pt; } - virtual Rect GetTextBoundingRect(const char *from, const char *to) const + Rect GetTextBoundingRect(const char *from, const char *to) const override { int delta = min(this->width - this->line_offset - _iconsole_cmdline.pixels - ICON_RIGHT_BORDERWIDTH, 0); @@ -375,21 +373,26 @@ struct IConsoleWindow : Window return r; } - virtual const char *GetTextCharacterAtPosition(const Point &pt) const + const char *GetTextCharacterAtPosition(const Point &pt) const override { int delta = min(this->width - this->line_offset - _iconsole_cmdline.pixels - ICON_RIGHT_BORDERWIDTH, 0); - if (!IsInsideMM(pt.y, this->height - this->line_height, this->height)) return NULL; + if (!IsInsideMM(pt.y, this->height - this->line_height, this->height)) return nullptr; return GetCharAtPosition(_iconsole_cmdline.buf, pt.x - delta); } - virtual void OnMouseWheel(int wheel) + void OnMouseWheel(int wheel) override { this->Scroll(-wheel); } - virtual void OnFocusLost() + void OnFocus() override + { + VideoDriver::GetInstance()->EditBoxGainedFocus(); + } + + void OnFocusLost() override { VideoDriver::GetInstance()->EditBoxLostFocus(); } @@ -490,10 +493,10 @@ static const char *IConsoleHistoryAdd(const char *cmd) while (IsWhitespace(*cmd)) cmd++; /* Do not put empty command in history */ - if (StrEmpty(cmd)) return NULL; + if (StrEmpty(cmd)) return nullptr; /* Do not put in history if command is same as previous */ - if (_iconsole_history[0] == NULL || strcmp(_iconsole_history[0], cmd) != 0) { + if (_iconsole_history[0] == nullptr || strcmp(_iconsole_history[0], cmd) != 0) { free(_iconsole_history[ICON_HISTORY_SIZE - 1]); memmove(&_iconsole_history[1], &_iconsole_history[0], sizeof(_iconsole_history[0]) * (ICON_HISTORY_SIZE - 1)); _iconsole_history[0] = stredup(cmd); @@ -510,10 +513,10 @@ static const char *IConsoleHistoryAdd(const char *cmd) */ static void IConsoleHistoryNavigate(int direction) { - if (_iconsole_history[0] == NULL) return; // Empty history + if (_iconsole_history[0] == nullptr) return; // Empty history _iconsole_historypos = Clamp(_iconsole_historypos + direction, -1, ICON_HISTORY_SIZE - 1); - if (direction > 0 && _iconsole_history[_iconsole_historypos] == NULL) _iconsole_historypos--; + if (direction > 0 && _iconsole_history[_iconsole_historypos] == nullptr) _iconsole_historypos--; if (_iconsole_historypos == -1) { _iconsole_cmdline.DeleteAll(); diff --git a/src/console_gui.h b/src/console_gui.h index 54e8dc2bc8..96a3a1a5d3 100644 --- a/src/console_gui.h +++ b/src/console_gui.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/console_internal.h b/src/console_internal.h index 1b63b26f0d..630f69607b 100644 --- a/src/console_internal.h +++ b/src/console_internal.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. @@ -69,7 +67,7 @@ extern IConsoleAlias *_iconsole_aliases; ///< List of registered aliases. void IConsoleClearBuffer(); /* Commands */ -void IConsoleCmdRegister(const char *name, IConsoleCmdProc *proc, IConsoleHook *hook = NULL); +void IConsoleCmdRegister(const char *name, IConsoleCmdProc *proc, IConsoleHook *hook = nullptr); void IConsoleAliasRegister(const char *name, const char *cmd); IConsoleCmd *IConsoleCmdGet(const char *name); IConsoleAlias *IConsoleAliasGet(const char *name); diff --git a/src/console_type.h b/src/console_type.h index 18da4131db..b64acc93d0 100644 --- a/src/console_type.h +++ b/src/console_type.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/core/alloc_func.cpp b/src/core/alloc_func.cpp index b78023f4d6..86ba76623f 100644 --- a/src/core/alloc_func.cpp +++ b/src/core/alloc_func.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. diff --git a/src/core/alloc_func.hpp b/src/core/alloc_func.hpp index c33e733016..e8436e28d7 100644 --- a/src/core/alloc_func.hpp +++ b/src/core/alloc_func.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. @@ -53,23 +51,23 @@ static inline void CheckAllocationConstraints(size_t num_elements) * @note the memory contains garbage data (i.e. possibly non-zero values). * @tparam T the type of the variable(s) to allocation. * @param num_elements the number of elements to allocate of the given type. - * @return NULL when num_elements == 0, non-NULL otherwise. + * @return nullptr when num_elements == 0, non-nullptr otherwise. */ template static inline T *MallocT(size_t num_elements) { /* * MorphOS cannot handle 0 elements allocations, or rather that always - * returns NULL. So we do that for *all* allocations, thus causing it + * returns nullptr. So we do that for *all* allocations, thus causing it * to behave the same on all OSes. */ - if (num_elements == 0) return NULL; + if (num_elements == 0) return nullptr; /* Ensure the size does not overflow. */ CheckAllocationConstraints(num_elements); T *t_ptr = (T*)malloc(num_elements * sizeof(T)); - if (t_ptr == NULL) MallocError(num_elements * sizeof(T)); + if (t_ptr == nullptr) MallocError(num_elements * sizeof(T)); return t_ptr; } @@ -81,20 +79,20 @@ static inline T *MallocT(size_t num_elements) * @note the memory contains all zero values. * @tparam T the type of the variable(s) to allocation. * @param num_elements the number of elements to allocate of the given type. - * @return NULL when num_elements == 0, non-NULL otherwise. + * @return nullptr when num_elements == 0, non-nullptr otherwise. */ template static inline T *CallocT(size_t num_elements) { /* * MorphOS cannot handle 0 elements allocations, or rather that always - * returns NULL. So we do that for *all* allocations, thus causing it + * returns nullptr. So we do that for *all* allocations, thus causing it * to behave the same on all OSes. */ - if (num_elements == 0) return NULL; + if (num_elements == 0) return nullptr; T *t_ptr = (T*)calloc(num_elements, sizeof(T)); - if (t_ptr == NULL) MallocError(num_elements * sizeof(T)); + if (t_ptr == nullptr) MallocError(num_elements * sizeof(T)); return t_ptr; } @@ -107,26 +105,26 @@ static inline T *CallocT(size_t num_elements) * @tparam T the type of the variable(s) to allocation. * @param t_ptr the previous allocation to extend/shrink. * @param num_elements the number of elements to allocate of the given type. - * @return NULL when num_elements == 0, non-NULL otherwise. + * @return nullptr when num_elements == 0, non-nullptr otherwise. */ template static inline T *ReallocT(T *t_ptr, size_t num_elements) { /* * MorphOS cannot handle 0 elements allocations, or rather that always - * returns NULL. So we do that for *all* allocations, thus causing it + * returns nullptr. So we do that for *all* allocations, thus causing it * to behave the same on all OSes. */ if (num_elements == 0) { free(t_ptr); - return NULL; + return nullptr; } /* Ensure the size does not overflow. */ CheckAllocationConstraints(num_elements); t_ptr = (T*)realloc(static_cast(t_ptr), num_elements * sizeof(T)); - if (t_ptr == NULL) ReallocError(num_elements * sizeof(T)); + if (t_ptr == nullptr) ReallocError(num_elements * sizeof(T)); return t_ptr; } diff --git a/src/core/alloc_type.hpp b/src/core/alloc_type.hpp index 9c25cc9e3f..773de58837 100644 --- a/src/core/alloc_type.hpp +++ b/src/core/alloc_type.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. @@ -14,69 +12,6 @@ #include "alloc_func.hpp" -/** - * A small 'wrapper' for allocations that can be done on most OSes on the - * stack, but are just too large to fit in the stack on devices with a small - * stack such as the NDS. - * So when it is possible a stack allocation is made, otherwise a heap - * allocation is made and this is freed once the struct goes out of scope. - * @param T the type to make the allocation for - * @param length the amount of items to allocate - */ -template -struct SmallStackSafeStackAlloc { -#if !defined(__NDS__) - /** Storing the data on the stack */ - T data[length]; -#else - /** Storing it on the heap */ - T *data; - /** The length (in elements) of data in this allocator. */ - size_t len; - - /** Allocating the memory */ - SmallStackSafeStackAlloc() : data(MallocT(length)), len(length) {} - - /** And freeing when it goes out of scope */ - ~SmallStackSafeStackAlloc() - { - free(data); - } -#endif - - /** - * Gets a pointer to the data stored in this wrapper. - * @return the pointer. - */ - inline operator T *() - { - return data; - } - - /** - * Gets a pointer to the data stored in this wrapper. - * @return the pointer. - */ - inline T *operator -> () - { - return data; - } - - /** - * Gets a pointer to the last data element stored in this wrapper. - * @note needed because endof does not work properly for pointers. - * @return the 'endof' pointer. - */ - inline T *EndOf() - { -#if !defined(__NDS__) - return endof(data); -#else - return &data[len]; -#endif - } -}; - /** * A reusable buffer that can be used for places that temporary allocate * a bit of memory and do that very often, or for places where static @@ -93,7 +28,7 @@ private: public: /** Create a new buffer */ - ReusableBuffer() : buffer(NULL), count(0) {} + ReusableBuffer() : buffer(nullptr), count(0) {} /** Clear the buffer */ ~ReusableBuffer() { free(this->buffer); } @@ -180,38 +115,4 @@ public: inline void operator delete[](void *ptr) { free(ptr); } }; -/** - * A smart pointer class that free()'s the pointer on destruction. - * @tparam T Storage type. - */ -template -class AutoFreePtr -{ - T *ptr; ///< Stored pointer. - -public: - AutoFreePtr(T *ptr) : ptr(ptr) {} - ~AutoFreePtr() { free(this->ptr); } - - /** - * Take ownership of a new pointer and free the old one if needed. - * @param ptr NEw pointer. - */ - inline void Assign(T *ptr) - { - free(this->ptr); - this->ptr = ptr; - } - - /** Dereference pointer. */ - inline T *operator ->() { return this->ptr; } - /** Dereference pointer. */ - inline const T *operator ->() const { return this->ptr; } - - /** Cast to underlaying regular pointer. */ - inline operator T *() { return this->ptr; } - /** Cast to underlaying regular pointer. */ - inline operator const T *() const { return this->ptr; } -}; - #endif /* ALLOC_TYPE_HPP */ diff --git a/src/core/backup_type.hpp b/src/core/backup_type.hpp index 7e3771b70f..8c9c73851b 100644 --- a/src/core/backup_type.hpp +++ b/src/core/backup_type.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/core/bitmath_func.cpp b/src/core/bitmath_func.cpp index 7763227315..803eb9e1ca 100644 --- a/src/core/bitmath_func.cpp +++ b/src/core/bitmath_func.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. diff --git a/src/core/bitmath_func.hpp b/src/core/bitmath_func.hpp index fd05aa3f59..4af46d3430 100644 --- a/src/core/bitmath_func.hpp +++ b/src/core/bitmath_func.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. @@ -367,12 +365,12 @@ static inline T ROR(const T x, const uint8 n) * (since it will use hardware swapping if available). * Even though they should return uint16 and uint32, we get * warnings if we don't cast those (why?) */ - #define BSWAP32(x) ((uint32)CFSwapInt32(x)) - #define BSWAP16(x) ((uint16)CFSwapInt16(x)) +# define BSWAP32(x) (static_cast(CFSwapInt32(x))) +# define BSWAP16(x) (static_cast(CFSwapInt16(x))) #elif defined(_MSC_VER) /* MSVC has intrinsics for swapping, resulting in faster code */ - #define BSWAP32(x) (_byteswap_ulong(x)) - #define BSWAP16(x) (_byteswap_ushort(x)) +# define BSWAP32(x) (_byteswap_ulong(x)) +# define BSWAP16(x) (_byteswap_ushort(x)) #else /** * Perform a 32 bits endianness bitswap on x. @@ -383,7 +381,7 @@ static inline T ROR(const T x, const uint8 n) { #if !defined(__ICC) && defined(__GNUC__) && ((__GNUC__ > 4) || ((__GNUC__ == 4) && __GNUC_MINOR__ >= 3)) /* GCC >= 4.3 provides a builtin, resulting in faster code */ - return (uint32)__builtin_bswap32((int32)x); + return static_cast(__builtin_bswap32(static_cast(x))); #else return ((x >> 24) & 0xFF) | ((x >> 8) & 0xFF00) | ((x << 8) & 0xFF0000) | ((x << 24) & 0xFF000000); #endif /* defined(__GNUC__) */ diff --git a/src/core/endian_func.hpp b/src/core/endian_func.hpp index ab5b181500..b1a584785b 100644 --- a/src/core/endian_func.hpp +++ b/src/core/endian_func.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/core/endian_type.hpp b/src/core/endian_type.hpp index 4058c5c19a..b674928ee6 100644 --- a/src/core/endian_type.hpp +++ b/src/core/endian_type.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. @@ -26,7 +24,7 @@ #define TTD_BIG_ENDIAN 1 /* Windows has always LITTLE_ENDIAN */ -#if defined(_WIN32) || defined(__OS2__) +#if defined(_WIN32) || defined(__OS2__) || defined(__HAIKU__) # define TTD_ENDIAN TTD_LITTLE_ENDIAN #elif defined(OSX) # include diff --git a/src/core/enum_type.hpp b/src/core/enum_type.hpp index 35a0cb2926..d4ea82eff1 100644 --- a/src/core/enum_type.hpp +++ b/src/core/enum_type.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. @@ -13,17 +11,17 @@ #define ENUM_TYPE_HPP /** Some enums need to have allowed incrementing (i.e. StationClassID) */ -#define DECLARE_POSTFIX_INCREMENT(type) \ - inline type operator ++(type& e, int) \ +#define DECLARE_POSTFIX_INCREMENT(enum_type) \ + inline enum_type operator ++(enum_type& e, int) \ { \ - type e_org = e; \ - e = (type)((int)e + 1); \ + enum_type e_org = e; \ + e = (enum_type)((std::underlying_type::type)e + 1); \ return e_org; \ } \ - inline type operator --(type& e, int) \ + inline enum_type operator --(enum_type& e, int) \ { \ - type e_org = e; \ - e = (type)((int)e - 1); \ + enum_type e_org = e; \ + e = (enum_type)((std::underlying_type::type)e - 1); \ return e_org; \ } @@ -31,13 +29,13 @@ /** Operators to allow to work with enum as with type safe bit set in C++ */ # define DECLARE_ENUM_AS_BIT_SET(mask_t) \ - inline mask_t operator | (mask_t m1, mask_t m2) {return (mask_t)((int)m1 | m2);} \ - inline mask_t operator & (mask_t m1, mask_t m2) {return (mask_t)((int)m1 & m2);} \ - inline mask_t operator ^ (mask_t m1, mask_t m2) {return (mask_t)((int)m1 ^ m2);} \ + inline mask_t operator | (mask_t m1, mask_t m2) {return (mask_t)((std::underlying_type::type)m1 | m2);} \ + inline mask_t operator & (mask_t m1, mask_t m2) {return (mask_t)((std::underlying_type::type)m1 & m2);} \ + inline mask_t operator ^ (mask_t m1, mask_t m2) {return (mask_t)((std::underlying_type::type)m1 ^ m2);} \ inline mask_t& operator |= (mask_t& m1, mask_t m2) {m1 = m1 | m2; return m1;} \ inline mask_t& operator &= (mask_t& m1, mask_t m2) {m1 = m1 & m2; return m1;} \ inline mask_t& operator ^= (mask_t& m1, mask_t m2) {m1 = m1 ^ m2; return m1;} \ - inline mask_t operator ~(mask_t m) {return (mask_t)(~(int)m);} + inline mask_t operator ~(mask_t m) {return (mask_t)(~(std::underlying_type::type)m);} /** @@ -46,8 +44,6 @@ * we will create specialization derived from MakeEnumPropsT<>. * i.e.: * template <> struct EnumPropsT : MakeEnumPropsT {}; - * followed by: - * typedef TinyEnumT TrackByte; */ template struct EnumPropsT; @@ -72,106 +68,4 @@ struct MakeEnumPropsT { static const uint num_bits = Tnum_bits; ///< Number of bits for storing the enum in command parameters }; - - -/** - * In some cases we use byte or uint16 to store values that are defined as enum. It is - * necessary in order to control the sizeof() such values. Some compilers make enum - * the same size as int (4 or 8 bytes instead of 1 or 2). As a consequence the strict - * compiler type - checking causes errors like: - * 'HasPowerOnRail' : cannot convert parameter 1 from 'byte' to 'RailType' when - * u->u.rail.railtype is passed as argument or type RailType. In such cases it is better - * to teach the compiler that u->u.rail.railtype is to be treated as RailType. - */ -template struct TinyEnumT; - -/** The general declaration of TinyEnumT<> (above) */ -template -struct TinyEnumT { - typedef Tenum_t enum_type; ///< expose our enumeration type (i.e. Trackdir) to outside - typedef EnumPropsT Props; ///< make easier access to our enumeration properties - typedef typename Props::storage storage_type; ///< small storage type - static const enum_type begin = Props::begin; ///< enum beginning (i.e. TRACKDIR_BEGIN) - static const enum_type end = Props::end; ///< enum end (i.e. TRACKDIR_END) - static const enum_type invalid = Props::invalid;///< invalid value (i.e. INVALID_TRACKDIR) - - storage_type m_val; ///< here we hold the actual value in small (i.e. byte) form - - /** Cast operator - invoked then the value is assigned to the Tenum_t type */ - inline operator enum_type () const - { - return (enum_type)m_val; - } - - /** Assignment operator (from Tenum_t type) */ - inline TinyEnumT& operator = (enum_type e) - { - m_val = (storage_type)e; - return *this; - } - - /** Assignment operator (from Tenum_t type) */ - inline TinyEnumT& operator = (uint u) - { - m_val = (storage_type)u; - return *this; - } - - /** postfix ++ operator on tiny type */ - inline TinyEnumT operator ++ (int) - { - TinyEnumT org = *this; - if (++m_val >= end) m_val -= (storage_type)(end - begin); - return org; - } - - /** prefix ++ operator on tiny type */ - inline TinyEnumT& operator ++ () - { - if (++m_val >= end) m_val -= (storage_type)(end - begin); - return *this; - } -}; - - -/** Template of struct holding enum types (on most archs, enums are stored in an int32). No math operators are provided. */ -template -struct SimpleTinyEnumT { - storage_type m_val; ///< here we hold the actual value in small (i.e. byte) form - - /** Cast operator - invoked then the value is assigned to the storage_type */ - inline operator enum_type () const - { - return (enum_type)this->m_val; - } - - /** Assignment operator (from enum_type) */ - inline SimpleTinyEnumT &operator = (enum_type e) - { - this->m_val = (storage_type)e; - return *this; - } - - /** Assignment operator (from general uint) */ - inline SimpleTinyEnumT &operator = (uint u) - { - this->m_val = (storage_type)u; - return *this; - } - - /** Bit math (or) assignment operator (from enum_type) */ - inline SimpleTinyEnumT &operator |= (enum_type e) - { - this->m_val = (storage_type)((enum_type)this->m_val | e); - return *this; - } - - /** Bit math (and) assignment operator (from enum_type) */ - inline SimpleTinyEnumT &operator &= (enum_type e) - { - this->m_val = (storage_type)((enum_type)this->m_val & e); - return *this; - } -}; - #endif /* ENUM_TYPE_HPP */ diff --git a/src/core/geometry_func.cpp b/src/core/geometry_func.cpp index 86f317a372..162f2eae57 100644 --- a/src/core/geometry_func.cpp +++ b/src/core/geometry_func.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. diff --git a/src/core/geometry_func.hpp b/src/core/geometry_func.hpp index e7c53251c7..cd136488ac 100644 --- a/src/core/geometry_func.hpp +++ b/src/core/geometry_func.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/core/geometry_type.hpp b/src/core/geometry_type.hpp index 2bd8ffbade..0e9f86e674 100644 --- a/src/core/geometry_type.hpp +++ b/src/core/geometry_type.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. @@ -12,11 +10,6 @@ #ifndef GEOMETRY_TYPE_HPP #define GEOMETRY_TYPE_HPP -#if defined(__AMIGA__) - /* AmigaOS already has a Point declared */ - #define Point OTTD_Point -#endif /* __AMIGA__ */ - #if defined(__APPLE__) /* Mac OS X already has both Rect and Point declared */ #define Rect OTTD_Rect @@ -34,6 +27,20 @@ struct Point { struct Dimension { uint width; uint height; + + Dimension(uint w = 0, uint h = 0) : width(w), height(h) {}; + + bool operator< (const Dimension &other) const + { + int x = (*this).width - other.width; + if (x != 0) return x < 0; + return (*this).height < other.height; + } + + bool operator== (const Dimension &other) const + { + return (*this).width == other.width && (*this).height == other.height; + } }; /** Specification of a rectangle with absolute coordinates of all edges */ diff --git a/src/core/kdtree.hpp b/src/core/kdtree.hpp new file mode 100644 index 0000000000..c37ab8eea2 --- /dev/null +++ b/src/core/kdtree.hpp @@ -0,0 +1,486 @@ +/* + * 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 kdtree.hpp K-d tree template specialised for 2-dimensional Manhattan geometry */ + +#ifndef KDTREE_HPP +#define KDTREE_HPP + +#include "../stdafx.h" +#include +#include +#include + +/** + * K-dimensional tree, specialised for 2-dimensional space. + * This is not intended as a primary storage of data, but as an index into existing data. + * Usually the type stored by this tree should be an index into an existing array. + * + * This implementation assumes Manhattan distances are used. + * + * Be careful when using this in game code, depending on usage pattern, the tree shape may + * end up different for different clients in multiplayer, causing iteration order to differ + * and possibly having elements returned in different order. The using code should be designed + * to produce the same result regardless of iteration order. + * + * The element type T must be less-than comparable for FindNearest to work. + * + * @tparam T Type stored in the tree, should be cheap to copy. + * @tparam TxyFunc Functor type to extract coordinate from a T value and dimension index (0 or 1). + * @tparam CoordT Type of coordinate values extracted via TxyFunc. + * @tparam DistT Type to use for representing distance values. + */ +template +class Kdtree { + /** Type of a node in the tree */ + struct node { + T element; ///< Element stored at node + size_t left; ///< Index of node to the left, INVALID_NODE if none + size_t right; ///< Index of node to the right, INVALID_NODE if none + + node(T element) : element(element), left(INVALID_NODE), right(INVALID_NODE) { } + }; + + static const size_t INVALID_NODE = SIZE_MAX; ///< Index value indicating no-such-node + + std::vector nodes; ///< Pool of all nodes in the tree + std::vector free_list; ///< List of dead indices in the nodes vector + size_t root; ///< Index of root node + TxyFunc xyfunc; ///< Functor to extract a coordinate from an element + size_t unbalanced; ///< Number approximating how unbalanced the tree might be + + /** Create one new node in the tree, return its index in the pool */ + size_t AddNode(const T &element) + { + if (this->free_list.size() == 0) { + this->nodes.emplace_back(element); + return this->nodes.size() - 1; + } else { + size_t newidx = this->free_list.back(); + this->free_list.pop_back(); + this->nodes[newidx] = node{ element }; + return newidx; + } + } + + /** Find a coordinate value to split a range of elements at */ + template + CoordT SelectSplitCoord(It begin, It end, int level) + { + It mid = begin + (end - begin) / 2; + std::nth_element(begin, mid, end, [&](T a, T b) { return this->xyfunc(a, level % 2) < this->xyfunc(b, level % 2); }); + return this->xyfunc(*mid, level % 2); + } + + /** Construct a subtree from elements between begin and end iterators, return index of root */ + template + size_t BuildSubtree(It begin, It end, int level) + { + ptrdiff_t count = end - begin; + + if (count == 0) { + return INVALID_NODE; + } else if (count == 1) { + return this->AddNode(*begin); + } else if (count > 1) { + CoordT split_coord = SelectSplitCoord(begin, end, level); + It split = std::partition(begin, end, [&](T v) { return this->xyfunc(v, level % 2) < split_coord; }); + size_t newidx = this->AddNode(*split); + this->nodes[newidx].left = this->BuildSubtree(begin, split, level + 1); + this->nodes[newidx].right = this->BuildSubtree(split + 1, end, level + 1); + return newidx; + } else { + NOT_REACHED(); + } + } + + /** Rebuild the tree with all existing elements, optionally adding or removing one more */ + bool Rebuild(const T *include_element, const T *exclude_element) + { + size_t initial_count = this->Count(); + if (initial_count < 8) return false; // arbitrary value for "not worth rebalancing" + + T root_element = this->nodes[this->root].element; + std::vector elements = this->FreeSubtree(this->root); + elements.push_back(root_element); + + if (include_element != nullptr) { + elements.push_back(*include_element); + initial_count++; + } + if (exclude_element != nullptr) { + typename std::vector::iterator removed = std::remove(elements.begin(), elements.end(), *exclude_element); + elements.erase(removed, elements.end()); + initial_count--; + } + + this->Build(elements.begin(), elements.end()); + assert(initial_count == this->Count()); + return true; + } + + /** Insert one element in the tree somewhere below node_idx */ + void InsertRecursive(const T &element, size_t node_idx, int level) + { + /* Dimension index of current level */ + int dim = level % 2; + /* Node reference */ + node &n = this->nodes[node_idx]; + + /* Coordinate of element splitting at this node */ + CoordT nc = this->xyfunc(n.element, dim); + /* Coordinate of the new element */ + CoordT ec = this->xyfunc(element, dim); + /* Which side to insert on */ + size_t &next = (ec < nc) ? n.left : n.right; + + if (next == INVALID_NODE) { + /* New leaf */ + size_t newidx = this->AddNode(element); + /* Vector may have been reallocated at this point, n and next are invalid */ + node &nn = this->nodes[node_idx]; + if (ec < nc) nn.left = newidx; else nn.right = newidx; + } else { + this->InsertRecursive(element, next, level + 1); + } + } + + /** + * Free all children of the given node + * @return Collection of elements that were removed from tree. + */ + std::vector FreeSubtree(size_t node_idx) + { + std::vector subtree_elements; + node &n = this->nodes[node_idx]; + + /* We'll be appending items to the free_list, get index of our first item */ + size_t first_free = this->free_list.size(); + /* Prepare the descent with our children */ + if (n.left != INVALID_NODE) this->free_list.push_back(n.left); + if (n.right != INVALID_NODE) this->free_list.push_back(n.right); + n.left = n.right = INVALID_NODE; + + /* Recursively free the nodes being collected */ + for (size_t i = first_free; i < this->free_list.size(); i++) { + node &fn = this->nodes[this->free_list[i]]; + subtree_elements.push_back(fn.element); + if (fn.left != INVALID_NODE) this->free_list.push_back(fn.left); + if (fn.right != INVALID_NODE) this->free_list.push_back(fn.right); + fn.left = fn.right = INVALID_NODE; + } + + return subtree_elements; + } + + /** + * Find and remove one element from the tree. + * @param element The element to search for + * @param node_idx Sub-tree to search in + * @param level Current depth in the tree + * @return New root node index of the sub-tree processed + */ + size_t RemoveRecursive(const T &element, size_t node_idx, int level) + { + /* Node reference */ + node &n = this->nodes[node_idx]; + + if (n.element == element) { + /* Remove this one */ + this->free_list.push_back(node_idx); + if (n.left == INVALID_NODE && n.right == INVALID_NODE) { + /* Simple case, leaf, new child node for parent is "none" */ + return INVALID_NODE; + } else { + /* Complex case, rebuild the sub-tree */ + std::vector subtree_elements = this->FreeSubtree(node_idx); + return this->BuildSubtree(subtree_elements.begin(), subtree_elements.end(), level);; + } + } else { + /* Search in a sub-tree */ + /* Dimension index of current level */ + int dim = level % 2; + /* Coordinate of element splitting at this node */ + CoordT nc = this->xyfunc(n.element, dim); + /* Coordinate of the element being removed */ + CoordT ec = this->xyfunc(element, dim); + /* Which side to remove from */ + size_t next = (ec < nc) ? n.left : n.right; + assert(next != INVALID_NODE); // node must exist somewhere and must be found before a leaf is reached + /* Descend */ + size_t new_branch = this->RemoveRecursive(element, next, level + 1); + if (new_branch != next) { + /* Vector may have been reallocated at this point, n and next are invalid */ + node &nn = this->nodes[node_idx]; + if (ec < nc) nn.left = new_branch; else nn.right = new_branch; + } + return node_idx; + } + } + + + DistT ManhattanDistance(const T &element, CoordT x, CoordT y) const + { + return abs((DistT)this->xyfunc(element, 0) - (DistT)x) + abs((DistT)this->xyfunc(element, 1) - (DistT)y); + } + + /** A data element and its distance to a searched-for point */ + using node_distance = std::pair; + /** Ordering function for node_distance objects, elements with equal distance are ordered by less-than comparison */ + static node_distance SelectNearestNodeDistance(const node_distance &a, const node_distance &b) + { + if (a.second < b.second) return a; + if (b.second < a.second) return b; + if (a.first < b.first) return a; + if (b.first < a.first) return b; + NOT_REACHED(); // a.first == b.first: same element must not be inserted twice + } + /** Search a sub-tree for the element nearest to a given point */ + node_distance FindNearestRecursive(CoordT xy[2], size_t node_idx, int level, DistT limit = std::numeric_limits::max()) const + { + /* Dimension index of current level */ + int dim = level % 2; + /* Node reference */ + const node &n = this->nodes[node_idx]; + + /* Coordinate of element splitting at this node */ + CoordT c = this->xyfunc(n.element, dim); + /* This node's distance to target */ + DistT thisdist = ManhattanDistance(n.element, xy[0], xy[1]); + /* Assume this node is the best choice for now */ + node_distance best = std::make_pair(n.element, thisdist); + + /* Next node to visit */ + size_t next = (xy[dim] < c) ? n.left : n.right; + if (next != INVALID_NODE) { + /* Check if there is a better node down the tree */ + best = SelectNearestNodeDistance(best, this->FindNearestRecursive(xy, next, level + 1)); + } + + limit = min(best.second, limit); + + /* Check if the distance from current best is worse than distance from target to splitting line, + * if it is we also need to check the other side of the split. */ + size_t opposite = (xy[dim] >= c) ? n.left : n.right; // reverse of above + if (opposite != INVALID_NODE && limit >= abs((int)xy[dim] - (int)c)) { + node_distance other_candidate = this->FindNearestRecursive(xy, opposite, level + 1, limit); + best = SelectNearestNodeDistance(best, other_candidate); + } + + return best; + } + + template + void FindContainedRecursive(CoordT p1[2], CoordT p2[2], size_t node_idx, int level, Outputter outputter) const + { + /* Dimension index of current level */ + int dim = level % 2; + /* Node reference */ + const node &n = this->nodes[node_idx]; + + /* Coordinate of element splitting at this node */ + CoordT ec = this->xyfunc(n.element, dim); + /* Opposite coordinate of element */ + CoordT oc = this->xyfunc(n.element, 1 - dim); + + /* Test if this element is within rectangle */ + if (ec >= p1[dim] && ec < p2[dim] && oc >= p1[1 - dim] && oc < p2[1 - dim]) outputter(n.element); + + /* Recurse left if part of rectangle is left of split */ + if (p1[dim] < ec && n.left != INVALID_NODE) this->FindContainedRecursive(p1, p2, n.left, level + 1, outputter); + + /* Recurse right if part of rectangle is right of split */ + if (p2[dim] > ec && n.right != INVALID_NODE) this->FindContainedRecursive(p1, p2, n.right, level + 1, outputter); + } + + /** Debugging function, counts number of occurrences of an element regardless of its correct position in the tree */ + size_t CountValue(const T &element, size_t node_idx) const + { + if (node_idx == INVALID_NODE) return 0; + const node &n = this->nodes[node_idx]; + return CountValue(element, n.left) + CountValue(element, n.right) + ((n.element == element) ? 1 : 0); + } + + void IncrementUnbalanced(size_t amount = 1) + { + this->unbalanced += amount; + } + + /** Check if the entire tree is in need of rebuilding */ + bool IsUnbalanced() + { + size_t count = this->Count(); + if (count < 8) return false; + return this->unbalanced > this->Count() / 4; + } + + /** Verify that the invariant is true for a sub-tree, assert if not */ + void CheckInvariant(size_t node_idx, int level, CoordT min_x, CoordT max_x, CoordT min_y, CoordT max_y) + { + if (node_idx == INVALID_NODE) return; + + const node &n = this->nodes[node_idx]; + CoordT cx = this->xyfunc(n.element, 0); + CoordT cy = this->xyfunc(n.element, 1); + + assert(cx >= min_x); + assert(cx < max_x); + assert(cy >= min_y); + assert(cy < max_y); + + if (level % 2 == 0) { + // split in dimension 0 = x + CheckInvariant(n.left, level + 1, min_x, cx, min_y, max_y); + CheckInvariant(n.right, level + 1, cx, max_x, min_y, max_y); + } else { + // split in dimension 1 = y + CheckInvariant(n.left, level + 1, min_x, max_x, min_y, cy); + CheckInvariant(n.right, level + 1, min_x, max_x, cy, max_y); + } + } + + /** Verify the invariant for the entire tree, does nothing unless KDTREE_DEBUG is defined */ + void CheckInvariant() + { +#ifdef KDTREE_DEBUG + CheckInvariant(this->root, 0, std::numeric_limits::min(), std::numeric_limits::max(), std::numeric_limits::min(), std::numeric_limits::max()); +#endif + } + +public: + /** Construct a new Kdtree with the given xyfunc */ + Kdtree(TxyFunc xyfunc) : root(INVALID_NODE), xyfunc(xyfunc), unbalanced(0) { } + + /** + * Clear and rebuild the tree from a new sequence of elements, + * @tparam It Iterator type for element sequence. + * @param begin First element in sequence. + * @param end One past last element in sequence. + */ + template + void Build(It begin, It end) + { + this->nodes.clear(); + this->free_list.clear(); + this->unbalanced = 0; + if (begin == end) return; + this->nodes.reserve(end - begin); + + this->root = this->BuildSubtree(begin, end, 0); + CheckInvariant(); + } + + /** + * Clear the tree. + */ + void Clear() + { + this->nodes.clear(); + this->free_list.clear(); + this->unbalanced = 0; + return; + } + + /** + * Reconstruct the tree with the same elements, letting it be fully balanced. + */ + void Rebuild() + { + this->Rebuild(nullptr, nullptr); + } + + /** + * Insert a single element in the tree. + * Repeatedly inserting single elements may cause the tree to become unbalanced. + * Undefined behaviour if the element already exists in the tree. + */ + void Insert(const T &element) + { + if (this->Count() == 0) { + this->root = this->AddNode(element); + } else { + if (!this->IsUnbalanced() || !this->Rebuild(&element, nullptr)) { + this->InsertRecursive(element, this->root, 0); + this->IncrementUnbalanced(); + } + CheckInvariant(); + } + } + + /** + * Remove a single element from the tree, if it exists. + * Since elements are stored in interior nodes as well as leaf nodes, removing one may + * require a larger sub-tree to be re-built. Because of this, worst case run time is + * as bad as a full tree rebuild. + */ + void Remove(const T &element) + { + size_t count = this->Count(); + if (count == 0) return; + if (!this->IsUnbalanced() || !this->Rebuild(nullptr, &element)) { + /* If the removed element is the root node, this modifies this->root */ + this->root = this->RemoveRecursive(element, this->root, 0); + this->IncrementUnbalanced(); + } + CheckInvariant(); + } + + /** Get number of elements stored in tree */ + size_t Count() const + { + assert(this->free_list.size() <= this->nodes.size()); + return this->nodes.size() - this->free_list.size(); + } + + /** + * Find the element closest to given coordinate, in Manhattan distance. + * For multiple elements with the same distance, the one comparing smaller with + * a less-than comparison is chosen. + */ + T FindNearest(CoordT x, CoordT y) const + { + assert(this->Count() > 0); + + CoordT xy[2] = { x, y }; + return this->FindNearestRecursive(xy, this->root, 0).first; + } + + /** + * Find all items contained within the given rectangle. + * @note Start coordinates are inclusive, end coordinates are exclusive. x1 + void FindContained(CoordT x1, CoordT y1, CoordT x2, CoordT y2, Outputter outputter) const + { + assert(x1 < x2); + assert(y1 < y2); + + if (this->Count() == 0) return; + + CoordT p1[2] = { x1, y1 }; + CoordT p2[2] = { x2, y2 }; + this->FindContainedRecursive(p1, p2, this->root, 0, outputter); + } + + /** + * Find all items contained within the given rectangle. + * @note End coordinates are exclusive, x1 FindContained(CoordT x1, CoordT y1, CoordT x2, CoordT y2) const + { + std::vector result; + this->FindContained(x1, y1, x2, y2, [&result](T e) {result.push_back(e); }); + return result; + } +}; + +#endif diff --git a/src/core/math_func.cpp b/src/core/math_func.cpp index d927702083..98fac81aa7 100644 --- a/src/core/math_func.cpp +++ b/src/core/math_func.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. diff --git a/src/core/math_func.hpp b/src/core/math_func.hpp index 4a19033f45..d36dc55f9c 100644 --- a/src/core/math_func.hpp +++ b/src/core/math_func.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. @@ -115,7 +113,7 @@ template static inline T *AlignPtr(T *x, uint n) { assert_compile(sizeof(size_t) == sizeof(void *)); - return (T *)Align((size_t)x, n); + return reinterpret_cast(Align((size_t)x, n)); } /** @@ -202,7 +200,7 @@ static inline uint ClampU(const uint a, const uint min, const uint max) */ static inline int32 ClampToI32(const int64 a) { - return (int32)Clamp(a, INT32_MIN, INT32_MAX); + return static_cast(Clamp(a, INT32_MIN, INT32_MAX)); } /** @@ -218,7 +216,7 @@ static inline uint16 ClampToU16(const uint64 a) * match for min(uint64, uint) than uint64 min(uint64, uint64). As such we * need to cast the UINT16_MAX to prevent MSVC from displaying its * infinite loads of warnings. */ - return (uint16)min(a, (uint64)UINT16_MAX); + return static_cast(min(a, static_cast(UINT16_MAX))); } /** @@ -247,9 +245,9 @@ static inline T Delta(const T a, const T b) * @return True if the value is in the interval, false else. */ template -static inline bool IsInsideBS(const T x, const uint base, const uint size) +static inline bool IsInsideBS(const T x, const size_t base, const size_t size) { - return (uint)(x - base) < size; + return (size_t)(x - base) < size; } /** @@ -263,9 +261,9 @@ static inline bool IsInsideBS(const T x, const uint base, const uint size) * @see IsInsideBS() */ template -static inline bool IsInsideMM(const T x, const uint min, const uint max) +static inline bool IsInsideMM(const T x, const size_t min, const size_t max) { - return (uint)(x - min) < (max - min); + return (size_t)(x - min) < (max - min); } /** @@ -339,10 +337,10 @@ static inline int RoundDivSU(int a, uint b) { if (a > 0) { /* 0.5 is rounded to 1 */ - return (a + (int)b / 2) / (int)b; + return (a + static_cast(b) / 2) / static_cast(b); } else { /* -0.5 is rounded to 0 */ - return (a - ((int)b - 1) / 2) / (int)b; + return (a - (static_cast(b) - 1) / 2) / static_cast(b); } } diff --git a/src/core/mem_func.hpp b/src/core/mem_func.hpp index 6878711645..12acce13fc 100644 --- a/src/core/mem_func.hpp +++ b/src/core/mem_func.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. @@ -78,7 +76,7 @@ static inline int MemCmpT(const T *ptr1, const T *ptr2, size_t num = 1) template static inline void MemReverseT(T *ptr1, T *ptr2) { - assert(ptr1 != NULL && ptr2 != NULL); + assert(ptr1 != nullptr && ptr2 != nullptr); assert(ptr1 < ptr2); do { @@ -95,7 +93,7 @@ static inline void MemReverseT(T *ptr1, T *ptr2) template static inline void MemReverseT(T *ptr, size_t num) { - assert(ptr != NULL); + assert(ptr != nullptr); MemReverseT(ptr, ptr + (num - 1)); } diff --git a/src/core/multimap.hpp b/src/core/multimap.hpp index e906677141..026488b355 100644 --- a/src/core/multimap.hpp +++ b/src/core/multimap.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/core/overflowsafe_type.hpp b/src/core/overflowsafe_type.hpp index edc25d2755..2b1edeeded 100644 --- a/src/core/overflowsafe_type.hpp +++ b/src/core/overflowsafe_type.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/core/pool_func.cpp b/src/core/pool_func.cpp index f8ff93cecc..79ea4b21ce 100644 --- a/src/core/pool_func.cpp +++ b/src/core/pool_func.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. @@ -21,8 +19,8 @@ /* virtual */ PoolBase::~PoolBase() { PoolVector *pools = PoolBase::GetPools(); - pools->Erase(pools->Find(this)); - if (pools->Length() == 0) delete pools; + pools->erase(std::find(pools->begin(), pools->end(), this)); + if (pools->size() == 0) delete pools; } /** @@ -31,10 +29,7 @@ */ /* static */ void PoolBase::Clean(PoolType pt) { - PoolVector *pools = PoolBase::GetPools(); - PoolBase **end = pools->End(); - for (PoolBase **ppool = pools->Begin(); ppool != end; ppool++) { - PoolBase *pool = *ppool; + for (PoolBase *pool : *PoolBase::GetPools()) { if (pool->type & pt) pool->CleanPool(); } } diff --git a/src/core/pool_func.hpp b/src/core/pool_func.hpp index 64af175649..db79ab2857 100644 --- a/src/core/pool_func.hpp +++ b/src/core/pool_func.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. @@ -39,8 +37,8 @@ DEFINE_POOL_METHOD(inline)::Pool(const char *name) : checked(0), #endif /* OTTD_ASSERT */ cleaning(false), - data(NULL), - alloc_cache(NULL) + data(nullptr), + alloc_cache(nullptr) { } /** @@ -71,7 +69,7 @@ DEFINE_POOL_METHOD(inline size_t)::FindFirstFree() size_t index = this->first_free; for (; index < this->first_unused; index++) { - if (this->data[index] == NULL) return index; + if (this->data[index] == nullptr) return index; } if (index < this->size) { @@ -96,17 +94,17 @@ DEFINE_POOL_METHOD(inline size_t)::FindFirstFree() * @param size size of item * @param index index of item * @pre index < this->size - * @pre this->Get(index) == NULL + * @pre this->Get(index) == nullptr */ DEFINE_POOL_METHOD(inline void *)::AllocateItem(size_t size, size_t index) { - assert(this->data[index] == NULL); + assert(this->data[index] == nullptr); this->first_unused = max(this->first_unused, index + 1); this->items++; Titem *item; - if (Tcache && this->alloc_cache != NULL) { + if (Tcache && this->alloc_cache != nullptr) { assert(sizeof(Titem) == size); item = (Titem *)this->alloc_cache; this->alloc_cache = this->alloc_cache->next; @@ -164,7 +162,7 @@ DEFINE_POOL_METHOD(void *)::GetNew(size_t size, size_t index) if (index >= this->size) this->ResizeFor(index); - if (this->data[index] != NULL) { + if (this->data[index] != nullptr) { SlErrorCorruptFmt("%s index " PRINTF_SIZE " already in use", this->name, index); } @@ -174,13 +172,13 @@ DEFINE_POOL_METHOD(void *)::GetNew(size_t size, size_t index) /** * Deallocates memory used by this index and marks item as free * @param index item to deallocate - * @pre unit is allocated (non-NULL) - * @note 'delete NULL' doesn't cause call of this function, so it is safe + * @pre unit is allocated (non-nullptr) + * @note 'delete nullptr' doesn't cause call of this function, so it is safe */ DEFINE_POOL_METHOD(void)::FreeItem(size_t index) { assert(index < this->size); - assert(this->data[index] != NULL); + assert(this->data[index] != nullptr); if (Tcache) { AllocCache *ac = (AllocCache *)this->data[index]; ac->next = this->alloc_cache; @@ -188,7 +186,7 @@ DEFINE_POOL_METHOD(void)::FreeItem(size_t index) } else { free(this->data[index]); } - this->data[index] = NULL; + this->data[index] = nullptr; this->first_free = min(this->first_free, index); this->items--; if (!this->cleaning) Titem::PostDestructor(index); @@ -199,16 +197,16 @@ DEFINE_POOL_METHOD(void)::CleanPool() { this->cleaning = true; for (size_t i = 0; i < this->first_unused; i++) { - delete this->Get(i); // 'delete NULL;' is very valid + delete this->Get(i); // 'delete nullptr;' is very valid } assert(this->items == 0); free(this->data); this->first_unused = this->first_free = this->size = 0; - this->data = NULL; + this->data = nullptr; this->cleaning = false; if (Tcache) { - while (this->alloc_cache != NULL) { + while (this->alloc_cache != nullptr) { AllocCache *ac = this->alloc_cache; this->alloc_cache = ac->next; free(ac); diff --git a/src/core/pool_type.hpp b/src/core/pool_type.hpp index 4d20ed1abb..9e6fc8fecd 100644 --- a/src/core/pool_type.hpp +++ b/src/core/pool_type.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. @@ -7,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 pool_type.hpp Defintion of Pool, structure used to access PoolItems, and PoolItem, base structure for Vehicle, Town, and other indexed items. */ +/** @file pool_type.hpp Definition of Pool, structure used to access PoolItems, and PoolItem, base structure for Vehicle, Town, and other indexed items. */ #ifndef POOL_TYPE_HPP #define POOL_TYPE_HPP @@ -26,7 +24,7 @@ enum PoolType { }; DECLARE_ENUM_AS_BIT_SET(PoolType) -typedef SmallVector PoolVector; ///< Vector of pointers to PoolBase +typedef std::vector PoolVector; ///< Vector of pointers to PoolBase /** Base class for base of all pools. */ struct PoolBase { @@ -50,7 +48,7 @@ struct PoolBase { */ PoolBase(PoolType pt) : type(pt) { - *PoolBase::GetPools()->Append() = this; + PoolBase::GetPools()->push_back(this); } virtual ~PoolBase(); @@ -91,7 +89,7 @@ struct Pool : PoolBase { size_t size; ///< Current allocated size size_t first_free; ///< No item with index lower than this is free (doesn't say anything about this one!) size_t first_unused; ///< This and all higher indexes are free (doesn't say anything about first_unused-1 !) - size_t items; ///< Number of used indexes (non-NULL) + size_t items; ///< Number of used indexes (non-nullptr) #ifdef OTTD_ASSERT size_t checked; ///< Number of items we checked for #endif /* OTTD_ASSERT */ @@ -115,13 +113,13 @@ struct Pool : PoolBase { } /** - * Tests whether given index can be used to get valid (non-NULL) Titem + * Tests whether given index can be used to get valid (non-nullptr) Titem * @param index index to examine - * @return true if PoolItem::Get(index) will return non-NULL pointer + * @return true if PoolItem::Get(index) will return non-nullptr pointer */ inline bool IsValidID(size_t index) { - return index < this->first_unused && this->Get(index) != NULL; + return index < this->first_unused && this->Get(index) != nullptr; } /** @@ -138,6 +136,88 @@ struct Pool : PoolBase { return ret; } + /** + * Iterator to iterate all valid T of a pool + * @tparam T Type of the class/struct that is going to be iterated + */ + template + struct PoolIterator { + typedef T value_type; + typedef T* pointer; + typedef T& reference; + typedef size_t difference_type; + typedef std::forward_iterator_tag iterator_category; + + explicit PoolIterator(size_t index) : index(index) + { + this->ValidateIndex(); + }; + + bool operator==(const PoolIterator &other) const { return this->index == other.index; } + bool operator!=(const PoolIterator &other) const { return !(*this == other); } + T * operator*() const { return T::Get(this->index); } + PoolIterator & operator++() { this->index++; this->ValidateIndex(); return *this; } + + private: + size_t index; + void ValidateIndex() { while (this->index < T::GetPoolSize() && !(T::IsValidID(this->index))) this->index++; } + }; + + /* + * Iterable ensemble of all valid T + * @tparam T Type of the class/struct that is going to be iterated + */ + template + struct IterateWrapper { + size_t from; + IterateWrapper(size_t from = 0) : from(from) {} + PoolIterator begin() { return PoolIterator(this->from); } + PoolIterator end() { return PoolIterator(T::GetPoolSize()); } + bool empty() { return this->begin() == this->end(); } + }; + + /** + * Iterator to iterate all valid T of a pool + * @tparam T Type of the class/struct that is going to be iterated + */ + template + struct PoolIteratorFiltered { + typedef T value_type; + typedef T* pointer; + typedef T& reference; + typedef size_t difference_type; + typedef std::forward_iterator_tag iterator_category; + + explicit PoolIteratorFiltered(size_t index, F filter) : index(index), filter(filter) + { + this->ValidateIndex(); + }; + + bool operator==(const PoolIteratorFiltered &other) const { return this->index == other.index; } + bool operator!=(const PoolIteratorFiltered &other) const { return !(*this == other); } + T * operator*() const { return T::Get(this->index); } + PoolIteratorFiltered & operator++() { this->index++; this->ValidateIndex(); return *this; } + + private: + size_t index; + F filter; + void ValidateIndex() { while (this->index < T::GetPoolSize() && !(T::IsValidID(this->index) && this->filter(this->index))) this->index++; } + }; + + /* + * Iterable ensemble of all valid T + * @tparam T Type of the class/struct that is going to be iterated + */ + template + struct IterateWrapperFiltered { + size_t from; + F filter; + IterateWrapperFiltered(size_t from, F filter) : from(from), filter(filter) {} + PoolIteratorFiltered begin() { return PoolIteratorFiltered(this->from, this->filter); } + PoolIteratorFiltered end() { return PoolIteratorFiltered(T::GetPoolSize(), this->filter); } + bool empty() { return this->begin() == this->end(); } + }; + /** * Base class for all PoolItems * @tparam Tpool The pool this item is going to be part of @@ -146,11 +226,14 @@ struct Pool : PoolBase { struct PoolItem { Tindex index; ///< Index of this pool item + /** Type of the pool this item is going to be part of */ + typedef struct Pool Pool; + /** * Allocates space for new Titem * @param size size of Titem * @return pointer to allocated memory - * @note can never fail (return NULL), use CanAllocate() to check first! + * @note can never fail (return nullptr), use CanAllocate() to check first! */ inline void *operator new(size_t size) { @@ -164,7 +247,7 @@ struct Pool : PoolBase { */ inline void operator delete(void *p) { - if (p == NULL) return; + if (p == nullptr) return; Titem *pn = (Titem *)p; assert(pn == Tpool->Get(pn->index)); Tpool->FreeItem(pn->index); @@ -175,7 +258,7 @@ struct Pool : PoolBase { * @param size size of Titem * @param index index of item * @return pointer to allocated memory - * @note can never fail (return NULL), use CanAllocate() to check first! + * @note can never fail (return nullptr), use CanAllocate() to check first! * @pre index has to be unused! Else it will crash */ inline void *operator new(size_t size, size_t index) @@ -228,9 +311,9 @@ struct Pool : PoolBase { } /** - * Tests whether given index can be used to get valid (non-NULL) Titem + * Tests whether given index can be used to get valid (non-nullptr) Titem * @param index index to examine - * @return true if PoolItem::Get(index) will return non-NULL pointer + * @return true if PoolItem::Get(index) will return non-nullptr pointer */ static inline bool IsValidID(size_t index) { @@ -252,11 +335,11 @@ struct Pool : PoolBase { * Returns Titem with given index * @param index of item to get * @return pointer to Titem - * @note returns NULL for invalid index + * @note returns nullptr for invalid index */ static inline Titem *GetIfValid(size_t index) { - return index < Tpool->first_unused ? Tpool->Get(index) : NULL; + return index < Tpool->first_unused ? Tpool->Get(index) : nullptr; } /** @@ -282,10 +365,17 @@ struct Pool : PoolBase { * Dummy function called after destructor of each member. * If you want to use it, override it in PoolItem's subclass. * @param index index of deleted item - * @note when this function is called, PoolItem::Get(index) == NULL. + * @note when this function is called, PoolItem::Get(index) == nullptr. * @note it's called only when !CleaningPool() */ static inline void PostDestructor(size_t index) { } + + /** + * Returns an iterable ensemble of all valid Titem + * @param from index of the first Titem to consider + * @return an iterable ensemble of all valid Titem + */ + static Pool::IterateWrapper Iterate(size_t from = 0) { return Pool::IterateWrapper(from); } }; private: @@ -313,10 +403,4 @@ private: void FreeItem(size_t index); }; -#define FOR_ALL_ITEMS_FROM(type, iter, var, start) \ - for (size_t iter = start; var = NULL, iter < type::GetPoolSize(); iter++) \ - if ((var = type::Get(iter)) != NULL) - -#define FOR_ALL_ITEMS(type, iter, var) FOR_ALL_ITEMS_FROM(type, iter, var, 0) - #endif /* POOL_TYPE_HPP */ diff --git a/src/core/random_func.cpp b/src/core/random_func.cpp index e4593c4076..439f95d158 100644 --- a/src/core/random_func.cpp +++ b/src/core/random_func.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. diff --git a/src/core/random_func.hpp b/src/core/random_func.hpp index ae476624e8..7a40c9b740 100644 --- a/src/core/random_func.hpp +++ b/src/core/random_func.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/core/smallmap_type.hpp b/src/core/smallmap_type.hpp index dda0fc2a1e..478e7515a6 100644 --- a/src/core/smallmap_type.hpp +++ b/src/core/smallmap_type.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. @@ -13,7 +11,6 @@ #define SMALLMAP_TYPE_HPP #include "smallvec_type.hpp" -#include "sort_func.hpp" /** * Simple pair of data. Both types have to be POD ("Plain Old Data")! @@ -27,6 +24,7 @@ struct SmallPair { /** Initializes this Pair with data */ inline SmallPair(const T &first, const U &second) : first(first), second(second) { } + SmallPair() = default; }; /** @@ -38,8 +36,8 @@ struct SmallPair { * * @see SmallVector */ -template -struct SmallMap : SmallVector, S> { +template +struct SmallMap : std::vector > { typedef ::SmallPair Pair; typedef Pair *iterator; typedef const Pair *const_iterator; @@ -54,12 +52,13 @@ struct SmallMap : SmallVector, S> { * @param key key to find * @return &Pair(key, data) if found, this->End() if not */ - inline const Pair *Find(const T &key) const + inline typename std::vector::const_iterator Find(const T &key) const { - for (uint i = 0; i < this->items; i++) { - if (key == this->data[i].first) return &this->data[i]; + typename std::vector::const_iterator it; + for (it = std::vector::begin(); it != std::vector::end(); it++) { + if (key == it->first) return it; } - return this->End(); + return it; } /** @@ -69,18 +68,39 @@ struct SmallMap : SmallVector, S> { */ inline Pair *Find(const T &key) { - for (uint i = 0; i < this->items; i++) { - if (key == this->data[i].first) return &this->data[i]; + for (uint i = 0; i < std::vector::size(); i++) { + if (key == std::vector::operator[](i).first) return &std::vector::operator[](i); } return this->End(); } + inline const Pair *End() const + { + return std::vector::data() + std::vector::size(); + } + + inline Pair *End() + { + return std::vector::data() + std::vector::size(); + } + + /** * Tests whether a key is assigned in this map. * @param key key to test * @return true iff the item is present */ inline bool Contains(const T &key) const + { + return this->Find(key) != std::vector::end(); + } + + /** + * Tests whether a key is assigned in this map. + * @param key key to test + * @return true iff the item is present + */ + inline bool Contains(const T &key) { return this->Find(key) != this->End(); } @@ -92,8 +112,9 @@ struct SmallMap : SmallVector, S> { */ inline void Erase(Pair *pair) { - assert(pair >= this->Begin() && pair < this->End()); - *pair = this->data[--this->items]; + assert(pair >= std::vector::data() && pair < this->End()); + auto distance = pair - std::vector::data(); + std::vector::erase(std::vector::begin() + distance); } /** @@ -104,13 +125,11 @@ struct SmallMap : SmallVector, S> { */ inline bool Erase(const T &key) { - for (uint i = 0; i < this->items; i++) { - if (key == this->data[i].first) { - this->data[i] = this->data[--this->items]; - return true; - } - } - return false; + auto *pair = this->Find(key); + if (pair == this->End()) return false; + + this->Erase(pair); + return true; } /** @@ -122,9 +141,7 @@ struct SmallMap : SmallVector, S> { inline bool Insert(const T &key, const U &data) { if (this->Contains(key)) return false; - Pair *n = this->Append(); - n->first = key; - n->second = data; + std::vector::emplace_back(key, data); return true; } @@ -136,22 +153,13 @@ struct SmallMap : SmallVector, S> { */ inline U &operator[](const T &key) { - for (uint i = 0; i < this->items; i++) { - if (key == this->data[i].first) return this->data[i].second; + for (uint i = 0; i < std::vector::size(); i++) { + if (key == std::vector::operator[](i).first) return std::vector::operator[](i).second; } - Pair *n = this->Append(); - n->first = key; - return n->second; - } - - inline void SortByKey() - { - QSortT(this->Begin(), this->items, KeySorter); - } - - static int CDECL KeySorter(const Pair *a, const Pair *b) - { - return a->first - b->first; + /*C++17: Pair &n = */ std::vector::emplace_back(); + Pair &n = std::vector::back(); + n.first = key; + return n.second; } }; diff --git a/src/core/smallmatrix_type.hpp b/src/core/smallmatrix_type.hpp index cd4dee4e3a..0aeac10e13 100644 --- a/src/core/smallmatrix_type.hpp +++ b/src/core/smallmatrix_type.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. @@ -46,13 +44,13 @@ protected: public: - SmallMatrix() : data(NULL), width(0), height(0), capacity(0) {} + SmallMatrix() : data(nullptr), width(0), height(0), capacity(0) {} /** * Copy constructor. * @param other The other matrix to copy. */ - SmallMatrix(const SmallMatrix &other) : data(NULL), width(0), height(0), capacity(0) + SmallMatrix(const SmallMatrix &other) : data(nullptr), width(0), height(0), capacity(0) { this->Assign(other); } @@ -112,7 +110,7 @@ public: this->width = 0; this->capacity = 0; free(this->data); - this->data = NULL; + this->data = nullptr; } /** @@ -216,8 +214,8 @@ public: inline void Resize(uint new_width, uint new_height) { uint new_capacity = new_width * new_height; - T *new_data = NULL; - void (*copy)(T *dest, const T *src, size_t count) = NULL; + 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); diff --git a/src/core/smallstack_type.hpp b/src/core/smallstack_type.hpp index 06b5aaafa6..bf44f00c8f 100644 --- a/src/core/smallstack_type.hpp +++ b/src/core/smallstack_type.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. @@ -13,7 +11,7 @@ #define SMALLSTACK_TYPE_HPP #include "smallvec_type.hpp" -#include "../thread/thread.h" +#include /** * A simplified pool which stores values instead of pointers and doesn't @@ -23,15 +21,14 @@ template class SimplePool { public: - inline SimplePool() : first_unused(0), first_free(0), mutex(ThreadMutex::New()) {} - inline ~SimplePool() { delete this->mutex; } + inline SimplePool() : first_unused(0), first_free(0) {} /** * Get the mutex. We don't lock the mutex in the pool methods as the * SmallStack isn't necessarily in a consistent state after each method. * @return Mutex. */ - inline ThreadMutex *GetMutex() { return this->mutex; } + inline std::mutex &GetMutex() { return this->mutex; } /** * Get the item at position index. @@ -73,8 +70,8 @@ private: if (!this->data[index].valid) return index; } - if (index >= this->data.Length() && index < Tmax_size) { - this->data.Resize(index + 1); + if (index >= this->data.size() && index < Tmax_size) { + this->data.resize(index + 1); } return index; } @@ -86,8 +83,8 @@ private: Tindex first_unused; Tindex first_free; - ThreadMutex *mutex; - SmallVector data; + std::mutex mutex; + std::vector data; }; /** @@ -106,6 +103,7 @@ struct SmallStackItem { */ inline SmallStackItem(const Titem &value, Tindex next) : next(next), value(value) {} + SmallStackItem() = default; }; /** @@ -195,7 +193,7 @@ public: inline void Push(const Titem &item) { if (this->value != Tinvalid) { - ThreadMutexLocker lock(SmallStack::GetPool().GetMutex()); + std::lock_guard lock(SmallStack::GetPool().GetMutex()); Tindex new_item = SmallStack::GetPool().Create(); if (new_item != Tmax_size) { PooledSmallStack &pushed = SmallStack::GetPool().Get(new_item); @@ -218,7 +216,7 @@ public: if (this->next == Tmax_size) { this->value = Tinvalid; } else { - ThreadMutexLocker lock(SmallStack::GetPool().GetMutex()); + std::lock_guard lock(SmallStack::GetPool().GetMutex()); PooledSmallStack &popped = SmallStack::GetPool().Get(this->next); this->value = popped.value; if (popped.branch_count == 0) { @@ -257,7 +255,7 @@ public: { if (item == Tinvalid || item == this->value) return true; if (this->next != Tmax_size) { - ThreadMutexLocker lock(SmallStack::GetPool().GetMutex()); + std::lock_guard lock(SmallStack::GetPool().GetMutex()); const SmallStack *in_list = this; do { in_list = static_cast( @@ -281,7 +279,7 @@ protected: inline void Branch() { if (this->next != Tmax_size) { - ThreadMutexLocker lock(SmallStack::GetPool().GetMutex()); + std::lock_guard lock(SmallStack::GetPool().GetMutex()); ++(SmallStack::GetPool().Get(this->next).branch_count); } } diff --git a/src/core/smallvec_type.hpp b/src/core/smallvec_type.hpp index 588dd599dc..2f65f02926 100644 --- a/src/core/smallvec_type.hpp +++ b/src/core/smallvec_type.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. @@ -14,438 +12,42 @@ #include "alloc_func.hpp" #include "mem_func.hpp" +#include +#include /** - * Simple vector template class. + * Helper function to append an item to a vector if it is not already contained + * Consider using std::set, std::unordered_set or std::flat_set in new code * - * @note There are no asserts in the class so you have - * to care about that you grab an item which is - * inside the list. + * @param vec A reference to the vector to be extended + * @param item Reference to the item to be copy-constructed if not found * - * @tparam T The type of the items stored - * @tparam S The steps of allocation + * @return Whether the item was already present */ -template -class SmallVector { -protected: - T *data; ///< The pointer to the first item - uint items; ///< The number of items stored - uint capacity; ///< The available space for storing items - -public: - SmallVector() : data(NULL), items(0), capacity(0) { } - - /** - * Copy constructor. - * @param other The other vector to copy. - */ - SmallVector(const SmallVector &other) : data(NULL), items(0), capacity(0) - { - this->Assign(other); - } - - /** - * Generic copy constructor. - * @param other The other vector to copy. - */ - template - SmallVector(const SmallVector &other) : data(NULL), items(0), capacity(0) - { - this->Assign(other); - } - - /** - * Assignment. - * @param other The other vector to assign. - */ - SmallVector &operator=(const SmallVector &other) - { - this->Assign(other); - return *this; - } - - /** - * Generic assignment. - * @param other The other vector to assign. - */ - template - SmallVector &operator=(const SmallVector &other) - { - this->Assign(other); - return *this; - } - - ~SmallVector() - { - free(this->data); - } - - /** - * Assign items from other vector. - */ - template - inline void Assign(const SmallVector &other) - { - if ((const void *)&other == (void *)this) return; - - this->Clear(); - if (other.Length() > 0) MemCpyT(this->Append(other.Length()), other.Begin(), other.Length()); - } - - /** - * Remove all items from the list. - */ - inline void Clear() - { - /* In fact we just reset the item counter avoiding the need to - * probably reallocate the same amount of memory the list was - * previously using. */ - this->items = 0; - } - - /** - * Remove all items from the list and free allocated memory. - */ - inline void Reset() - { - this->items = 0; - this->capacity = 0; - free(data); - data = NULL; - } - - /** - * Compact the list down to the smallest block size boundary. - */ - inline void Compact() - { - uint capacity = Align(this->items, S); - if (capacity >= this->capacity) return; - - this->capacity = capacity; - this->data = ReallocT(this->data, this->capacity); - } - - /** - * Append an item and return it. - * @param to_add the number of items to append - * @return pointer to newly allocated item - */ - inline T *Append(uint to_add = 1) - { - uint begin = this->items; - this->items += to_add; - - if (this->items > this->capacity) { - this->capacity = Align(this->items, S); - this->data = ReallocT(this->data, this->capacity); - } - - return &this->data[begin]; - } - - /** - * Set the size of the vector, effectively truncating items from the end or appending uninitialised ones. - * @param num_items Target size. - */ - inline void Resize(uint num_items) - { - this->items = num_items; - - if (this->items > this->capacity) { - this->capacity = Align(this->items, S); - this->data = ReallocT(this->data, this->capacity); - } - } - - /** - * Insert a new item at a specific position into the vector, moving all following items. - * @param item Position at which the new item should be inserted - * @return pointer to the new item - */ - inline T *Insert(T *item) - { - assert(item >= this->Begin() && item <= this->End()); - - size_t to_move = this->End() - item; - size_t start = item - this->Begin(); - - this->Append(); - if (to_move > 0) MemMoveT(this->Begin() + start + 1, this->Begin() + start, to_move); - return this->Begin() + start; - } - - /** - * Search for the first occurrence of an item. - * The '!=' operator of T is used for comparison. - * @param item Item to search for - * @return The position of the item, or End() when not present - */ - inline const T *Find(const T &item) const - { - const T *pos = this->Begin(); - const T *end = this->End(); - while (pos != end && *pos != item) pos++; - return pos; - } - - /** - * Search for the first occurrence of an item. - * The '!=' operator of T is used for comparison. - * @param item Item to search for - * @return The position of the item, or End() when not present - */ - inline T *Find(const T &item) - { - T *pos = this->Begin(); - const T *end = this->End(); - while (pos != end && *pos != item) pos++; - return pos; - } - - /** - * Search for the first occurrence of an item. - * The '!=' operator of T is used for comparison. - * @param item Item to search for - * @return The position of the item, or -1 when not present - */ - inline int FindIndex(const T &item) const - { - int index = 0; - const T *pos = this->Begin(); - const T *end = this->End(); - while (pos != end && *pos != item) { - pos++; - index++; - } - return pos == end ? -1 : index; - } - - /** - * Tests whether a item is present in the vector. - * The '!=' operator of T is used for comparison. - * @param item Item to test for - * @return true iff the item is present - */ - inline bool Contains(const T &item) const - { - return this->Find(item) != this->End(); - } - - /** - * Removes given item from this vector - * @param item item to remove - * @note it has to be pointer to item in this map. It is overwritten by the last item. - */ - inline void Erase(T *item) - { - assert(item >= this->Begin() && item < this->End()); - *item = this->data[--this->items]; - } - - /** - * Remove items from the vector while preserving the order of other items. - * @param pos First item to remove. - * @param count Number of consecutive items to remove. - */ - void ErasePreservingOrder(uint pos, uint count = 1) - { - ErasePreservingOrder(this->data + pos, count); - } - - /** - * Remove items from the vector while preserving the order of other items. - * @param item First item to remove. - * @param count Number of consecutive items to remove. - */ - inline void ErasePreservingOrder(T *item, uint count = 1) - { - if (count == 0) return; - assert(item >= this->Begin()); - assert(item + count <= this->End()); - - this->items -= count; - ptrdiff_t to_move = this->End() - item; - if (to_move > 0) MemMoveT(item, item + count, to_move); - } - - /** - * Tests whether a item is present in the vector, and appends it to the end if not. - * The '!=' operator of T is used for comparison. - * @param item Item to test for - * @return true iff the item is was already present - */ - inline bool Include(const T &item) - { - bool is_member = this->Contains(item); - if (!is_member) *this->Append() = item; - return is_member; - } - - /** - * Get the number of items in the list. - * - * @return The number of items in the list. - */ - inline uint Length() const - { - return this->items; - } - - /** - * Get the pointer to the first item (const) - * - * @return the pointer to the first item - */ - inline const T *Begin() const - { - return this->data; - } - - /** - * Get the pointer to the first item - * - * @return the pointer to the first item - */ - inline T *Begin() - { - return this->data; - } - - /** - * Get the pointer behind the last valid item (const) - * - * @return the pointer behind the last valid item - */ - inline const T *End() const - { - return &this->data[this->items]; - } - - /** - * Get the pointer behind the last valid item - * - * @return the pointer behind the last valid item - */ - inline T *End() - { - return &this->data[this->items]; - } - - /** - * Get the pointer to item "number" (const) - * - * @param index the position of the item - * @return the pointer to the item - */ - inline const T *Get(uint index) const - { - /* Allow access to the 'first invalid' item */ - assert(index <= this->items); - return &this->data[index]; - } - - /** - * Get the pointer to item "number" - * - * @param index the position of the item - * @return the pointer to the item - */ - inline T *Get(uint index) - { - /* Allow access to the 'first invalid' item */ - assert(index <= this->items); - return &this->data[index]; - } - - /** - * Get item "number" (const) - * - * @param index the position of the item - * @return the item - */ - inline const T &operator[](uint index) const - { - assert(index < this->items); - return this->data[index]; - } - - /** - * Get item "number" - * - * @param index the position of the item - * @return the item - */ - inline T &operator[](uint index) - { - assert(index < this->items); - return this->data[index]; - } -}; - +template +inline bool include(std::vector& vec, const T &item) +{ + const bool is_member = std::find(vec.begin(), vec.end(), item) != vec.end(); + if (!is_member) vec.emplace_back(item); + return is_member; +} /** - * Simple vector template class, with automatic free. + * Helper function to get the index of an item + * Consider using std::set, std::unordered_set or std::flat_set in new code * - * @note There are no asserts in the class so you have - * to care about that you grab an item which is - * inside the list. + * @param vec A reference to the vector to be extended + * @param item Reference to the item to be search for * - * @param T The type of the items stored, must be a pointer - * @param S The steps of allocation + * @return Index of element if found, otherwise -1 */ -template -class AutoFreeSmallVector : public SmallVector { -public: - ~AutoFreeSmallVector() - { - this->Clear(); - } +template +int find_index(std::vector const& vec, T const& item) +{ + auto const it = std::find(vec.begin(), vec.end(), item); + if (it != vec.end()) return it - vec.begin(); - /** - * Remove all items from the list. - */ - inline void Clear() - { - for (uint i = 0; i < this->items; i++) { - free(this->data[i]); - } - - this->items = 0; - } -}; - -/** - * Simple vector template class, with automatic delete. - * - * @note There are no asserts in the class so you have - * to care about that you grab an item which is - * inside the list. - * - * @param T The type of the items stored, must be a pointer - * @param S The steps of allocation - */ -template -class AutoDeleteSmallVector : public SmallVector { -public: - ~AutoDeleteSmallVector() - { - this->Clear(); - } - - /** - * Remove all items from the list. - */ - inline void Clear() - { - for (uint i = 0; i < this->items; i++) { - delete this->data[i]; - } - - this->items = 0; - } -}; - -typedef AutoFreeSmallVector StringList; ///< Type for a list of strings. + return -1; +} #endif /* SMALLVEC_TYPE_HPP */ diff --git a/src/core/sort_func.hpp b/src/core/sort_func.hpp deleted file mode 100644 index 470a0ccf4d..0000000000 --- a/src/core/sort_func.hpp +++ /dev/null @@ -1,89 +0,0 @@ -/* $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. - * 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 sort_func.hpp Functions related to sorting operations. */ - -#ifndef SORT_FUNC_HPP -#define SORT_FUNC_HPP - -#include "mem_func.hpp" - -/** - * Type safe qsort() - * - * @note Use this sort for irregular sorted data. - * - * @param base Pointer to the first element of the array to be sorted. - * @param num Number of elements in the array pointed by base. - * @param comparator Function that compares two elements. - * @param desc Sort descending. - */ -template -static inline void QSortT(T *base, uint num, int (CDECL *comparator)(const T*, const T*), bool desc = false) -{ - if (num < 2) return; - - qsort(base, num, sizeof(T), (int (CDECL *)(const void *, const void *))comparator); - - if (desc) MemReverseT(base, num); -} - -/** - * Type safe Gnome Sort. - * - * This is a slightly modified Gnome search. The basic - * Gnome search tries to sort already sorted list parts. - * The modification skips these. - * - * @note Use this sort for presorted / regular sorted data. - * - * @param base Pointer to the first element of the array to be sorted. - * @param num Number of elements in the array pointed by base. - * @param comparator Function that compares two elements. - * @param desc Sort descending. - */ -template -static inline void GSortT(T *base, uint num, int (CDECL *comparator)(const T*, const T*), bool desc = false) -{ - if (num < 2) return; - - assert(base != NULL); - assert(comparator != NULL); - - T *a = base; - T *b = base + 1; - uint offset = 0; - - while (num > 1) { - const int diff = comparator(a, b); - if ((!desc && diff <= 0) || (desc && diff >= 0)) { - if (offset != 0) { - /* Jump back to the last direction switch point */ - a += offset; - b += offset; - offset = 0; - continue; - } - - a++; - b++; - num--; - } else { - Swap(*a, *b); - - if (a == base) continue; - - a--; - b--; - offset++; - } - } -} - -#endif /* SORT_FUNC_HPP */ diff --git a/src/core/string_compare_type.hpp b/src/core/string_compare_type.hpp index 77180747ba..1c6a411d09 100644 --- a/src/core/string_compare_type.hpp +++ b/src/core/string_compare_type.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/cpu.cpp b/src/cpu.cpp index 9393ea0613..87aa841324 100644 --- a/src/cpu.cpp +++ b/src/cpu.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. @@ -18,7 +16,7 @@ /* rdtsc for MSC_VER, uses simple inline assembly, or _rdtsc * from external win64.asm because VS2005 does not support inline assembly */ -#if defined(_MSC_VER) && !defined(RDTSC_AVAILABLE) +#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) && !defined(RDTSC_AVAILABLE) #include uint64 ottd_rdtsc() { @@ -35,7 +33,7 @@ unsigned __int64 ottd_rdtsc(); #endif /* rdtsc for all other *nix-en (hopefully). Use GCC syntax */ -#if (defined(__i386__) || defined(__x86_64__)) && !defined(__DJGPP__) && !defined(RDTSC_AVAILABLE) +#if (defined(__i386__) || defined(__x86_64__)) && !defined(RDTSC_AVAILABLE) uint64 ottd_rdtsc() { uint32 high, low; @@ -87,7 +85,7 @@ uint64 ottd_rdtsc() {return 0;} * Other platforms/architectures don't have CPUID, so zero the info and then * most (if not all) of the features are set as if they do not exist. */ -#if defined(_MSC_VER) +#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_X64)) void ottd_cpuid(int info[4], int type) { __cpuid(info, type); diff --git a/src/cpu.h b/src/cpu.h index 08495dfc14..13eaa4f991 100644 --- a/src/cpu.h +++ b/src/cpu.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/crashlog.cpp b/src/crashlog.cpp index ab27837078..c7cf48154c 100644 --- a/src/crashlog.cpp +++ b/src/crashlog.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. @@ -52,27 +50,27 @@ # include # include FT_FREETYPE_H #endif /* WITH_FREETYPE */ -#if defined(WITH_ICU_LAYOUT) || defined(WITH_ICU_SORT) +#if defined(WITH_ICU_LX) || defined(WITH_ICU_I18N) # include -#endif /* WITH_ICU_SORT || WITH_ICU_LAYOUT */ -#ifdef WITH_LZMA +#endif /* WITH_ICU_LX || WITH_ICU_I18N */ +#ifdef WITH_LIBLZMA # include #endif #ifdef WITH_LZO #include #endif -#ifdef WITH_SDL +#if defined(WITH_SDL) || defined(WITH_SDL2) # include -#endif /* WITH_SDL */ +#endif /* WITH_SDL || WITH_SDL2 */ #ifdef WITH_ZLIB # include #endif #include "safeguards.h" -/* static */ const char *CrashLog::message = NULL; -/* static */ char *CrashLog::gamelog_buffer = NULL; -/* static */ const char *CrashLog::gamelog_last = NULL; +/* static */ const char *CrashLog::message = nullptr; +/* static */ char *CrashLog::gamelog_buffer = nullptr; +/* static */ const char *CrashLog::gamelog_last = nullptr; char *CrashLog::LogCompiler(char *buffer, const char *last) const { @@ -168,18 +166,18 @@ char *CrashLog::LogConfiguration(char *buffer, const char *last) const " Sound driver: %s\n" " Sound set: %s (%u)\n" " Video driver: %s\n\n", - BlitterFactory::GetCurrentBlitter() == NULL ? "none" : BlitterFactory::GetCurrentBlitter()->GetName(), - BaseGraphics::GetUsedSet() == NULL ? "none" : BaseGraphics::GetUsedSet()->name, - BaseGraphics::GetUsedSet() == NULL ? UINT32_MAX : BaseGraphics::GetUsedSet()->version, - _current_language == NULL ? "none" : _current_language->file, - MusicDriver::GetInstance() == NULL ? "none" : MusicDriver::GetInstance()->GetName(), - BaseMusic::GetUsedSet() == NULL ? "none" : BaseMusic::GetUsedSet()->name, - BaseMusic::GetUsedSet() == NULL ? UINT32_MAX : BaseMusic::GetUsedSet()->version, + BlitterFactory::GetCurrentBlitter() == nullptr ? "none" : BlitterFactory::GetCurrentBlitter()->GetName(), + BaseGraphics::GetUsedSet() == nullptr ? "none" : BaseGraphics::GetUsedSet()->name, + BaseGraphics::GetUsedSet() == nullptr ? UINT32_MAX : BaseGraphics::GetUsedSet()->version, + _current_language == nullptr ? "none" : _current_language->file, + MusicDriver::GetInstance() == nullptr ? "none" : MusicDriver::GetInstance()->GetName(), + BaseMusic::GetUsedSet() == nullptr ? "none" : BaseMusic::GetUsedSet()->name, + BaseMusic::GetUsedSet() == nullptr ? UINT32_MAX : BaseMusic::GetUsedSet()->version, _networking ? (_network_server ? "server" : "client") : "no", - SoundDriver::GetInstance() == NULL ? "none" : SoundDriver::GetInstance()->GetName(), - BaseSounds::GetUsedSet() == NULL ? "none" : BaseSounds::GetUsedSet()->name, - BaseSounds::GetUsedSet() == NULL ? UINT32_MAX : BaseSounds::GetUsedSet()->version, - VideoDriver::GetInstance() == NULL ? "none" : VideoDriver::GetInstance()->GetName() + SoundDriver::GetInstance() == nullptr ? "none" : SoundDriver::GetInstance()->GetName(), + BaseSounds::GetUsedSet() == nullptr ? "none" : BaseSounds::GetUsedSet()->name, + BaseSounds::GetUsedSet() == nullptr ? UINT32_MAX : BaseSounds::GetUsedSet()->version, + VideoDriver::GetInstance() == nullptr ? "none" : VideoDriver::GetInstance()->GetName() ); buffer += seprintf(buffer, last, @@ -195,16 +193,15 @@ char *CrashLog::LogConfiguration(char *buffer, const char *last) const ); buffer += seprintf(buffer, last, "AI Configuration (local: %i) (current: %i):\n", (int)_local_company, (int)_current_company); - const Company *c; - FOR_ALL_COMPANIES(c) { - if (c->ai_info == NULL) { + for (const Company *c : Company::Iterate()) { + if (c->ai_info == nullptr) { buffer += seprintf(buffer, last, " %2i: Human\n", (int)c->index); } else { buffer += seprintf(buffer, last, " %2i: %s (v%d)\n", (int)c->index, c->ai_info->GetName(), c->ai_info->GetVersion()); } } - if (Game::GetInfo() != NULL) { + if (Game::GetInfo() != nullptr) { buffer += seprintf(buffer, last, " GS: %s (v%d)\n", Game::GetInfo()->GetName(), Game::GetInfo()->GetVersion()); } buffer += seprintf(buffer, last, "\n"); @@ -240,21 +237,21 @@ char *CrashLog::LogLibraries(char *buffer, const char *last) const buffer += seprintf(buffer, last, " FreeType: %d.%d.%d\n", major, minor, patch); #endif /* WITH_FREETYPE */ -#if defined(WITH_ICU_LAYOUT) || defined(WITH_ICU_SORT) +#if defined(WITH_ICU_LX) || defined(WITH_ICU_I18N) /* 4 times 0-255, separated by dots (.) and a trailing '\0' */ char buf[4 * 3 + 3 + 1]; UVersionInfo ver; u_getVersion(ver); u_versionToString(ver, buf); -#ifdef WITH_ICU_SORT +#ifdef WITH_ICU_I18N buffer += seprintf(buffer, last, " ICU i18n: %s\n", buf); #endif -#ifdef WITH_ICU_LAYOUT +#ifdef WITH_ICU_LX buffer += seprintf(buffer, last, " ICU lx: %s\n", buf); #endif -#endif /* WITH_ICU_SORT || WITH_ICU_LAYOUT */ +#endif /* WITH_ICU_LX || WITH_ICU_I18N */ -#ifdef WITH_LZMA +#ifdef WITH_LIBLZMA buffer += seprintf(buffer, last, " LZMA: %s\n", lzma_version_string()); #endif @@ -263,13 +260,17 @@ char *CrashLog::LogLibraries(char *buffer, const char *last) const #endif #ifdef WITH_PNG - buffer += seprintf(buffer, last, " PNG: %s\n", png_get_libpng_ver(NULL)); + buffer += seprintf(buffer, last, " PNG: %s\n", png_get_libpng_ver(nullptr)); #endif /* WITH_PNG */ #ifdef WITH_SDL - const SDL_version *v = SDL_Linked_Version(); - buffer += seprintf(buffer, last, " SDL: %d.%d.%d\n", v->major, v->minor, v->patch); -#endif /* WITH_SDL */ + const SDL_version *sdl_v = SDL_Linked_Version(); + buffer += seprintf(buffer, last, " SDL1: %d.%d.%d\n", sdl_v->major, sdl_v->minor, sdl_v->patch); +#elif defined(WITH_SDL2) + SDL_version sdl2_v; + SDL_GetVersion(&sdl2_v); + buffer += seprintf(buffer, last, " SDL2: %d.%d.%d\n", sdl2_v.major, sdl2_v.minor, sdl2_v.patch); +#endif #ifdef WITH_ZLIB buffer += seprintf(buffer, last, " Zlib: %s\n", zlibVersion()); @@ -303,7 +304,7 @@ char *CrashLog::LogGamelog(char *buffer, const char *last) const } /** - * Writes any recent news messages to the buffer. + * Writes up to 32 recent news messages to the buffer, with the most recent first. * @param buffer The begin where to write at. * @param last The last position in the buffer to write to. * @return the position of the \c '\0' character after the buffer. @@ -312,7 +313,8 @@ char *CrashLog::LogRecentNews(char *buffer, const char *last) const { buffer += seprintf(buffer, last, "Recent news messages:\n"); - for (NewsItem *news = _oldest_news; news != NULL; news = news->next) { + int i = 0; + for (NewsItem *news = _latest_news; i < 32 && news != nullptr; news = news->prev, i++) { YearMonthDay ymd; ConvertDateToYMD(news->date, &ymd); buffer += seprintf(buffer, last, "(%i-%02i-%02i) StringID: %u, Type: %u, Ref1: %u, %u, Ref2: %u, %u\n", @@ -331,7 +333,7 @@ char *CrashLog::LogRecentNews(char *buffer, const char *last) const */ char *CrashLog::FillCrashLog(char *buffer, const char *last) const { - time_t cur_time = time(NULL); + time_t cur_time = time(nullptr); buffer += seprintf(buffer, last, "*** OpenTTD Crash Report ***\n\n"); buffer += seprintf(buffer, last, "Crash at: %s", asctime(gmtime(&cur_time))); @@ -369,7 +371,7 @@ bool CrashLog::WriteCrashLog(const char *buffer, char *filename, const char *fil seprintf(filename, filename_last, "%scrash.log", _personal_dir); FILE *file = FioFOpenFile(filename, "w", NO_DIRECTORY); - if (file == NULL) return false; + if (file == nullptr) return false; size_t len = strlen(buffer); size_t written = fwrite(buffer, 1, len, file); @@ -396,7 +398,7 @@ 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 * initialised, there is a big chance the rest is initialised too. */ - if (_m == NULL) return false; + if (_m == nullptr) return false; try { GamelogEmergency(); @@ -421,7 +423,7 @@ bool CrashLog::WriteSavegame(char *filename, const char *filename_last) const bool CrashLog::WriteScreenshot(char *filename, const char *filename_last) const { /* Don't draw when we have invalid screen size */ - if (_screen.width < 1 || _screen.height < 1 || _screen.dst_ptr == NULL) return false; + if (_screen.width < 1 || _screen.height < 1 || _screen.dst_ptr == nullptr) return false; bool res = MakeScreenshot(SC_CRASHLOG, "crash"); if (res) strecpy(filename, _full_screenshot_name, filename_last); @@ -504,7 +506,7 @@ bool CrashLog::MakeCrashLog() const */ /* static */ void CrashLog::AfterCrashLogCleanup() { - if (MusicDriver::GetInstance() != NULL) MusicDriver::GetInstance()->Stop(); - if (SoundDriver::GetInstance() != NULL) SoundDriver::GetInstance()->Stop(); - if (VideoDriver::GetInstance() != NULL) VideoDriver::GetInstance()->Stop(); + if (MusicDriver::GetInstance() != nullptr) MusicDriver::GetInstance()->Stop(); + if (SoundDriver::GetInstance() != nullptr) SoundDriver::GetInstance()->Stop(); + if (VideoDriver::GetInstance() != nullptr) VideoDriver::GetInstance()->Stop(); } diff --git a/src/crashlog.h b/src/crashlog.h index b9bc8afa24..7f1ff47edd 100644 --- a/src/crashlog.h +++ b/src/crashlog.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. @@ -48,7 +46,7 @@ protected: * 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 NULL. + * @param message Message passed to use for possible errors. Can be nullptr. * @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/currency.cpp b/src/currency.cpp index b87f77393b..b6d6821055 100644 --- a/src/currency.cpp +++ b/src/currency.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. @@ -64,6 +62,9 @@ static const CurrencySpec origin_currency_specs[CURRENCY_END] = { { 4901, "", CF_NOEURO, "", NBSP "Rls", 1, STR_GAME_OPTIONS_CURRENCY_IRR }, ///< Iranian Rial { 80, "", CF_NOEURO, "", NBSP "rub", 1, STR_GAME_OPTIONS_CURRENCY_RUB }, ///< New Russian Ruble { 24, "", CF_NOEURO, "$", "", 0, STR_GAME_OPTIONS_CURRENCY_MXN }, ///< Mexican peso + { 40, "", CF_NOEURO, "NTD" NBSP, "", 0, STR_GAME_OPTIONS_CURRENCY_NTD }, ///< new taiwan dollar + { 8, "", CF_NOEURO, "\xC2\xA5", "", 0, STR_GAME_OPTIONS_CURRENCY_CNY }, ///< chinese renminbi + { 10, "", CF_NOEURO, "HKD" NBSP, "", 0, STR_GAME_OPTIONS_CURRENCY_HKD }, ///< hong kong dollar }; /** Array of currencies used by the system */ diff --git a/src/currency.h b/src/currency.h index 401df5ec1f..58c385a8b4 100644 --- a/src/currency.h +++ b/src/currency.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. @@ -60,6 +58,9 @@ enum Currencies { CURRENCY_IRR, ///< Iranian Rial CURRENCY_RUB, ///< New Russian Ruble CURRENCY_MXN, ///< Mexican Peso + CURRENCY_NTD, ///< New Taiwan Dollar + CURRENCY_CNY, ///< Chinese Renminbi + CURRENCY_HKD, ///< Hong Kong Dollar CURRENCY_END, ///< always the last item }; diff --git a/src/date.cpp b/src/date.cpp index 9c25af40ee..97758a3ebf 100644 --- a/src/date.cpp +++ b/src/date.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. @@ -20,6 +18,7 @@ #include "rail_gui.h" #include "linkgraph/linkgraph.h" #include "saveload/saveload.h" +#include "newgrf_profiling.h" #include "safeguards.h" @@ -29,6 +28,8 @@ Date _date; ///< Current date in days (day counter) DateFract _date_fract; ///< Fractional part of the day. uint16 _tick_counter; ///< Ever incrementing (and sometimes wrapping) tick counter for setting off various events +int32 _old_ending_year_slv_105; ///< Old ending year for savegames before SLV_105 + /** * Set the date. * @param date New date @@ -195,33 +196,26 @@ static void OnNewYear() VehiclesYearlyLoop(); TownsYearlyLoop(); InvalidateWindowClassesData(WC_BUILD_STATION); -#ifdef ENABLE_NETWORK if (_network_server) NetworkServerYearlyLoop(); -#endif /* ENABLE_NETWORK */ if (_cur_year == _settings_client.gui.semaphore_build_before) ResetSignalVariant(); - /* check if we reached end of the game */ - if (_cur_year == ORIGINAL_END_YEAR) { + /* check if we reached end of the game (end of ending year) */ + if (_cur_year == _settings_game.game_creation.ending_year + 1) { ShowEndGameChart(); /* check if we reached the maximum year, decrement dates by a year */ } else if (_cur_year == MAX_YEAR + 1) { - Vehicle *v; int days_this_year; _cur_year--; days_this_year = IsLeapYear(_cur_year) ? DAYS_IN_LEAP_YEAR : DAYS_IN_YEAR; _date -= days_this_year; - FOR_ALL_VEHICLES(v) v->date_of_last_service -= days_this_year; + for (Vehicle *v : Vehicle::Iterate()) v->date_of_last_service -= days_this_year; + for (LinkGraph *lg : LinkGraph::Iterate()) lg->ShiftDates(-days_this_year); - LinkGraph *lg; - FOR_ALL_LINK_GRAPHS(lg) lg->ShiftDates(-days_this_year); - -#ifdef ENABLE_NETWORK /* Because the _date wraps here, and text-messages expire by game-days, we have to clean out * all of them if the date is set back, else those messages will hang for ever */ NetworkInitChatMessage(); -#endif /* ENABLE_NETWORK */ } if (_settings_client.gui.auto_euro) CheckSwitchToEuro(); @@ -244,9 +238,7 @@ static void OnNewMonth() IndustryMonthlyLoop(); SubsidyMonthlyLoop(); StationMonthlyLoop(); -#ifdef ENABLE_NETWORK if (_network_server) NetworkServerMonthlyLoop(); -#endif /* ENABLE_NETWORK */ } /** @@ -254,9 +246,11 @@ static void OnNewMonth() */ static void OnNewDay() { -#ifdef ENABLE_NETWORK + if (!_newgrf_profilers.empty() && _newgrf_profile_end_date <= _date) { + NewGRFProfiler::FinishAll(); + } + if (_network_server) NetworkServerDailyLoop(); -#endif /* ENABLE_NETWORK */ DisasterDailyLoop(); IndustryDailyLoop(); diff --git a/src/date_func.h b/src/date_func.h index 6bbde59556..58b16bafdc 100644 --- a/src/date_func.h +++ b/src/date_func.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/date_gui.cpp b/src/date_gui.cpp index 468a74db99..4d8ff2a89e 100644 --- a/src/date_gui.cpp +++ b/src/date_gui.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. @@ -55,7 +53,7 @@ struct SetDateWindow : Window { this->date.year = Clamp(this->date.year, min_year, max_year); } - virtual Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number) + Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number) override { Point pt = { this->parent->left + this->parent->width / 2 - sm_width / 2, this->parent->top + this->parent->height / 2 - sm_height / 2 }; return pt; @@ -68,21 +66,21 @@ struct SetDateWindow : Window { void ShowDateDropDown(int widget) { int selected; - DropDownList *list = new DropDownList(); + DropDownList list; switch (widget) { default: NOT_REACHED(); case WID_SD_DAY: for (uint i = 0; i < 31; i++) { - *list->Append() = new DropDownListStringItem(STR_DAY_NUMBER_1ST + i, i + 1, false); + list.emplace_back(new DropDownListStringItem(STR_DAY_NUMBER_1ST + i, i + 1, false)); } selected = this->date.day; break; case WID_SD_MONTH: for (uint i = 0; i < 12; i++) { - *list->Append() = new DropDownListStringItem(STR_MONTH_JAN + i, i, false); + list.emplace_back(new DropDownListStringItem(STR_MONTH_JAN + i, i, false)); } selected = this->date.month; break; @@ -91,16 +89,16 @@ struct SetDateWindow : Window { for (Year i = this->min_year; i <= this->max_year; i++) { DropDownListParamStringItem *item = new DropDownListParamStringItem(STR_JUST_INT, i, false); item->SetParam(0, i); - *list->Append() = item; + list.emplace_back(item); } selected = this->date.year; break; } - ShowDropDownList(this, list, selected, widget); + ShowDropDownList(this, std::move(list), selected, widget); } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { Dimension d = {0, 0}; switch (widget) { @@ -129,7 +127,7 @@ struct SetDateWindow : Window { *size = d; } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { switch (widget) { case WID_SD_DAY: SetDParam(0, this->date.day - 1 + STR_DAY_NUMBER_1ST); break; @@ -138,7 +136,7 @@ struct SetDateWindow : Window { } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_SD_DAY: @@ -148,13 +146,13 @@ struct SetDateWindow : Window { break; case WID_SD_SET_DATE: - if (this->callback != NULL) this->callback(this, ConvertYMDToDate(this->date.year, this->date.month, this->date.day)); + if (this->callback != nullptr) this->callback(this, ConvertYMDToDate(this->date.year, this->date.month, this->date.day)); delete this; break; } } - virtual void OnDropdownSelect(int widget, int index) + void OnDropdownSelect(int widget, int index) override { switch (widget) { case WID_SD_DAY: @@ -197,7 +195,7 @@ static const NWidgetPart _nested_set_date_widgets[] = { /** Description of the date setting window. */ static WindowDesc _set_date_desc( - WDP_CENTER, NULL, 0, 0, + WDP_CENTER, nullptr, 0, 0, WC_SET_DATE, WC_NONE, 0, _nested_set_date_widgets, lengthof(_nested_set_date_widgets) diff --git a/src/date_gui.h b/src/date_gui.h index 314baba3ca..8d41ee3e71 100644 --- a/src/date_gui.h +++ b/src/date_gui.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/date_type.h b/src/date_type.h index b20ace91ec..4cbcfac4ed 100644 --- a/src/date_type.h +++ b/src/date_type.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. @@ -86,6 +84,8 @@ static const Year MIN_YEAR = 0; /** The default starting year */ static const Year DEF_START_YEAR = 1950; +/** The default scoring end year */ +static const Year DEF_END_YEAR = ORIGINAL_END_YEAR - 1; /** * MAX_YEAR, nicely rounded value of the number of years that can diff --git a/src/debug.cpp b/src/debug.cpp index 5c140122a6..7f7d5e7563 100644 --- a/src/debug.cpp +++ b/src/debug.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. @@ -26,10 +24,8 @@ #include -#if defined(ENABLE_NETWORK) #include "network/network_admin.h" SOCKET _debug_socket = INVALID_SOCKET; -#endif /* ENABLE_NETWORK */ #include "safeguards.h" @@ -117,7 +113,6 @@ static void debug_print(const char *dbg, const char *buf) #ifdef __ANDROID__ __android_log_print(ANDROID_LOG_INFO, "OpenTTD", "[%s] %s", dbg, buf); #endif -#if defined(ENABLE_NETWORK) if (_debug_socket != INVALID_SOCKET) { char buf2[1024 + 32]; @@ -127,17 +122,16 @@ static void debug_print(const char *dbg, const char *buf) send(_debug_socket, buf2, (int)strlen(buf2), 0); return; } -#endif /* ENABLE_NETWORK */ if (strcmp(dbg, "desync") == 0) { static FILE *f = FioFOpenFile("commands-out.log", "wb", AUTOSAVE_DIR); - if (f == NULL) return; + if (f == nullptr) return; fprintf(f, "%s%s\n", GetLogPrefix(), buf); fflush(f); #ifdef RANDOM_DEBUG } else if (strcmp(dbg, "random") == 0) { static FILE *f = FioFOpenFile("random-out.log", "wb", AUTOSAVE_DIR); - if (f == NULL) return; + if (f == nullptr) return; fprintf(f, "%s\n", buf); fflush(f); @@ -152,9 +146,7 @@ static void debug_print(const char *dbg, const char *buf) #else fputs(buffer, stderr); #endif -#ifdef ENABLE_NETWORK NetworkAdminConsole(dbg, buf); -#endif /* ENABLE_NETWORK */ IConsoleDebug(dbg, buf); } } @@ -212,7 +204,7 @@ void SetDebugString(const char *s) while (*s >= 'a' && *s <= 'z') s++; /* check debugging levels */ - p = NULL; + p = nullptr; for (i = debug_level; i != endof(debug_level); ++i) { if (s == t + strlen(i->name) && strncmp(t, i->name, s - t) == 0) { p = i->level; @@ -223,7 +215,7 @@ void SetDebugString(const char *s) if (*s == '=') s++; v = strtoul(s, &end, 0); s = end; - if (p != NULL) { + if (p != nullptr) { *p = v; } else { ShowInfoF("Unknown debug level '%.*s'", (int)(s - t), t); @@ -258,13 +250,13 @@ const char *GetDebugString() /** * Get the prefix for logs; if show_date_in_logs is enabled it returns * the date, otherwise it returns nothing. - * @return the prefix for logs (do not free), never NULL + * @return the prefix for logs (do not free), never nullptr */ const char *GetLogPrefix() { static char _log_prefix[24]; if (_settings_client.gui.show_date_in_logs) { - time_t cur_time = time(NULL); + time_t cur_time = time(nullptr); strftime(_log_prefix, sizeof(_log_prefix), "[%Y-%m-%d %H:%M:%S] ", localtime(&cur_time)); } else { *_log_prefix = '\0'; diff --git a/src/debug.h b/src/debug.h index ce454c962e..1a0955b55b 100644 --- a/src/debug.h +++ b/src/debug.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. @@ -13,6 +11,7 @@ #define DEBUG_H #include "cpu.h" +#include /* Debugging messages policy: * These should be the severities used for direct DEBUG() calls @@ -83,21 +82,40 @@ const char *GetDebugString(); * * TIC() / TOC() creates its own block, so make sure not the mangle * it with another block. + * + * The output is counted in CPU cycles, and not comparable across + * machines. Mainly useful for local optimisations. **/ #define TIC() {\ uint64 _xxx_ = ottd_rdtsc();\ - static uint64 __sum__ = 0;\ - static uint32 __i__ = 0; + static uint64 _sum_ = 0;\ + static uint32 _i_ = 0; #define TOC(str, count)\ - __sum__ += ottd_rdtsc() - _xxx_;\ - if (++__i__ == count) {\ - DEBUG(misc, 0, "[%s] " OTTD_PRINTF64 " [avg: %.1f]", str, __sum__, __sum__/(double)__i__);\ - __i__ = 0;\ - __sum__ = 0;\ + _sum_ += ottd_rdtsc() - _xxx_;\ + if (++_i_ == count) {\ + DEBUG(misc, 0, "[%s] " OTTD_PRINTF64 " [avg: %.1f]", str, _sum_, _sum_/(double)_i_);\ + _i_ = 0;\ + _sum_ = 0;\ }\ } +/* Chrono based version. The output is in microseconds. */ +#define TICC() {\ + auto _start_ = std::chrono::high_resolution_clock::now();\ + static uint64 _sum_ = 0;\ + static uint32 _i_ = 0; + +#define TOCC(str, _count_)\ + _sum_ += (std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - _start_)).count();\ + if (++_i_ == _count_) {\ + DEBUG(misc, 0, "[%s] " OTTD_PRINTF64 " us [avg: %.1f us]", str, _sum_, _sum_/(double)_i_);\ + _i_ = 0;\ + _sum_ = 0;\ + }\ +} + + void ShowInfo(const char *str); void CDECL ShowInfoF(const char *str, ...) WARN_FORMAT(1, 2); diff --git a/src/dedicated.cpp b/src/dedicated.cpp index ce383ee4a5..8ab035e61d 100644 --- a/src/dedicated.cpp +++ b/src/dedicated.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. @@ -11,21 +9,18 @@ #include "stdafx.h" -#ifdef ENABLE_NETWORK +char *_log_file = nullptr; ///< File to reroute output of a forked OpenTTD to +FILE *_log_fd = nullptr; ///< File to reroute output of a forked OpenTTD to -char *_log_file = NULL; ///< File to reroute output of a forked OpenTTD to -FILE *_log_fd = NULL; ///< File to reroute output of a forked OpenTTD to - -#if defined(UNIX) && !defined(__MORPHOS__) +#if defined(UNIX) #include #include "safeguards.h" -#if (defined(SUNOS) && !defined(_LP64) && !defined(_I32LPx)) || defined(__HAIKU__) +#if defined(SUNOS) && !defined(_LP64) && !defined(_I32LPx) /* Solaris has, in certain situation, pid_t defined as long, while in other * cases it has it defined as int... this handles all cases nicely. - * Haiku has also defined pid_t as a long. */ # define PRINTF_PID_T "%ld" #else @@ -44,7 +39,7 @@ void DedicatedFork() case 0: { // We're the child /* Open the log-file to log all stuff too */ _log_fd = fopen(_log_file, "a"); - if (_log_fd == NULL) { + if (_log_fd == nullptr) { perror("Unable to open logfile"); exit(1); } @@ -68,10 +63,3 @@ void DedicatedFork() } } #endif - -#else - -/** Empty helper function call for NOT(UNIX and not MORPHOS) systems */ -void DedicatedFork() {} - -#endif /* ENABLE_NETWORK */ diff --git a/src/depend/depend.cpp b/src/depend/depend.cpp index 9f8de891bd..5a3bd868de 100644 --- a/src/depend/depend.cpp +++ b/src/depend/depend.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. @@ -54,7 +52,7 @@ * * Copies the source string to the destination buffer with respect of the * terminating null-character and the last pointer to the last element in - * the destination buffer. If the last pointer is set to NULL no boundary + * the destination buffer. If the last pointer is set to nullptr no boundary * check is performed. * * @note usage: strecpy(dst, src, lastof(dst)); @@ -85,7 +83,7 @@ char *strecpy(char *dst, const char *src, const char *last) * * Appends the source string to the destination string with respect of the * terminating null-character and and the last pointer to the last element - * in the destination buffer. If the last pointer is set to NULL no + * in the destination buffer. If the last pointer is set to nullptr no * boundary check is performed. * * @note usage: strecat(dst, src, lastof(dst)); @@ -107,6 +105,23 @@ static char *strecat(char *dst, const char *src, const char *last) return strecpy(dst, src, last); } +#if defined(__CYGWIN__) +/** + * Version of strdup copied from glibc. + * Duplicate S, returning an identical malloc'd string. + * @param s The string to duplicate. + */ +char * +strdup (const char *s) +{ + size_t len = strlen(s) + 1; + void *n = malloc(len); + + if (n == NULL) return NULL; + return (char *) memcpy(n, s, len); +} +#endif + /** * Version of the standard free that accepts const pointers. * @param ptr The data to free. @@ -163,13 +178,13 @@ public: File(const char *filename) { this->fp = fopen(filename, "r"); - if (this->fp == NULL) { + if (this->fp == nullptr) { fprintf(stdout, "Could not open %s for reading\n", filename); exit(1); } this->dirname = strdup(filename); char *last = strrchr(this->dirname, '/'); - if (last != NULL) { + if (last != nullptr) { *last = '\0'; } else { *this->dirname = '\0'; @@ -247,7 +262,7 @@ public: * Create the lexer and fill the keywords table. * @param file the file to read from. */ - Lexer(const File *file) : file(file), current_char('\0'), string(NULL), token(TOKEN_UNKNOWN) + Lexer(const File *file) : file(file), current_char('\0'), string(nullptr), token(TOKEN_UNKNOWN) { this->keywords["define"] = TOKEN_DEFINE; this->keywords["defined"] = TOKEN_DEFINED; @@ -292,8 +307,8 @@ public: } /** - * Read the currenty processed string. - * @return the string, can be NULL. + * Read the currently processed string. + * @return the string, can be nullptr. */ const char *GetString() const { @@ -308,7 +323,7 @@ public: { for (;;) { free(this->string); - this->string = NULL; + this->string = nullptr; this->token = TOKEN_UNKNOWN; switch (this->current_char) { @@ -503,10 +518,13 @@ private: * @param dirname the directory to look in. * @param filename the file to look for. * @param local whether to look locally (in dirname) for the file. - * @return the absolute path, or NULL if the file doesn't exist. + * @return the absolute path, or nullptr if the file doesn't exist. */ const char *GeneratePath(const char *dirname, const char *filename, bool local) { + /* Ignore C++ standard library headers. */ + if (strchr(filename, '.') == nullptr) return nullptr; + if (local) { if (access(filename, R_OK) == 0) return strdup(filename); @@ -517,7 +535,7 @@ const char *GeneratePath(const char *dirname, const char *filename, bool local) while (*p == '.') { if (*(++p) == '.') { char *s = strrchr(path, '/'); - if (s != NULL) *s = '\0'; + if (s != nullptr) *s = '\0'; p += 2; } } @@ -535,7 +553,7 @@ const char *GeneratePath(const char *dirname, const char *filename, bool local) while (*p == '.') { if (*(++p) == '.') { char *s = strrchr(path, '/'); - if (s != NULL) *s = '\0'; + if (s != nullptr) *s = '\0'; p += 2; } } @@ -545,7 +563,7 @@ const char *GeneratePath(const char *dirname, const char *filename, bool local) if (access(path, R_OK) == 0) return strdup(path); } - return NULL; + return nullptr; } /** @@ -730,7 +748,7 @@ void ScanFile(const char *filename, const char *ext, bool header, bool verbose) break; } const char *h = GeneratePath(file.GetDirname(), lexer.GetString(), lexer.GetToken() == TOKEN_LOCAL); - if (h != NULL) { + if (h != nullptr) { StringMap::iterator it = _headers.find(h); if (it == _headers.end()) { it = (_headers.insert(StringMapItem(strdup(h), new StringSet()))).first; @@ -745,7 +763,7 @@ void ScanFile(const char *filename, const char *ext, bool header, bool verbose) char path[PATH_MAX]; strecpy(path, filename, lastof(path)); *(strrchr(path, '.')) = '\0'; - strecat(path, ext != NULL ? ext : ".o", lastof(path)); + strecat(path, ext != nullptr ? ext : ".o", lastof(path)); curfile = _files.find(path); if (curfile == _files.end()) { curfile = (_files.insert(StringMapItem(strdup(path), new StringSet()))).first; @@ -909,9 +927,9 @@ void ScanFile(const char *filename, const char *ext, bool header, bool verbose) int main(int argc, char *argv[]) { bool ignorenext = true; - char *filename = NULL; - char *ext = NULL; - char *delimiter = NULL; + char *filename = nullptr; + char *ext = nullptr; + char *delimiter = nullptr; bool append = false; bool verbose = false; @@ -936,25 +954,25 @@ int main(int argc, char *argv[]) /* Define */ if (strncmp(argv[i], "-D", 2) == 0) { char *p = strchr(argv[i], '='); - if (p != NULL) *p = '\0'; + if (p != nullptr) *p = '\0'; _defines.insert(strdup(&argv[i][2])); continue; } /* Output file */ if (strncmp(argv[i], "-f", 2) == 0) { - if (filename != NULL) continue; + if (filename != nullptr) continue; filename = strdup(&argv[i][2]); continue; } /* Object file extension */ if (strncmp(argv[i], "-o", 2) == 0) { - if (ext != NULL) continue; + if (ext != nullptr) continue; ext = strdup(&argv[i][2]); continue; } /* Starting string delimiter */ if (strncmp(argv[i], "-s", 2) == 0) { - if (delimiter != NULL) continue; + if (delimiter != nullptr) continue; delimiter = strdup(&argv[i][2]); continue; } @@ -966,22 +984,22 @@ int main(int argc, char *argv[]) } /* Default output file is Makefile */ - if (filename == NULL) filename = strdup("Makefile"); + if (filename == nullptr) filename = strdup("Makefile"); /* Default delimiter string */ - if (delimiter == NULL) delimiter = strdup("# DO NOT DELETE"); + if (delimiter == nullptr) delimiter = strdup("# DO NOT DELETE"); char backup[PATH_MAX]; strecpy(backup, filename, lastof(backup)); strecat(backup, ".bak", lastof(backup)); - char *content = NULL; + char *content = nullptr; long size = 0; /* Read in the current file; so we can overwrite everything from the * end of non-depend data marker down till the end. */ FILE *src = fopen(filename, "rb"); - if (src != NULL) { + if (src != nullptr) { fseek(src, 0, SEEK_END); if ((size = ftell(src)) < 0) { fprintf(stderr, "Could not read %s\n", filename); @@ -1009,7 +1027,7 @@ int main(int argc, char *argv[]) /* Then append it to the real file. */ src = fopen(backup, "r"); - while (fgets(content, size, src) != NULL) { + while (fgets(content, size, src) != nullptr) { fputs(content, dst); if (!strncmp(content, delimiter, strlen(delimiter))) found_delimiter = true; if (!append && found_delimiter) break; diff --git a/src/depot.cpp b/src/depot.cpp index 821399fd2b..05e2af3d4a 100644 --- a/src/depot.cpp +++ b/src/depot.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. diff --git a/src/depot_base.h b/src/depot_base.h index e5eb3b622c..aab2b2ae42 100644 --- a/src/depot_base.h +++ b/src/depot_base.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. @@ -46,7 +44,4 @@ struct Depot : DepotPool::PoolItem<&_depot_pool> { } }; -#define FOR_ALL_DEPOTS_FROM(var, start) FOR_ALL_ITEMS_FROM(Depot, depot_index, var, start) -#define FOR_ALL_DEPOTS(var) FOR_ALL_DEPOTS_FROM(var, 0) - #endif /* DEPOT_BASE_H */ diff --git a/src/depot_cmd.cpp b/src/depot_cmd.cpp index 5101b7c2ca..a142fbe7d3 100644 --- a/src/depot_cmd.cpp +++ b/src/depot_cmd.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. @@ -30,10 +28,8 @@ */ static bool IsUniqueDepotName(const char *name) { - const Depot *d; - - FOR_ALL_DEPOTS(d) { - if (d->name != NULL && strcmp(d->name, name) == 0) return false; + for (const Depot *d : Depot::Iterate()) { + if (d->name != nullptr && strcmp(d->name, name) == 0) return false; } return true; @@ -51,7 +47,7 @@ static bool IsUniqueDepotName(const char *name) CommandCost CmdRenameDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { Depot *d = Depot::GetIfValid(p1); - if (d == NULL) return CMD_ERROR; + if (d == nullptr) return CMD_ERROR; CommandCost ret = CheckTileOwnership(d->xy); if (ret.Failed()) return ret; @@ -67,7 +63,7 @@ CommandCost CmdRenameDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 free(d->name); if (reset) { - d->name = NULL; + d->name = nullptr; MakeDefaultName(d); } else { d->name = stredup(text); diff --git a/src/depot_func.h b/src/depot_func.h index f0d65e7640..42ac476ec3 100644 --- a/src/depot_func.h +++ b/src/depot_func.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/depot_gui.cpp b/src/depot_gui.cpp index 22e14c7ad6..7ff2d90f1f 100644 --- a/src/depot_gui.cpp +++ b/src/depot_gui.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. @@ -117,8 +115,9 @@ extern void DepotSortList(VehicleList *list); * @param tile unused * @param p1 unused * @param p2 unused + * @param cmd unused */ -void CcCloneVehicle(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) +void CcCloneVehicle(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) { if (result.Failed()) return; @@ -133,16 +132,16 @@ static void TrainDepotMoveVehicle(const Vehicle *wagon, VehicleID sel, const Veh if (v == wagon) return; - if (wagon == NULL) { - if (head != NULL) wagon = head->Last(); + if (wagon == nullptr) { + if (head != nullptr) wagon = head->Last(); } else { wagon = wagon->Previous(); - if (wagon == NULL) return; + if (wagon == nullptr) return; } if (wagon == v) return; - DoCommandP(v->tile, v->index | (_ctrl_pressed ? 1 : 0) << 20, wagon == NULL ? INVALID_VEHICLE : wagon->index, CMD_MOVE_RAIL_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_MOVE_VEHICLE)); + DoCommandP(v->tile, v->index | (_ctrl_pressed ? 1 : 0) << 20, wagon == nullptr ? INVALID_VEHICLE : wagon->index, CMD_MOVE_RAIL_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_MOVE_VEHICLE)); } static VehicleCellSize _base_block_sizes_depot[VEH_COMPANY_END]; ///< Cell size for vehicle images in the depot view. @@ -171,8 +170,7 @@ static void InitBlocksizeForVehicles(VehicleType type, EngineImageType image_typ int max_extend_right = 0; uint max_height = 0; - const Engine *e; - FOR_ALL_ENGINES_OF_TYPE(e, type) { + for (const Engine *e : Engine::IterateType(type)) { if (!e->IsEnabled()) continue; EngineID eid = e->index; @@ -223,12 +221,11 @@ void InitDepotWindowBlockSizes() _consistent_train_width = TRAININFO_DEFAULT_VEHICLE_WIDTH; bool first = true; - const Engine *e; - FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) { + for (const Engine *e : Engine::IterateType(VEH_TRAIN)) { if (!e->IsEnabled()) continue; uint w = TRAININFO_DEFAULT_VEHICLE_WIDTH; - if (e->GetGRF() != NULL && is_custom_sprite(e->u.rail.image_index)) { + if (e->GetGRF() != nullptr && is_custom_sprite(e->u.rail.image_index)) { w = e->GetGRF()->traininfo_vehicle_width; if (w != VEHICLEINFO_FULL_VEHICLE_WIDTH) { /* Hopeless. @@ -279,7 +276,7 @@ struct DepotWindow : Window { this->unitnumber_digits = 2; this->CreateNestedTree(); - this->hscroll = (this->type == VEH_TRAIN ? this->GetScrollbar(WID_D_H_SCROLL) : NULL); + this->hscroll = (this->type == VEH_TRAIN ? this->GetScrollbar(WID_D_H_SCROLL) : nullptr); this->vscroll = this->GetScrollbar(WID_D_V_SCROLL); /* Don't show 'rename button' of aircraft hangar */ this->GetWidget(WID_D_SHOW_RENAME)->SetDisplayedPlane(type == VEH_AIRCRAFT ? SZSP_NONE : 0); @@ -366,7 +363,7 @@ struct DepotWindow : Window { } } - void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { if (widget != WID_D_MATRIX) return; @@ -400,7 +397,7 @@ struct DepotWindow : Window { uint16 rows_in_display = wid->current_y / wid->resize_y; uint16 num = this->vscroll->GetPosition() * this->num_columns; - int maxval = min(this->vehicle_list.Length(), num + (rows_in_display * this->num_columns)); + int maxval = min((uint)this->vehicle_list.size(), num + (rows_in_display * this->num_columns)); int y; for (y = r.top; num < maxval; y += this->resize.step_height) { // Draw the rows for (byte i = 0; i < this->num_columns && num < maxval; i++, num++) { @@ -415,16 +412,16 @@ struct DepotWindow : Window { } } - maxval = min(this->vehicle_list.Length() + this->wagon_list.Length(), (this->vscroll->GetPosition() * this->num_columns) + (rows_in_display * this->num_columns)); + maxval = min((uint)this->vehicle_list.size() + (uint)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) { - const Vehicle *v = this->wagon_list[num - this->vehicle_list.Length()]; + const Vehicle *v = this->wagon_list[num - this->vehicle_list.size()]; this->DrawVehicleInDepot(v, r.left, r.right, y); } } - void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { if (widget != WID_D_CAPTION) return; @@ -467,12 +464,12 @@ struct DepotWindow : Window { uint pos = ((row + this->vscroll->GetPosition()) * this->num_columns) + xt; - if (this->vehicle_list.Length() + this->wagon_list.Length() <= pos) { + if (this->vehicle_list.size() + this->wagon_list.size() <= pos) { /* Clicking on 'line' / 'block' without a vehicle */ if (this->type == VEH_TRAIN) { /* End the dragging */ - d->head = NULL; - d->wagon = NULL; + d->head = nullptr; + d->wagon = nullptr; return MODE_DRAG_VEHICLE; } else { return MODE_ERROR; // empty block, so no vehicle is selected @@ -480,19 +477,19 @@ struct DepotWindow : Window { } bool wagon = false; - if (this->vehicle_list.Length() > pos) { + if (this->vehicle_list.size() > pos) { *veh = this->vehicle_list[pos]; /* Skip vehicles that are scrolled off the list */ if (this->type == VEH_TRAIN) x += this->hscroll->GetPosition(); } else { - pos -= this->vehicle_list.Length(); + 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); wagon = true; } - const Train *v = NULL; + const Train *v = nullptr; if (this->type == VEH_TRAIN) { v = Train::From(*veh); d->head = d->wagon = v; @@ -527,12 +524,12 @@ struct DepotWindow : Window { x -= this->header_width; /* find the vehicle in this row that was clicked */ - for (; v != NULL; v = v->Next()) { + for (; v != nullptr; v = v->Next()) { x -= v->GetDisplayImageWidth(); if (x < 0) break; } - d->wagon = (v != NULL ? v->GetFirstEnginePart() : NULL); + d->wagon = (v != nullptr ? v->GetFirstEnginePart() : nullptr); return MODE_DRAG_VEHICLE; } @@ -544,8 +541,8 @@ struct DepotWindow : Window { */ void DepotClick(int x, int y) { - GetDepotVehiclePtData gdvp = { NULL, NULL }; - const Vehicle *v = NULL; + GetDepotVehiclePtData gdvp = { nullptr, nullptr }; + const Vehicle *v = nullptr; DepotGUIAction mode = this->GetVehicleFromDepotWndPt(x, y, &v, &gdvp); if (this->type == VEH_TRAIN) v = gdvp.wagon; @@ -555,14 +552,14 @@ struct DepotWindow : Window { return; case MODE_DRAG_VEHICLE: { // start dragging of vehicle - if (v != NULL && VehicleClicked(v)) return; + if (v != nullptr && VehicleClicked(v)) return; VehicleID sel = this->sel; if (this->type == VEH_TRAIN && sel != INVALID_VEHICLE) { this->sel = INVALID_VEHICLE; TrainDepotMoveVehicle(v, sel, gdvp.head); - } else if (v != NULL) { + } else if (v != nullptr) { SetObjectToPlaceWnd(SPR_CURSOR_MOUSE, PAL_NONE, HT_DRAG, this); SetMouseCursorVehicle(v, EIT_IN_DEPOT); _cursor.vehchain = _ctrl_pressed; @@ -652,7 +649,7 @@ struct DepotWindow : Window { uint flag_width; uint flag_height; - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_D_MATRIX: { @@ -704,12 +701,12 @@ struct DepotWindow : Window { * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { this->generate_list = true; } - virtual void OnPaint() + void OnPaint() override { if (this->generate_list) { /* Generate the vehicle list @@ -729,19 +726,19 @@ struct DepotWindow : Window { /* determine amount of items for scroller */ if (this->type == VEH_TRAIN) { uint max_width = ScaleGUITrad(VEHICLEINFO_FULL_VEHICLE_WIDTH); - for (uint num = 0; num < this->vehicle_list.Length(); num++) { + for (uint num = 0; num < this->vehicle_list.size(); num++) { uint width = 0; - for (const Train *v = Train::From(this->vehicle_list[num]); v != NULL; v = v->Next()) { + for (const Train *v = Train::From(this->vehicle_list[num]); v != nullptr; v = v->Next()) { width += v->GetDisplayImageWidth(); } max_width = max(max_width, width); } /* Always have 1 empty row, so people can change the setting of the train */ - this->vscroll->SetCount(this->vehicle_list.Length() + this->wagon_list.Length() + 1); + 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)); } else { - this->vscroll->SetCount(CeilDiv(this->vehicle_list.Length(), this->num_columns)); + this->vscroll->SetCount(CeilDiv((uint)this->vehicle_list.size(), this->num_columns)); } /* Setup disabled buttons. */ @@ -761,7 +758,7 @@ struct DepotWindow : Window { this->DrawWidgets(); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_D_MATRIX: { // List @@ -814,7 +811,7 @@ struct DepotWindow : Window { case WID_D_SELL_ALL: /* Only open the confirmation window if there are anything to sell */ - if (this->vehicle_list.Length() != 0 || this->wagon_list.Length() != 0) { + if (this->vehicle_list.size() != 0 || this->wagon_list.size() != 0) { TileIndex tile = this->window_number; byte vehtype = this->type; @@ -840,26 +837,26 @@ struct DepotWindow : Window { } } - virtual void OnQueryTextFinished(char *str) + void OnQueryTextFinished(char *str) override { - if (str == NULL) return; + if (str == nullptr) return; /* Do depot renaming */ - DoCommandP(0, GetDepotIndex(this->window_number), 0, CMD_RENAME_DEPOT | CMD_MSG(STR_ERROR_CAN_T_RENAME_DEPOT), NULL, str); + DoCommandP(0, GetDepotIndex(this->window_number), 0, CMD_RENAME_DEPOT | CMD_MSG(STR_ERROR_CAN_T_RENAME_DEPOT), nullptr, str); } - virtual bool OnRightClick(Point pt, int widget) + bool OnRightClick(Point pt, int widget) override { if (widget != WID_D_MATRIX) return false; - GetDepotVehiclePtData gdvp = { NULL, NULL }; - const Vehicle *v = NULL; + GetDepotVehiclePtData gdvp = { nullptr, nullptr }; + const Vehicle *v = nullptr; NWidgetBase *nwi = this->GetWidget(WID_D_MATRIX); DepotGUIAction mode = this->GetVehicleFromDepotWndPt(pt.x - nwi->pos_x, pt.y - nwi->pos_y, &v, &gdvp); if (this->type == VEH_TRAIN) v = gdvp.wagon; - if (v == NULL || mode != MODE_DRAG_VEHICLE) return false; + if (v == nullptr || mode != MODE_DRAG_VEHICLE) return false; CargoArray capacity, loaded; @@ -868,7 +865,7 @@ struct DepotWindow : Window { /* loop through vehicle chain and collect cargoes */ uint num = 0; - for (const Vehicle *w = v; w != NULL; w = w->Next()) { + for (const Vehicle *w = v; w != nullptr; w = w->Next()) { if (w->cargo_cap > 0 && w->cargo_type < NUM_CARGO) { capacity[w->cargo_type] += w->cargo_cap; loaded [w->cargo_type] += w->cargo.StoredCount(); @@ -909,11 +906,11 @@ struct DepotWindow : Window { * @param v the original vehicle to clone * @return Always true. */ - virtual bool OnVehicleSelect(const Vehicle *v) + bool OnVehicleSelect(const Vehicle *v) override { if (_ctrl_pressed) { /* Share-clone, do not open new viewport, and keep tool active */ - DoCommandP(this->window_number, v->index, 1, CMD_CLONE_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_BUY_TRAIN + v->type), NULL); + DoCommandP(this->window_number, v->index, 1, CMD_CLONE_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_BUY_TRAIN + v->type), nullptr); } else { /* Copy-clone, open viewport for new vehicle, and deselect the tool (assume player wants to changs things on new vehicle) */ if (DoCommandP(this->window_number, v->index, 0, CMD_CLONE_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_BUY_TRAIN + v->type), CcCloneVehicle)) { @@ -924,7 +921,7 @@ struct DepotWindow : Window { return true; } - virtual void OnPlaceObjectAbort() + void OnPlaceObjectAbort() override { /* abort clone */ this->RaiseWidget(WID_D_CLONE); @@ -942,7 +939,7 @@ struct DepotWindow : Window { } } - virtual void OnMouseDrag(Point pt, int widget) + void OnMouseDrag(Point pt, int widget) override { if (this->sel == INVALID_VEHICLE) return; if (widget != this->hovered_widget) { @@ -968,20 +965,20 @@ struct DepotWindow : Window { } NWidgetBase *matrix = this->GetWidget(widget); - const Vehicle *v = NULL; - GetDepotVehiclePtData gdvp = {NULL, NULL}; + const Vehicle *v = nullptr; + GetDepotVehiclePtData gdvp = {nullptr, nullptr}; if (this->GetVehicleFromDepotWndPt(pt.x - matrix->pos_x, pt.y - matrix->pos_y, &v, &gdvp) != MODE_DRAG_VEHICLE) return; VehicleID new_vehicle_over = INVALID_VEHICLE; - if (gdvp.head != NULL) { - if (gdvp.wagon == NULL && gdvp.head->Last()->index != this->sel) { // ..at the end of the train. + if (gdvp.head != nullptr) { + if (gdvp.wagon == nullptr && gdvp.head->Last()->index != this->sel) { // ..at the end of the train. /* NOTE: As a wagon can't be moved at the begin of a train, head index isn't used to mark a drag-and-drop * destination inside a train. This head index is then used to indicate that a wagon is inserted at * the end of the train. */ new_vehicle_over = gdvp.head->index; - } else if (gdvp.wagon != NULL && gdvp.head != gdvp.wagon && + } else if (gdvp.wagon != nullptr && gdvp.head != gdvp.wagon && gdvp.wagon->index != this->sel && gdvp.wagon->Previous()->index != this->sel) { // ..over an existing wagon. new_vehicle_over = gdvp.wagon->index; @@ -994,11 +991,11 @@ struct DepotWindow : Window { this->SetWidgetDirty(widget); } - virtual void OnDragDrop(Point pt, int widget) + void OnDragDrop(Point pt, int widget) override { switch (widget) { case WID_D_MATRIX: { - const Vehicle *v = NULL; + const Vehicle *v = nullptr; VehicleID sel = this->sel; this->sel = INVALID_VEHICLE; @@ -1006,20 +1003,20 @@ struct DepotWindow : Window { NWidgetBase *nwi = this->GetWidget(WID_D_MATRIX); if (this->type == VEH_TRAIN) { - GetDepotVehiclePtData gdvp = { NULL, NULL }; + GetDepotVehiclePtData gdvp = { nullptr, nullptr }; if (this->GetVehicleFromDepotWndPt(pt.x - nwi->pos_x, pt.y - nwi->pos_y, &v, &gdvp) == MODE_DRAG_VEHICLE && sel != INVALID_VEHICLE) { - if (gdvp.wagon != NULL && gdvp.wagon->index == sel && _ctrl_pressed) { + if (gdvp.wagon != nullptr && gdvp.wagon->index == sel && _ctrl_pressed) { DoCommandP(Vehicle::Get(sel)->tile, Vehicle::Get(sel)->index, true, CMD_REVERSE_TRAIN_DIRECTION | CMD_MSG(STR_ERROR_CAN_T_REVERSE_DIRECTION_RAIL_VEHICLE)); - } else if (gdvp.wagon == NULL || gdvp.wagon->index != sel) { + } else if (gdvp.wagon == nullptr || gdvp.wagon->index != sel) { this->vehicle_over = INVALID_VEHICLE; TrainDepotMoveVehicle(gdvp.wagon, sel, gdvp.head); - } else if (gdvp.head != NULL && gdvp.head->IsFrontEngine()) { + } else if (gdvp.head != nullptr && gdvp.head->IsFrontEngine()) { ShowVehicleViewWindow(gdvp.head); } } - } else if (this->GetVehicleFromDepotWndPt(pt.x - nwi->pos_x, pt.y - nwi->pos_y, &v, NULL) == MODE_DRAG_VEHICLE && v != NULL && sel == v->index) { + } else if (this->GetVehicleFromDepotWndPt(pt.x - nwi->pos_x, pt.y - nwi->pos_y, &v, nullptr) == MODE_DRAG_VEHICLE && v != nullptr && sel == v->index) { ShowVehicleViewWindow(v); } break; @@ -1049,19 +1046,19 @@ struct DepotWindow : Window { _cursor.vehchain = false; } - virtual void OnTimeout() + void OnTimeout() override { if (!this->IsWidgetDisabled(WID_D_SELL)) { this->RaiseWidget(WID_D_SELL); this->SetWidgetDirty(WID_D_SELL); } - if (this->nested_array[WID_D_SELL] != NULL && !this->IsWidgetDisabled(WID_D_SELL_CHAIN)) { + if (this->nested_array[WID_D_SELL] != nullptr && !this->IsWidgetDisabled(WID_D_SELL_CHAIN)) { this->RaiseWidget(WID_D_SELL_CHAIN); this->SetWidgetDirty(WID_D_SELL_CHAIN); } } - virtual void OnResize() + void OnResize() override { this->vscroll->SetCapacityFromWidget(this, WID_D_MATRIX); NWidgetCore *nwi = this->GetWidget(WID_D_MATRIX); @@ -1072,7 +1069,7 @@ struct DepotWindow : Window { } } - virtual EventState OnCTRLStateChange() + EventState OnCTRLStateChange() override { if (this->sel != INVALID_VEHICLE) { _cursor.vehchain = _ctrl_pressed; @@ -1101,7 +1098,7 @@ static void DepotSellAllConfirmationCallback(Window *win, bool confirmed) */ void ShowDepotWindow(TileIndex tile, VehicleType type) { - if (BringWindowToFrontById(WC_VEHICLE_DEPOT, tile) != NULL) return; + if (BringWindowToFrontById(WC_VEHICLE_DEPOT, tile) != nullptr) return; WindowDesc *desc; switch (type) { @@ -1129,7 +1126,7 @@ void DeleteDepotHighlightOfVehicle(const Vehicle *v) if (_special_mouse_mode != WSM_DRAGDROP) return; w = dynamic_cast(FindWindowById(WC_VEHICLE_DEPOT, v->tile)); - if (w != NULL) { + if (w != nullptr) { if (w->sel == v->index) ResetObjectToPlace(); } } diff --git a/src/depot_map.h b/src/depot_map.h index c304790f8a..f92ca9f6e4 100644 --- a/src/depot_map.h +++ b/src/depot_map.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/depot_type.h b/src/depot_type.h index d6374bed51..a2326794a0 100644 --- a/src/depot_type.h +++ b/src/depot_type.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/direction_func.h b/src/direction_func.h index 12aee58639..e1bad998aa 100644 --- a/src/direction_func.h +++ b/src/direction_func.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/direction_type.h b/src/direction_type.h index e6e08a182f..55e430e8cd 100644 --- a/src/direction_type.h +++ b/src/direction_type.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. @@ -23,7 +21,7 @@ * your viewport and not rotated by 45 degrees left or right to get * a "north" used in you games. */ -enum Direction { +enum Direction : byte { DIR_BEGIN = 0, ///< Used to iterate DIR_N = 0, ///< North DIR_NE = 1, ///< Northeast @@ -42,7 +40,6 @@ DECLARE_POSTFIX_INCREMENT(Direction) /** Define basic enum properties */ template <> struct EnumPropsT : MakeEnumPropsT {}; -typedef TinyEnumT DirectionByte; ///< typedefing-enumification of Direction /** @@ -77,7 +74,7 @@ enum DirDiff { * * This enumeration is used for the 4 direction of the tile-edges. */ -enum DiagDirection { +enum DiagDirection : byte { DIAGDIR_BEGIN = 0, ///< Used for iterations DIAGDIR_NE = 0, ///< Northeast, upper right on your monitor DIAGDIR_SE = 1, ///< Southeast @@ -92,7 +89,6 @@ DECLARE_POSTFIX_INCREMENT(DiagDirection) /** Define basic enum properties */ template <> struct EnumPropsT : MakeEnumPropsT {}; -typedef TinyEnumT DiagDirectionByte; ///< typedefing-enumification of DiagDirection /** diff --git a/src/disaster_vehicle.cpp b/src/disaster_vehicle.cpp index 64ebcd3fa1..1244f99aba 100644 --- a/src/disaster_vehicle.cpp +++ b/src/disaster_vehicle.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. @@ -62,7 +60,7 @@ static void DisasterClearSquare(TileIndex tile) switch (GetTileType(tile)) { case MP_RAILWAY: if (Company::IsHumanID(GetTileOwner(tile)) && !IsRailDepot(tile)) { - Backup cur_company(_current_company, OWNER_WATER, FILE_LINE); + Backup cur_company(_current_company, OWNER_WATER, FILE_LINE); DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR); cur_company.Restore(); @@ -72,7 +70,7 @@ static void DisasterClearSquare(TileIndex tile) break; case MP_HOUSE: { - Backup cur_company(_current_company, OWNER_NONE, FILE_LINE); + Backup cur_company(_current_company, OWNER_NONE, FILE_LINE); DoCommand(tile, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR); cur_company.Restore(); break; @@ -137,11 +135,11 @@ DisasterVehicle::DisasterVehicle(int x, int y, Direction direction, DisasterSubT case ST_HELICOPTER: case ST_BIG_UFO: case ST_BIG_UFO_DESTROYER: - GetAircraftFlightLevelBounds(this, &this->z_pos, NULL); + GetAircraftFlightLevelBounds(this, &this->z_pos, nullptr); break; case ST_HELICOPTER_ROTORS: - GetAircraftFlightLevelBounds(this, &this->z_pos, NULL); + GetAircraftFlightLevelBounds(this, &this->z_pos, nullptr); this->z_pos += ROTOR_Z_OFFSET; break; @@ -190,7 +188,7 @@ void DisasterVehicle::UpdatePosition(int x, int y, int z) this->UpdatePositionAndViewport(); DisasterVehicle *u = this->Next(); - if (u != NULL) { + if (u != nullptr) { int safe_x = Clamp(x, 0, MapMaxX() * TILE_SIZE); int safe_y = Clamp(y - 1, 0, MapMaxY() * TILE_SIZE); @@ -203,7 +201,7 @@ void DisasterVehicle::UpdatePosition(int x, int y, int z) u->UpdateImage(); u->UpdatePositionAndViewport(); - if ((u = u->Next()) != NULL) { + if ((u = u->Next()) != nullptr) { u->x_pos = x; u->y_pos = y; u->z_pos = z + ROTOR_Z_OFFSET; @@ -333,8 +331,7 @@ static bool DisasterTick_Ufo(DisasterVehicle *v) v->current_order.SetDestination(1); uint n = 0; // Total number of targetable road vehicles. - RoadVehicle *u; - FOR_ALL_ROADVEHICLES(u) { + for (const RoadVehicle *u : RoadVehicle::Iterate()) { if (u->IsFrontEngine()) n++; } @@ -345,19 +342,21 @@ static bool DisasterTick_Ufo(DisasterVehicle *v) } n = RandomRange(n); // Choose one of them. - FOR_ALL_ROADVEHICLES(u) { + for (const RoadVehicle *u : RoadVehicle::Iterate()) { /* Find (n+1)-th road vehicle. */ - if (u->IsFrontEngine() && (n-- == 0)) break; + if (u->IsFrontEngine() && (n-- == 0)) { + /* Target it. */ + v->dest_tile = u->index; + v->age = 0; + break; + } } - /* Target it. */ - v->dest_tile = u->index; - v->age = 0; return true; } else { /* Target a vehicle */ RoadVehicle *u = RoadVehicle::Get(v->dest_tile); - assert(u != NULL && u->type == VEH_ROAD && u->IsFrontEngine()); + assert(u != nullptr && u->type == VEH_ROAD && u->IsFrontEngine()); uint dist = Delta(v->x_pos, u->x_pos) + Delta(v->y_pos, u->y_pos); @@ -542,8 +541,7 @@ static bool DisasterTick_Big_Ufo(DisasterVehicle *v) v->current_order.SetDestination(2); - Vehicle *target; - FOR_ALL_VEHICLES(target) { + for (Vehicle *target : Vehicle::Iterate()) { if (target->IsGroundVehicle()) { if (Delta(target->x_pos, v->x_pos) + Delta(target->y_pos, v->y_pos) <= 12 * (int)TILE_SIZE) { target->breakdown_ctr = 5; @@ -710,8 +708,7 @@ static void Disaster_Zeppeliner_Init() /* Pick a random place, unless we find a small airport */ int x = TileX(Random()) * TILE_SIZE + TILE_SIZE / 2; - Station *st; - FOR_ALL_STATIONS(st) { + for (const Station *st : Station::Iterate()) { if (st->airport.tile != INVALID_TILE && (st->airport.type == AT_SMALL || st->airport.type == AT_LARGE)) { x = (TileX(st->airport.tile) + 2) * TILE_SIZE; break; @@ -748,16 +745,16 @@ static void Disaster_Airplane_Init() { if (!Vehicle::CanAllocateItem(2)) return; - Industry *i, *found = NULL; + Industry *found = nullptr; - FOR_ALL_INDUSTRIES(i) { + for (Industry *i : Industry::Iterate()) { if ((GetIndustrySpec(i->type)->behaviour & INDUSTRYBEH_AIRPLANE_ATTACKS) && - (found == NULL || Chance16(1, 2))) { + (found == nullptr || Chance16(1, 2))) { found = i; } } - if (found == NULL) return; + if (found == nullptr) return; /* Start from the bottom (south side) of the map */ int x = (MapSizeX() + 9) * TILE_SIZE - 1; @@ -774,16 +771,16 @@ static void Disaster_Helicopter_Init() { if (!Vehicle::CanAllocateItem(3)) return; - Industry *i, *found = NULL; + Industry *found = nullptr; - FOR_ALL_INDUSTRIES(i) { + for (Industry *i : Industry::Iterate()) { if ((GetIndustrySpec(i->type)->behaviour & INDUSTRYBEH_CHOPPER_ATTACKS) && - (found == NULL || Chance16(1, 2))) { + (found == nullptr || Chance16(1, 2))) { found = i; } } - if (found == NULL) return; + if (found == nullptr) return; int x = -16 * (int)TILE_SIZE; int y = TileY(found->location.tile) * TILE_SIZE + 37; @@ -861,9 +858,7 @@ static void Disaster_CoalMine_Init() uint m; for (m = 0; m < 15; m++) { - const Industry *i; - - FOR_ALL_INDUSTRIES(i) { + for (const Industry *i : Industry::Iterate()) { if ((GetIndustrySpec(i->type)->behaviour & INDUSTRYBEH_CAN_SUBSIDENCE) && --index < 0) { SetDParam(0, i->town->index); AddTileNewsItem(STR_NEWS_DISASTER_COAL_MINE_SUBSIDENCE, NT_ACCIDENT, i->location.tile + TileDiffXY(1, 1)); // keep the news, even when the mine closes @@ -942,8 +937,7 @@ void StartupDisasters() */ void ReleaseDisastersTargetingIndustry(IndustryID i) { - DisasterVehicle *v; - FOR_ALL_DISASTERVEHICLES(v) { + for (DisasterVehicle *v : DisasterVehicle::Iterate()) { /* primary disaster vehicles that have chosen target */ if (v->subtype == ST_AIRPLANE || v->subtype == ST_HELICOPTER) { /* if it has chosen target, and it is this industry (yes, dest_tile is IndustryID here), set order to "leaving map peacefully" */ @@ -958,15 +952,14 @@ void ReleaseDisastersTargetingIndustry(IndustryID i) */ void ReleaseDisastersTargetingVehicle(VehicleID vehicle) { - DisasterVehicle *v; - FOR_ALL_DISASTERVEHICLES(v) { + for (DisasterVehicle *v : DisasterVehicle::Iterate()) { /* primary disaster vehicles that have chosen target */ if (v->subtype == ST_SMALL_UFO) { if (v->current_order.GetDestination() != 0 && v->dest_tile == vehicle) { /* Revert to target-searching */ v->current_order.SetDestination(0); v->dest_tile = RandomTile(); - GetAircraftFlightLevelBounds(v, &v->z_pos, NULL); + GetAircraftFlightLevelBounds(v, &v->z_pos, nullptr); v->age = 0; } } diff --git a/src/disaster_vehicle.h b/src/disaster_vehicle.h index e86d96e97d..dff97a69e9 100644 --- a/src/disaster_vehicle.h +++ b/src/disaster_vehicle.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. @@ -53,10 +51,4 @@ struct DisasterVehicle FINAL : public SpecializedVehicle max_length) break; if (GetTileMaxZ(endtile) > z) { - if (tile_to != NULL) *tile_to = endtile; + if (tile_to != nullptr) *tile_to = endtile; break; } } @@ -107,6 +105,7 @@ struct BuildDocksToolbarWindow : Window { ~BuildDocksToolbarWindow() { if (_thd.GetCallbackWnd() == this) this->OnPlaceObjectAbort(); + if (_game_mode == GM_NORMAL && this->IsWidgetLowered(WID_DT_STATION)) SetViewportCatchmentStation(nullptr, true); if (_settings_client.gui.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0, false); } @@ -115,7 +114,7 @@ struct BuildDocksToolbarWindow : Window { * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; @@ -131,7 +130,7 @@ struct BuildDocksToolbarWindow : Window { } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_DT_CANAL: // Build canal button @@ -175,7 +174,7 @@ struct BuildDocksToolbarWindow : Window { this->last_clicked_widget = (DockToolbarWidgets)widget; } - virtual void OnPlaceObject(Point pt, TileIndex tile) + void OnPlaceObject(Point pt, TileIndex tile) override { switch (this->last_clicked_widget) { case WID_DT_CANAL: // Build canal button @@ -214,7 +213,7 @@ struct BuildDocksToolbarWindow : Window { MoveAllWindowsOffScreen(); } - virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) + void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) override { switch (last_clicked_widget) { case WID_DT_BUILD_AQUEDUCT: @@ -228,7 +227,7 @@ struct BuildDocksToolbarWindow : Window { } } - virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) + void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) override { if (pt.x != -1) { switch (select_proc) { @@ -284,8 +283,10 @@ struct BuildDocksToolbarWindow : Window { } } - virtual void OnPlaceObjectAbort() + void OnPlaceObjectAbort() override { + if (_game_mode != GM_EDITOR && this->IsWidgetLowered(WID_DT_STATION)) SetViewportCatchmentStation(nullptr, true); + MoveAllHiddenWindowsBackToScreen(); this->RaiseButtons(); @@ -305,7 +306,7 @@ struct BuildDocksToolbarWindow : Window { this->OnClick(dummy, this->last_clicked_widget, 0); } - virtual void OnPlacePresize(Point pt, TileIndex tile_from) + void OnPlacePresize(Point pt, TileIndex tile_from) override { if (!IsValidTile(tile_from)) return; TileIndex tile_to = tile_from; @@ -337,7 +338,7 @@ static EventState DockToolbarGlobalHotkeys(int hotkey) { if (_game_mode != GM_NORMAL) return ES_NOT_HANDLED; Window *w = ShowBuildDocksToolbar(); - if (w == NULL) return ES_NOT_HANDLED; + if (w == nullptr) return ES_NOT_HANDLED; return w->OnHotkey(hotkey); } @@ -391,11 +392,11 @@ static WindowDesc _build_docks_toolbar_desc( * * If the terraform toolbar is linked to the toolbar, that window is also opened. * - * @return newly opened water toolbar, or NULL if the toolbar could not be opened. + * @return newly opened water toolbar, or nullptr if the toolbar could not be opened. */ Window *ShowBuildDocksToolbar() { - if (!Company::IsValidID(_local_company)) return NULL; + if (!Company::IsValidID(_local_company)) return nullptr; DeleteToolbarLinkedWindows(); return AllocateWindowDescFront(&_build_docks_toolbar_desc, TRANSPORT_WATER); @@ -432,7 +433,7 @@ static WindowDesc _build_docks_scen_toolbar_desc( /** * Open the build water toolbar window for the scenario editor. * - * @return newly opened water toolbar, or NULL if the toolbar could not be opened. + * @return newly opened water toolbar, or nullptr if the toolbar could not be opened. */ Window *ShowBuildDocksScenToolbar() { @@ -461,7 +462,7 @@ public: DeleteWindowById(WC_SELECT_STATION, 0); } - virtual void OnPaint() + void OnPaint() override { int rad = (_settings_game.station.modified_catchment) ? CA_DOCK : CA_UNMODIFIED; @@ -488,7 +489,7 @@ public: } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case BDSW_LT_OFF: @@ -502,7 +503,7 @@ public: } } - virtual void OnRealtimeTick(uint delta_ms) + void OnRealtimeTick(uint delta_ms) override { CheckRedrawStationCoverage(this); } @@ -526,7 +527,7 @@ static const NWidgetPart _nested_build_dock_station_widgets[] = { }; static WindowDesc _build_dock_station_desc( - WDP_AUTO, NULL, 0, 0, + WDP_AUTO, nullptr, 0, 0, WC_BUILD_STATION, WC_BUILD_TOOLBAR, WDF_CONSTRUCTION, _nested_build_dock_station_widgets, lengthof(_nested_build_dock_station_widgets) @@ -556,7 +557,7 @@ public: UpdateDocksDirection(); } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_BDD_X: @@ -567,7 +568,7 @@ public: } } - virtual void OnPaint() + void OnPaint() override { this->DrawWidgets(); @@ -582,7 +583,7 @@ public: DrawShipDepotSprite(this->GetWidget(WID_BDD_Y)->pos_x + x1, this->GetWidget(WID_BDD_Y)->pos_y + y2, AXIS_Y, DEPOT_PART_SOUTH); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_BDD_X: @@ -619,7 +620,7 @@ static const NWidgetPart _nested_build_docks_depot_widgets[] = { }; static WindowDesc _build_docks_depot_desc( - WDP_AUTO, NULL, 0, 0, + WDP_AUTO, nullptr, 0, 0, WC_BUILD_DEPOT, WC_BUILD_TOOLBAR, WDF_CONSTRUCTION, _nested_build_docks_depot_widgets, lengthof(_nested_build_docks_depot_widgets) diff --git a/src/driver.cpp b/src/driver.cpp index b8c075f427..a642a2f867 100644 --- a/src/driver.cpp +++ b/src/driver.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. @@ -18,18 +16,17 @@ #include "safeguards.h" -char *_ini_videodriver; ///< The video driver a stored in the configuration file. -int _num_resolutions; ///< The number of resolutions. -Dimension _resolutions[100]; ///< List of resolutions. -Dimension _cur_resolution; ///< The current resolution. -bool _rightclick_emulate; ///< Whether right clicking is emulated. +char *_ini_videodriver; ///< The video driver a stored in the configuration file. +std::vector _resolutions; ///< List of resolutions. +Dimension _cur_resolution; ///< The current resolution. +bool _rightclick_emulate; ///< Whether right clicking is emulated. -char *_ini_sounddriver; ///< The sound driver a stored in the configuration file. +char *_ini_sounddriver; ///< The sound driver a stored in the configuration file. -char *_ini_musicdriver; ///< The music driver a stored in the configuration file. +char *_ini_musicdriver; ///< The music driver a stored in the configuration file. -char *_ini_blitter; ///< The blitter as stored in the configuration file. -bool _blitter_autodetected; ///< Was the blitter autodetected or specified by the user? +char *_ini_blitter; ///< The blitter as stored in the configuration file. +bool _blitter_autodetected; ///< Was the blitter autodetected or specified by the user? /** * Get a string parameter the list of parameters. @@ -41,10 +38,10 @@ const char *GetDriverParam(const char * const *parm, const char *name) { size_t len; - if (parm == NULL) return NULL; + if (parm == nullptr) return nullptr; len = strlen(name); - for (; *parm != NULL; parm++) { + for (; *parm != nullptr; parm++) { const char *p = *parm; if (strncmp(p, name, len) == 0) { @@ -52,7 +49,7 @@ const char *GetDriverParam(const char * const *parm, const char *name) if (p[len] == '\0') return p + len; } } - return NULL; + return nullptr; } /** @@ -63,7 +60,7 @@ const char *GetDriverParam(const char * const *parm, const char *name) */ bool GetDriverParamBool(const char * const *parm, const char *name) { - return GetDriverParam(parm, name) != NULL; + return GetDriverParam(parm, name) != nullptr; } /** @@ -76,7 +73,7 @@ bool GetDriverParamBool(const char * const *parm, const char *name) int GetDriverParamInt(const char * const *parm, const char *name, int def) { const char *p = GetDriverParam(parm, name); - return p != NULL ? atoi(p) : def; + return p != nullptr ? atoi(p) : def; } /** @@ -120,8 +117,8 @@ bool DriverFactoryBase::SelectDriverImpl(const char *name, Driver::Type type) Driver *newd = d->CreateInstance(); *GetActiveDriver(type) = newd; - const char *err = newd->Start(NULL); - if (err == NULL) { + const char *err = newd->Start(nullptr); + if (err == nullptr) { DEBUG(driver, 1, "Successfully probed %s driver '%s'", GetDriverTypeName(type), d->name); delete oldd; return true; @@ -141,8 +138,8 @@ bool DriverFactoryBase::SelectDriverImpl(const char *name, Driver::Type type) /* Extract the driver name and put parameter list in parm */ strecpy(buffer, name, lastof(buffer)); parm = strchr(buffer, ':'); - parms[0] = NULL; - if (parm != NULL) { + parms[0] = nullptr; + if (parm != nullptr) { uint np = 0; /* Tokenize the parm. */ do { @@ -150,7 +147,7 @@ bool DriverFactoryBase::SelectDriverImpl(const char *name, Driver::Type type) if (np < lengthof(parms) - 1) parms[np++] = parm; while (*parm != '\0' && *parm != ',') parm++; } while (*parm == ','); - parms[np] = NULL; + parms[np] = nullptr; } /* Find this driver */ @@ -168,7 +165,7 @@ bool DriverFactoryBase::SelectDriverImpl(const char *name, Driver::Type type) Driver *newd = d->CreateInstance(); const char *err = newd->Start(parms); - if (err != NULL) { + if (err != nullptr) { delete newd; usererror("Unable to load driver '%s'. The error was: %s", d->name, err); } diff --git a/src/driver.h b/src/driver.h index 12ca4474d4..3ac4f7f8a4 100644 --- a/src/driver.h +++ b/src/driver.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. @@ -26,7 +24,7 @@ public: /** * Start this driver. * @param parm Parameters passed to the driver. - * @return NULL if everything went okay, otherwise an error message. + * @return nullptr if everything went okay, otherwise an error message. */ virtual const char *Start(const char * const *parm) = 0; @@ -86,7 +84,7 @@ private: */ static Driver **GetActiveDriver(Driver::Type type) { - static Driver *s_driver[3] = { NULL, NULL, NULL }; + static Driver *s_driver[3] = { nullptr, nullptr, nullptr }; return &s_driver[type]; } @@ -116,7 +114,7 @@ public: { for (Driver::Type dt = Driver::DT_BEGIN; dt < Driver::DT_END; dt++) { Driver *driver = *GetActiveDriver(dt); - if (driver != NULL) driver->Stop(); + if (driver != nullptr) driver->Stop(); } } diff --git a/src/economy.cpp b/src/economy.cpp index fc2759bd2c..59983884d5 100644 --- a/src/economy.cpp +++ b/src/economy.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. @@ -77,7 +75,7 @@ static inline int32 BigMulS(const int32 a, const int32 b, const uint8 shift) return (int32)((int64)a * (int64)b >> shift); } -typedef SmallVector SmallIndustryList; +typedef std::vector SmallIndustryList; /** * Score info, values used for computing the detailed performance rating. @@ -114,17 +112,15 @@ Money CalculateCompanyValue(const Company *c, bool including_loan) { Owner owner = c->index; - Station *st; uint num = 0; - FOR_ALL_STATIONS(st) { + for (const Station *st : Station::Iterate()) { if (st->owner == owner) num += CountBits((byte)st->facilities); } Money value = num * _price[PR_STATION_VALUE] * 25; - Vehicle *v; - FOR_ALL_VEHICLES(v) { + for (const Vehicle *v : Vehicle::Iterate()) { if (v->owner != owner) continue; if (v->type == VEH_TRAIN || @@ -159,12 +155,11 @@ int UpdateCompanyRatingAndValue(Company *c, bool update) /* Count vehicles */ { - Vehicle *v; Money min_profit = 0; bool min_profit_first = true; uint num = 0; - FOR_ALL_VEHICLES(v) { + for (const Vehicle *v : Vehicle::Iterate()) { if (v->owner != owner) continue; if (IsCompanyBuildableVehicleType(v->type) && v->IsPrimaryVehicle()) { if (v->profit_last_year > 0) num++; // For the vehicle score only count profitable vehicles @@ -190,9 +185,7 @@ int UpdateCompanyRatingAndValue(Company *c, bool update) /* Count stations */ { uint num = 0; - const Station *st; - - FOR_ALL_STATIONS(st) { + for (const Station *st : Station::Iterate()) { /* Only count stations that are actually serviced */ if (st->owner == owner && (st->time_since_load <= 20 || st->time_since_unload <= 20)) num += CountBits((byte)st->facilities); } @@ -291,18 +284,15 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) /* We need to set _current_company to old_owner before we try to move * the client. This is needed as it needs to know whether "you" really * are the current local company. */ - Backup cur_company(_current_company, old_owner, FILE_LINE); -#ifdef ENABLE_NETWORK + Backup cur_company(_current_company, old_owner, FILE_LINE); /* In all cases, make spectators of clients connected to that company */ if (_networking) NetworkClientsToSpectators(old_owner); -#endif /* ENABLE_NETWORK */ if (old_owner == _local_company) { /* Single player cheated to AI company. * There are no spectators in single player, so we must pick some other company. */ assert(!_networking); - Backup cur_company2(_current_company, FILE_LINE); - Company *c; - FOR_ALL_COMPANIES(c) { + Backup cur_company2(_current_company, FILE_LINE); + for (const Company *c : Company::Iterate()) { if (c->index != old_owner) { SetLocalCompany(c->index); break; @@ -312,16 +302,13 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) assert(old_owner != _local_company); } - Town *t; - assert(old_owner != new_owner); { - Company *c; uint i; /* See if the old_owner had shares in other companies */ - FOR_ALL_COMPANIES(c) { + for (const Company *c : Company::Iterate()) { for (i = 0; i < 4; i++) { if (c->share_owners[i] == old_owner) { /* Sell his shares */ @@ -334,8 +321,8 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) } /* Sell all the shares that people have on this company */ - Backup cur_company2(_current_company, FILE_LINE); - c = Company::Get(old_owner); + Backup cur_company2(_current_company, FILE_LINE); + const Company *c = Company::Get(old_owner); for (i = 0; i < 4; i++) { cur_company2.Change(c->share_owners[i]); if (_current_company != INVALID_OWNER) { @@ -356,8 +343,7 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) Company::Get(old_owner)->money = UINT64_MAX >> 2; // jackpot ;p } - Subsidy *s; - FOR_ALL_SUBSIDIES(s) { + for (Subsidy *s : Subsidy::Iterate()) { if (s->awarded == old_owner) { if (new_owner == INVALID_OWNER) { delete s; @@ -369,7 +355,7 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) if (new_owner == INVALID_OWNER) RebuildSubsidisedSourceAndDestinationCache(); /* Take care of rating and transport rights in towns */ - FOR_ALL_TOWNS(t) { + for (Town *t : Town::Iterate()) { /* If a company takes over, give the ratings to that company. */ if (new_owner != INVALID_OWNER) { if (HasBit(t->have_ratings, old_owner)) { @@ -399,11 +385,10 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) } { - Vehicle *v; - FOR_ALL_VEHICLES(v) { + for (Vehicle *v : Vehicle::Iterate()) { if (v->owner == old_owner && IsCompanyBuildableVehicleType(v->type)) { if (new_owner == INVALID_OWNER) { - if (v->Previous() == NULL) delete v; + if (v->Previous() == nullptr) delete v; } else { if (v->IsEngineCountable()) GroupStatistics::CountEngine(v, -1); if (v->IsPrimaryVehicle()) GroupStatistics::CountVehicle(v, -1); @@ -419,8 +404,7 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) if (new_owner == INVALID_OWNER) { RemoveAllGroupsForCompany(old_owner); } else { - Group *g; - FOR_ALL_GROUPS(g) { + for (Group *g : Group::Iterate()) { if (g->owner == old_owner) g->owner = new_owner; } } @@ -445,8 +429,7 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) old_company->settings.vehicle.servint_ispercent = new_company->settings.vehicle.servint_ispercent; } - Vehicle *v; - FOR_ALL_VEHICLES(v) { + for (Vehicle *v : Vehicle::Iterate()) { if (v->owner == old_owner && IsCompanyBuildableVehicleType(v->type)) { assert(new_owner != INVALID_OWNER); @@ -478,7 +461,7 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) } /* Invalidate the vehicle's cargo payment "owner cache". */ - if (v->cargo_payment != NULL) v->cargo_payment->owner = NULL; + if (v->cargo_payment != nullptr) v->cargo_payment->owner = nullptr; } } @@ -520,8 +503,7 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) if (new_owner != INVALID_OWNER) Company::Get(new_owner)->infrastructure.airport += Company::Get(old_owner)->infrastructure.airport; /* convert owner of stations (including deleted ones, but excluding buoys) */ - Station *st; - FOR_ALL_STATIONS(st) { + for (Station *st : Station::Iterate()) { if (st->owner == old_owner) { /* if a company goes bankrupt, set owner to OWNER_NONE so the sign doesn't disappear immediately * also, drawing station window would cause reading invalid company's colour */ @@ -530,29 +512,25 @@ void ChangeOwnershipOfCompanyItems(Owner old_owner, Owner new_owner) } /* do the same for waypoints (we need to do this here so deleted waypoints are converted too) */ - Waypoint *wp; - FOR_ALL_WAYPOINTS(wp) { + for (Waypoint *wp : Waypoint::Iterate()) { if (wp->owner == old_owner) { wp->owner = new_owner == INVALID_OWNER ? OWNER_NONE : new_owner; } } - Sign *si; - FOR_ALL_SIGNS(si) { + for (Sign *si : Sign::Iterate()) { if (si->owner == old_owner) si->owner = new_owner == INVALID_OWNER ? OWNER_NONE : new_owner; } /* Remove Game Script created Goals, CargoMonitors and Story pages. */ - Goal *g; - FOR_ALL_GOALS(g) { + for (Goal *g : Goal::Iterate()) { if (g->company == old_owner) delete g; } ClearCargoPickupMonitoring(old_owner); ClearCargoDeliveryMonitoring(old_owner); - StoryPage *sp; - FOR_ALL_STORY_PAGES(sp) { + for (StoryPage *sp : StoryPage::Iterate()) { if (sp->company == old_owner) delete sp; } @@ -572,8 +550,10 @@ 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) { + int previous_months_of_bankruptcy = CeilDiv(c->months_of_bankruptcy, 3); c->months_of_bankruptcy = 0; c->bankrupt_asked = 0; + if (previous_months_of_bankruptcy != 0) CompanyAdminUpdate(c); return; } @@ -642,10 +622,15 @@ static void CompanyCheckBankrupt(Company *c) * that changing the current company is okay. In case of single * player we are sure (the above check) that we are not the local * company and thus we won't be moved. */ - if (!_networking || _network_server) DoCommandP(0, CCA_DELETE | (c->index << 16), CRR_BANKRUPT, CMD_COMPANY_CTRL); + if (!_networking || _network_server) { + DoCommandP(0, CCA_DELETE | (c->index << 16) | (CRR_BANKRUPT << 24), 0, CMD_COMPANY_CTRL); + return; + } break; } } + + if (CeilDiv(c->months_of_bankruptcy, 3) != CeilDiv(c->months_of_bankruptcy - 1, 3)) CompanyAdminUpdate(c); } /** @@ -655,23 +640,21 @@ static void CompanyCheckBankrupt(Company *c) static void CompaniesGenStatistics() { /* Check for bankruptcy each month */ - Company *c; - FOR_ALL_COMPANIES(c) { + for (Company *c : Company::Iterate()) { CompanyCheckBankrupt(c); } - Backup cur_company(_current_company, FILE_LINE); + Backup cur_company(_current_company, FILE_LINE); if (!_settings_game.economy.infrastructure_maintenance) { - Station *st; - FOR_ALL_STATIONS(st) { + for (const Station *st : Station::Iterate()) { cur_company.Change(st->owner); CommandCost cost(EXPENSES_PROPERTY, _price[PR_STATION_VALUE] >> 1); SubtractMoneyFromCompany(cost); } } else { /* Improved monthly infrastructure costs. */ - FOR_ALL_COMPANIES(c) { + for (const Company *c : Company::Iterate()) { cur_company.Change(c->index); CommandCost cost(EXPENSES_PROPERTY); @@ -680,8 +663,10 @@ static void CompaniesGenStatistics() if (c->infrastructure.rail[rt] != 0) cost.AddCost(RailMaintenanceCost(rt, c->infrastructure.rail[rt], rail_total)); } cost.AddCost(SignalMaintenanceCost(c->infrastructure.signal)); + uint32 road_total = c->infrastructure.GetRoadTotal(); + uint32 tram_total = c->infrastructure.GetTramTotal(); for (RoadType rt = ROADTYPE_BEGIN; rt < ROADTYPE_END; rt++) { - if (c->infrastructure.road[rt] != 0) cost.AddCost(RoadMaintenanceCost(rt, c->infrastructure.road[rt])); + if (c->infrastructure.road[rt] != 0) cost.AddCost(RoadMaintenanceCost(rt, c->infrastructure.road[rt], RoadTypeIsRoad(rt) ? road_total : tram_total)); } cost.AddCost(CanalMaintenanceCost(c->infrastructure.water)); cost.AddCost(StationMaintenanceCost(c->infrastructure.station)); @@ -695,7 +680,7 @@ static void CompaniesGenStatistics() /* Only run the economic statics and update company stats every 3rd month (1st of quarter). */ if (!HasBit(1 << 0 | 1 << 3 | 1 << 6 | 1 << 9, _cur_month)) return; - FOR_ALL_COMPANIES(c) { + for (Company *c : Company::Iterate()) { /* Drop the oldest history off the end */ std::copy_backward(c->old_economy, c->old_economy + MAX_HISTORY_QUARTERS - 1, c->old_economy + MAX_HISTORY_QUARTERS); c->old_economy[0] = c->cur_economy; @@ -828,10 +813,8 @@ void RecomputePrices() /** Let all companies pay the monthly interest on their loan. */ static void CompaniesPayInterest() { - const Company *c; - - Backup cur_company(_current_company, FILE_LINE); - FOR_ALL_COMPANIES(c) { + Backup cur_company(_current_company, FILE_LINE); + for (const Company *c : Company::Iterate()) { cur_company.Change(c->index); /* Over a year the paid interest should be "loan * interest percentage", @@ -961,7 +944,7 @@ Money GetPrice(Price index, uint cost_factor, const GRFFile *grf_file, int shift if (index >= PR_END) return 0; Money cost = _price[index] * cost_factor; - if (grf_file != NULL) shift += grf_file->price_base_multipliers[index]; + if (grf_file != nullptr) shift += grf_file->price_base_multipliers[index]; if (shift >= 0) { cost <<= shift; @@ -1044,8 +1027,9 @@ static uint DeliverGoodsToIndustry(const Station *st, CargoID cargo_type, uint n uint accepted = 0; - for (uint i = 0; i < st->industries_near.Length() && num_pieces != 0; i++) { - Industry *ind = st->industries_near[i]; + for (Industry *ind : st->industries_near) { + if (num_pieces == 0) break; + if (ind->index == source) continue; uint cargo_index; @@ -1059,7 +1043,7 @@ static uint DeliverGoodsToIndustry(const Station *st, CargoID cargo_type, uint n if (IndustryTemporarilyRefusesCargo(ind, cargo_type)) continue; /* Insert the industry into _cargo_delivery_destinations, if not yet contained */ - _cargo_delivery_destinations.Include(ind); + include(_cargo_delivery_destinations, ind); uint amount = min(num_pieces, 0xFFFFU - ind->incoming_cargo_waiting[cargo_index]); ind->incoming_cargo_waiting[cargo_index] += amount; @@ -1181,11 +1165,11 @@ CargoPayment::~CargoPayment() { if (this->CleaningPool()) return; - this->front->cargo_payment = NULL; + this->front->cargo_payment = nullptr; if (this->visual_profit == 0 && this->visual_transfer == 0) return; - Backup cur_company(_current_company, this->front->owner, FILE_LINE); + Backup cur_company(_current_company, this->front->owner, FILE_LINE); SubtractMoneyFromCompany(CommandCost(this->front->GetExpenseType(true), -this->route_profit)); this->front->profit_this_year += (this->visual_profit + this->visual_transfer) << 8; @@ -1212,7 +1196,7 @@ CargoPayment::~CargoPayment() */ void CargoPayment::PayFinalDelivery(const CargoPacket *cp, uint count) { - if (this->owner == NULL) { + if (this->owner == nullptr) { this->owner = Company::Get(this->front->owner); } @@ -1232,10 +1216,11 @@ void CargoPayment::PayFinalDelivery(const CargoPacket *cp, uint count) */ Money CargoPayment::PayTransfer(const CargoPacket *cp, uint count) { - Money profit = GetTransportedGoodsIncome( + Money profit = -cp->FeederShare(count) + GetTransportedGoodsIncome( count, - /* pay transfer vehicle for only the part of transfer it has done: ie. cargo_loaded_at_xy to here */ - DistanceManhattan(cp->LoadedAtXY(), Station::Get(this->current_station)->xy), + /* pay transfer vehicle the difference between the payment for the journey from + * the source to the current point, and the sum of the previous transfer payments */ + DistanceManhattan(cp->SourceStationXY(), Station::Get(this->current_station)->xy), cp->DaysInTransit(), this->ct); @@ -1260,7 +1245,7 @@ void PrepareUnload(Vehicle *front_v) /* Start unloading at the first possible moment */ front_v->load_unload_ticks = 1; - assert(front_v->cargo_payment == NULL); + assert(front_v->cargo_payment == nullptr); /* One CargoPayment per vehicle and the vehicle limit equals the * limit in number of CargoPayments. Can't go wrong. */ assert_compile(CargoPaymentPool::MAX_SIZE == VehiclePool::MAX_SIZE); @@ -1268,9 +1253,9 @@ void PrepareUnload(Vehicle *front_v) front_v->cargo_payment = new CargoPayment(front_v); StationIDStack next_station = front_v->GetNextStoppingStation(); - if (front_v->orders.list == NULL || (front_v->current_order.GetUnloadType() & OUFB_NO_UNLOAD) == 0) { + if (front_v->orders.list == nullptr || (front_v->current_order.GetUnloadType() & OUFB_NO_UNLOAD) == 0) { Station *st = Station::Get(front_v->last_station_visited); - for (Vehicle *v = front_v; v != NULL; v = v->Next()) { + for (Vehicle *v = front_v; v != nullptr; v = v->Next()) { const GoodsEntry *ge = &st->goods[v->cargo_type]; if (v->cargo_cap > 0 && v->cargo.TotalCount() > 0) { v->cargo.Stage( @@ -1301,7 +1286,7 @@ static uint GetLoadAmount(Vehicle *v) if (_settings_game.order.gradual_loading) { uint16 cb_load_amount = CALLBACK_FAILED; - if (e->GetGRF() != NULL && e->GetGRF()->grf_version >= 8) { + if (e->GetGRF() != nullptr && e->GetGRF()->grf_version >= 8) { /* Use callback 36 */ cb_load_amount = GetVehicleProperty(v, PROP_VEHICLE_LOAD_AMOUNT, CALLBACK_FAILED); } else if (HasBit(e->info.callback_mask, CBM_VEHICLE_LOAD_AMOUNT)) { @@ -1337,8 +1322,8 @@ static uint GetLoadAmount(Vehicle *v) template bool IterateVehicleParts(Vehicle *v, Taction action) { - for (Vehicle *w = v; w != NULL; - w = w->HasArticulatedPart() ? w->GetNextArticulatedPart() : NULL) { + for (Vehicle *w = v; w != nullptr; + w = w->HasArticulatedPart() ? w->GetNextArticulatedPart() : nullptr) { if (!action(w)) return false; if (w->type == VEH_TRAIN) { Train *train = Train::From(w); @@ -1472,7 +1457,7 @@ static void HandleStationRefit(Vehicle *v, CargoArray &consist_capleft, Station Vehicle *v_start = v->GetFirstEnginePart(); if (!IterateVehicleParts(v_start, IsEmptyAction())) return; - Backup cur_company(_current_company, v->owner, FILE_LINE); + Backup cur_company(_current_company, v->owner, FILE_LINE); CargoTypes refit_mask = v->GetEngine()->info.refit_mask; @@ -1565,8 +1550,8 @@ static void ReserveConsist(Station *st, Vehicle *u, CargoArray *consist_capleft, /* If there is a cargo payment not all vehicles of the consist have tried to do the refit. * In that case, only reserve if it's a fixed refit and the equivalent of "articulated chain" * a vehicle belongs to already has the right cargo. */ - bool must_reserve = !u->current_order.IsRefit() || u->cargo_payment == NULL; - for (Vehicle *v = u; v != NULL; v = v->Next()) { + bool must_reserve = !u->current_order.IsRefit() || u->cargo_payment == nullptr; + for (Vehicle *v = u; v != nullptr; v = v->Next()) { assert(v->cargo_cap >= v->cargo.RemainingCount()); /* Exclude various ways in which the vehicle might not be the head of an equivalent of @@ -1578,7 +1563,7 @@ static void ReserveConsist(Station *st, Vehicle *u, CargoArray *consist_capleft, (must_reserve || u->current_order.GetRefitCargo() == v->cargo_type)) { IterateVehicleParts(v, ReserveCargoAction(st, next_station)); } - if (consist_capleft == NULL || v->cargo_cap == 0) continue; + if (consist_capleft == nullptr || v->cargo_cap == 0) continue; (*consist_capleft)[v->cargo_type] += v->cargo_cap - v->cargo.RemainingCount(); } } @@ -1619,9 +1604,9 @@ static void LoadUnloadVehicle(Vehicle *front) bool use_autorefit = front->current_order.IsRefit() && front->current_order.GetRefitCargo() == CT_AUTO_REFIT; CargoArray consist_capleft; if (_settings_game.order.improved_load && use_autorefit ? - front->cargo_payment == NULL : (front->current_order.GetLoadType() & OLFB_FULL_LOAD) != 0) { + front->cargo_payment == nullptr : (front->current_order.GetLoadType() & OLFB_FULL_LOAD) != 0) { ReserveConsist(st, front, - (use_autorefit && front->load_unload_ticks != 0) ? &consist_capleft : NULL, + (use_autorefit && front->load_unload_ticks != 0) ? &consist_capleft : nullptr, &next_station); } @@ -1653,7 +1638,7 @@ static void LoadUnloadVehicle(Vehicle *front) CargoPayment *payment = front->cargo_payment; uint artic_part = 0; // Articulated part we are currently trying to load. (not counting parts without capacity) - for (Vehicle *v = front; v != NULL; v = v->Next()) { + for (Vehicle *v = front; v != nullptr; v = v->Next()) { if (v == front || !v->Previous()->HasArticulatedPart()) artic_part = 0; if (v->cargo_cap == 0) continue; artic_part++; @@ -1665,7 +1650,7 @@ static void LoadUnloadVehicle(Vehicle *front) uint amount_unloaded = _settings_game.order.gradual_loading ? min(cargo_count, GetLoadAmount(v)) : cargo_count; bool remaining = false; // Are there cargo entities in this vehicle that can still be unloaded here? - assert(payment != NULL); + assert(payment != nullptr); payment->SetCargo(v->cargo_type); if (!HasBit(ge->status, GoodsEntry::GES_ACCEPTANCE) && v->cargo.ActionCount(VehicleCargoList::MTA_DELIVER) > 0) { @@ -1698,7 +1683,7 @@ static void LoadUnloadVehicle(Vehicle *front) dirty_station = true; if (!ge->HasRating()) { - /* Upon transfering cargo, make sure the station has a rating. Fake a pickup for the + /* Upon transferring cargo, make sure the station has a rating. Fake a pickup for the * first unload to prevent the cargo from quickly decaying after the initial drop. */ ge->time_since_pickup = 0; SetBit(ge->status, GoodsEntry::GES_RATING); @@ -1762,53 +1747,59 @@ static void LoadUnloadVehicle(Vehicle *front) /* if last speed is 0, we treat that as if no vehicle has ever visited the station. */ ge->last_speed = min(t, 255); ge->last_age = min(_cur_year - front->build_year, 255); - ge->time_since_pickup = 0; assert(v->cargo_cap >= v->cargo.StoredCount()); - /* If there's goods waiting at the station, and the vehicle - * has capacity for it, load it on the vehicle. */ + /* Capacity available for loading more cargo. */ uint cap_left = v->cargo_cap - v->cargo.StoredCount(); - if (cap_left > 0 && (v->cargo.ActionCount(VehicleCargoList::MTA_LOAD) > 0 || ge->cargo.AvailableCount() > 0) && MayLoadUnderExclusiveRights(st, v)) { - if (v->cargo.StoredCount() == 0) TriggerVehicle(v, VEHICLE_TRIGGER_NEW_CARGO); - if (_settings_game.order.gradual_loading) cap_left = min(cap_left, GetLoadAmount(v)); - uint loaded = ge->cargo.Load(cap_left, &v->cargo, st->xy, next_station); - if (v->cargo.ActionCount(VehicleCargoList::MTA_LOAD) > 0) { - /* Remember if there are reservations left so that we don't stop - * loading before they're loaded. */ - SetBit(reservation_left, v->cargo_type); - } + if (cap_left > 0) { + /* If vehicle can load cargo, reset time_since_pickup. */ + ge->time_since_pickup = 0; - /* Store whether the maximum possible load amount was loaded or not.*/ - if (loaded == cap_left) { - SetBit(full_load_amount, v->cargo_type); - } else { - ClrBit(full_load_amount, v->cargo_type); - } + /* If there's goods waiting at the station, and the vehicle + * has capacity for it, load it on the vehicle. */ + if ((v->cargo.ActionCount(VehicleCargoList::MTA_LOAD) > 0 || ge->cargo.AvailableCount() > 0) && MayLoadUnderExclusiveRights(st, v)) { + if (v->cargo.StoredCount() == 0) TriggerVehicle(v, VEHICLE_TRIGGER_NEW_CARGO); + if (_settings_game.order.gradual_loading) cap_left = min(cap_left, GetLoadAmount(v)); - /* TODO: Regarding this, when we do gradual loading, we - * should first unload all vehicles and then start - * loading them. Since this will cause - * VEHICLE_TRIGGER_EMPTY to be called at the time when - * the whole vehicle chain is really totally empty, the - * completely_emptied assignment can then be safely - * removed; that's how TTDPatch behaves too. --pasky */ - if (loaded > 0) { - completely_emptied = false; - anything_loaded = true; - - st->time_since_load = 0; - st->last_vehicle_type = v->type; - - if (ge->cargo.TotalCount() == 0) { - 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); + uint loaded = ge->cargo.Load(cap_left, &v->cargo, st->xy, next_station); + if (v->cargo.ActionCount(VehicleCargoList::MTA_LOAD) > 0) { + /* Remember if there are reservations left so that we don't stop + * loading before they're loaded. */ + SetBit(reservation_left, v->cargo_type); } - new_load_unload_ticks += loaded; + /* Store whether the maximum possible load amount was loaded or not.*/ + if (loaded == cap_left) { + SetBit(full_load_amount, v->cargo_type); + } else { + ClrBit(full_load_amount, v->cargo_type); + } - dirty_vehicle = dirty_station = true; + /* TODO: Regarding this, when we do gradual loading, we + * should first unload all vehicles and then start + * loading them. Since this will cause + * VEHICLE_TRIGGER_EMPTY to be called at the time when + * the whole vehicle chain is really totally empty, the + * completely_emptied assignment can then be safely + * removed; that's how TTDPatch behaves too. --pasky */ + if (loaded > 0) { + completely_emptied = false; + anything_loaded = true; + + st->time_since_load = 0; + st->last_vehicle_type = v->type; + + if (ge->cargo.TotalCount() == 0) { + 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); + } + + new_load_unload_ticks += loaded; + + dirty_vehicle = dirty_station = true; + } } } @@ -1919,7 +1910,7 @@ void LoadUnloadStation(Station *st) /* No vehicle is here... */ if (st->loading_vehicles.empty()) return; - Vehicle *last_loading = NULL; + Vehicle *last_loading = nullptr; std::list::iterator iter; /* Check if anything will be loaded at all. Otherwise we don't need to reserve either. */ @@ -1939,7 +1930,7 @@ void LoadUnloadStation(Station *st) * consist in a station which is not allowed to load yet because its * load_unload_ticks is still not 0. */ - if (last_loading == NULL) return; + if (last_loading == nullptr) return; for (iter = st->loading_vehicles.begin(); iter != st->loading_vehicles.end(); ++iter) { Vehicle *v = *iter; @@ -1948,11 +1939,10 @@ void LoadUnloadStation(Station *st) } /* Call the production machinery of industries */ - const Industry * const *isend = _cargo_delivery_destinations.End(); - for (Industry **iid = _cargo_delivery_destinations.Begin(); iid != isend; iid++) { - TriggerIndustryProduction(*iid); + for (Industry *iid : _cargo_delivery_destinations) { + TriggerIndustryProduction(iid); } - _cargo_delivery_destinations.Clear(); + _cargo_delivery_destinations.clear(); } /** @@ -2022,10 +2012,10 @@ CommandCost CmdBuyShareInCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, /* Check if buying shares is allowed (protection against modified clients) * Cannot buy own shares */ - if (c == NULL || !_settings_game.economy.allow_shares || _current_company == target_company) return CMD_ERROR; + if (c == nullptr || !_settings_game.economy.allow_shares || _current_company == target_company) return CMD_ERROR; /* Protect new companies from hostile takeovers */ - if (_cur_year - c->inaugurated_year < 6) return_cmd_error(STR_ERROR_PROTECTED); + if (_cur_year - c->inaugurated_year < _settings_game.economy.min_years_for_shares) return_cmd_error(STR_ERROR_PROTECTED); /* Those lines are here for network-protection (clients can be slow) */ if (GetAmountOwnedBy(c, COMPANY_SPECTATOR) == 0) return cost; @@ -2039,7 +2029,7 @@ CommandCost CmdBuyShareInCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, cost.AddCost(CalculateCompanyValue(c) >> 2); if (flags & DC_EXEC) { - OwnerByte *b = c->share_owners; + Owner *b = c->share_owners; while (*b != COMPANY_SPECTATOR) b++; // share owners is guaranteed to contain at least one COMPANY_SPECTATOR *b = _current_company; @@ -2072,7 +2062,7 @@ CommandCost CmdSellShareInCompany(TileIndex tile, DoCommandFlag flags, uint32 p1 Company *c = Company::GetIfValid(target_company); /* Cannot sell own shares */ - if (c == NULL || _current_company == target_company) return CMD_ERROR; + if (c == nullptr || _current_company == target_company) return CMD_ERROR; /* Check if selling shares is allowed (protection against modified clients). * However, we must sell shares of companies being closed down. */ @@ -2086,7 +2076,7 @@ CommandCost CmdSellShareInCompany(TileIndex tile, DoCommandFlag flags, uint32 p1 cost = -(cost - (cost >> 7)); if (flags & DC_EXEC) { - OwnerByte *b = c->share_owners; + Owner *b = c->share_owners; while (*b != _current_company) b++; // share owners is guaranteed to contain company *b = COMPANY_SPECTATOR; InvalidateWindowData(WC_COMPANY, target_company); @@ -2111,7 +2101,7 @@ CommandCost CmdBuyCompany(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 { CompanyID target_company = (CompanyID)p1; Company *c = Company::GetIfValid(target_company); - if (c == NULL) return CMD_ERROR; + if (c == nullptr) return CMD_ERROR; /* Disable takeovers when not asked */ if (!HasBit(c->bankrupt_asked, _current_company)) return CMD_ERROR; diff --git a/src/economy_base.h b/src/economy_base.h index 60b0964a95..5c9d79b8c8 100644 --- a/src/economy_base.h +++ b/src/economy_base.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. @@ -49,17 +47,4 @@ struct CargoPayment : CargoPaymentPool::PoolItem<&_cargo_payment_pool> { void SetCargo(CargoID ct) { this->ct = ct; } }; -/** - * Iterate over all cargo payments from a given start position. - * @param var The variable used for iterating. - * @param start The start of the iteration. - */ -#define FOR_ALL_CARGO_PAYMENTS_FROM(var, start) FOR_ALL_ITEMS_FROM(CargoPayment, cargo_payment_index, var, start) - -/** - * Iterate over all cargo payments. - * @param var The variable used for iterating. - */ -#define FOR_ALL_CARGO_PAYMENTS(var) FOR_ALL_CARGO_PAYMENTS_FROM(var, 0) - #endif /* ECONOMY_BASE_H */ diff --git a/src/economy_func.h b/src/economy_func.h index 7b369b7d60..d26b344e9a 100644 --- a/src/economy_func.h +++ b/src/economy_func.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/economy_type.h b/src/economy_type.h index 31f74aacc7..87e4482672 100644 --- a/src/economy_type.h +++ b/src/economy_type.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. @@ -147,7 +145,7 @@ typedef Money Prices[PR_END]; ///< Prices of everything. @see Price typedef int8 PriceMultipliers[PR_END]; /** Types of expenses. */ -enum ExpensesType { +enum ExpensesType : byte { EXPENSES_CONSTRUCTION = 0, ///< Construction costs. EXPENSES_NEW_VEHICLES, ///< New vehicles. EXPENSES_TRAIN_RUN, ///< Running costs trains. @@ -167,7 +165,6 @@ enum ExpensesType { /** Define basic enum properties for ExpensesType */ template <> struct EnumPropsT : MakeEnumPropsT {}; -typedef TinyEnumT ExpensesTypeByte; ///< typedefing-enumification of ExpensesType /** * Categories of a price bases. diff --git a/src/effectvehicle.cpp b/src/effectvehicle.cpp index 4d8f58acb8..f11a92e5d6 100644 --- a/src/effectvehicle.cpp +++ b/src/effectvehicle.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. @@ -595,7 +593,7 @@ assert_compile(lengthof(_effect_transparency_options) == EV_END); */ EffectVehicle *CreateEffectVehicle(int x, int y, int z, EffectVehicleType type) { - if (!Vehicle::CanAllocateItem()) return NULL; + if (!Vehicle::CanAllocateItem()) return nullptr; EffectVehicle *v = new EffectVehicle(); v->subtype = type; diff --git a/src/effectvehicle_base.h b/src/effectvehicle_base.h index d809657fab..73a49046bf 100644 --- a/src/effectvehicle_base.h +++ b/src/effectvehicle_base.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. @@ -37,10 +35,4 @@ struct EffectVehicle FINAL : public SpecializedVehicle 0)) { + if (override != nullptr && (IsTunnel(t) || GetTunnelBridgeLength(t, GetOtherBridgeEnd(t)) > 0)) { *override = 1 << GetTunnelBridgeDirection(t); } return DiagDirToDiagTrackBits(GetTunnelBridgeDirection(t)); @@ -326,7 +324,7 @@ static void DrawRailCatenaryRailway(const TileInfo *ti) /* Here's one of the main headaches. GetTileSlope does not correct for possibly * existing foundataions, so we do have to do that manually later on.*/ tileh[TS_NEIGHBOUR] = GetTileSlope(neighbour); - trackconfig[TS_NEIGHBOUR] = GetRailTrackBitsUniversal(neighbour, NULL); + trackconfig[TS_NEIGHBOUR] = GetRailTrackBitsUniversal(neighbour, nullptr); wireconfig[TS_NEIGHBOUR] = MaskWireBits(neighbour, trackconfig[TS_NEIGHBOUR]); if (IsTunnelTile(neighbour) && i != GetTunnelBridgeDirection(neighbour)) wireconfig[TS_NEIGHBOUR] = trackconfig[TS_NEIGHBOUR] = TRACK_BIT_NONE; @@ -593,8 +591,6 @@ void DrawRailCatenary(const TileInfo *ti) bool SettingsDisableElrail(int32 p1) { - Company *c; - Train *t; bool disable = (p1 != 0); /* we will now walk through all electric train engines and change their railtypes if it is the wrong one*/ @@ -602,8 +598,7 @@ bool SettingsDisableElrail(int32 p1) const RailType new_railtype = disable ? RAILTYPE_RAIL : RAILTYPE_ELECTRIC; /* walk through all train engines */ - Engine *e; - FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) { + 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) { @@ -615,7 +610,7 @@ bool SettingsDisableElrail(int32 p1) /* when disabling elrails, make sure that all existing trains can run on * normal rail too */ if (disable) { - FOR_ALL_TRAINS(t) { + for (Train *t : Train::Iterate()) { if (t->railtype == RAILTYPE_ELECTRIC) { /* this railroad vehicle is now compatible only with elrail, * so add there also normal rail compatibility */ @@ -627,14 +622,14 @@ bool SettingsDisableElrail(int32 p1) } /* Fix the total power and acceleration for trains */ - FOR_ALL_TRAINS(t) { + for (Train *t : Train::Iterate()) { /* power and acceleration is cached only for front engines */ if (t->IsFrontEngine()) { t->ConsistChanged(CCF_TRACK); } } - FOR_ALL_COMPANIES(c) c->avail_railtypes = GetCompanyRailtypes(c->index); + for (Company *c : Company::Iterate()) c->avail_railtypes = GetCompanyRailtypes(c->index); /* This resets the _last_built_railtype, which will be invalid for electric * rails. It may have unintended consequences if that function is ever diff --git a/src/elrail_func.h b/src/elrail_func.h index 5cdae20c54..0438437241 100644 --- a/src/elrail_func.h +++ b/src/elrail_func.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/engine.cpp b/src/engine.cpp index d539a48520..c3e9329fb7 100644 --- a/src/engine.cpp +++ b/src/engine.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. @@ -69,9 +67,9 @@ assert_compile(lengthof(_orig_rail_vehicle_info) + lengthof(_orig_road_vehicle_i const uint EngineOverrideManager::NUM_DEFAULT_ENGINES = _engine_counts[VEH_TRAIN] + _engine_counts[VEH_ROAD] + _engine_counts[VEH_SHIP] + _engine_counts[VEH_AIRCRAFT]; Engine::Engine() : - name(NULL), + name(nullptr), overrides_count(0), - overrides(NULL) + overrides(nullptr) { } @@ -162,7 +160,7 @@ bool Engine::IsEnabled() const uint32 Engine::GetGRFID() const { const GRFFile *file = this->GetGRF(); - return file == NULL ? 0 : file->grfid; + return file == nullptr ? 0 : file->grfid; } /** @@ -199,28 +197,28 @@ bool Engine::CanCarryCargo() const /** * Determines capacity of a given vehicle from scratch. * For aircraft the main capacity is determined. Mail might be present as well. - * @param v Vehicle of interest; NULL in purchase list + * @param v Vehicle of interest; nullptr in purchase list * @param mail_capacity returns secondary cargo (mail) capacity of aircraft * @return Capacity */ uint Engine::DetermineCapacity(const Vehicle *v, uint16 *mail_capacity) const { - assert(v == NULL || this->index == v->engine_type); - if (mail_capacity != NULL) *mail_capacity = 0; + assert(v == nullptr || this->index == v->engine_type); + if (mail_capacity != nullptr) *mail_capacity = 0; if (!this->CanCarryCargo()) return 0; bool new_multipliers = HasBit(this->info.misc_flags, EF_NO_DEFAULT_CARGO_MULTIPLIER); CargoID default_cargo = this->GetDefaultCargoType(); - CargoID cargo_type = (v != NULL) ? v->cargo_type : default_cargo; + CargoID cargo_type = (v != nullptr) ? v->cargo_type : default_cargo; - if (mail_capacity != NULL && this->type == VEH_AIRCRAFT && IsCargoInClass(cargo_type, CC_PASSENGERS)) { + if (mail_capacity != nullptr && this->type == VEH_AIRCRAFT && IsCargoInClass(cargo_type, CC_PASSENGERS)) { *mail_capacity = GetEngineProperty(this->index, PROP_AIRCRAFT_MAIL_CAPACITY, this->u.air.mail_capacity, v); } /* Check the refit capacity callback if we are not in the default configuration, or if we are using the new multiplier algorithm. */ if (HasBit(this->info.callback_mask, CBM_VEHICLE_REFIT_CAPACITY) && - (new_multipliers || default_cargo != cargo_type || (v != NULL && v->cargo_subtype != 0))) { + (new_multipliers || default_cargo != cargo_type || (v != nullptr && v->cargo_subtype != 0))) { uint16 callback = GetVehicleCallback(CBID_VEHICLE_REFIT_CAPACITY, 0, 0, this->index, v); if (callback != CALLBACK_FAILED) return callback; } @@ -233,7 +231,7 @@ uint Engine::DetermineCapacity(const Vehicle *v, uint16 *mail_capacity) const capacity = GetEngineProperty(this->index, PROP_TRAIN_CARGO_CAPACITY, this->u.rail.capacity, v); /* In purchase list add the capacity of the second head. Always use the plain property for this. */ - if (v == NULL && this->u.rail.railveh_type == RAILVEH_MULTIHEAD) capacity += this->u.rail.capacity; + if (v == nullptr && this->u.rail.railveh_type == RAILVEH_MULTIHEAD) capacity += this->u.rail.capacity; break; case VEH_ROAD: @@ -487,14 +485,15 @@ StringID Engine::GetAircraftTypeText() const */ void EngineOverrideManager::ResetToDefaultMapping() { - this->Clear(); + this->clear(); for (VehicleType type = VEH_TRAIN; type <= VEH_AIRCRAFT; type++) { for (uint internal_id = 0; internal_id < _engine_counts[type]; internal_id++) { - EngineIDMapping *eid = this->Append(); - eid->type = type; - eid->grfid = INVALID_GRFID; - eid->internal_id = internal_id; - eid->substitute_id = internal_id; + /*C++17: EngineIDMapping &eid = */ this->emplace_back(); + EngineIDMapping &eid = this->back(); + eid.type = type; + eid.grfid = INVALID_GRFID; + eid.internal_id = internal_id; + eid.substitute_id = internal_id; } } } @@ -510,12 +509,12 @@ void EngineOverrideManager::ResetToDefaultMapping() */ EngineID EngineOverrideManager::GetID(VehicleType type, uint16 grf_local_id, uint32 grfid) { - const EngineIDMapping *end = this->End(); EngineID index = 0; - for (const EngineIDMapping *eid = this->Begin(); eid != end; eid++, index++) { - if (eid->type == type && eid->grfid == grfid && eid->internal_id == grf_local_id) { + for (const EngineIDMapping &eid : *this) { + if (eid.type == type && eid.grfid == grfid && eid.internal_id == grf_local_id) { return index; } + index++; } return INVALID_ENGINE; } @@ -527,8 +526,7 @@ EngineID EngineOverrideManager::GetID(VehicleType type, uint16 grf_local_id, uin */ bool EngineOverrideManager::ResetToCurrentNewGRFConfig() { - const Vehicle *v; - FOR_ALL_VEHICLES(v) { + for (const Vehicle *v : Vehicle::Iterate()) { if (IsCompanyBuildableVehicleType(v)) return false; } @@ -547,15 +545,15 @@ void SetupEngines() DeleteWindowByClass(WC_ENGINE_PREVIEW); _engine_pool.CleanPool(); - assert(_engine_mngr.Length() >= _engine_mngr.NUM_DEFAULT_ENGINES); - const EngineIDMapping *end = _engine_mngr.End(); + assert(_engine_mngr.size() >= _engine_mngr.NUM_DEFAULT_ENGINES); uint index = 0; - for (const EngineIDMapping *eid = _engine_mngr.Begin(); eid != end; eid++, index++) { + 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. */ assert(Engine::CanAllocateItem()); - const Engine *e = new Engine(eid->type, eid->internal_id); + const Engine *e = new Engine(eid.type, eid.internal_id); assert(e->index == index); + index++; } } @@ -619,8 +617,7 @@ void SetYearEngineAgingStops() /* Determine last engine aging year, default to 2050 as previously. */ _year_engine_aging_stops = 2050; - const Engine *e; - FOR_ALL_ENGINES(e) { + for (const Engine *e : Engine::Iterate()) { const EngineInfo *ei = &e->info; /* Exclude certain engines */ @@ -695,25 +692,68 @@ void StartupOneEngine(Engine *e, Date aging_date) */ void StartupEngines() { - Engine *e; /* Aging of vehicles stops, so account for that when starting late */ const Date aging_date = min(_date, ConvertYMDToDate(_year_engine_aging_stops, 0, 1)); - FOR_ALL_ENGINES(e) { + for (Engine *e : Engine::Iterate()) { StartupOneEngine(e, aging_date); } /* Update the bitmasks for the vehicle lists */ - Company *c; - FOR_ALL_COMPANIES(c) { + for (Company *c : Company::Iterate()) { c->avail_railtypes = GetCompanyRailtypes(c->index); - c->avail_roadtypes = GetCompanyRoadtypes(c->index); + c->avail_roadtypes = GetCompanyRoadTypes(c->index); } /* Invalidate any open purchase lists */ InvalidateWindowClassesData(WC_BUILD_VEHICLE); } +/** + * Allows engine \a eid to be used by a company \a company. + * @param eid The engine to enable. + * @param company The company to allow using the engine. + */ +static void EnableEngineForCompany(EngineID eid, CompanyID company) +{ + Engine *e = Engine::Get(eid); + Company *c = Company::Get(company); + + SetBit(e->company_avail, company); + if (e->type == VEH_TRAIN) { + assert(e->u.rail.railtype < RAILTYPE_END); + c->avail_railtypes = AddDateIntroducedRailTypes(c->avail_railtypes | GetRailTypeInfo(e->u.rail.railtype)->introduces_railtypes, _date); + } else if (e->type == VEH_ROAD) { + assert(e->u.road.roadtype < ROADTYPE_END); + c->avail_roadtypes = AddDateIntroducedRoadTypes(c->avail_roadtypes | GetRoadTypeInfo(e->u.road.roadtype)->introduces_roadtypes, _date); + } + + if (company == _local_company) { + AddRemoveEngineFromAutoreplaceAndBuildWindows(e->type); + + /* Update the toolbar. */ + InvalidateWindowData(WC_MAIN_TOOLBAR, 0); + if (e->type == VEH_ROAD) InvalidateWindowData(WC_BUILD_TOOLBAR, TRANSPORT_ROAD); + if (e->type == VEH_SHIP) InvalidateWindowData(WC_BUILD_TOOLBAR, TRANSPORT_WATER); + } +} + +/** + * Forbids engine \a eid to be used by a company \a company. + * @param eid The engine to disable. + * @param company The company to forbid using the engine. + */ +static void DisableEngineForCompany(EngineID eid, CompanyID company) +{ + Engine *e = Engine::Get(eid); + + ClrBit(e->company_avail, company); + + if (company == _local_company) { + AddRemoveEngineFromAutoreplaceAndBuildWindows(e->type); + } +} + /** * Company \a company accepts engine \a eid for preview. * @param eid Engine being accepted (is under preview). @@ -722,25 +762,11 @@ void StartupEngines() static void AcceptEnginePreview(EngineID eid, CompanyID company) { Engine *e = Engine::Get(eid); - Company *c = Company::Get(company); - - SetBit(e->company_avail, company); - if (e->type == VEH_TRAIN) { - assert(e->u.rail.railtype < RAILTYPE_END); - c->avail_railtypes = AddDateIntroducedRailTypes(c->avail_railtypes | GetRailTypeInfo(e->u.rail.railtype)->introduces_railtypes, _date); - } else if (e->type == VEH_ROAD) { - SetBit(c->avail_roadtypes, HasBit(e->info.misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD); - } e->preview_company = INVALID_COMPANY; e->preview_asked = (CompanyMask)-1; - if (company == _local_company) { - AddRemoveEngineFromAutoreplaceAndBuildWindows(e->type); - } - /* Update the toolbar. */ - if (e->type == VEH_ROAD) InvalidateWindowData(WC_BUILD_TOOLBAR, TRANSPORT_ROAD); - if (e->type == VEH_SHIP) InvalidateWindowData(WC_BUILD_TOOLBAR, TRANSPORT_WATER); + EnableEngineForCompany(eid, company); /* Notify preview window, that it might want to close. * Note: We cannot directly close the window. @@ -763,14 +789,12 @@ static CompanyID GetPreviewCompany(Engine *e) CargoTypes cargomask = e->type != VEH_TRAIN ? GetUnionOfArticulatedRefitMasks(e->index, true) : ALL_CARGOTYPES; int32 best_hist = -1; - const Company *c; - FOR_ALL_COMPANIES(c) { + for (const Company *c : Company::Iterate()) { if (c->block_preview == 0 && !HasBit(e->preview_asked, c->index) && c->old_economy[0].performance_history > best_hist) { /* Check whether the company uses similar vehicles */ - Vehicle *v; - FOR_ALL_VEHICLES(v) { + for (const Vehicle *v : Vehicle::Iterate()) { if (v->owner != c->index || v->type != e->type) continue; if (!v->GetEngine()->CanCarryCargo() || !HasBit(cargomask, v->cargo_type)) continue; @@ -806,15 +830,14 @@ static bool IsVehicleTypeDisabled(VehicleType type, bool ai) /** Daily check to offer an exclusive engine preview to the companies. */ void EnginesDailyLoop() { - Company *c; - FOR_ALL_COMPANIES(c) { + for (Company *c : Company::Iterate()) { c->avail_railtypes = AddDateIntroducedRailTypes(c->avail_railtypes, _date); + c->avail_roadtypes = AddDateIntroducedRoadTypes(c->avail_roadtypes, _date); } if (_cur_year >= _year_engine_aging_stops) return; - Engine *e; - FOR_ALL_ENGINES(e) { + for (Engine *e : Engine::Iterate()) { EngineID i = e->index; if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) { if (e->preview_company != INVALID_COMPANY) { @@ -850,8 +873,7 @@ void EnginesDailyLoop() */ void ClearEnginesHiddenFlagOfCompany(CompanyID cid) { - Engine *e; - FOR_ALL_ENGINES(e) { + for (Engine *e : Engine::Iterate()) { SB(e->company_hidden, cid, 1, 0); } } @@ -868,7 +890,7 @@ void ClearEnginesHiddenFlagOfCompany(CompanyID cid) CommandCost CmdSetVehicleVisibility(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { Engine *e = Engine::GetIfValid(GB(p2, 0, 31)); - if (e == NULL || _current_company >= MAX_COMPANIES) return CMD_ERROR; + if (e == nullptr || _current_company >= MAX_COMPANIES) return CMD_ERROR; if (!IsEngineBuildable(e->index, e->type, _current_company)) return CMD_ERROR; if ((flags & DC_EXEC) != 0) { @@ -892,13 +914,44 @@ CommandCost CmdSetVehicleVisibility(TileIndex tile, DoCommandFlag flags, uint32 CommandCost CmdWantEnginePreview(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { Engine *e = Engine::GetIfValid(p1); - if (e == NULL || !(e->flags & ENGINE_EXCLUSIVE_PREVIEW) || e->preview_company != _current_company) return CMD_ERROR; + if (e == nullptr || !(e->flags & ENGINE_EXCLUSIVE_PREVIEW) || e->preview_company != _current_company) return CMD_ERROR; if (flags & DC_EXEC) AcceptEnginePreview(p1, _current_company); return CommandCost(); } +/** + * Allow or forbid a specific company to use an engine + * @param tile unused + * @param flags operation to perform + * @param p1 engine id + * @param p2 various bitstuffed elements + * - p2 = (bit 0 - 7) - Company to allow/forbid the use of an engine. + * - p2 = (bit 31) - 0 to forbid, 1 to allow. + * @param text unused + * @return the cost of this operation or an error + */ +CommandCost CmdEngineCtrl(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) +{ + if (_current_company != OWNER_DEITY) return CMD_ERROR; + EngineID engine_id = (EngineID)p1; + CompanyID company_id = (CompanyID)GB(p2, 0, 8); + bool allow = HasBit(p2, 31); + + if (!Engine::IsValidID(engine_id) || !Company::IsValidID(company_id)) return CMD_ERROR; + + if (flags & DC_EXEC) { + if (allow) { + EnableEngineForCompany(engine_id, company_id); + } else { + DisableEngineForCompany(engine_id, company_id); + } + } + + return CommandCost(); +} + /** * An engine has become available for general use. * Also handle the exclusive engine preview contract. @@ -906,14 +959,12 @@ CommandCost CmdWantEnginePreview(TileIndex tile, DoCommandFlag flags, uint32 p1, */ static void NewVehicleAvailable(Engine *e) { - Vehicle *v; - Company *c; EngineID index = e->index; /* In case the company didn't build the vehicle during the intro period, * prevent that company from getting future intro periods for a while. */ if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) { - FOR_ALL_COMPANIES(c) { + for (Company *c : Company::Iterate()) { uint block_preview = c->block_preview; if (!HasBit(e->company_avail, c->index)) continue; @@ -921,7 +972,7 @@ static void NewVehicleAvailable(Engine *e) /* We assume the user did NOT build it.. prove me wrong ;) */ c->block_preview = 20; - FOR_ALL_VEHICLES(v) { + for (const Vehicle *v : Vehicle::Iterate()) { if (v->type == VEH_TRAIN || v->type == VEH_ROAD || v->type == VEH_SHIP || (v->type == VEH_AIRCRAFT && Aircraft::From(v)->IsNormalAircraft())) { if (v->owner == c->index && v->engine_type == index) { @@ -947,10 +998,11 @@ static void NewVehicleAvailable(Engine *e) /* maybe make another rail type available */ RailType railtype = e->u.rail.railtype; assert(railtype < RAILTYPE_END); - FOR_ALL_COMPANIES(c) c->avail_railtypes = AddDateIntroducedRailTypes(c->avail_railtypes | GetRailTypeInfo(e->u.rail.railtype)->introduces_railtypes, _date); + for (Company *c : Company::Iterate()) c->avail_railtypes = AddDateIntroducedRailTypes(c->avail_railtypes | GetRailTypeInfo(e->u.rail.railtype)->introduces_railtypes, _date); } else if (e->type == VEH_ROAD) { /* maybe make another road type available */ - FOR_ALL_COMPANIES(c) SetBit(c->avail_roadtypes, HasBit(e->info.misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD); + assert(e->u.road.roadtype < ROADTYPE_END); + for (Company* c : Company::Iterate()) c->avail_roadtypes = AddDateIntroducedRoadTypes(c->avail_roadtypes | GetRoadTypeInfo(e->u.road.roadtype)->introduces_roadtypes, _date); } /* Only broadcast event if AIs are able to build this vehicle type. */ @@ -975,8 +1027,7 @@ static void NewVehicleAvailable(Engine *e) void EnginesMonthlyLoop() { if (_cur_year < _year_engine_aging_stops) { - Engine *e; - FOR_ALL_ENGINES(e) { + for (Engine *e : Engine::Iterate()) { /* Age the vehicle */ if ((e->flags & ENGINE_AVAILABLE) && e->age != MAX_DAY) { e->age++; @@ -1017,10 +1068,8 @@ void EnginesMonthlyLoop() */ static bool IsUniqueEngineName(const char *name) { - const Engine *e; - - FOR_ALL_ENGINES(e) { - if (e->name != NULL && strcmp(e->name, name) == 0) return false; + for (const Engine *e : Engine::Iterate()) { + if (e->name != nullptr && strcmp(e->name, name) == 0) return false; } return true; @@ -1038,7 +1087,7 @@ static bool IsUniqueEngineName(const char *name) CommandCost CmdRenameEngine(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { Engine *e = Engine::GetIfValid(p1); - if (e == NULL) return CMD_ERROR; + if (e == nullptr) return CMD_ERROR; bool reset = StrEmpty(text); @@ -1051,7 +1100,7 @@ CommandCost CmdRenameEngine(TileIndex tile, DoCommandFlag flags, uint32 p1, uint free(e->name); if (reset) { - e->name = NULL; + e->name = nullptr; } else { e->name = stredup(text); } @@ -1076,7 +1125,7 @@ bool IsEngineBuildable(EngineID engine, VehicleType type, CompanyID company) const Engine *e = Engine::GetIfValid(engine); /* check if it's an engine that is in the engine array */ - if (e == NULL) return false; + if (e == nullptr) return false; /* check if it's an engine of specified type */ if (e->type != type) return false; @@ -1097,6 +1146,11 @@ bool IsEngineBuildable(EngineID engine, VehicleType type, CompanyID company) const Company *c = Company::Get(company); if (((GetRailTypeInfo(e->u.rail.railtype))->compatible_railtypes & c->avail_railtypes) == 0) return false; } + if (type == VEH_ROAD && company != OWNER_DEITY) { + /* Check if the road type is available to this company */ + const Company *c = Company::Get(company); + if ((GetRoadTypeInfo(e->u.road.roadtype)->powered_roadtypes & c->avail_roadtypes) == ROADTYPES_NONE) return false; + } return true; } @@ -1112,7 +1166,7 @@ bool IsEngineRefittable(EngineID engine) const Engine *e = Engine::GetIfValid(engine); /* check if it's an engine that is in the engine array */ - if (e == NULL) return false; + if (e == nullptr) return false; if (!e->CanCarryCargo()) return false; @@ -1135,10 +1189,9 @@ bool IsEngineRefittable(EngineID engine) */ void CheckEngines() { - const Engine *e; Date min_date = INT32_MAX; - FOR_ALL_ENGINES(e) { + for (const Engine *e : Engine::Iterate()) { if (!e->IsEnabled()) continue; /* We have an available engine... yay! */ diff --git a/src/engine_base.h b/src/engine_base.h index 25c6bfbeb9..203d35f201 100644 --- a/src/engine_base.h +++ b/src/engine_base.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. @@ -34,7 +32,7 @@ struct Engine : EnginePool::PoolItem<&_engine_pool> { uint16 duration_phase_3; ///< Third reliability phase on months, decaying to #reliability_final. byte flags; ///< Flags of the engine. @see EngineFlags CompanyMask preview_asked; ///< Bit for each company which has already been offered a preview. - CompanyByte preview_company;///< Company which is currently being offered a preview \c INVALID_COMPANY means no company. + CompanyID preview_company; ///< Company which is currently being offered a preview \c INVALID_COMPANY means no company. byte preview_wait; ///< Daily countdown timer for timeout of offering the engine to the #preview_company company. CompanyMask company_avail; ///< Bit for each company whether the engine is available for that company. CompanyMask company_hidden; ///< Bit for each company whether the engine is normally hidden in the build gui for that company. @@ -83,7 +81,7 @@ struct Engine : EnginePool::PoolItem<&_engine_pool> { return this->info.cargo_type; } - uint DetermineCapacity(const Vehicle *v, uint16 *mail_capacity = NULL) const; + uint DetermineCapacity(const Vehicle *v, uint16 *mail_capacity = nullptr) const; bool CanCarryCargo() const; @@ -98,9 +96,9 @@ struct Engine : EnginePool::PoolItem<&_engine_pool> { * @return The default capacity * @see GetDefaultCargoType */ - uint GetDisplayDefaultCapacity(uint16 *mail_capacity = NULL) const + uint GetDisplayDefaultCapacity(uint16 *mail_capacity = nullptr) const { - return this->DetermineCapacity(NULL, mail_capacity); + return this->DetermineCapacity(nullptr, mail_capacity); } Money GetRunningCost() const; @@ -118,7 +116,7 @@ struct Engine : EnginePool::PoolItem<&_engine_pool> { * @param c Company to check. * @return \c true iff the engine is hidden in the GUI for the given company. */ - inline bool IsHidden(CompanyByte c) const + inline bool IsHidden(CompanyID c) const { return c < MAX_COMPANIES && HasBit(this->company_hidden, c); } @@ -143,12 +141,29 @@ struct Engine : EnginePool::PoolItem<&_engine_pool> { } uint32 GetGRFID() const; + + struct EngineTypeFilter { + VehicleType vt; + + bool operator() (size_t index) { return Engine::Get(index)->type == this->vt; } + }; + + /** + * Returns an iterable ensemble of all valid engines of the given type + * @param vt the VehicleType for engines to be valid + * @param from index of the first engine to consider + * @return an iterable ensemble of all valid engines of the given type + */ + static Pool::IterateWrapperFiltered IterateType(VehicleType vt, size_t from = 0) + { + return Pool::IterateWrapperFiltered(from, EngineTypeFilter{ vt }); + } }; struct EngineIDMapping { uint32 grfid; ///< The GRF ID of the file the entity belongs to uint16 internal_id; ///< The internal ID within the GRF file - VehicleTypeByte type; ///< The engine type + VehicleType type; ///< The engine type uint8 substitute_id; ///< The (original) entity ID to use if this GRF is not available (currently not used) }; @@ -156,7 +171,7 @@ struct EngineIDMapping { * Stores the mapping of EngineID to the internal id of newgrfs. * Note: This is not part of Engine, as the data in the EngineOverrideManager and the engine pool get resetted in different cases. */ -struct EngineOverrideManager : SmallVector { +struct EngineOverrideManager : std::vector { static const uint NUM_DEFAULT_ENGINES; ///< Number of default entries void ResetToDefaultMapping(); @@ -167,11 +182,6 @@ struct EngineOverrideManager : SmallVector { extern EngineOverrideManager _engine_mngr; -#define FOR_ALL_ENGINES_FROM(var, start) FOR_ALL_ITEMS_FROM(Engine, engine_index, var, start) -#define FOR_ALL_ENGINES(var) FOR_ALL_ENGINES_FROM(var, 0) - -#define FOR_ALL_ENGINES_OF_TYPE(e, engine_type) FOR_ALL_ENGINES(e) if (e->type == engine_type) - static inline const EngineInfo *EngInfo(EngineID e) { return &Engine::Get(e)->info; diff --git a/src/engine_func.h b/src/engine_func.h index 37fb005092..472600cf77 100644 --- a/src/engine_func.h +++ b/src/engine_func.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. @@ -26,7 +24,7 @@ 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); +void GetArticulatedVehicleCargoesAndRefits(EngineID engine, CargoArray *cargoes, CargoTypes *refits, CargoID cargo_type, uint16 cargo_capacity); void SetYearEngineAgingStops(); void StartupOneEngine(Engine *e, Date aging_date); diff --git a/src/engine_gui.cpp b/src/engine_gui.cpp index 51c7e14836..b71fa7a6bd 100644 --- a/src/engine_gui.cpp +++ b/src/engine_gui.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. @@ -19,6 +17,7 @@ #include "vehicle_func.h" #include "company_func.h" #include "rail.h" +#include "road.h" #include "settings_type.h" #include "train.h" #include "roadveh.h" @@ -41,7 +40,8 @@ StringID GetEngineCategoryName(EngineID engine) const Engine *e = Engine::Get(engine); switch (e->type) { default: NOT_REACHED(); - case VEH_ROAD: return STR_ENGINE_PREVIEW_ROAD_VEHICLE; + case VEH_ROAD: + return GetRoadTypeInfo(e->u.road.roadtype)->strings.new_engine; case VEH_AIRCRAFT: return STR_ENGINE_PREVIEW_AIRCRAFT; case VEH_SHIP: return STR_ENGINE_PREVIEW_SHIP; case VEH_TRAIN: @@ -75,7 +75,7 @@ struct EnginePreviewWindow : Window { this->flags |= WF_STICKY; } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { if (widget != WID_EP_QUESTION) return; @@ -102,7 +102,7 @@ struct EnginePreviewWindow : Window { size->height += GetStringHeight(GetEngineInfoString(engine), size->width); } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { if (widget != WID_EP_QUESTION) return; @@ -121,7 +121,7 @@ struct EnginePreviewWindow : Window { DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, r.bottom, GetEngineInfoString(engine), TC_FROMSTRING, SA_CENTER); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_EP_YES: @@ -133,7 +133,7 @@ struct EnginePreviewWindow : Window { } } - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; @@ -325,11 +325,8 @@ void DrawVehicleEngine(int left, int right, int preferred_x, int y, EngineID eng */ void EngList_Sort(GUIEngineList *el, EngList_SortTypeFunction compare) { - uint size = el->Length(); - /* out-of-bounds access at the next line for size == 0 (even with operator[] at some systems) - * generally, do not sort if there are less than 2 items */ - if (size < 2) return; - QSortT(el->Begin(), size, compare); + if (el->size() < 2) return; + std::sort(el->begin(), el->end(), compare); } /** @@ -342,8 +339,8 @@ void EngList_Sort(GUIEngineList *el, EngList_SortTypeFunction compare) void EngList_SortPartial(GUIEngineList *el, EngList_SortTypeFunction compare, uint begin, uint num_items) { if (num_items < 2) return; - assert(begin < el->Length()); - assert(begin + num_items <= el->Length()); - QSortT(el->Get(begin), num_items, compare); + assert(begin < el->size()); + assert(begin + num_items <= el->size()); + std::sort(el->begin() + begin, el->begin() + begin + num_items, compare); } diff --git a/src/engine_gui.h b/src/engine_gui.h index fc0b7ad7d9..f987f57d35 100644 --- a/src/engine_gui.h +++ b/src/engine_gui.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. @@ -19,7 +17,7 @@ typedef GUIList GUIEngineList; -typedef int CDECL EngList_SortTypeFunction(const EngineID*, const EngineID*); ///< argument type for #EngList_Sort. +typedef bool EngList_SortTypeFunction(const EngineID&, const EngineID&); ///< 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); diff --git a/src/engine_type.h b/src/engine_type.h index 82f10d9d87..83f8dc307e 100644 --- a/src/engine_type.h +++ b/src/engine_type.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. @@ -14,6 +12,7 @@ #include "economy_type.h" #include "rail_type.h" +#include "road_type.h" #include "cargo_type.h" #include "date_type.h" #include "sound_type.h" @@ -44,7 +43,7 @@ struct RailVehicleInfo { byte image_index; RailVehicleTypes railveh_type; byte cost_factor; ///< Purchase cost factor; For multiheaded engines the sum of both engine prices. - RailTypeByte railtype; + RailType railtype; 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. @@ -123,6 +122,7 @@ struct RoadVehicleInfo { uint8 air_drag; ///< Coefficient of air drag byte visual_effect; ///< Bitstuffed NewGRF visual effect data byte shorten_factor; ///< length on main map for this type is 8 - shorten_factor + RoadType roadtype; ///< Road type }; /** diff --git a/src/error.h b/src/error.h index 597b62efbe..78ee9c5918 100644 --- a/src/error.h +++ b/src/error.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. @@ -43,7 +41,7 @@ protected: 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 = NULL, uint textref_stack_size = 0, const uint32 *textref_stack = NULL); + 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); /** Check whether error window shall display a company manager face */ bool HasFace() const { return face != INVALID_COMPANY; } @@ -56,7 +54,7 @@ public: 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 = NULL, uint textref_stack_size = 0, const uint32 *textref_stack = NULL); +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 ClearErrorMessages(); void ShowFirstError(); void UnshowCriticalError(); diff --git a/src/error_gui.cpp b/src/error_gui.cpp index 90f1698f1b..f02f114eb9 100644 --- a/src/error_gui.cpp +++ b/src/error_gui.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. @@ -78,11 +76,15 @@ static WindowDesc _errmsg_face_desc( * Copy the given data into our instance. * @param data The data to copy. */ -ErrorMessageData::ErrorMessageData(const ErrorMessageData &data) +ErrorMessageData::ErrorMessageData(const ErrorMessageData &data) : + duration(data.duration), 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) { - *this = data; + memcpy(this->textref_stack, data.textref_stack, sizeof(this->textref_stack)); + memcpy(this->decode_params, data.decode_params, sizeof(this->decode_params)); + memcpy(this->strings, data.strings, sizeof(this->strings)); for (size_t i = 0; i < lengthof(this->strings); i++) { - if (this->strings[i] != NULL) { + if (this->strings[i] != nullptr) { this->strings[i] = stredup(this->strings[i]); this->decode_params[i] = (size_t)this->strings[i]; } @@ -186,7 +188,7 @@ public: this->InitNested(); } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_EM_MESSAGE: { @@ -214,7 +216,7 @@ public: } } - virtual Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number) + Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number) override { /* Position (0, 0) given, center the window. */ if (this->position.x == 0 && this->position.y == 0) { @@ -228,7 +230,7 @@ public: int scr_top = GetMainViewTop() + 20; int scr_bot = GetMainViewBottom() - 20; - Point pt = RemapCoords2(this->position.x, this->position.y); + 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; if (this->face == INVALID_COMPANY) { /* move x pos to opposite corner */ @@ -250,18 +252,18 @@ public: * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { /* If company gets shut down, while displaying an error about it, remove the error message. */ if (this->face != INVALID_COMPANY && !Company::IsValidID(this->face)) delete this; } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { if (widget == WID_EM_CAPTION) CopyInDParam(0, this->decode_params, lengthof(this->decode_params)); } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { switch (widget) { case WID_EM_FACE: { @@ -298,13 +300,13 @@ public: } } - virtual void OnMouseLoop() + void OnMouseLoop() override { /* Disallow closing the window too easily, if timeout is disabled */ if (_right_button_down && this->duration != 0) delete this; } - virtual void OnHundredthTick() + void OnHundredthTick() override { /* Timeout enabled? */ if (this->duration != 0) { @@ -319,7 +321,7 @@ public: if (_window_system_initialized) ShowFirstError(); } - virtual EventState OnKeyPress(WChar key, uint16 keycode) + EventState OnKeyPress(WChar key, uint16 keycode) override { if (keycode != WKC_SPACE) return ES_NOT_HANDLED; delete this; @@ -375,7 +377,7 @@ void ShowFirstError() void UnshowCriticalError() { ErrmsgWindow *w = (ErrmsgWindow*)FindWindowById(WC_ERRMSG, 0); - if (_window_system_initialized && w != NULL) { + if (_window_system_initialized && w != nullptr) { if (w->IsCritical()) _error_list.push_front(*w); _window_system_initialized = false; delete w; @@ -395,7 +397,7 @@ void UnshowCriticalError() */ 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) { - assert(textref_stack_size == 0 || (textref_stack_grffile != NULL && textref_stack != NULL)); + assert(textref_stack_size == 0 || (textref_stack_grffile != nullptr && textref_stack != nullptr)); if (summary_msg == STR_NULL) summary_msg = STR_EMPTY; if (wl != WL_INFO) { @@ -426,7 +428,7 @@ void ShowErrorMessage(StringID summary_msg, StringID detailed_msg, WarningLevel data.CopyOutDParams(); ErrmsgWindow *w = (ErrmsgWindow*)FindWindowById(WC_ERRMSG, 0); - if (w != NULL && w->IsCritical()) { + if (w != nullptr && w->IsCritical()) { /* A critical error is currently shown. */ if (wl == WL_CRITICAL) { /* Push another critical error in the queue of errors, diff --git a/src/fileio.cpp b/src/fileio.cpp index 0e6d86e3c7..dc3813bcaa 100644 --- a/src/fileio.cpp +++ b/src/fileio.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. @@ -29,7 +27,7 @@ #include #ifdef WITH_XDG_BASEDIR -#include "basedir.h" +#include #endif #include "safeguards.h" @@ -99,7 +97,7 @@ void FioSeekTo(size_t pos, int mode) static void FioRestoreFile(int slot) { /* Do we still have the file open, or should we reopen it? */ - if (_fio.handles[slot] == NULL) { + if (_fio.handles[slot] == nullptr) { DEBUG(misc, 6, "Restoring file '%s' in slot '%d' from disk", _fio.filenames[slot], slot); FioOpenFile(slot, _fio.filenames[slot]); } @@ -120,7 +118,7 @@ void FioSeekToFile(uint8 slot, size_t pos) FioRestoreFile(slot); #endif /* LIMITED_FDS */ f = _fio.handles[slot]; - assert(f != NULL); + assert(f != nullptr); _fio.cur_fh = f; _fio.filename = _fio.filenames[slot]; FioSeekTo(pos, SEEK_SET); @@ -196,13 +194,13 @@ void FioReadBlock(void *ptr, size_t size) */ static inline void FioCloseFile(int slot) { - if (_fio.handles[slot] != NULL) { + if (_fio.handles[slot] != nullptr) { fclose(_fio.handles[slot]); free(_fio.shortnames[slot]); - _fio.shortnames[slot] = NULL; + _fio.shortnames[slot] = nullptr; - _fio.handles[slot] = NULL; + _fio.handles[slot] = nullptr; #if defined(LIMITED_FDS) _fio.open_handles--; #endif /* LIMITED_FDS */ @@ -229,7 +227,7 @@ static void FioFreeHandle() slot = -1; /* Find the file that is used the least */ for (i = 0; i < lengthof(_fio.handles); i++) { - if (_fio.handles[i] != NULL && _fio.usage_count[i] < count) { + if (_fio.handles[i] != nullptr && _fio.usage_count[i] < count) { count = _fio.usage_count[i]; slot = i; } @@ -255,7 +253,7 @@ void FioOpenFile(int slot, const char *filename, Subdirectory subdir) FioFreeHandle(); #endif /* LIMITED_FDS */ f = FioFOpenFile(filename, "rb", subdir); - if (f == NULL) usererror("Cannot open file '%s'", filename); + if (f == nullptr) usererror("Cannot open file '%s'", filename); long pos = ftell(f); if (pos < 0) usererror("Cannot read file '%s'", filename); @@ -265,9 +263,9 @@ void FioOpenFile(int slot, const char *filename, Subdirectory subdir) /* Store the filename without path and extension */ const char *t = strrchr(filename, PATHSEPCHAR); - _fio.shortnames[slot] = stredup(t == NULL ? filename : t); + _fio.shortnames[slot] = stredup(t == nullptr ? filename : t); char *t2 = strrchr(_fio.shortnames[slot], '.'); - if (t2 != NULL) *t2 = '\0'; + if (t2 != nullptr) *t2 = '\0'; strtolower(_fio.shortnames[slot]); #if defined(LIMITED_FDS) @@ -312,7 +310,7 @@ static TarLinkList _tar_linklist[NUM_SUBDIRS]; ///< List of directory links bool FioCheckFileExists(const char *filename, Subdirectory subdir) { FILE *f = FioFOpenFile(filename, "rb", subdir); - if (f == NULL) return false; + if (f == nullptr) return false; FioFCloseFile(f); return true; @@ -351,7 +349,7 @@ char *FioGetFullPath(char *buf, const char *last, Searchpath sp, Subdirectory su * @param last End of the destination buffer. * @param subdir Subdirectory to try. * @param filename Filename to look for. - * @return \a buf containing the path if the path was found, else \c NULL. + * @return \a buf containing the path if the path was found, else \c nullptr. */ char *FioFindFullPath(char *buf, const char *last, Subdirectory subdir, const char *filename) { @@ -369,7 +367,7 @@ char *FioFindFullPath(char *buf, const char *last, Subdirectory subdir, const ch #endif } - return NULL; + return nullptr; } char *FioAppendDirectory(char *buf, const char *last, Searchpath sp, Subdirectory subdir) @@ -407,7 +405,7 @@ static FILE *FioFOpenFileSp(const char *filename, const char *mode, Searchpath s wchar_t Lmode[5]; MultiByteToWideChar(CP_ACP, 0, mode, -1, Lmode, lengthof(Lmode)); #endif - FILE *f = NULL; + FILE *f = nullptr; char buf[MAX_PATH]; if (subdir == NO_DIRECTORY) { @@ -417,16 +415,16 @@ static FILE *FioFOpenFileSp(const char *filename, const char *mode, Searchpath s } #if defined(_WIN32) - if (mode[0] == 'r' && GetFileAttributes(OTTD2FS(buf)) == INVALID_FILE_ATTRIBUTES) return NULL; + if (mode[0] == 'r' && GetFileAttributes(OTTD2FS(buf)) == INVALID_FILE_ATTRIBUTES) return nullptr; #endif f = fopen(buf, mode); #if !defined(_WIN32) - if (f == NULL && strtolower(buf + ((subdir == NO_DIRECTORY) ? 0 : strlen(_searchpaths[sp]) - 1))) { + if (f == nullptr && strtolower(buf + ((subdir == NO_DIRECTORY) ? 0 : strlen(_searchpaths[sp]) - 1))) { f = fopen(buf, mode); } #endif - if (f != NULL && filesize != NULL) { + if (f != nullptr && filesize != nullptr) { /* Find the size of the file */ fseek(f, 0, SEEK_END); *filesize = ftell(f); @@ -438,21 +436,21 @@ static FILE *FioFOpenFileSp(const char *filename, const char *mode, Searchpath s /** * Opens a file from inside a tar archive. * @param entry The entry to open. - * @param[out] filesize If not \c NULL, size of the opened file. - * @return File handle of the opened file, or \c NULL if the file is not available. + * @param[out] filesize If not \c nullptr, size of the opened file. + * @return File handle of the opened file, or \c nullptr if the file is not available. * @note The file is read from within the tar file, and may not return \c EOF after reading the whole file. */ FILE *FioFOpenFileTar(TarFileListEntry *entry, size_t *filesize) { FILE *f = fopen(entry->tar_filename, "rb"); - if (f == NULL) return f; + if (f == nullptr) return f; if (fseek(f, entry->position, SEEK_SET) < 0) { fclose(f); - return NULL; + return nullptr; } - if (filesize != NULL) *filesize = entry->size; + if (filesize != nullptr) *filesize = entry->size; return f; } @@ -460,22 +458,22 @@ FILE *FioFOpenFileTar(TarFileListEntry *entry, size_t *filesize) * Opens a OpenTTD file somewhere in a personal or global directory. * @param filename Name of the file to open. * @param subdir Subdirectory to open. - * @return File handle of the opened file, or \c NULL if the file is not available. + * @return File handle of the opened file, or \c nullptr if the file is not available. */ FILE *FioFOpenFile(const char *filename, const char *mode, Subdirectory subdir, size_t *filesize) { - FILE *f = NULL; + FILE *f = nullptr; Searchpath sp; assert(subdir < NUM_SUBDIRS || subdir == NO_DIRECTORY); FOR_ALL_SEARCHPATHS(sp) { f = FioFOpenFileSp(filename, mode, sp, subdir, filesize); - if (f != NULL || subdir == NO_DIRECTORY) break; + if (f != nullptr || subdir == NO_DIRECTORY) break; } /* We can only use .tar in case of data-dir, and read-mode */ - if (f == NULL && mode[0] == 'r' && subdir != NO_DIRECTORY) { + if (f == nullptr && mode[0] == 'r' && subdir != NO_DIRECTORY) { static const uint MAX_RESOLVED_LENGTH = 2 * (100 + 100 + 155) + 1; // Enough space to hold two filenames plus link. See 'TarHeader'. char resolved_name[MAX_RESOLVED_LENGTH]; @@ -508,11 +506,11 @@ FILE *FioFOpenFile(const char *filename, const char *mode, Subdirectory subdir, /* Sometimes a full path is given. To support * the 'subdirectory' must be 'removed'. */ - if (f == NULL && subdir != NO_DIRECTORY) { + if (f == nullptr && subdir != NO_DIRECTORY) { switch (subdir) { case BASESET_DIR: f = FioFOpenFile(filename, mode, OLD_GM_DIR, filesize); - if (f != NULL) break; + if (f != nullptr) break; FALLTHROUGH; case NEWGRF_DIR: f = FioFOpenFile(filename, mode, OLD_DATA_DIR, filesize); @@ -536,19 +534,9 @@ void FioCreateDirectory(const char *name) /* Ignore directory creation errors; they'll surface later on, and most * of the time they are 'directory already exists' errors anyhow. */ #if defined(_WIN32) - CreateDirectory(OTTD2FS(name), NULL); + CreateDirectory(OTTD2FS(name), nullptr); #elif defined(OS2) && !defined(__INNOTEK_LIBC__) mkdir(OTTD2FS(name)); -#elif defined(__MORPHOS__) || defined(__AMIGAOS__) - char buf[MAX_PATH]; - strecpy(buf, name, lastof(buf)); - - size_t len = strlen(name) - 1; - if (buf[len] == '/') { - buf[len] = '\0'; // Kill pathsep, so mkdir() will not fail - } - - mkdir(OTTD2FS(buf), 0755); #else mkdir(OTTD2FS(name), 0755); #endif @@ -575,18 +563,6 @@ bool AppendPathSeparator(char *buf, const char *last) return true; } -/** - * Find the first directory in a tar archive. - * @param tarname the name of the tar archive to look in. - * @param subdir the subdirectory to look in. - */ -const char *FioTarFirstDir(const char *tarname, Subdirectory subdir) -{ - TarList::iterator it = _tar_list[subdir].find(tarname); - if (it == _tar_list[subdir].end()) return NULL; - return (*it).second.dirname; -} - static void TarAddLink(const std::string &srcParam, const std::string &destParam, Subdirectory subdir) { std::string src = srcParam; @@ -608,11 +584,6 @@ static void TarAddLink(const std::string &srcParam, const std::string &destParam } } -void FioTarAddLink(const char *src, const char *dest, Subdirectory subdir) -{ - TarAddLink(src, dest, subdir); -} - /** * Simplify filenames from tars. * Replace '/' by #PATHSEPCHAR, and force 'name' to lowercase. @@ -685,7 +656,7 @@ bool TarScanner::AddFile(Subdirectory sd, const char *filename) bool TarScanner::AddFile(const char *filename, size_t basepath_length, const char *tar_filename) { /* No tar within tar. */ - assert(tar_filename == NULL); + assert(tar_filename == nullptr); /* The TAR-header, repeated for every file */ struct TarHeader { @@ -718,11 +689,11 @@ bool TarScanner::AddFile(const char *filename, size_t basepath_length, const cha * a number of reasons we cannot open the file. * Most common case is when we simply have not * been given read access. */ - if (f == NULL) return false; + if (f == nullptr) return false; const char *dupped_filename = stredup(filename); _tar_list[this->subdir][filename].filename = dupped_filename; - _tar_list[this->subdir][filename].dirname = NULL; + _tar_list[this->subdir][filename].dirname = nullptr; TarLinkList links; ///< Temporary list to collect links @@ -811,13 +782,13 @@ bool TarScanner::AddFile(const char *filename, size_t basepath_length, const cha * Note: The destination of links must not contain any directory-links. */ strecpy(dest, name, lastof(dest)); char *destpos = strrchr(dest, PATHSEPCHAR); - if (destpos == NULL) destpos = dest; + if (destpos == nullptr) destpos = dest; *destpos = '\0'; char *pos = link; while (*pos != '\0') { char *next = strchr(pos, PATHSEPCHAR); - if (next == NULL) { + if (next == nullptr) { next = pos + strlen(pos); } else { /* Terminate the substring up to the path separator character. */ @@ -836,7 +807,7 @@ bool TarScanner::AddFile(const char *filename, size_t basepath_length, const cha /* Truncate 'dest' after last PATHSEPCHAR. * This assumes that the truncated part is a real directory and not a link. */ destpos = strrchr(dest, PATHSEPCHAR); - if (destpos == NULL) destpos = dest; + if (destpos == nullptr) destpos = dest; *destpos = '\0'; } else { /* Append at end of 'dest' */ @@ -866,7 +837,7 @@ bool TarScanner::AddFile(const char *filename, size_t basepath_length, const cha /* Store the first directory name we detect */ DEBUG(misc, 6, "Found dir in tar: %s", name); - if (_tar_list[this->subdir][filename].dirname == NULL) _tar_list[this->subdir][filename].dirname = stredup(name); + if (_tar_list[this->subdir][filename].dirname == nullptr) _tar_list[this->subdir][filename].dirname = stredup(name); break; default: @@ -921,13 +892,13 @@ bool ExtractTar(const char *tar_filename, Subdirectory subdir) const char *dirname = (*it).second.dirname; /* The file doesn't have a sub directory! */ - if (dirname == NULL) return false; + if (dirname == nullptr) return false; char filename[MAX_PATH]; strecpy(filename, tar_filename, lastof(filename)); char *p = strrchr(filename, PATHSEPCHAR); /* The file's path does not have a separator? */ - if (p == NULL) return false; + if (p == nullptr) return false; p++; strecpy(p, dirname, lastof(filename)); @@ -944,14 +915,14 @@ bool ExtractTar(const char *tar_filename, Subdirectory subdir) /* First open the file in the .tar. */ size_t to_copy = 0; FILE *in = FioFOpenFileTar(&(*it2).second, &to_copy); - if (in == NULL) { + if (in == nullptr) { DEBUG(misc, 6, "Extracting %s failed; could not open %s", filename, tar_filename); return false; } /* Now open the 'output' file. */ FILE *out = fopen(filename, "wb"); - if (out == NULL) { + if (out == nullptr) { DEBUG(misc, 6, "Extracting %s failed; could not open %s", filename, filename); fclose(in); return false; @@ -1003,17 +974,13 @@ static bool ChangeWorkingDirectoryToExecutable(const char *exe) bool success = false; #ifdef WITH_COCOA char *app_bundle = strchr(tmp, '.'); - while (app_bundle != NULL && strncasecmp(app_bundle, ".app", 4) != 0) app_bundle = strchr(&app_bundle[1], '.'); + while (app_bundle != nullptr && strncasecmp(app_bundle, ".app", 4) != 0) app_bundle = strchr(&app_bundle[1], '.'); - if (app_bundle != NULL) *app_bundle = '\0'; + if (app_bundle != nullptr) *app_bundle = '\0'; #endif /* WITH_COCOA */ char *s = strrchr(tmp, PATHSEPCHAR); - if (s != NULL) { + if (s != nullptr) { *s = '\0'; -#if defined(__DJGPP__) - /* If we want to go to the root, we can't use cd C:, but we must use '/' */ - if (s > tmp && *(s - 1) == ':') chdir("/"); -#endif if (chdir(tmp) != 0) { DEBUG(misc, 0, "Directory with the binary does not exist?"); } else { @@ -1036,13 +1003,13 @@ static bool ChangeWorkingDirectoryToExecutable(const char *exe) bool DoScanWorkingDirectory() { /* No working directory, so nothing to do. */ - if (_searchpaths[SP_WORKING_DIR] == NULL) return false; + if (_searchpaths[SP_WORKING_DIR] == nullptr) return false; /* Working directory is root, so do nothing. */ if (strcmp(_searchpaths[SP_WORKING_DIR], PATHSEP) == 0) return false; /* No personal/home directory, so the working directory won't be that. */ - if (_searchpaths[SP_PERSONAL_DIR] == NULL) return true; + if (_searchpaths[SP_PERSONAL_DIR] == nullptr) return true; char tmp[MAX_PATH]; seprintf(tmp, lastof(tmp), "%s%s", _searchpaths[SP_WORKING_DIR], PERSONAL_DIR); @@ -1058,7 +1025,7 @@ void DetermineBasePaths(const char *exe) { char tmp[MAX_PATH]; #if defined(WITH_XDG_BASEDIR) && defined(WITH_PERSONAL_DIR) - const char *xdg_data_home = xdgDataHome(NULL); + const char *xdg_data_home = xdgDataHome(nullptr); seprintf(tmp, lastof(tmp), "%s" PATHSEP "%s", xdg_data_home, PERSONAL_DIR[0] == '.' ? &PERSONAL_DIR[1] : PERSONAL_DIR); free(xdg_data_home); @@ -1066,8 +1033,8 @@ void DetermineBasePaths(const char *exe) AppendPathSeparator(tmp, lastof(tmp)); _searchpaths[SP_PERSONAL_DIR_XDG] = stredup(tmp); #endif -#if defined(__MORPHOS__) || defined(__AMIGA__) || defined(DOS) || defined(OS2) || !defined(WITH_PERSONAL_DIR) - _searchpaths[SP_PERSONAL_DIR] = NULL; +#if defined(OS2) || !defined(WITH_PERSONAL_DIR) + _searchpaths[SP_PERSONAL_DIR] = nullptr; #else #ifdef __HAIKU__ BPath path; @@ -1079,17 +1046,17 @@ void DetermineBasePaths(const char *exe) * variables in any way. It can also contain all kinds of * unvalidated data we rather not want internally. */ const char *homedir = getenv("HOME"); - if (homedir != NULL) { + if (homedir != nullptr) { homedir = stredup(homedir); } - if (homedir == NULL) { + if (homedir == nullptr) { const struct passwd *pw = getpwuid(getuid()); - homedir = (pw == NULL) ? NULL : stredup(pw->pw_dir); + homedir = (pw == nullptr) ? nullptr : stredup(pw->pw_dir); } #endif - if (homedir != NULL) { + if (homedir != nullptr) { ValidateString(homedir); seprintf(tmp, lastof(tmp), "%s" PATHSEP "%s", homedir, PERSONAL_DIR); AppendPathSeparator(tmp, lastof(tmp)); @@ -1097,7 +1064,7 @@ void DetermineBasePaths(const char *exe) _searchpaths[SP_PERSONAL_DIR] = stredup(tmp); free(homedir); } else { - _searchpaths[SP_PERSONAL_DIR] = NULL; + _searchpaths[SP_PERSONAL_DIR] = nullptr; } #endif @@ -1106,37 +1073,33 @@ void DetermineBasePaths(const char *exe) AppendPathSeparator(tmp, lastof(tmp)); _searchpaths[SP_SHARED_DIR] = stredup(tmp); #else - _searchpaths[SP_SHARED_DIR] = NULL; + _searchpaths[SP_SHARED_DIR] = nullptr; #endif -#if defined(__MORPHOS__) || defined(__AMIGA__) - _searchpaths[SP_WORKING_DIR] = NULL; -#else - if (getcwd(tmp, MAX_PATH) == NULL) *tmp = '\0'; + if (getcwd(tmp, MAX_PATH) == nullptr) *tmp = '\0'; AppendPathSeparator(tmp, lastof(tmp)); _searchpaths[SP_WORKING_DIR] = stredup(tmp); -#endif _do_scan_working_directory = DoScanWorkingDirectory(); /* Change the working directory to that one of the executable */ if (ChangeWorkingDirectoryToExecutable(exe)) { - if (getcwd(tmp, MAX_PATH) == NULL) *tmp = '\0'; + if (getcwd(tmp, MAX_PATH) == nullptr) *tmp = '\0'; AppendPathSeparator(tmp, lastof(tmp)); _searchpaths[SP_BINARY_DIR] = stredup(tmp); } else { - _searchpaths[SP_BINARY_DIR] = NULL; + _searchpaths[SP_BINARY_DIR] = nullptr; } - if (_searchpaths[SP_WORKING_DIR] != NULL) { + if (_searchpaths[SP_WORKING_DIR] != nullptr) { /* Go back to the current working directory. */ if (chdir(_searchpaths[SP_WORKING_DIR]) != 0) { DEBUG(misc, 0, "Failed to return to working directory!"); } } -#if defined(__MORPHOS__) || defined(__AMIGA__) || defined(DOS) || defined(OS2) - _searchpaths[SP_INSTALLATION_DIR] = NULL; +#if !defined(GLOBAL_DATA_DIR) + _searchpaths[SP_INSTALLATION_DIR] = nullptr; #else seprintf(tmp, lastof(tmp), "%s", GLOBAL_DATA_DIR); AppendPathSeparator(tmp, lastof(tmp)); @@ -1146,7 +1109,7 @@ void DetermineBasePaths(const char *exe) extern void cocoaSetApplicationBundleDir(); cocoaSetApplicationBundleDir(); #else - _searchpaths[SP_APPLICATION_BUNDLE_DIR] = NULL; + _searchpaths[SP_APPLICATION_BUNDLE_DIR] = nullptr; #endif } #endif /* defined(_WIN32) */ @@ -1166,7 +1129,7 @@ void DeterminePaths(const char *exe) #if defined(WITH_XDG_BASEDIR) && defined(WITH_PERSONAL_DIR) char config_home[MAX_PATH]; - const char *xdg_config_home = xdgConfigHome(NULL); + const char *xdg_config_home = xdgConfigHome(nullptr); seprintf(config_home, lastof(config_home), "%s" PATHSEP "%s", xdg_config_home, PERSONAL_DIR[0] == '.' ? &PERSONAL_DIR[1] : PERSONAL_DIR); free(xdg_config_home); @@ -1181,19 +1144,19 @@ void DeterminePaths(const char *exe) } char *config_dir; - if (_config_file != NULL) { + if (_config_file != nullptr) { config_dir = stredup(_config_file); char *end = strrchr(config_dir, PATHSEPCHAR); - if (end == NULL) { + if (end == nullptr) { config_dir[0] = '\0'; } else { end[1] = '\0'; } } else { char personal_dir[MAX_PATH]; - if (FioFindFullPath(personal_dir, lastof(personal_dir), BASE_DIR, "openttd.cfg") != NULL) { + if (FioFindFullPath(personal_dir, lastof(personal_dir), BASE_DIR, "openttd.cfg") != nullptr) { char *end = strrchr(personal_dir, PATHSEPCHAR); - if (end != NULL) end[1] = '\0'; + if (end != nullptr) end[1] = '\0'; config_dir = stredup(personal_dir); _config_file = str_fmt("%sopenttd.cfg", config_dir); } else { @@ -1205,14 +1168,14 @@ void DeterminePaths(const char *exe) SP_PERSONAL_DIR, SP_BINARY_DIR, SP_WORKING_DIR, SP_SHARED_DIR, SP_INSTALLATION_DIR }; - config_dir = NULL; + config_dir = nullptr; for (uint i = 0; i < lengthof(new_openttd_cfg_order); i++) { if (IsValidSearchPath(new_openttd_cfg_order[i])) { config_dir = stredup(_searchpaths[new_openttd_cfg_order[i]]); break; } } - assert(config_dir != NULL); + assert(config_dir != nullptr); #endif _config_file = str_fmt("%sopenttd.cfg", config_dir); } @@ -1239,7 +1202,7 @@ void DeterminePaths(const char *exe) } /* Make the necessary folders */ -#if !defined(__MORPHOS__) && !defined(__AMIGA__) && defined(WITH_PERSONAL_DIR) +#if defined(WITH_PERSONAL_DIR) FioCreateDirectory(config_dir); if (config_dir != _personal_dir) FioCreateDirectory(_personal_dir); #endif @@ -1258,7 +1221,6 @@ void DeterminePaths(const char *exe) /* If we have network we make a directory for the autodownloading of content */ _searchpaths[SP_AUTODOWNLOAD_DIR] = str_fmt("%s%s", _personal_dir, "content_download" PATHSEP); -#ifdef ENABLE_NETWORK FioCreateDirectory(_searchpaths[SP_AUTODOWNLOAD_DIR]); /* Create the directory for each of the types of content */ @@ -1271,14 +1233,6 @@ void DeterminePaths(const char *exe) extern char *_log_file; _log_file = str_fmt("%sopenttd.log", _personal_dir); -#else /* ENABLE_NETWORK */ - /* If we don't have networking, we don't need to make the directory. But - * if it exists we keep it, otherwise remove it from the search paths. */ - if (!FileExists(_searchpaths[SP_AUTODOWNLOAD_DIR])) { - free(_searchpaths[SP_AUTODOWNLOAD_DIR]); - _searchpaths[SP_AUTODOWNLOAD_DIR] = NULL; - } -#endif /* ENABLE_NETWORK */ } /** @@ -1304,27 +1258,27 @@ void SanitizeFilename(char *filename) * @param filename Name of the file to load. * @param[out] lenp Length of loaded data. * @param maxsize Maximum size to load. - * @return Pointer to new memory containing the loaded data, or \c NULL if loading failed. + * @return Pointer to new memory containing the loaded data, or \c nullptr if loading failed. * @note If \a maxsize less than the length of the file, loading fails. */ void *ReadFileToMem(const char *filename, size_t *lenp, size_t maxsize) { FILE *in = fopen(filename, "rb"); - if (in == NULL) return NULL; + if (in == nullptr) return nullptr; fseek(in, 0, SEEK_END); size_t len = ftell(in); fseek(in, 0, SEEK_SET); if (len > maxsize) { fclose(in); - return NULL; + return nullptr; } byte *mem = MallocT(len + 1); mem[len] = 0; if (fread(mem, len, 1, in) != 1) { fclose(in); free(mem); - return NULL; + return nullptr; } fclose(in); @@ -1336,14 +1290,14 @@ void *ReadFileToMem(const char *filename, size_t *lenp, size_t maxsize) * Helper to see whether a given filename matches the extension. * @param extension The extension to look for. * @param filename The filename to look in for the extension. - * @return True iff the extension is NULL, or the filename ends with it. + * @return True iff the extension is nullptr, or the filename ends with it. */ static bool MatchesExtension(const char *extension, const char *filename) { - if (extension == NULL) return true; + if (extension == nullptr) return true; const char *ext = strrchr(filename, extension[0]); - return ext != NULL && strcasecmp(ext, extension) == 0; + return ext != nullptr && strcasecmp(ext, extension) == 0; } /** @@ -1364,9 +1318,9 @@ static uint ScanPath(FileScanner *fs, const char *extension, const char *path, s struct dirent *dirent; DIR *dir; - if (path == NULL || (dir = ttd_opendir(path)) == NULL) return 0; + if (path == nullptr || (dir = ttd_opendir(path)) == nullptr) return 0; - while ((dirent = readdir(dir)) != NULL) { + while ((dirent = readdir(dir)) != nullptr) { const char *d_name = FS2OTTD(dirent->d_name); char filename[MAX_PATH]; @@ -1382,7 +1336,7 @@ static uint ScanPath(FileScanner *fs, const char *extension, const char *path, s num += ScanPath(fs, extension, filename, basepath_length, recursive); } else if (S_ISREG(sb.st_mode)) { /* File */ - if (MatchesExtension(extension, filename) && fs->AddFile(filename, basepath_length, NULL)) num++; + if (MatchesExtension(extension, filename) && fs->AddFile(filename, basepath_length, nullptr)) num++; } } diff --git a/src/fileio_func.h b/src/fileio_func.h index f5ef58ac06..dec1931939 100644 --- a/src/fileio_func.h +++ b/src/fileio_func.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. @@ -30,7 +28,7 @@ void FioSkipBytes(int n); /** * The search paths OpenTTD could search through. * At least one of the slots has to be filled with a path. - * NULL paths tell that there is no such path for the + * nullptr paths tell that there is no such path for the * current operating system. */ extern const char *_searchpaths[NUM_SEARCHPATHS]; @@ -42,14 +40,14 @@ extern const char *_searchpaths[NUM_SEARCHPATHS]; */ static inline bool IsValidSearchPath(Searchpath sp) { - return sp < NUM_SEARCHPATHS && _searchpaths[sp] != NULL; + return sp < NUM_SEARCHPATHS && _searchpaths[sp] != nullptr; } /** Iterator for all the search paths */ #define FOR_ALL_SEARCHPATHS(sp) for (sp = SP_FIRST_DIR; sp < NUM_SEARCHPATHS; sp++) if (IsValidSearchPath(sp)) void FioFCloseFile(FILE *f); -FILE *FioFOpenFile(const char *filename, const char *mode, Subdirectory subdir, size_t *filesize = NULL); +FILE *FioFOpenFile(const char *filename, const char *mode, Subdirectory subdir, size_t *filesize = nullptr); bool FioCheckFileExists(const char *filename, Subdirectory subdir); char *FioGetFullPath(char *buf, const char *last, Searchpath sp, Subdirectory subdir, const char *filename); char *FioFindFullPath(char *buf, const char *last, Subdirectory subdir, const char *filename); @@ -64,8 +62,6 @@ bool AppendPathSeparator(char *buf, const char *last); void DeterminePaths(const char *exe); void *ReadFileToMem(const char *filename, size_t *lenp, size_t maxsize); bool FileExists(const char *filename); -const char *FioTarFirstDir(const char *tarname, Subdirectory subdir); -void FioTarAddLink(const char *src, const char *dest, Subdirectory subdir); bool ExtractTar(const char *tar_filename, Subdirectory subdir); extern const char *_personal_dir; ///< custom directory for personal settings, saves, newgrf, etc. @@ -107,7 +103,7 @@ public: ALL = BASESET | NEWGRF | AI | SCENARIO | GAME, ///< Scan for everything. }; - /* virtual */ bool AddFile(const char *filename, size_t basepath_length, const char *tar_filename = NULL); + bool AddFile(const char *filename, size_t basepath_length, const char *tar_filename = nullptr) override; bool AddFile(Subdirectory sd, const char *filename); diff --git a/src/fileio_type.h b/src/fileio_type.h index fd3ac84554..15f886d050 100644 --- a/src/fileio_type.h +++ b/src/fileio_type.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/fios.cpp b/src/fios.cpp index 73365ddc29..24487174b8 100644 --- a/src/fios.cpp +++ b/src/fios.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. @@ -13,11 +11,13 @@ */ #include "stdafx.h" -#include "fios.h" +#include "3rdparty/md5/md5.h" #include "fileio_func.h" -#include "tar_type.h" +#include "fios.h" +#include "network/network_content.h" #include "screenshot.h" #include "string_func.h" +#include "tar_type.h" #include #ifndef _WIN32 @@ -45,22 +45,20 @@ extern void GetOldSaveGameName(const char *file, char *title, const char *last); /** * Compare two FiosItem's. Used with sort when sorting the file list. - * @param da A pointer to the first FiosItem to compare. - * @param db A pointer to the second FiosItem to compare. - * @return -1, 0 or 1, depending on how the two items should be sorted. + * @param other The FiosItem to compare to. + * @return for ascending order: returns true if da < db. Vice versa for descending order. */ -int CDECL CompareFiosItems(const FiosItem *da, const FiosItem *db) +bool FiosItem::operator< (const FiosItem &other) const { - int r = 0; + int r = false; - if ((_savegame_sort_order & SORT_BY_NAME) == 0 && da->mtime != db->mtime) { - r = da->mtime < db->mtime ? -1 : 1; + if ((_savegame_sort_order & SORT_BY_NAME) == 0 && (*this).mtime != other.mtime) { + r = (*this).mtime - other.mtime; } else { - r = strcasecmp(da->title, db->title); + r = strnatcmp((*this).title, other.title); } - - if (_savegame_sort_order & SORT_DESCENDING) r = -r; - return r; + if (r == 0) return false; + return (_savegame_sort_order & SORT_DESCENDING) ? r > 0 : r < 0; } FileList::~FileList() @@ -103,7 +101,7 @@ void FileList::BuildFileList(AbstractFileType abstract_filetype, SaveLoadOperati * Find file information of a file by its name from the file list. * @param file The filename to return information about. Can be the actual name * or a numbered entry into the filename list. - * @return The information on the file, or \c NULL if the file is not available. + * @return The information on the file, or \c nullptr if the file is not available. */ const FiosItem *FileList::FindItem(const char *file) { @@ -128,14 +126,14 @@ const FiosItem *FileList::FindItem(const char *file) if (strcmp(long_file, item->title) == 0) return item; } - return NULL; + return nullptr; } /** * Get descriptive texts. Returns the path and free space * left on the device * @param path string describing the path - * @param total_free total free space in megabytes, optional (can be NULL) + * @param total_free total free space in megabytes, optional (can be nullptr) * @return StringID describing the path (free space or failure) */ StringID FiosGetDescText(const char **path, uint64 *total_free) @@ -147,7 +145,7 @@ StringID FiosGetDescText(const char **path, uint64 *total_free) /** * Browse to a new path based on the passed \a item, starting at #_fios_path. * @param *item Item telling us what to do. - * @return A filename w/path if we reached a file, otherwise \c NULL. + * @return A filename w/path if we reached a file, otherwise \c nullptr. */ const char *FiosBrowseTo(const FiosItem *item) { @@ -162,19 +160,14 @@ const char *FiosBrowseTo(const FiosItem *item) break; case FIOS_TYPE_PARENT: { - /* Check for possible NULL ptr (not required for UNIXes, but AmigaOS-alikes) */ + /* Check for possible nullptr ptr */ char *s = strrchr(_fios_path, PATHSEPCHAR); - if (s != NULL && s != _fios_path) { + if (s != nullptr && s != _fios_path) { s[0] = '\0'; // Remove last path separator character, so we can go up one level. } s = strrchr(_fios_path, PATHSEPCHAR); - if (s != NULL) { + if (s != nullptr) { s[1] = '\0'; // go up a directory -#if defined(__MORPHOS__) || defined(__AMIGAOS__) - /* On MorphOS or AmigaOS paths look like: "Volume:directory/subdirectory" */ - } else if ((s = strrchr(_fios_path, ':')) != NULL) { - s[1] = '\0'; -#endif } break; } @@ -197,39 +190,31 @@ const char *FiosBrowseTo(const FiosItem *item) return item->name; } - return NULL; + return nullptr; } /** * Construct a filename from its components in destination buffer \a buf. * @param buf Destination buffer. - * @param path Directory path, may be \c NULL. + * @param path Directory path, may be \c nullptr. * @param name Filename. * @param ext Filename extension (use \c "" for no extension). * @param last Last element of buffer \a buf. */ static void FiosMakeFilename(char *buf, const char *path, const char *name, const char *ext, const char *last) { - const char *period; + if (path != nullptr) { + const char *buf_start = buf; + buf = strecpy(buf, path, last); + /* Remove trailing path separator, if present */ + if (buf > buf_start && buf[-1] == PATHSEPCHAR) buf--; + } /* Don't append the extension if it is already there */ - period = strrchr(name, '.'); - if (period != NULL && strcasecmp(period, ext) == 0) ext = ""; -#if defined(__MORPHOS__) || defined(__AMIGAOS__) - if (path != NULL) { - unsigned char sepchar = path[(strlen(path) - 1)]; + const char *period = strrchr(name, '.'); + if (period != nullptr && strcasecmp(period, ext) == 0) ext = ""; - if (sepchar != ':' && sepchar != '/') { - seprintf(buf, last, "%s" PATHSEP "%s%s", path, name, ext); - } else { - seprintf(buf, last, "%s%s%s", path, name, ext); - } - } else { - seprintf(buf, last, "%s%s", name, ext); - } -#else - seprintf(buf, last, "%s" PATHSEP "%s%s", path, name, ext); -#endif + seprintf(buf, last, PATHSEP "%s%s", name, ext); } /** @@ -293,7 +278,7 @@ public: fop(fop), callback_proc(callback_proc), file_list(file_list) {} - /* virtual */ bool AddFile(const char *filename, size_t basepath_length, const char *tar_filename); + bool AddFile(const char *filename, size_t basepath_length, const char *tar_filename) override; }; /** @@ -305,7 +290,7 @@ public: bool FiosFileScanner::AddFile(const char *filename, size_t basepath_length, const char *tar_filename) { const char *ext = strrchr(filename, '.'); - if (ext == NULL) return false; + if (ext == nullptr) return false; char fios_title[64]; fios_title[0] = '\0'; // reset the title; @@ -319,13 +304,29 @@ bool FiosFileScanner::AddFile(const char *filename, size_t basepath_length, cons FiosItem *fios = file_list.Append(); #ifdef _WIN32 - struct _stat sb; - if (_tstat(OTTD2FS(filename), &sb) == 0) { + // Retrieve the file modified date using GetFileTime rather than stat to work around an obscure MSVC bug that affects Windows XP + HANDLE fh = CreateFile(OTTD2FS(filename), GENERIC_READ, FILE_SHARE_READ | FILE_SHARE_WRITE, nullptr, OPEN_EXISTING, 0, nullptr); + + if (fh != INVALID_HANDLE_VALUE) { + FILETIME ft; + ULARGE_INTEGER ft_int64; + + if (GetFileTime(fh, nullptr, nullptr, &ft) != 0) { + ft_int64.HighPart = ft.dwHighDateTime; + ft_int64.LowPart = ft.dwLowDateTime; + + // Convert from hectonanoseconds since 01/01/1601 to seconds since 01/01/1970 + fios->mtime = ft_int64.QuadPart / 10000000ULL - 11644473600ULL; + } else { + fios->mtime = 0; + } + + CloseHandle(fh); #else struct stat sb; if (stat(filename, &sb) == 0) { -#endif fios->mtime = sb.st_mtime; +#endif } else { fios->mtime = 0; } @@ -337,7 +338,7 @@ bool FiosFileScanner::AddFile(const char *filename, size_t basepath_length, cons const char *t = fios_title; if (StrEmpty(fios_title)) { t = strrchr(filename, PATHSEPCHAR); - t = (t == NULL) ? filename : (t + 1); + t = (t == nullptr) ? filename : (t + 1); } strecpy(fios->title, t, lastof(fios->title)); str_validate(fios->title, lastof(fios->title)); @@ -359,7 +360,7 @@ static void FiosGetFileList(SaveLoadOperation fop, fios_getlist_callback_proc *c struct dirent *dirent; DIR *dir; FiosItem *fios; - int sort_start; + size_t sort_start; char d_name[sizeof(fios->name)]; file_list.Clear(); @@ -374,8 +375,8 @@ static void FiosGetFileList(SaveLoadOperation fop, fios_getlist_callback_proc *c } /* Show subdirectories */ - if ((dir = ttd_opendir(_fios_path)) != NULL) { - while ((dirent = readdir(dir)) != NULL) { + if ((dir = ttd_opendir(_fios_path)) != nullptr) { + while ((dirent = readdir(dir)) != nullptr) { strecpy(d_name, FS2OTTD(dirent->d_name), lastof(d_name)); /* found file must be directory, but not '.' or '..' */ @@ -397,7 +398,7 @@ static void FiosGetFileList(SaveLoadOperation fop, fios_getlist_callback_proc *c { SortingBits order = _savegame_sort_order; _savegame_sort_order = SORT_BY_NAME | SORT_ASCENDING; - QSortT(file_list.files.Begin(), file_list.files.Length(), CompareFiosItems); + std::sort(file_list.files.begin(), file_list.files.end()); _savegame_sort_order = order; } @@ -407,12 +408,12 @@ static void FiosGetFileList(SaveLoadOperation fop, fios_getlist_callback_proc *c /* Show files */ FiosFileScanner scanner(fop, callback_proc, file_list); if (subdir == NO_DIRECTORY) { - scanner.Scan(NULL, _fios_path, false); + scanner.Scan(nullptr, _fios_path, false); } else { - scanner.Scan(NULL, subdir, true, true); + scanner.Scan(nullptr, subdir, true, true); } - QSortT(file_list.Get(sort_start), file_list.Length() - sort_start, CompareFiosItems); + std::sort(file_list.files.begin() + sort_start, file_list.files.end()); /* Show drives */ FiosGetDrives(file_list); @@ -435,7 +436,7 @@ static void GetFileTitle(const char *file, char *title, const char *last, Subdir strecat(buf, ".title", lastof(buf)); FILE *f = FioFOpenFile(buf, "r", subdir); - if (f == NULL) return; + if (f == nullptr) return; size_t read = fread(title, 1, last - title, f); assert(title + read <= last); @@ -449,8 +450,8 @@ static void GetFileTitle(const char *file, char *title, const char *last, Subdir * @param fop Purpose of collecting the list. * @param file Name of the file to check. * @param ext A pointer to the extension identifier inside file - * @param title Buffer if a callback wants to lookup the title of the file; NULL to skip the lookup - * @param last Last available byte in buffer (to prevent buffer overflows); not used when title == NULL + * @param title Buffer if a callback wants to lookup the title of the file; nullptr to skip the lookup + * @param last Last available byte in buffer (to prevent buffer overflows); not used when title == nullptr * @return a FIOS_TYPE_* type of the found file, FIOS_TYPE_INVALID if not a savegame * @see FiosGetFileList * @see FiosGetSavegameList @@ -464,7 +465,7 @@ FiosType FiosGetSavegameListCallback(SaveLoadOperation fop, const char *file, co * .SV2 Transport Tycoon Deluxe (Patch) saved 2-player game */ /* Don't crash if we supply no extension */ - if (ext == NULL) return FIOS_TYPE_INVALID; + if (ext == nullptr) return FIOS_TYPE_INVALID; if (strcasecmp(ext, ".sav") == 0) { GetFileTitle(file, title, last, SAVE_DIR); @@ -474,7 +475,7 @@ FiosType FiosGetSavegameListCallback(SaveLoadOperation fop, const char *file, co if (fop == SLO_LOAD) { if (strcasecmp(ext, ".ss1") == 0 || strcasecmp(ext, ".sv1") == 0 || strcasecmp(ext, ".sv2") == 0) { - if (title != NULL) GetOldSaveGameName(file, title, last); + if (title != nullptr) GetOldSaveGameName(file, title, last); return FIOS_TYPE_OLDFILE; } } @@ -490,10 +491,10 @@ FiosType FiosGetSavegameListCallback(SaveLoadOperation fop, const char *file, co */ void FiosGetSavegameList(SaveLoadOperation fop, FileList &file_list) { - static char *fios_save_path = NULL; - static char *fios_save_path_last = NULL; + static char *fios_save_path = nullptr; + static char *fios_save_path_last = nullptr; - if (fios_save_path == NULL) { + if (fios_save_path == nullptr) { fios_save_path = MallocT(MAX_PATH); fios_save_path_last = fios_save_path + MAX_PATH - 1; FioGetDirectory(fios_save_path, fios_save_path_last, SAVE_DIR); @@ -545,11 +546,11 @@ static FiosType FiosGetScenarioListCallback(SaveLoadOperation fop, const char *f */ void FiosGetScenarioList(SaveLoadOperation fop, FileList &file_list) { - static char *fios_scn_path = NULL; - static char *fios_scn_path_last = NULL; + static char *fios_scn_path = nullptr; + static char *fios_scn_path_last = nullptr; /* Copy the default path on first run or on 'New Game' */ - if (fios_scn_path == NULL) { + if (fios_scn_path == nullptr) { fios_scn_path = MallocT(MAX_PATH); fios_scn_path_last = fios_scn_path + MAX_PATH - 1; FioGetDirectory(fios_scn_path, fios_scn_path_last, SCENARIO_DIR); @@ -616,10 +617,10 @@ static FiosType FiosGetHeightmapListCallback(SaveLoadOperation fop, const char * */ void FiosGetHeightmapList(SaveLoadOperation fop, FileList &file_list) { - static char *fios_hmap_path = NULL; - static char *fios_hmap_path_last = NULL; + static char *fios_hmap_path = nullptr; + static char *fios_hmap_path_last = nullptr; - if (fios_hmap_path == NULL) { + if (fios_hmap_path == nullptr) { fios_hmap_path = MallocT(MAX_PATH); fios_hmap_path_last = fios_hmap_path + MAX_PATH - 1; FioGetDirectory(fios_hmap_path, fios_hmap_path_last, HEIGHTMAP_DIR); @@ -641,9 +642,9 @@ void FiosGetHeightmapList(SaveLoadOperation fop, FileList &file_list) */ const char *FiosGetScreenshotDir() { - static char *fios_screenshot_path = NULL; + static char *fios_screenshot_path = nullptr; - if (fios_screenshot_path == NULL) { + if (fios_screenshot_path == nullptr) { fios_screenshot_path = MallocT(MAX_PATH); FioGetDirectory(fios_screenshot_path, fios_screenshot_path + MAX_PATH - 1, SCREENSHOT_DIR); } @@ -651,10 +652,6 @@ const char *FiosGetScreenshotDir() return fios_screenshot_path; } -#if defined(ENABLE_NETWORK) -#include "network/network_content.h" -#include "3rdparty/md5/md5.h" - /** Basic data to distinguish a scenario. Used in the server list window */ struct ScenarioIdentifier { uint32 scenid; ///< ID for the scenario (generated by content). @@ -676,7 +673,7 @@ struct ScenarioIdentifier { /** * Scanner to find the unique IDs of scenarios */ -class ScenarioScanner : protected FileScanner, public SmallVector { +class ScenarioScanner : protected FileScanner, public std::vector { bool scanned; ///< Whether we've already scanned public: /** Initialise */ @@ -694,10 +691,10 @@ public: this->scanned = true; } - /* virtual */ bool AddFile(const char *filename, size_t basepath_length, const char *tar_filename) + bool AddFile(const char *filename, size_t basepath_length, const char *tar_filename) override { FILE *f = FioFOpenFile(filename, "r", SCENARIO_DIR); - if (f == NULL) return false; + if (f == nullptr) return false; ScenarioIdentifier id; int fret = fscanf(f, "%i", &id.scenid); @@ -716,7 +713,7 @@ public: strecpy(basename, filename, lastof(basename)); *strrchr(basename, '.') = '\0'; f = FioFOpenFile(basename, "rb", SCENARIO_DIR, &size); - if (f == NULL) return false; + if (f == nullptr) return false; /* calculate md5sum */ while ((len = fread(buffer, 1, (size > sizeof(buffer)) ? sizeof(buffer) : size, f)) != 0 && size != 0) { @@ -727,7 +724,7 @@ public: FioFCloseFile(f); - this->Include(id); + include(*this, id); return true; } }; @@ -739,20 +736,20 @@ static ScenarioScanner _scanner; * Find a given scenario based on its unique ID. * @param ci The content info to compare it to. * @param md5sum Whether to look at the md5sum or the id. - * @return The filename of the file, else \c NULL. + * @return The filename of the file, else \c nullptr. */ const char *FindScenario(const ContentInfo *ci, bool md5sum) { _scanner.Scan(false); - for (ScenarioIdentifier *id = _scanner.Begin(); id != _scanner.End(); id++) { - if (md5sum ? (memcmp(id->md5sum, ci->md5sum, sizeof(id->md5sum)) == 0) - : (id->scenid == ci->unique_id)) { - return id->filename; + for (ScenarioIdentifier &id : _scanner) { + if (md5sum ? (memcmp(id.md5sum, ci->md5sum, sizeof(id.md5sum)) == 0) + : (id.scenid == ci->unique_id)) { + return id.filename; } } - return NULL; + return nullptr; } /** @@ -763,7 +760,7 @@ const char *FindScenario(const ContentInfo *ci, bool md5sum) */ bool HasScenario(const ContentInfo *ci, bool md5sum) { - return (FindScenario(ci, md5sum) != NULL); + return (FindScenario(ci, md5sum) != nullptr); } /** @@ -773,5 +770,3 @@ void ScanScenarios() { _scanner.Scan(true); } - -#endif /* ENABLE_NETWORK */ diff --git a/src/fios.h b/src/fios.h index 24c9f370eb..6a7b6bf01f 100644 --- a/src/fios.h +++ b/src/fios.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. @@ -48,8 +46,8 @@ struct LoadCheckData { struct LoggedAction *gamelog_action; ///< Gamelog actions uint gamelog_actions; ///< Number of gamelog actions - LoadCheckData() : error_data(NULL), grfconfig(NULL), - grf_compatibility(GLC_NOT_FOUND), gamelog_action(NULL), gamelog_actions(0) + LoadCheckData() : error_data(nullptr), grfconfig(nullptr), + grf_compatibility(GLC_NOT_FOUND), gamelog_action(nullptr), gamelog_actions(0) { this->Clear(); } @@ -77,7 +75,7 @@ struct LoadCheckData { */ bool HasNewGrfs() { - return this->checkable && this->error == INVALID_STRING_ID && this->grfconfig != NULL; + return this->checkable && this->error == INVALID_STRING_ID && this->grfconfig != nullptr; } void Clear(); @@ -107,6 +105,7 @@ struct FiosItem { uint64 mtime; char title[64]; char name[MAX_PATH]; + bool operator< (const FiosItem &other) const; }; /** List of file information. */ @@ -120,16 +119,17 @@ public: */ inline FiosItem *Append() { - return this->files.Append(); + /*C++17: return &*/ this->files.emplace_back(); + return &this->files.back(); } /** * Get the number of files in the list. * @return The number of files stored in the list. */ - inline uint Length() const + inline size_t Length() const { - return this->files.Length(); + return this->files.size(); } /** @@ -138,7 +138,7 @@ public: */ inline const FiosItem *Begin() const { - return this->files.Begin(); + return this->files.data(); } /** @@ -147,28 +147,28 @@ public: */ inline const FiosItem *End() const { - return this->files.End(); + return this->Begin() + this->Length(); } /** * Get a pointer to the indicated file information. File information must exist. * @return Address of the indicated existing file information. */ - inline const FiosItem *Get(uint index) const + inline const FiosItem *Get(size_t index) const { - return this->files.Get(index); + return this->files.data() + index; } /** * Get a pointer to the indicated file information. File information must exist. * @return Address of the indicated existing file information. */ - inline FiosItem *Get(uint index) + inline FiosItem *Get(size_t index) { - return this->files.Get(index); + return this->files.data() + index; } - inline const FiosItem &operator[](uint index) const + inline const FiosItem &operator[](size_t index) const { return this->files[index]; } @@ -177,7 +177,7 @@ public: * Get a reference to the indicated file information. File information must exist. * @return The requested file information. */ - inline FiosItem &operator[](uint index) + inline FiosItem &operator[](size_t index) { return this->files[index]; } @@ -185,19 +185,19 @@ public: /** Remove all items from the list. */ inline void Clear() { - this->files.Clear(); + this->files.clear(); } /** Compact the list down to the smallest block size boundary. */ inline void Compact() { - this->files.Compact(); + this->files.shrink_to_fit(); } void BuildFileList(AbstractFileType abstract_filetype, SaveLoadOperation fop); const FiosItem *FindItem(const char *file); - SmallVector files; ///< The list of files. + std::vector files; ///< The list of files. }; enum SortingBits { @@ -226,6 +226,4 @@ void FiosMakeSavegameName(char *buf, const char *name, const char *last); FiosType FiosGetSavegameListCallback(SaveLoadOperation fop, const char *file, const char *ext, char *title, const char *last); -int CDECL CompareFiosItems(const FiosItem *a, const FiosItem *b); - #endif /* FIOS_H */ diff --git a/src/fios_gui.cpp b/src/fios_gui.cpp index 55ff76e6bd..167003e9cd 100644 --- a/src/fios_gui.cpp +++ b/src/fios_gui.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. @@ -55,20 +53,19 @@ void LoadCheckData::Clear() this->checkable = false; this->error = INVALID_STRING_ID; free(this->error_data); - this->error_data = NULL; + this->error_data = nullptr; this->map_size_x = this->map_size_y = 256; // Default for old savegames which do not store mapsize. this->current_date = 0; memset(&this->settings, 0, sizeof(this->settings)); - const CompanyPropertiesMap::iterator end = this->companies.End(); - for (CompanyPropertiesMap::iterator it = this->companies.Begin(); it != end; it++) { - delete it->second; + for (auto &pair : this->companies) { + delete pair.second; } - companies.Clear(); + companies.clear(); GamelogFree(this->gamelog_action, this->gamelog_actions); - this->gamelog_action = NULL; + this->gamelog_action = nullptr; this->gamelog_actions = 0; ClearGRFConfigList(&this->grfconfig); @@ -252,8 +249,8 @@ static const TextColour _fios_colours[] = { */ static void SortSaveGameList(FileList &file_list) { - uint sort_start = 0; - uint sort_end = 0; + size_t sort_start = 0; + size_t sort_end = 0; /* Directories are always above the files (FIOS_TYPE_DIR) * Drives (A:\ (windows only) are always under the files (FIOS_TYPE_DRIVE) @@ -268,8 +265,7 @@ static void SortSaveGameList(FileList &file_list) } } - uint s_amount = file_list.Length() - sort_start - sort_end; - QSortT(file_list.Get(sort_start), s_amount, CompareFiosItems); + std::sort(file_list.files.begin() + sort_start, file_list.files.end() - sort_end); } struct SaveLoadWindow : public Window { @@ -280,13 +276,14 @@ private: AbstractFileType abstract_filetype; /// Type of file to select. SaveLoadOperation fop; ///< File operation to perform. FileList fios_items; ///< Save game list. - FiosItem o_dir; - const FiosItem *selected; ///< Selected game in #fios_items, or \c NULL. + FiosItem o_dir; ///< Original dir (home dir for this browser) + const FiosItem *selected; ///< Selected game in #fios_items, or \c nullptr. + const FiosItem *highlighted; ///< Item in fios_items highlighted by mouse pointer, or \c nullptr. Scrollbar *vscroll; StringFilter string_filter; ///< Filter for available games. QueryString filter_editbox; ///< Filter editbox; - SmallVector fios_items_shown; ///< Map of the filtered out fios items + std::vector fios_items_shown; ///< Map of the filtered out fios items static void SaveGameConfirmationCallback(Window *w, bool confirmed) { @@ -415,7 +412,7 @@ public: } } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { switch (widget) { case WID_SL_SORT_BYNAME: @@ -426,7 +423,7 @@ public: break; case WID_SL_BACKGROUND: { - static const char *path = NULL; + static const char *path = nullptr; static StringID str = STR_ERROR_UNABLE_TO_READ_DRIVE; static uint64 tot = 0; @@ -457,6 +454,8 @@ public: if (item == this->selected) { GfxFillRect(r.left + 1, y, r.right, y + this->resize.step_height, PC_DARK_BLUE); + } else if (item == this->highlighted) { + GfxFillRect(r.left + 1, y, r.right, y + this->resize.step_height, PC_VERY_DARK_BLUE); } DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, Center(y, this->resize.step_height), item->title, _fios_colours[GetDetailedFileType(item->type)]); y += this->resize.step_height; @@ -470,7 +469,7 @@ public: 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 == NULL) break; + 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; @@ -526,7 +525,7 @@ public: if (y > y_max) break; /* NewGrf compatibility */ - SetDParam(0, _load_check_data.grfconfig == NULL ? STR_NEWGRF_LIST_NONE : + 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; @@ -539,11 +538,10 @@ public: if (y > y_max) break; /* Companies / AIs */ - CompanyPropertiesMap::const_iterator end = _load_check_data.companies.End(); - for (CompanyPropertiesMap::const_iterator it = _load_check_data.companies.Begin(); it != end; it++) { - SetDParam(0, it->first + 1); - const CompanyProperties &c = *it->second; - if (c.name != NULL) { + for (auto &pair : _load_check_data.companies) { + SetDParam(0, pair.first + 1); + const CompanyProperties &c = *pair.second; + if (c.name != nullptr) { SetDParam(1, STR_JUST_RAW_STRING); SetDParamStr(2, c.name); } else { @@ -561,7 +559,7 @@ public: } } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_SL_BACKGROUND: @@ -583,7 +581,7 @@ public: } } - virtual void OnPaint() + void OnPaint() override { if (_savegame_sort_dirty) { _savegame_sort_dirty = false; @@ -594,7 +592,7 @@ public: this->DrawWidgets(); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_SL_SORT_BYNAME: // Sort save names by name @@ -616,24 +614,24 @@ public: this->InvalidateData(SLIWD_RESCAN_FILES); break; - case WID_SL_LOAD_BUTTON: - if (this->selected != NULL && !_load_check_data.HasErrors()) { - const char *name = FiosBrowseTo(this->selected); - _file_to_saveload.SetMode(this->selected->type); - _file_to_saveload.SetName(name); - _file_to_saveload.SetTitle(this->selected->title); + case WID_SL_LOAD_BUTTON: { + if (this->selected == nullptr || _load_check_data.HasErrors()) break; - if (this->abstract_filetype == FT_HEIGHTMAP) { - delete this; - ShowHeightmapLoad(); + const char *name = FiosBrowseTo(this->selected); + _file_to_saveload.SetMode(this->selected->type); + _file_to_saveload.SetName(name); + _file_to_saveload.SetTitle(this->selected->title); - } else if (!_load_check_data.HasNewGrfs() || _load_check_data.grf_compatibility != GLC_NOT_FOUND || _settings_client.gui.UserIsAllowedToChangeNewGRFs()) { - _switch_mode = (_game_mode == GM_EDITOR) ? SM_LOAD_SCENARIO : SM_LOAD_GAME; - ClearErrorMessages(); - delete this; - } + if (this->abstract_filetype == FT_HEIGHTMAP) { + delete this; + ShowHeightmapLoad(); + } else if (!_load_check_data.HasNewGrfs() || _load_check_data.grf_compatibility != GLC_NOT_FOUND || _settings_client.gui.UserIsAllowedToChangeNewGRFs()) { + _switch_mode = (_game_mode == GM_EDITOR) ? SM_LOAD_SCENARIO : SM_LOAD_GAME; + ClearErrorMessages(); + delete this; } break; + } case WID_SL_NEWGRF_INFO: if (_load_check_data.HasNewGrfs()) { @@ -645,9 +643,7 @@ public: if (!_network_available) { ShowErrorMessage(STR_NETWORK_ERROR_NOTAVAILABLE, INVALID_STRING_ID, WL_ERROR); } else if (_load_check_data.HasNewGrfs()) { -#if defined(ENABLE_NETWORK) ShowMissingContentWindow(_load_check_data.grfconfig); -#endif } break; @@ -664,43 +660,44 @@ public: const FiosItem *file = this->fios_items.Get(y); const char *name = FiosBrowseTo(file); - if (name != NULL) { - if (click_count == 1) { - if (this->selected != file) { - this->selected = file; - _load_check_data.Clear(); - - if (GetDetailedFileType(file->type) == DFT_GAME_FILE) { - /* Other detailed file types cannot be checked before. */ - SaveOrLoad(name, SLO_CHECK, DFT_GAME_FILE, NO_DIRECTORY, false); - } - - this->InvalidateData(SLIWD_SELECTION_CHANGES); - } - if (this->fop == SLO_SAVE) { - /* Copy clicked name to editbox */ - this->filename_editbox.text.Assign(file->title); - this->SetWidgetDirty(WID_SL_SAVE_OSK_TITLE); - } - } else if (!_load_check_data.HasErrors()) { - this->selected = file; - if (this->fop == SLO_LOAD) { - if (this->abstract_filetype == FT_SAVEGAME || this->abstract_filetype == FT_SCENARIO) { - this->OnClick(pt, WID_SL_LOAD_BUTTON, 1); - } else { - assert(this->abstract_filetype == FT_HEIGHTMAP); - _file_to_saveload.SetMode(file->type); - _file_to_saveload.SetName(name); - _file_to_saveload.SetTitle(file->title); - - delete this; - ShowHeightmapLoad(); - } - } - } - } else { + if (name == nullptr) { /* Changed directory, need refresh. */ this->InvalidateData(SLIWD_RESCAN_FILES); + break; + } + + if (click_count == 1) { + if (this->selected != file) { + this->selected = file; + _load_check_data.Clear(); + + if (GetDetailedFileType(file->type) == DFT_GAME_FILE) { + /* Other detailed file types cannot be checked before. */ + SaveOrLoad(name, SLO_CHECK, DFT_GAME_FILE, NO_DIRECTORY, false); + } + + this->InvalidateData(SLIWD_SELECTION_CHANGES); + } + if (this->fop == SLO_SAVE) { + /* Copy clicked name to editbox */ + this->filename_editbox.text.Assign(file->title); + this->SetWidgetDirty(WID_SL_SAVE_OSK_TITLE); + } + } else if (!_load_check_data.HasErrors()) { + this->selected = file; + if (this->fop == SLO_LOAD) { + if (this->abstract_filetype == FT_SAVEGAME || this->abstract_filetype == FT_SCENARIO) { + this->OnClick(pt, WID_SL_LOAD_BUTTON, 1); + } else { + assert(this->abstract_filetype == FT_HEIGHTMAP); + _file_to_saveload.SetMode(file->type); + _file_to_saveload.SetName(name); + _file_to_saveload.SetTitle(file->title); + + delete this; + ShowHeightmapLoad(); + } + } } break; } @@ -709,14 +706,12 @@ public: if (!_network_available) { ShowErrorMessage(STR_NETWORK_ERROR_NOTAVAILABLE, INVALID_STRING_ID, WL_ERROR); } else { -#if defined(ENABLE_NETWORK) assert(this->fop == SLO_LOAD); switch (this->abstract_filetype) { default: NOT_REACHED(); - case FT_SCENARIO: ShowNetworkContentListWindow(NULL, CONTENT_TYPE_SCENARIO); break; - case FT_HEIGHTMAP: ShowNetworkContentListWindow(NULL, CONTENT_TYPE_HEIGHTMAP); break; + case FT_SCENARIO: ShowNetworkContentListWindow(nullptr, CONTENT_TYPE_SCENARIO); break; + case FT_HEIGHTMAP: ShowNetworkContentListWindow(nullptr, CONTENT_TYPE_HEIGHTMAP); break; } -#endif } break; @@ -751,7 +746,34 @@ public: } } - virtual EventState OnKeyPress(WChar key, uint16 keycode) + void OnMouseLoop() 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); + if (y == INT_MAX) return; + + /* Get the corresponding non-filtered out item from the list */ + int i = 0; + while (i <= y) { + if (!this->fios_items_shown[i]) y++; + i++; + } + const FiosItem *file = this->fios_items.Get(y); + + if (file != this->highlighted) { + this->highlighted = file; + this->SetWidgetDirty(WID_SL_DRIVES_DIRECTORIES_LIST); + } + } else if (this->highlighted != nullptr) { + this->highlighted = nullptr; + this->SetWidgetDirty(WID_SL_DRIVES_DIRECTORIES_LIST); + } + } + + EventState OnKeyPress(WChar key, uint16 keycode) override { if (keycode == WKC_ESC) { delete this; @@ -761,7 +783,7 @@ public: return ES_NOT_HANDLED; } - virtual void OnTimeout() + void OnTimeout() override { /* Widgets WID_SL_DELETE_SELECTION and WID_SL_SAVE_GAME only exist when saving to a file. */ if (this->fop != SLO_SAVE) return; @@ -796,7 +818,7 @@ public: } } - virtual void OnResize() + void OnResize() override { this->vscroll->SetCapacityFromWidget(this, WID_SL_DRIVES_DIRECTORIES_LIST); } @@ -806,19 +828,19 @@ public: * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { switch (data) { case SLIWD_RESCAN_FILES: /* Rescan files */ - this->selected = NULL; + this->selected = nullptr; _load_check_data.Clear(); if (!gui_scope) break; _fios_path_changed = true; this->fios_items.BuildFileList(this->abstract_filetype, this->fop); - this->vscroll->SetCount(this->fios_items.Length()); - this->selected = NULL; + this->vscroll->SetCount((uint)this->fios_items.Length()); + this->selected = nullptr; _load_check_data.Clear(); /* We reset the files filtered */ @@ -834,12 +856,12 @@ public: switch (this->abstract_filetype) { case FT_HEIGHTMAP: - this->SetWidgetDisabledState(WID_SL_LOAD_BUTTON, this->selected == NULL || _load_check_data.HasErrors()); + this->SetWidgetDisabledState(WID_SL_LOAD_BUTTON, this->selected == nullptr || _load_check_data.HasErrors()); break; case FT_SAVEGAME: case FT_SCENARIO: { - bool disabled = this->selected == NULL || _load_check_data.HasErrors(); + bool disabled = this->selected == nullptr || _load_check_data.HasErrors(); if (!_settings_client.gui.UserIsAllowedToChangeNewGRFs()) { disabled |= _load_check_data.HasNewGrfs() && _load_check_data.grf_compatibility == GLC_NOT_FOUND; } @@ -857,7 +879,7 @@ public: case SLIWD_FILTER_CHANGES: /* Filter changes */ - this->fios_items_shown.Resize(this->fios_items.Length()); + this->fios_items_shown.resize(this->fios_items.Length()); uint items_shown_count = 0; ///< The number of items shown in the list /* We pass through every fios item */ for (uint i = 0; i < this->fios_items.Length(); i++) { @@ -874,7 +896,7 @@ public: if (&(this->fios_items[i]) == this->selected && this->fios_items_shown[i] == false) { /* The selected element has been filtered out */ - this->selected = NULL; + this->selected = nullptr; this->OnInvalidateData(SLIWD_SELECTION_CHANGES); } } @@ -884,7 +906,7 @@ public: } } - virtual void OnEditboxChanged(int wid) + void OnEditboxChanged(int wid) override { if (wid == WID_SL_FILTER) { this->string_filter.SetFilterTerm(this->filter_editbox.text.buf); diff --git a/src/fontcache.cpp b/src/fontcache.cpp index 3677441a2b..e9d153e75b 100644 --- a/src/fontcache.cpp +++ b/src/fontcache.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. @@ -19,6 +17,7 @@ #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" @@ -41,7 +40,7 @@ FontCache::FontCache(FontSize fs) : parent(FontCache::Get(fs)), fs(fs), height(_ ascender(_default_font_ascender[fs]), descender(_default_font_ascender[fs] - _default_font_height[fs]), units_per_em(1) { - assert(this->parent == NULL || this->fs == this->parent->fs); + assert(this->parent == nullptr || this->fs == this->parent->fs); FontCache::caches[this->fs] = this; Layouter::ResetFontCache(this->fs); } @@ -84,7 +83,7 @@ public: virtual int GetHeight() const; 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 NULL; } + virtual const void *GetFontTable(uint32 tag, size_t &length) { length = 0; return nullptr; } virtual const char *GetFontName() { return "sprite"; } virtual bool IsBuiltInFont() { return true; } }; @@ -93,7 +92,7 @@ public: * 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(NULL) +SpriteFontCache::SpriteFontCache(FontSize fs) : FontCache(fs), glyph_to_spriteid_map(nullptr) { this->InitializeUnicodeGlyphMap(); } @@ -108,14 +107,14 @@ SpriteFontCache::~SpriteFontCache() SpriteID SpriteFontCache::GetUnicodeGlyph(GlyphID key) { - if (this->glyph_to_spriteid_map[GB(key, 8, 8)] == NULL) return 0; + 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(GlyphID key, SpriteID sprite) { - if (this->glyph_to_spriteid_map == NULL) this->glyph_to_spriteid_map = CallocT(256); - if (this->glyph_to_spriteid_map[GB(key, 8, 8)] == NULL) this->glyph_to_spriteid_map[GB(key, 8, 8)] = CallocT(256); + 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; } @@ -159,13 +158,13 @@ void SpriteFontCache::InitializeUnicodeGlyphMap() */ void SpriteFontCache::ClearGlyphToSpriteMap() { - if (this->glyph_to_spriteid_map == NULL) return; + 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 = NULL; + this->glyph_to_spriteid_map = nullptr; } void SpriteFontCache::ClearFontCache() @@ -199,16 +198,16 @@ bool SpriteFontCache::GetDrawGlyphShadow() /* static */ FontCache *FontCache::caches[FS_END] = { new SpriteFontCache(FS_NORMAL), new SpriteFontCache(FS_SMALL), new SpriteFontCache(FS_LARGE), new SpriteFontCache(FS_MONO) }; -#ifdef WITH_FREETYPE -#include -#include FT_FREETYPE_H -#include FT_GLYPH_H -#include FT_TRUETYPE_TABLES_H +#if defined(WITH_FREETYPE) || defined(_WIN32) -/** Font cache for fonts that are based on a freetype font. */ -class FreeTypeFontCache : public FontCache { -private: - FT_Face face; ///< The font face associated with this font. +FreeTypeSettings _freetype; + +static const byte FACE_COLOUR = 1; +static const byte SHADOW_COLOUR = 2; + +/** Font cache for fonts that are based on a TrueType font. */ +class TrueTypeFontCache : public FontCache { +protected: int req_size; ///< Requested font size. int used_size; ///< Used font size. @@ -239,31 +238,233 @@ private: GlyphEntry *GetGlyphPtr(GlyphID key); void SetGlyphPtr(GlyphID key, const GlyphEntry *glyph, bool duplicate = false); - void SetFontSize(FontSize fs, FT_Face face, int pixels); + + virtual const void *InternalGetFontTable(uint32 tag, size_t &length) = 0; + virtual const Sprite *InternalGetGlyph(GlyphID key, bool aa) = 0; public: - FreeTypeFontCache(FontSize fs, FT_Face face, int pixels); - ~FreeTypeFontCache(); + TrueTypeFontCache(FontSize fs, int pixels); + virtual ~TrueTypeFontCache(); virtual int GetFontSize() const { return this->used_size; } virtual SpriteID GetUnicodeGlyph(WChar key) { return this->parent->GetUnicodeGlyph(key); } virtual void SetUnicodeGlyph(WChar key, SpriteID sprite) { this->parent->SetUnicodeGlyph(key, sprite); } virtual void InitializeUnicodeGlyphMap() { this->parent->InitializeUnicodeGlyphMap(); } - virtual void ClearFontCache(); virtual const Sprite *GetGlyph(GlyphID key); + virtual const void *GetFontTable(uint32 tag, size_t &length); + virtual void ClearFontCache(); virtual uint GetGlyphWidth(GlyphID key); virtual bool GetDrawGlyphShadow(); + virtual bool IsBuiltInFont() { return false; } +}; + +/** + * 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() +{ + this->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 %u", 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%02X00, size %u", 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 %u", 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; +} + +static void *AllocateFont(size_t size) +{ + return MallocT(size); +} + + +/* Check if a glyph should be rendered with anti-aliasing. */ +static bool GetFontAAState(FontSize size) +{ + /* AA is only supported for 32 bpp */ + if (BlitterFactory::GetCurrentBlitter()->GetScreenDepth() != 32 && BlitterFactory::GetCurrentBlitter()->GetScreenDepth() != 16) 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; + } +} + +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, + builtin_questionmark_data + }; + + Sprite *spr = BlitterFactory::GetCurrentBlitter()->Encode(&builtin_questionmark, AllocateFont); + 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, SmallPair(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 void *GetFontTable(uint32 tag, size_t &length); virtual const char *GetFontName() { return face->family_name; } virtual bool IsBuiltInFont() { return false; } }; -FT_Library _library = NULL; +FT_Library _library = nullptr; -FreeTypeSettings _freetype; - -static const byte FACE_COLOUR = 1; -static const byte SHADOW_COLOUR = 2; /** * Create a new FreeTypeFontCache. @@ -271,9 +472,9 @@ static const byte SHADOW_COLOUR = 2; * @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) : FontCache(fs), face(face), req_size(pixels), glyph_to_sprite(NULL) +FreeTypeFontCache::FreeTypeFontCache(FontSize fs, FT_Face face, int pixels) : TrueTypeFontCache(fs, pixels), face(face) { - assert(face != NULL); + assert(face != nullptr); this->SetFontSize(fs, face, pixels); } @@ -286,7 +487,7 @@ void FreeTypeFontCache::SetFontSize(FontSize fs, FT_Face face, int pixels) pixels = scaled_height; TT_Header *head = (TT_Header *)FT_Get_Sfnt_Table(this->face, ft_sfnt_head); - if (head != NULL) { + 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(_default_font_height[FS_SMALL]); @@ -338,7 +539,7 @@ void FreeTypeFontCache::SetFontSize(FontSize fs, FT_Face face, int pixels) */ static void LoadFreeTypeFont(FontSize fs) { - FreeTypeSubSetting *settings = NULL; + FreeTypeSubSetting *settings = nullptr; switch (fs) { default: NOT_REACHED(); case FS_SMALL: settings = &_freetype.small; break; @@ -349,7 +550,7 @@ static void LoadFreeTypeFont(FontSize fs) if (StrEmpty(settings->font)) return; - if (_library == NULL) { + if (_library == nullptr) { if (FT_Init_FreeType(&_library) != FT_Err_Ok) { ShowInfoF("Unable to initialize FreeType, using sprite fonts instead"); return; @@ -358,7 +559,7 @@ static void LoadFreeTypeFont(FontSize fs) DEBUG(freetype, 2, "Initialized"); } - FT_Face face = NULL; + FT_Face face = nullptr; FT_Error error = FT_New_Face(_library, settings->font, 0, &face); if (error != FT_Err_Ok) error = GetFontByFaceName(settings->font, &face); @@ -384,7 +585,7 @@ static void LoadFreeTypeFont(FontSize fs) } } - if (found != NULL) { + if (found != nullptr) { error = FT_Set_Charmap(face, found); if (error == FT_Err_Ok) goto found_face; } @@ -408,12 +609,8 @@ found_face: FreeTypeFontCache::~FreeTypeFontCache() { FT_Done_Face(this->face); - this->face = NULL; + this->face = nullptr; this->ClearFontCache(); - - for (FontTable::iterator iter = this->font_tables.Begin(); iter != this->font_tables.End(); iter++) { - free(iter->second.second); - } } /** @@ -422,132 +619,16 @@ FreeTypeFontCache::~FreeTypeFontCache() void FreeTypeFontCache::ClearFontCache() { /* Font scaling might have changed, determine font size anew if it was automatically selected. */ - if (this->face != NULL) this->SetFontSize(this->fs, this->face, this->req_size); + if (this->face != nullptr) this->SetFontSize(this->fs, this->face, this->req_size); - if (this->glyph_to_sprite == NULL) return; - - for (int i = 0; i < 256; i++) { - if (this->glyph_to_sprite[i] == NULL) 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 = NULL; - - Layouter::ResetFontCache(this->fs); -} - -FreeTypeFontCache::GlyphEntry *FreeTypeFontCache::GetGlyphPtr(GlyphID key) -{ - if (this->glyph_to_sprite == NULL) return NULL; - if (this->glyph_to_sprite[GB(key, 8, 8)] == NULL) return NULL; - return &this->glyph_to_sprite[GB(key, 8, 8)][GB(key, 0, 8)]; + this->TrueTypeFontCache::ClearFontCache(); } -void FreeTypeFontCache::SetGlyphPtr(GlyphID key, const GlyphEntry *glyph, bool duplicate) +const Sprite *FreeTypeFontCache::InternalGetGlyph(GlyphID key, bool aa) { - if (this->glyph_to_sprite == NULL) { - DEBUG(freetype, 3, "Allocating root glyph cache for size %u", this->fs); - this->glyph_to_sprite = CallocT(256); - } - - if (this->glyph_to_sprite[GB(key, 8, 8)] == NULL) { - DEBUG(freetype, 3, "Allocating glyph cache for range 0x%02X00, size %u", 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 %u", 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; -} - -static void *AllocateFont(size_t size) -{ - return MallocT(size); -} - - -/* Check if a glyph should be rendered with antialiasing */ -static bool GetFontAAState(FontSize size) -{ - /* AA is only supported for 32 bpp */ - if (BlitterFactory::GetCurrentBlitter()->GetScreenDepth() != 32 && BlitterFactory::GetCurrentBlitter()->GetScreenDepth() != 16) 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; - } -} - - -const Sprite *FreeTypeFontCache::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 != NULL && glyph->sprite != NULL) return glyph->sprite; - FT_GlyphSlot slot = this->face->glyph; - bool aa = GetFontAAState(this->fs); - - GlyphEntry new_glyph; - 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, - builtin_questionmark_data - }; - - Sprite *spr = BlitterFactory::GetCurrentBlitter()->Encode(&builtin_questionmark, AllocateFont); - assert(spr != NULL); - 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; - } - } 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); @@ -591,6 +672,7 @@ const Sprite *FreeTypeFontCache::GetGlyph(GlyphID key) } } + GlyphEntry new_glyph; new_glyph.sprite = BlitterFactory::GetCurrentBlitter()->Encode(&sprite, AllocateFont); new_glyph.width = slot->advance.x >> 6; @@ -600,25 +682,6 @@ const Sprite *FreeTypeFontCache::GetGlyph(GlyphID key) } -bool FreeTypeFontCache::GetDrawGlyphShadow() -{ - return this->fs == FS_NORMAL && GetFontAAState(FS_NORMAL); -} - - -uint FreeTypeFontCache::GetGlyphWidth(GlyphID key) -{ - if ((key & SPRITE_GLYPH) != 0) return this->parent->GetGlyphWidth(key); - - GlyphEntry *glyph = this->GetGlyphPtr(key); - if (glyph == NULL || glyph->sprite == NULL) { - this->GetGlyph(key); - glyph = this->GetGlyphPtr(key); - } - - return glyph->width; -} - GlyphID FreeTypeFontCache::MapCharToGlyph(WChar key) { assert(IsPrintable(key)); @@ -630,31 +693,340 @@ GlyphID FreeTypeFontCache::MapCharToGlyph(WChar key) return FT_Get_Char_Index(this->face, key); } -const void *FreeTypeFontCache::GetFontTable(uint32 tag, size_t &length) +const void *FreeTypeFontCache::InternalGetFontTable(uint32 tag, size_t &length) { - const FontTable::iterator iter = this->font_tables.Find(tag); - if (iter != this->font_tables.End()) { - length = iter->second.first; - return iter->second.second; - } - FT_ULong len = 0; - FT_Byte *result = NULL; + FT_Byte *result = nullptr; - FT_Load_Sfnt_Table(this->face, tag, 0, NULL, &len); + 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; - this->font_tables.Insert(tag, SmallPair(length, result)); + length = len; return result; } +#elif defined(_WIN32) + +#include "os/windows/win32.h" +#ifndef ANTIALIASED_QUALITY +#define ANTIALIASED_QUALITY 4 +#endif + +/** Font cache for fonts that are based on a Win32 font. */ +class Win32FontCache : public TrueTypeFontCache { +private: + LOGFONT logfont; ///< Logical font information for selecting the font face. + HFONT font = nullptr; ///< The font face associated with this font. + 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. + + void SetFontSize(FontSize fs, int pixels); + virtual const void *InternalGetFontTable(uint32 tag, size_t &length); + virtual const Sprite *InternalGetGlyph(GlyphID key, bool aa); + +public: + Win32FontCache(FontSize fs, const LOGFONT &logfont, int pixels); + ~Win32FontCache(); + virtual void ClearFontCache(); + virtual GlyphID MapCharToGlyph(WChar key); + virtual const char *GetFontName() { return WIDE_TO_MB(this->logfont.lfFaceName); } + virtual bool IsBuiltInFont() { return false; } + virtual void *GetOSHandle() { return &this->logfont; } +}; + + +/** + * Create a new Win32FontCache. + * @param fs The font size that is going to be cached. + * @param logfont The font that has to be loaded. + * @param pixels The number of pixels this font should be high. + */ +Win32FontCache::Win32FontCache(FontSize fs, const LOGFONT &logfont, int pixels) : TrueTypeFontCache(fs, pixels), logfont(logfont) +{ + this->dc = CreateCompatibleDC(nullptr); + this->SetFontSize(fs, pixels); +} + +Win32FontCache::~Win32FontCache() +{ + this->ClearFontCache(); + DeleteDC(this->dc); + DeleteObject(this->font); +} + +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(_default_font_height[this->fs]); + pixels = scaled_height; + + HFONT temp = CreateFontIndirect(&this->logfont); + if (temp != nullptr) { + HGDIOBJ old = SelectObject(this->dc, temp); + + UINT size = GetOutlineTextMetrics(this->dc, 0, nullptr); + LPOUTLINETEXTMETRIC otm = (LPOUTLINETEXTMETRIC)AllocaM(BYTE, size); + GetOutlineTextMetrics(this->dc, size, otm); + + /* 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(_default_font_height[FS_SMALL]); + pixels = Clamp(min(otm->otmusMinimumPPEM, 20) + diff, scaled_height, MAX_FONT_SIZE); + + SelectObject(dc, old); + DeleteObject(temp); + } + } else { + pixels = ScaleFontTrad(pixels); + } + this->used_size = pixels; + + /* Create GDI font handle. */ + this->logfont.lfHeight = -pixels; + this->logfont.lfWidth = 0; + this->logfont.lfOutPrecision = ANTIALIASED_QUALITY; + + if (this->font != nullptr) { + SelectObject(dc, this->old_font); + DeleteObject(this->font); + } + this->font = CreateFontIndirect(&this->logfont); + this->old_font = SelectObject(this->dc, this->font); + + /* Query the font metrics we needed. */ + UINT otmSize = GetOutlineTextMetrics(this->dc, 0, nullptr); + POUTLINETEXTMETRIC otm = (POUTLINETEXTMETRIC)AllocaM(BYTE, otmSize); + GetOutlineTextMetrics(this->dc, otmSize, otm); + + this->units_per_em = otm->otmEMSquare; + this->ascender = otm->otmTextMetrics.tmAscent; + this->descender = otm->otmTextMetrics.tmDescent; + this->height = this->ascender + this->descender; + this->glyph_size.cx = otm->otmTextMetrics.tmMaxCharWidth; + this->glyph_size.cy = otm->otmTextMetrics.tmHeight; + + DEBUG(freetype, 2, "Loaded font '%s' with size %d", FS2OTTD((LPTSTR)((BYTE *)otm + (ptrdiff_t)otm->otmpFullName)), pixels); +} + +/** + * Reset cached glyphs. + */ +void Win32FontCache::ClearFontCache() +{ + /* GUI scaling might have changed, determine font size anew if it was automatically selected. */ + if (this->font != nullptr) this->SetFontSize(this->fs, this->req_size); + + this->TrueTypeFontCache::ClearFontCache(); +} + +/* virtual */ const Sprite *Win32FontCache::InternalGetGlyph(GlyphID key, bool aa) +{ + 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 : 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); + } + + /* Add 1 pixel for the shadow on the medium font. Our sprite must be at least 1x1 pixel. */ + uint width = max(1U, (uint)gm.gmBlackBoxX + (this->fs == FS_NORMAL)); + uint height = max(1U, (uint)gm.gmBlackBoxY + (this->fs == FS_NORMAL)); + + /* Limit glyph size to prevent overflows later on. */ + if (width > 256 || height > 256) usererror("Font glyph is too large"); + + /* 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); + sprite.type = ST_FONT; + sprite.width = width; + sprite.height = height; + sprite.x_offs = gm.gmptGlyphOrigin.x; + sprite.y_offs = this->ascender - gm.gmptGlyphOrigin.y; + + if (size > 0) { + /* All pixel data returned by GDI is in the form of DWORD-aligned rows. + * For a non anti-aliased glyph, the returned bitmap has one bit per pixel. + * For anti-aliased rendering, GDI uses the strange value range of 0 to 64, + * inclusively. To map this to 0 to 255, we shift left by two and then + * subtract one. */ + uint pitch = Align(aa ? gm.gmBlackBoxX : max(gm.gmBlackBoxX / 8u, 1u), 4); + + /* Draw shadow for medium size. */ + if (this->fs == FS_NORMAL && !aa) { + 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; + } + } + } + } + + 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[x + y * sprite.width].m = FACE_COLOUR; + sprite.data[x + y * sprite.width].a = aa ? (bmp[x + y * pitch] << 2) - 1 : 0xFF; + } + } + } + } + + GlyphEntry new_glyph; + new_glyph.sprite = BlitterFactory::GetCurrentBlitter()->Encode(&sprite, AllocateFont); + new_glyph.width = gm.gmCellIncX; + + this->SetGlyphPtr(key, &new_glyph); + + return new_glyph.sprite; +} + +/* virtual */ GlyphID Win32FontCache::MapCharToGlyph(WChar key) +{ + assert(IsPrintable(key)); + + if (key >= SCC_SPRITE_START && key <= SCC_SPRITE_END) { + return this->parent->MapCharToGlyph(key); + } + + /* Convert characters outside of the BMP into surrogate pairs. */ + WCHAR chars[2]; + if (key >= 0x010000U) { + chars[0] = (WCHAR)(((key - 0x010000U) >> 10) + 0xD800); + chars[1] = (WCHAR)(((key - 0x010000U) & 0x3FF) + 0xDC00); + } else { + chars[0] = (WCHAR)(key & 0xFFFF); + } + + WORD glyphs[2] = {0, 0}; + GetGlyphIndicesW(this->dc, chars, key >= 0x010000U ? 2 : 1, glyphs, GGI_MARK_NONEXISTING_GLYPHS); + + return glyphs[0] != 0xFFFF ? glyphs[0] : 0; +} + +/* virtual */ const void *Win32FontCache::InternalGetFontTable(uint32 tag, size_t &length) +{ + DWORD len = GetFontData(this->dc, tag, 0, nullptr, 0); + + void *result = nullptr; + if (len != GDI_ERROR && len > 0) { + result = MallocT(len); + GetFontData(this->dc, tag, 0, result, len); + } + + length = len; + return result; +} + +/** + * Loads the GDI font. + * If a GDI font description is present, e.g. from the automatic font + * fallback search, use it. Otherwise, try to resolve it by font name. + * @param fs The font size to load. + */ +static void LoadWin32Font(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; + } + + if (StrEmpty(settings->font)) return; + + LOGFONT logfont; + MemSetT(&logfont, 0); + logfont.lfPitchAndFamily = fs == FS_MONO ? FIXED_PITCH : VARIABLE_PITCH; + logfont.lfCharSet = DEFAULT_CHARSET; + logfont.lfOutPrecision = OUT_OUTLINE_PRECIS; + logfont.lfClipPrecision = CLIP_DEFAULT_PRECIS; + + if (settings->os_handle != nullptr) { + logfont = *(const LOGFONT *)settings->os_handle; + } else if (strchr(settings->font, '.') != nullptr && FileExists(settings->font)) { + /* Might be a font file name, try load it. */ + TCHAR fontPath[MAX_PATH]; + convert_to_fs(settings->font, fontPath, lengthof(fontPath), false); + + if (AddFontResourceEx(fontPath, FR_PRIVATE, 0) != 0) { + /* Try a nice little undocumented function first for getting the internal font name. + * Some documentation is found at: http://www.undocprint.org/winspool/getfontresourceinfo */ + typedef BOOL(WINAPI * PFNGETFONTRESOURCEINFO)(LPCTSTR, LPDWORD, LPVOID, DWORD); +#ifdef UNICODE + static PFNGETFONTRESOURCEINFO GetFontResourceInfo = (PFNGETFONTRESOURCEINFO)GetProcAddress(GetModuleHandle(_T("Gdi32")), "GetFontResourceInfoW"); +#else + static PFNGETFONTRESOURCEINFO GetFontResourceInfo = (PFNGETFONTRESOURCEINFO)GetProcAddress(GetModuleHandle(_T("Gdi32")), "GetFontResourceInfoA"); +#endif + + if (GetFontResourceInfo != nullptr) { + /* Try to query an array of LOGFONTs that describe the file. */ + DWORD len = 0; + if (GetFontResourceInfo(fontPath, &len, nullptr, 2) && len >= sizeof(LOGFONT)) { + LOGFONT *buf = (LOGFONT *)AllocaM(byte, len); + if (GetFontResourceInfo(fontPath, &len, buf, 2)) { + logfont = *buf; // Just use first entry. + } + } + } + + /* No dice yet. Use the file name as the font face name, hoping it matches. */ + if (logfont.lfFaceName[0] == 0) { + TCHAR fname[_MAX_FNAME]; + _tsplitpath(fontPath, nullptr, nullptr, fname, nullptr); + + _tcsncpy_s(logfont.lfFaceName, lengthof(logfont.lfFaceName), fname, _TRUNCATE); + logfont.lfWeight = strcasestr(settings->font, " bold") != nullptr || strcasestr(settings->font, "-bold") != nullptr ? FW_BOLD : FW_NORMAL; // Poor man's way to allow selecting bold fonts. + } + } else { + ShowInfoF("Unable to load file '%s' for %s font, using default windows font selection instead", settings->font, SIZE_TO_NAME[fs]); + } + } + + if (logfont.lfFaceName[0] == 0) { + logfont.lfWeight = strcasestr(settings->font, " bold") != nullptr ? FW_BOLD : FW_NORMAL; // Poor man's way to allow selecting bold fonts. + convert_to_fs(settings->font, logfont.lfFaceName, lengthof(logfont.lfFaceName), false); + } + + HFONT font = CreateFontIndirect(&logfont); + if (font == nullptr) { + ShowInfoF("Unable to use '%s' for %s font, Win32 reported error 0x%lX, using sprite font instead", settings->font, SIZE_TO_NAME[fs], GetLastError()); + return; + } + DeleteObject(font); + + new Win32FontCache(fs, logfont, settings->size); +} + #endif /* WITH_FREETYPE */ +#endif /* defined(WITH_FREETYPE) || defined(_WIN32) */ + /** * (Re)initialize the freetype related things, i.e. load the non-sprite fonts. * @param monospace Whether to initialise the monospace or regular fonts. @@ -669,6 +1041,8 @@ void InitFreeType(bool monospace) #ifdef WITH_FREETYPE LoadFreeTypeFont(fs); +#elif defined(_WIN32) + LoadWin32Font(fs); #endif } } @@ -685,6 +1059,6 @@ void UninitFreeType() #ifdef WITH_FREETYPE FT_Done_FreeType(_library); - _library = NULL; + _library = nullptr; #endif /* WITH_FREETYPE */ } diff --git a/src/fontcache.h b/src/fontcache.h index 1f5e56d924..716b3e7d77 100644 --- a/src/fontcache.h +++ b/src/fontcache.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. @@ -125,6 +123,15 @@ public: */ virtual const void *GetFontTable(uint32 tag, size_t &length) = 0; + /** + * Get the native OS font handle, if there is one. + * @return Opaque OS font handle. + */ + virtual void *GetOSHandle() + { + return nullptr; + } + /** * Get the name of this font. * @return The name of the font. @@ -147,7 +154,7 @@ public: */ inline bool HasParent() { - return this->parent != NULL; + return this->parent != nullptr; } /** @@ -202,13 +209,15 @@ static inline bool GetDrawGlyphShadow(FontSize size) return FontCache::Get(size)->GetDrawGlyphShadow(); } -#ifdef WITH_FREETYPE +#if defined(WITH_FREETYPE) || defined(_WIN32) /** Settings for a single freetype font. */ struct FreeTypeSubSetting { char font[MAX_PATH]; ///< The name of the font, or path to the font. uint size; ///< The (requested) size of the font. bool aa; ///< Whether to do anti aliasing or not. + + const void *os_handle = nullptr; ///< Optional native OS font info. }; /** Settings for the freetype fonts. */ @@ -221,7 +230,7 @@ struct FreeTypeSettings { extern FreeTypeSettings _freetype; -#endif /* WITH_FREETYPE */ +#endif /* defined(WITH_FREETYPE) || defined(_WIN32) */ void InitFreeType(bool monospace); void UninitFreeType(); diff --git a/src/fontdetection.cpp b/src/fontdetection.cpp index 8e9b20a94f..bfa0ef6570 100644 --- a/src/fontdetection.cpp +++ b/src/fontdetection.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. @@ -9,7 +7,7 @@ /** @file fontdetection.cpp Detection of the right font. */ -#ifdef WITH_FREETYPE +#if defined(WITH_FREETYPE) || defined(_WIN32) #include "stdafx.h" #include "debug.h" @@ -17,7 +15,9 @@ #include "string_func.h" #include "strings_func.h" +#ifdef WITH_FREETYPE extern FT_Library _library; +#endif /* WITH_FREETYPE */ /** * Get the font loaded into a Freetype face by using a font-name. @@ -37,6 +37,7 @@ extern FT_Library _library; #include "safeguards.h" +#ifdef WITH_FREETYPE /** * Get the short DOS 8.3 format for paths. * FreeType doesn't support Unicode filenames and Windows' fopen (as used @@ -53,7 +54,7 @@ const char *GetShortPath(const TCHAR *long_path) #ifdef UNICODE WCHAR short_path_w[MAX_PATH]; GetShortPathName(long_path, short_path_w, lengthof(short_path_w)); - WideCharToMultiByte(CP_ACP, 0, short_path_w, -1, short_path, lengthof(short_path), NULL, NULL); + WideCharToMultiByte(CP_ACP, 0, short_path_w, -1, short_path, lengthof(short_path), nullptr, nullptr); #else /* Technically not needed, but do it for consistency. */ GetShortPathName(long_path, short_path, lengthof(short_path)); @@ -101,7 +102,7 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face) DWORD vbuflen = lengthof(vbuffer); DWORD dbuflen = lengthof(dbuffer); - ret = RegEnumValue(hKey, index, vbuffer, &vbuflen, NULL, NULL, (byte*)dbuffer, &dbuflen); + ret = RegEnumValue(hKey, index, vbuffer, &vbuflen, nullptr, nullptr, (byte*)dbuffer, &dbuflen); if (ret != ERROR_SUCCESS) goto registry_no_font_found; /* The font names in the registry are of the following 3 forms: @@ -114,16 +115,16 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face) * by '&'. Our best bet will be to do substr match for the fontname * and then let FreeType figure out which index to load */ s = _tcschr(vbuffer, _T('(')); - if (s != NULL) s[-1] = '\0'; + if (s != nullptr) s[-1] = '\0'; - if (_tcschr(vbuffer, _T('&')) == NULL) { + if (_tcschr(vbuffer, _T('&')) == nullptr) { if (_tcsicmp(vbuffer, font_namep) == 0) break; } else { - if (_tcsstr(vbuffer, font_namep) != NULL) break; + if (_tcsstr(vbuffer, font_namep) != nullptr) break; } } - if (!SUCCEEDED(OTTDSHGetFolderPath(NULL, CSIDL_FONTS, NULL, SHGFP_TYPE_CURRENT, vbuffer))) { + if (!SUCCEEDED(OTTDSHGetFolderPath(nullptr, CSIDL_FONTS, nullptr, SHGFP_TYPE_CURRENT, vbuffer))) { DEBUG(freetype, 0, "SHGetFolderPath cannot return fonts directory"); goto folder_error; } @@ -175,7 +176,7 @@ registry_no_font_found: static const char *GetEnglishFontName(const ENUMLOGFONTEX *logfont) { static char font_name[MAX_PATH]; - const char *ret_font_name = NULL; + const char *ret_font_name = nullptr; uint pos = 0; HDC dc; HGDIOBJ oldfont; @@ -184,11 +185,11 @@ static const char *GetEnglishFontName(const ENUMLOGFONTEX *logfont) uint16 format, count, stringOffset, platformId, encodingId, languageId, nameId, length, offset; HFONT font = CreateFontIndirect(&logfont->elfLogFont); - if (font == NULL) goto err1; + if (font == nullptr) goto err1; - dc = GetDC(NULL); + dc = GetDC(nullptr); oldfont = SelectObject(dc, font); - dw = GetFontData(dc, 'eman', 0, NULL, 0); + dw = GetFontData(dc, 'eman', 0, nullptr, 0); if (dw == GDI_ERROR) goto err2; buf = MallocT(dw); @@ -236,11 +237,12 @@ err3: free(buf); err2: SelectObject(dc, oldfont); - ReleaseDC(NULL, dc); + ReleaseDC(nullptr, dc); DeleteObject(font); err1: - return ret_font_name == NULL ? WIDE_TO_MB((const TCHAR*)logfont->elfFullName) : ret_font_name; + return ret_font_name == nullptr ? WIDE_TO_MB((const TCHAR*)logfont->elfFullName) : ret_font_name; } +#endif /* WITH_FREETYPE */ class FontList { protected: @@ -249,10 +251,10 @@ protected: uint capacity; public: - FontList() : fonts(NULL), items(0), capacity(0) { }; + FontList() : fonts(nullptr), items(0), capacity(0) { }; ~FontList() { - if (this->fonts == NULL) return; + if (this->fonts == nullptr) return; for (uint i = 0; i < this->items; i++) { free(this->fonts[i]); @@ -303,12 +305,12 @@ static int CALLBACK EnumFontCallback(const ENUMLOGFONTEX *logfont, const NEWTEXT FONTSIGNATURE fs; memset(&fs, 0, sizeof(fs)); HFONT font = CreateFontIndirect(&logfont->elfLogFont); - if (font != NULL) { - HDC dc = GetDC(NULL); + if (font != nullptr) { + HDC dc = GetDC(nullptr); HGDIOBJ oldfont = SelectObject(dc, font); GetTextCharsetInfo(dc, &fs, 0); SelectObject(dc, oldfont); - ReleaseDC(NULL, dc); + ReleaseDC(nullptr, dc); DeleteObject(font); } if ((fs.fsCsb[0] & info->locale.lsCsbSupported[0]) == 0 && (fs.fsCsb[1] & info->locale.lsCsbSupported[1]) == 0) return 1; @@ -317,12 +319,13 @@ static int CALLBACK EnumFontCallback(const ENUMLOGFONTEX *logfont, const NEWTEXT char font_name[MAX_PATH]; convert_from_fs((const TCHAR *)logfont->elfFullName, font_name, lengthof(font_name)); +#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)); /* Check whether we can actually load the font. */ - bool ft_init = _library != NULL; + bool ft_init = _library != nullptr; bool found = false; FT_Face face; /* Init FreeType if needed. */ @@ -333,13 +336,18 @@ static int CALLBACK EnumFontCallback(const ENUMLOGFONTEX *logfont, const NEWTEXT if (!ft_init) { /* Uninit FreeType if we did the init. */ FT_Done_FreeType(_library); - _library = NULL; + _library = nullptr; } if (!found) return 1; +#else + const char *english_name = font_name; +#endif /* WITH_FREETYPE */ - info->callback->SetFontNames(info->settings, font_name); - if (info->callback->FindMissingGlyphs(NULL)) return 1; + PLOGFONT os_data = MallocT(1); + *os_data = logfont->elfLogFont; + info->callback->SetFontNames(info->settings, font_name, os_data); + if (info->callback->FindMissingGlyphs(nullptr)) return 1; DEBUG(freetype, 1, "Fallback font: %s (%s)", font_name, english_name); return 0; // stop enumerating } @@ -362,9 +370,9 @@ bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, i font.lfFaceName[0] = '\0'; font.lfPitchAndFamily = 0; - HDC dc = GetDC(NULL); + HDC dc = GetDC(nullptr); int ret = EnumFontFamiliesEx(dc, &font, (FONTENUMPROC)&EnumFontCallback, (LPARAM)&langInfo, 0); - ReleaseDC(NULL, dc); + ReleaseDC(nullptr, dc); return ret == 0; } @@ -384,36 +392,29 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face) /* Get font reference from name. */ UInt8 file_path[PATH_MAX]; OSStatus os_err = -1; - CFStringRef name = CFStringCreateWithCString(kCFAllocatorDefault, font_name, kCFStringEncodingUTF8); + CFAutoRelease name(CFStringCreateWithCString(kCFAllocatorDefault, font_name, kCFStringEncodingUTF8)); #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6) if (MacOSVersionIsAtLeast(10, 6, 0)) { /* Simply creating the font using CTFontCreateWithNameAndSize will *always* return - * something, no matter the name. As such, we can't use it to check for existance. + * something, no matter the name. As such, we can't use it to check for existence. * We instead query the list of all font descriptors that match the given name which * does not do this stupid name fallback. */ - CTFontDescriptorRef name_desc = CTFontDescriptorCreateWithNameAndSize(name, 0.0); - CFSetRef mandatory_attribs = CFSetCreate(kCFAllocatorDefault, (const void **)&kCTFontNameAttribute, 1, &kCFTypeSetCallBacks); - CFArrayRef descs = CTFontDescriptorCreateMatchingFontDescriptors(name_desc, mandatory_attribs); - CFRelease(mandatory_attribs); - CFRelease(name_desc); - CFRelease(name); + CFAutoRelease name_desc(CTFontDescriptorCreateWithNameAndSize(name.get(), 0.0)); + CFAutoRelease mandatory_attribs(CFSetCreate(kCFAllocatorDefault, (const void **)&kCTFontNameAttribute, 1, &kCFTypeSetCallBacks)); + CFAutoRelease descs(CTFontDescriptorCreateMatchingFontDescriptors(name_desc.get(), mandatory_attribs.get())); /* Loop over all matches until we can get a path for one of them. */ - for (CFIndex i = 0; descs != NULL && i < CFArrayGetCount(descs) && os_err != noErr; i++) { - CTFontRef font = CTFontCreateWithFontDescriptor((CTFontDescriptorRef)CFArrayGetValueAtIndex(descs, i), 0.0, NULL); - CFURLRef fontURL = (CFURLRef)CTFontCopyAttribute(font, kCTFontURLAttribute); - if (CFURLGetFileSystemRepresentation(fontURL, true, file_path, lengthof(file_path))) os_err = noErr; - CFRelease(font); - CFRelease(fontURL); + for (CFIndex i = 0; descs.get() != nullptr && i < CFArrayGetCount(descs.get()) && os_err != noErr; i++) { + CFAutoRelease font(CTFontCreateWithFontDescriptor((CTFontDescriptorRef)CFArrayGetValueAtIndex(descs.get(), i), 0.0, nullptr)); + CFAutoRelease fontURL((CFURLRef)CTFontCopyAttribute(font.get(), kCTFontURLAttribute)); + if (CFURLGetFileSystemRepresentation(fontURL.get(), true, file_path, lengthof(file_path))) os_err = noErr; } - if (descs != NULL) CFRelease(descs); } else #endif { #if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_6) - ATSFontRef font = ATSFontFindFromName(name, kATSOptionFlagsDefault); - CFRelease(name); + ATSFontRef font = ATSFontFindFromName(name.get(), kATSOptionFlagsDefault); if (font == kInvalidFont) return err; /* Get a file system reference for the font. */ @@ -467,34 +468,31 @@ bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, i /* Just copy the first part of the isocode. */ strecpy(lang, language_isocode, lastof(lang)); char *sep = strchr(lang, '_'); - if (sep != NULL) *sep = '\0'; + if (sep != nullptr) *sep = '\0'; } - /* Create a font descriptor matching the wanted language and latin (english) glyphs. */ + /* Create a font descriptor matching the wanted language and latin (english) glyphs. + * Can't use CFAutoRelease here for everything due to the way the dictionary has to be created. */ CFStringRef lang_codes[2]; lang_codes[0] = CFStringCreateWithCString(kCFAllocatorDefault, lang, kCFStringEncodingUTF8); lang_codes[1] = CFSTR("en"); CFArrayRef lang_arr = CFArrayCreate(kCFAllocatorDefault, (const void **)lang_codes, lengthof(lang_codes), &kCFTypeArrayCallBacks); - CFDictionaryRef lang_attribs = CFDictionaryCreate(kCFAllocatorDefault, (const void**)&kCTFontLanguagesAttribute, (const void **)&lang_arr, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks); - CTFontDescriptorRef lang_desc = CTFontDescriptorCreateWithAttributes(lang_attribs); + CFAutoRelease lang_attribs(CFDictionaryCreate(kCFAllocatorDefault, (const void**)&kCTFontLanguagesAttribute, (const void **)&lang_arr, 1, &kCFTypeDictionaryKeyCallBacks, &kCFTypeDictionaryValueCallBacks)); + CFAutoRelease lang_desc(CTFontDescriptorCreateWithAttributes(lang_attribs.get())); CFRelease(lang_arr); - CFRelease(lang_attribs); CFRelease(lang_codes[0]); /* Get array of all font descriptors for the wanted language. */ - CFSetRef mandatory_attribs = CFSetCreate(kCFAllocatorDefault, (const void **)&kCTFontLanguagesAttribute, 1, &kCFTypeSetCallBacks); - CFArrayRef descs = CTFontDescriptorCreateMatchingFontDescriptors(lang_desc, mandatory_attribs); - CFRelease(mandatory_attribs); - CFRelease(lang_desc); + CFAutoRelease mandatory_attribs(CFSetCreate(kCFAllocatorDefault, (const void **)&kCTFontLanguagesAttribute, 1, &kCFTypeSetCallBacks)); + CFAutoRelease descs(CTFontDescriptorCreateMatchingFontDescriptors(lang_desc.get(), mandatory_attribs.get())); - for (CFIndex i = 0; descs != NULL && i < CFArrayGetCount(descs); i++) { - CTFontDescriptorRef font = (CTFontDescriptorRef)CFArrayGetValueAtIndex(descs, i); + for (CFIndex i = 0; descs.get() != nullptr && i < CFArrayGetCount(descs.get()); i++) { + CTFontDescriptorRef font = (CTFontDescriptorRef)CFArrayGetValueAtIndex(descs.get(), i); /* Get font traits. */ - CFDictionaryRef traits = (CFDictionaryRef)CTFontDescriptorCopyAttribute(font, kCTFontTraitsAttribute); + CFAutoRelease traits((CFDictionaryRef)CTFontDescriptorCopyAttribute(font, kCTFontTraitsAttribute)); CTFontSymbolicTraits symbolic_traits; - CFNumberGetValue((CFNumberRef)CFDictionaryGetValue(traits, kCTFontSymbolicTrait), kCFNumberIntType, &symbolic_traits); - CFRelease(traits); + CFNumberGetValue((CFNumberRef)CFDictionaryGetValue(traits.get(), kCTFontSymbolicTrait), kCFNumberIntType, &symbolic_traits); /* Skip symbol fonts and vertical fonts. */ if ((symbolic_traits & kCTFontClassMaskTrait) == (CTFontStylisticClass)kCTFontSymbolicClass || (symbolic_traits & kCTFontVerticalTrait)) continue; @@ -505,9 +503,8 @@ bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, i /* Get font name. */ char name[128]; - CFStringRef font_name = (CFStringRef)CTFontDescriptorCopyAttribute(font, kCTFontDisplayNameAttribute); - CFStringGetCString(font_name, name, lengthof(name), kCFStringEncodingUTF8); - CFRelease(font_name); + CFAutoRelease font_name((CFStringRef)CTFontDescriptorCopyAttribute(font, kCTFontDisplayNameAttribute)); + CFStringGetCString(font_name.get(), name, lengthof(name), kCFStringEncodingUTF8); /* There are some special fonts starting with an '.' and the last * resort font that aren't usable. Skip them. */ @@ -515,13 +512,12 @@ bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, i /* Save result. */ callback->SetFontNames(settings, name); - if (!callback->FindMissingGlyphs(NULL)) { + if (!callback->FindMissingGlyphs(nullptr)) { DEBUG(freetype, 2, "CT-Font for %s: %s", language_isocode, name); result = true; break; } } - if (descs != NULL) CFRelease(descs); } else #endif { @@ -530,7 +526,7 @@ bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, i * are available to the application. */ ATSFontIterator itr; ATSFontRef font; - ATSFontIteratorCreate(kATSFontContextLocal, NULL, NULL, kATSOptionFlagsDefaultScope, &itr); + ATSFontIteratorCreate(kATSFontContextLocal, nullptr, nullptr, kATSOptionFlagsDefaultScope, &itr); while (!result && ATSFontIteratorNext(itr, &font) == noErr) { /* Get font name. */ char name[128]; @@ -545,14 +541,14 @@ bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, i if (monospace != callback->Monospace()) continue; /* We only want the base font and not bold or italic variants. */ - if (strstr(name, "Italic") != NULL || strstr(name, "Bold")) continue; + if (strstr(name, "Italic") != nullptr || strstr(name, "Bold")) continue; /* Skip some inappropriate or ugly looking fonts that have better alternatives. */ if (name[0] == '.' || strncmp(name, "Apple Symbols", 13) == 0 || strncmp(name, "LastResort", 10) == 0) continue; /* Save result. */ callback->SetFontNames(settings, name); - if (!callback->FindMissingGlyphs(NULL)) { + if (!callback->FindMissingGlyphs(nullptr)) { DEBUG(freetype, 2, "ATS-Font for %s: %s", language_isocode, name); result = true; break; @@ -566,10 +562,10 @@ bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, i /* For some OS versions, the font 'Arial Unicode MS' does not report all languages it * supports. If we didn't find any other font, just try it, maybe we get lucky. */ callback->SetFontNames(settings, "Arial Unicode MS"); - result = !callback->FindMissingGlyphs(NULL); + result = !callback->FindMissingGlyphs(nullptr); } - callback->FindMissingGlyphs(NULL); + callback->FindMissingGlyphs(nullptr); return result; } @@ -599,7 +595,7 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face) /* Split & strip the font's style */ font_family = stredup(font_name); font_style = strchr(font_family, ','); - if (font_style != NULL) { + if (font_style != nullptr) { font_style[0] = '\0'; font_style++; while (*font_style == ' ' || *font_style == '\t') font_style++; @@ -607,13 +603,13 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face) /* Resolve the name and populate the information structure */ pat = FcNameParse((FcChar8*)font_family); - if (font_style != NULL) FcPatternAddString(pat, FC_STYLE, (FcChar8*)font_style); + if (font_style != nullptr) FcPatternAddString(pat, FC_STYLE, (FcChar8*)font_style); FcConfigSubstitute(0, pat, FcMatchPattern); FcDefaultSubstitute(pat); fs = FcFontSetCreate(); match = FcFontMatch(0, pat, &result); - if (fs != NULL && match != NULL) { + if (fs != nullptr && match != nullptr) { int i; FcChar8 *family; FcChar8 *style; @@ -627,7 +623,7 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face) FcPatternGetString(fs->fonts[i], FC_STYLE, 0, &style) == FcResultMatch) { /* The correct style? */ - if (font_style != NULL && strcasecmp(font_style, (char*)style) != 0) continue; + if (font_style != nullptr && strcasecmp(font_style, (char*)style) != 0) continue; /* Font config takes the best shot, which, if the family name is spelled * wrongly a 'random' font, so check whether the family name is the @@ -660,31 +656,31 @@ bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, i char lang[16]; seprintf(lang, lastof(lang), ":lang=%s", language_isocode); char *split = strchr(lang, '_'); - if (split != NULL) *split = '\0'; + if (split != nullptr) *split = '\0'; /* First create a pattern to match the wanted language. */ //FcPattern *pat = FcNameParse((FcChar8*)lang); FcPattern *pat = FcPatternCreate(); /* We only want to know the filename. */ - FcObjectSet *os = FcObjectSetBuild(FC_FILE, FC_SPACING, FC_SLANT, FC_WEIGHT, NULL); + FcObjectSet *os = FcObjectSetBuild(FC_FILE, FC_SPACING, FC_SLANT, FC_WEIGHT, nullptr); /* Get the list of filenames matching the wanted language. */ - FcFontSet *fs = FcFontList(NULL, pat, os); + FcFontSet *fs = FcFontList(nullptr, pat, os); /* We don't need these anymore. */ FcObjectSetDestroy(os); FcPatternDestroy(pat); - if (fs != NULL) { + if (fs != nullptr) { int best_weight = -1; - const char *best_font = NULL; + const char *best_font = nullptr; int best_missing_glypths = 65536; for (int i = 0; i < fs->nfont; i++) { FcPattern *font = fs->fonts[i]; - FcChar8 *file = NULL; + FcChar8 *file = nullptr; FcResult res = FcPatternGetString(font, FC_FILE, 0, &file); - if (res != FcResultMatch || file == NULL) { + if (res != FcResultMatch || file == nullptr) { continue; } DEBUG(freetype, 1, "Got font %s", file); @@ -705,7 +701,7 @@ bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, i callback->SetFontNames(settings, (const char*)file); - missing += callback->FindMissingGlyphs(NULL); + missing += callback->FindMissingGlyphs(nullptr); DEBUG(freetype, 1, "Font \"%s\" misses %d glyphs for lang %s", file, missing, lang); if (missing < best_missing_glypths) { @@ -716,7 +712,7 @@ bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, i } } - if (best_font != NULL) { + if (best_font != nullptr) { ret = true; callback->SetFontNames(settings, best_font); InitFreeType(callback->Monospace()); diff --git a/src/fontdetection.h b/src/fontdetection.h index edb961e6d3..70b2fe236e 100644 --- a/src/fontdetection.h +++ b/src/fontdetection.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. @@ -27,6 +25,9 @@ */ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face); +#endif /* WITH_FREETYPE */ + +#if defined(WITH_FREETYPE) || defined(_WIN32) /** * We would like to have a fallback font as the current one * doesn't contain all characters we need. @@ -39,6 +40,6 @@ FT_Error GetFontByFaceName(const char *font_name, FT_Face *face); */ bool SetFallbackFont(FreeTypeSettings *settings, const char *language_isocode, int winlangid, class MissingGlyphSearcher *callback); -#endif /* WITH_FREETYPE */ +#endif /* defined(WITH_FREETYPE) || defined(WIN32)*/ #endif diff --git a/src/framerate_gui.cpp b/src/framerate_gui.cpp index 060b19a4a1..d34f59e09f 100644 --- a/src/framerate_gui.cpp +++ b/src/framerate_gui.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. @@ -22,6 +20,9 @@ #include "guitimer_func.h" #include "company_base.h" #include "ai/ai_info.hpp" +#include "ai/ai_instance.hpp" +#include "game/game.hpp" +#include "game/game_instance.hpp" #include "widgets/framerate_widget.h" #include "safeguards.h" @@ -365,6 +366,9 @@ static const NWidgetPart _framerate_window_widgets[] = { 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), + NWidget(NWID_SELECTION, INVALID_COLOUR, WID_FRW_SEL_MEMORY), + 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), EndContainer(), @@ -378,6 +382,7 @@ static const NWidgetPart _framerate_window_widgets[] = { struct FramerateWindow : Window { bool small; + bool showing_memory; GUITimer next_update; int num_active; int num_displayed; @@ -424,6 +429,7 @@ struct FramerateWindow : Window { { this->InitNested(number); this->small = this->IsShaded(); + this->showing_memory = true; this->UpdateData(); this->num_displayed = this->num_active; this->next_update.SetInterval(100); @@ -432,7 +438,7 @@ struct FramerateWindow : Window { ResizeWindow(this, 0, (max(MIN_ELEMENTS, this->num_displayed) - MIN_ELEMENTS) * FONT_HEIGHT_NORMAL); } - virtual void OnRealtimeTick(uint delta_ms) + void OnRealtimeTick(uint delta_ms) override { bool elapsed = this->next_update.Elapsed(delta_ms); @@ -453,6 +459,7 @@ struct FramerateWindow : Window { void UpdateData() { double gl_rate = _pf_data[PFE_GAMELOOP].GetRate(); + bool have_script = false; this->rate_gameloop.SetRate(gl_rate, _pf_data[PFE_GAMELOOP].expected_rate); this->speed_gameloop.SetRate(gl_rate / _pf_data[PFE_GAMELOOP].expected_rate, 1.0); if (this->small) return; // in small mode, this is everything needed @@ -463,7 +470,16 @@ struct FramerateWindow : Window { for (PerformanceElement e = PFE_FIRST; e < PFE_MAX; e++) { this->times_shortterm[e].SetTime(_pf_data[e].GetAverageDurationMilliseconds(8), MILLISECONDS_PER_TICK); this->times_longterm[e].SetTime(_pf_data[e].GetAverageDurationMilliseconds(NUM_FRAMERATE_POINTS), MILLISECONDS_PER_TICK); - if (_pf_data[e].num_valid > 0) new_active++; + if (_pf_data[e].num_valid > 0) { + new_active++; + if (e == PFE_GAMESCRIPT || e >= PFE_AI0) have_script = true; + } + } + + if (this->showing_memory != have_script) { + NWidgetStacked *plane = this->GetWidget(WID_FRW_SEL_MEMORY); + plane->SetDisplayedPlane(have_script ? 0 : SZSP_VERTICAL); + this->showing_memory = have_script; } if (new_active != this->num_active) { @@ -475,7 +491,7 @@ struct FramerateWindow : Window { } } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { switch (widget) { case WID_FRW_CAPTION: @@ -503,7 +519,7 @@ struct FramerateWindow : Window { } } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_FRW_RATE_GAMELOOP: @@ -545,7 +561,8 @@ struct FramerateWindow : Window { } case WID_FRW_TIMES_CURRENT: - case WID_FRW_TIMES_AVERAGE: { + case WID_FRW_TIMES_AVERAGE: + case WID_FRW_ALLOCSIZE: { *size = GetStringBoundingBox(STR_FRAMERATE_CURRENT + (widget - WID_FRW_TIMES_CURRENT)); SetDParam(0, 999999); SetDParam(1, 2); @@ -582,7 +599,38 @@ struct FramerateWindow : Window { } } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawElementAllocationsColumn(const Rect &r) const + { + const Scrollbar *sb = this->GetScrollbar(WID_FRW_SCROLLBAR); + uint16 skip = sb->GetPosition(); + 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; + for (PerformanceElement e : DISPLAY_ORDER_PFE) { + if (_pf_data[e].num_valid == 0) continue; + if (skip > 0) { + skip--; + } else if (e == PFE_GAMESCRIPT || e >= PFE_AI0) { + if (e == PFE_GAMESCRIPT) { + SetDParam(0, Game::GetInstance()->GetAllocatedMemory()); + } else { + SetDParam(0, Company::Get(e - PFE_AI0)->ai_instance->GetAllocatedMemory()); + } + DrawString(r.left, r.right, y, STR_FRAMERATE_BYTES_GOOD, TC_FROMSTRING, SA_RIGHT); + y += FONT_HEIGHT_NORMAL; + drawable--; + if (drawable == 0) break; + } else { + /* skip non-script */ + y += FONT_HEIGHT_NORMAL; + drawable--; + if (drawable == 0) break; + } + } + } + + void DrawWidget(const Rect &r, int widget) const override { switch (widget) { case WID_FRW_TIMES_NAMES: { @@ -618,10 +666,13 @@ struct FramerateWindow : Window { /* Render averages of all recorded values */ DrawElementTimesColumn(r, STR_FRAMERATE_AVERAGE, this->times_longterm); break; + case WID_FRW_ALLOCSIZE: + DrawElementAllocationsColumn(r); + break; } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_FRW_TIMES_NAMES: @@ -646,7 +697,7 @@ struct FramerateWindow : Window { } } - virtual void OnResize() + 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 @@ -694,7 +745,7 @@ struct FrametimeGraphWindow : Window { this->InitNested(number); } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { switch (widget) { case WID_FGW_CAPTION: @@ -709,7 +760,7 @@ struct FrametimeGraphWindow : Window { } } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { if (widget == WID_FGW_GRAPH) { SetDParam(0, 100); @@ -807,7 +858,7 @@ struct FrametimeGraphWindow : Window { this->SelectVerticalScale(peak_value); } - virtual void OnRealtimeTick(uint delta_ms) + void OnRealtimeTick(uint delta_ms) override { this->SetDirty(); @@ -826,7 +877,7 @@ struct FrametimeGraphWindow : Window { return (value - src_min) * dst_diff / src_diff + dst_min; } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { if (widget == WID_FGW_GRAPH) { const TimingMeasurement *durations = _pf_data[this->element].durations; @@ -865,7 +916,7 @@ struct FrametimeGraphWindow : Window { } } } - /* Draw divison lines and labels for the horizontal axis */ + /* Draw division lines and labels for the horizontal axis */ for (uint division = horz_divisions; division > 0; division--) { int x = Scinterlate(x_zero, x_max, 0, (int)horz_divisions, (int)horz_divisions - (int)division); GfxDrawLine(x, y_max, x, y_zero, c_grid); diff --git a/src/framerate_type.h b/src/framerate_type.h index 3c54e03078..1fa6e35ac8 100644 --- a/src/framerate_type.h +++ b/src/framerate_type.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/game/game.hpp b/src/game/game.hpp index 329ba5e500..8381a6c148 100644 --- a/src/game/game.hpp +++ b/src/game/game.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. @@ -112,11 +110,9 @@ public: */ static class GameInstance *GetInstance() { return Game::instance; } -#if defined(ENABLE_NETWORK) /** Wrapper function for GameScanner::HasGame */ static bool HasGame(const struct ContentInfo *ci, bool md5sum); static bool HasGameLibrary(const ContentInfo *ci, bool md5sum); -#endif /** Gets the ScriptScanner instance that is used to find Game scripts */ static GameScannerInfo *GetScannerInfo(); /** Gets the ScriptScanner instance that is used to find Game Libraries */ diff --git a/src/game/game_config.cpp b/src/game/game_config.cpp index 50cd5da4e0..89283129e7 100644 --- a/src/game/game_config.cpp +++ b/src/game/game_config.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. @@ -25,7 +23,7 @@ } else { config = &_settings_game.game_config; } - if (*config == NULL) *config = new GameConfig(); + if (*config == nullptr) *config = new GameConfig(); return *config; } @@ -42,5 +40,5 @@ ScriptInfo *GameConfig::FindInfo(const char *name, int version, bool force_exact bool GameConfig::ResetInfo(bool force_exact_match) { this->info = (ScriptInfo *)Game::FindInfo(this->name, force_exact_match ? this->version : -1, force_exact_match); - return this->info != NULL; + return this->info != nullptr; } diff --git a/src/game/game_config.hpp b/src/game/game_config.hpp index e9ebdc38c1..a01128e671 100644 --- a/src/game/game_config.hpp +++ b/src/game/game_config.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. @@ -42,7 +40,7 @@ public: bool ResetInfo(bool force_exact_match); protected: - /* virtual */ ScriptInfo *FindInfo(const char *name, int version, bool force_exact_match); + ScriptInfo *FindInfo(const char *name, int version, bool force_exact_match) override; }; #endif /* GAME_CONFIG_HPP */ diff --git a/src/game/game_core.cpp b/src/game/game_core.cpp index 10b079bee3..fbe233c9f0 100644 --- a/src/game/game_core.cpp +++ b/src/game/game_core.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. @@ -25,10 +23,10 @@ #include "../safeguards.h" /* static */ uint Game::frame_counter = 0; -/* static */ GameInfo *Game::info = NULL; -/* static */ GameInstance *Game::instance = NULL; -/* static */ GameScannerInfo *Game::scanner_info = NULL; -/* static */ GameScannerLibrary *Game::scanner_library = NULL; +/* static */ GameInfo *Game::info = nullptr; +/* static */ GameInstance *Game::instance = nullptr; +/* static */ GameScannerInfo *Game::scanner_info = nullptr; +/* static */ GameScannerLibrary *Game::scanner_library = nullptr; /* static */ void Game::GameLoop() { @@ -36,7 +34,7 @@ PerformanceMeasurer::SetInactive(PFE_GAMESCRIPT); return; } - if (Game::instance == NULL) { + if (Game::instance == nullptr) { PerformanceMeasurer::SetInactive(PFE_GAMESCRIPT); return; } @@ -45,7 +43,7 @@ Game::frame_counter++; - Backup cur_company(_current_company, FILE_LINE); + Backup cur_company(_current_company, FILE_LINE); cur_company.Change(OWNER_DEITY); Game::instance->GameLoop(); cur_company.Restore(); @@ -58,11 +56,11 @@ /* static */ void Game::Initialize() { - if (Game::instance != NULL) Game::Uninitialize(true); + if (Game::instance != nullptr) Game::Uninitialize(true); Game::frame_counter = 0; - if (Game::scanner_info == NULL) { + if (Game::scanner_info == nullptr) { TarScanner::DoScan(TarScanner::GAME); Game::scanner_info = new GameScannerInfo(); Game::scanner_info->Initialize(); @@ -73,18 +71,18 @@ /* static */ void Game::StartNew() { - if (Game::instance != NULL) return; + if (Game::instance != nullptr) return; /* Clients shouldn't start GameScripts */ if (_networking && !_network_server) return; GameConfig *config = GameConfig::GetConfig(GameConfig::SSS_FORCE_GAME); GameInfo *info = config->GetInfo(); - if (info == NULL) return; + if (info == nullptr) return; config->AnchorUnchangeableSettings(); - Backup cur_company(_current_company, FILE_LINE); + Backup cur_company(_current_company, FILE_LINE); cur_company.Change(OWNER_DEITY); Game::info = info; @@ -98,11 +96,11 @@ /* static */ void Game::Uninitialize(bool keepConfig) { - Backup cur_company(_current_company, FILE_LINE); + Backup cur_company(_current_company, FILE_LINE); delete Game::instance; - Game::instance = NULL; - Game::info = NULL; + Game::instance = nullptr; + Game::info = nullptr; cur_company.Restore(); @@ -111,33 +109,33 @@ } else { delete Game::scanner_info; delete Game::scanner_library; - Game::scanner_info = NULL; - Game::scanner_library = NULL; + Game::scanner_info = nullptr; + Game::scanner_library = nullptr; - if (_settings_game.game_config != NULL) { + if (_settings_game.game_config != nullptr) { delete _settings_game.game_config; - _settings_game.game_config = NULL; + _settings_game.game_config = nullptr; } - if (_settings_newgame.game_config != NULL) { + if (_settings_newgame.game_config != nullptr) { delete _settings_newgame.game_config; - _settings_newgame.game_config = NULL; + _settings_newgame.game_config = nullptr; } } } /* static */ void Game::Pause() { - if (Game::instance != NULL) Game::instance->Pause(); + if (Game::instance != nullptr) Game::instance->Pause(); } /* static */ void Game::Unpause() { - if (Game::instance != NULL) Game::instance->Unpause(); + if (Game::instance != nullptr) Game::instance->Unpause(); } /* static */ bool Game::IsPaused() { - return Game::instance != NULL? Game::instance->IsPaused() : false; + return Game::instance != nullptr? Game::instance->IsPaused() : false; } /* static */ void Game::NewEvent(ScriptEvent *event) @@ -152,13 +150,13 @@ } /* Check if Game instance is alive */ - if (Game::instance == NULL) { + if (Game::instance == nullptr) { event->Release(); return; } /* Queue the event */ - Backup cur_company(_current_company, OWNER_DEITY, FILE_LINE); + Backup cur_company(_current_company, OWNER_DEITY, FILE_LINE); Game::instance->InsertEvent(event); cur_company.Restore(); @@ -169,23 +167,23 @@ { /* Check for both newgame as current game if we can reload the GameInfo inside * the GameConfig. If not, remove the Game from the list. */ - if (_settings_game.game_config != NULL && _settings_game.game_config->HasScript()) { + if (_settings_game.game_config != nullptr && _settings_game.game_config->HasScript()) { if (!_settings_game.game_config->ResetInfo(true)) { DEBUG(script, 0, "After a reload, the GameScript by the name '%s' was no longer found, and removed from the list.", _settings_game.game_config->GetName()); - _settings_game.game_config->Change(NULL); - if (Game::instance != NULL) { + _settings_game.game_config->Change(nullptr); + if (Game::instance != nullptr) { delete Game::instance; - Game::instance = NULL; - Game::info = NULL; + Game::instance = nullptr; + Game::info = nullptr; } - } else if (Game::instance != NULL) { + } else if (Game::instance != nullptr) { Game::info = _settings_game.game_config->GetInfo(); } } - if (_settings_newgame.game_config != NULL && _settings_newgame.game_config->HasScript()) { + if (_settings_newgame.game_config != nullptr && _settings_newgame.game_config->HasScript()) { if (!_settings_newgame.game_config->ResetInfo(false)) { DEBUG(script, 0, "After a reload, the GameScript by the name '%s' was no longer found, and removed from the list.", _settings_newgame.game_config->GetName()); - _settings_newgame.game_config->Change(NULL); + _settings_newgame.game_config->Change(nullptr); } } } @@ -206,8 +204,8 @@ /* static */ void Game::Save() { - if (Game::instance != NULL && (!_networking || _network_server)) { - Backup cur_company(_current_company, OWNER_DEITY, FILE_LINE); + if (Game::instance != nullptr && (!_networking || _network_server)) { + Backup cur_company(_current_company, OWNER_DEITY, FILE_LINE); Game::instance->Save(); cur_company.Restore(); } else { @@ -217,8 +215,8 @@ /* static */ void Game::Load(int version) { - if (Game::instance != NULL && (!_networking || _network_server)) { - Backup cur_company(_current_company, OWNER_DEITY, FILE_LINE); + if (Game::instance != nullptr && (!_networking || _network_server)) { + Backup cur_company(_current_company, OWNER_DEITY, FILE_LINE); Game::instance->Load(version); cur_company.Restore(); } else { @@ -257,8 +255,6 @@ return Game::scanner_library->FindLibrary(library, version); } -#if defined(ENABLE_NETWORK) - /** * Check whether we have an Game (library) with the exact characteristics as ci. * @param ci the characteristics to search on (shortname and md5sum) @@ -275,8 +271,6 @@ return Game::scanner_library->HasScript(ci, md5sum); } -#endif /* defined(ENABLE_NETWORK) */ - /* static */ GameScannerInfo *Game::GetScannerInfo() { return Game::scanner_info; diff --git a/src/game/game_info.cpp b/src/game/game_info.cpp index f8c04608b7..91a463bed5 100644 --- a/src/game/game_info.cpp +++ b/src/game/game_info.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. @@ -26,7 +24,7 @@ static bool CheckAPIVersion(const char *api_version) { return strcmp(api_version, "1.2") == 0 || strcmp(api_version, "1.3") == 0 || strcmp(api_version, "1.4") == 0 || strcmp(api_version, "1.5") == 0 || strcmp(api_version, "1.6") == 0 || strcmp(api_version, "1.7") == 0 || - strcmp(api_version, "1.8") == 0 || strcmp(api_version, "1.9") == 0; + strcmp(api_version, "1.8") == 0 || strcmp(api_version, "1.9") == 0 || strcmp(api_version, "1.10") == 0; } #if defined(_WIN32) @@ -55,8 +53,8 @@ template <> const char *GetClassName() { return "GSInfo"; } /* static */ SQInteger GameInfo::Constructor(HSQUIRRELVM vm) { /* Get the GameInfo */ - SQUserPointer instance = NULL; - if (SQ_FAILED(sq_getinstanceup(vm, 2, &instance, 0)) || instance == NULL) return sq_throwerror(vm, "Pass an instance of a child class of GameInfo to RegisterGame"); + SQUserPointer instance = nullptr; + if (SQ_FAILED(sq_getinstanceup(vm, 2, &instance, 0)) || instance == nullptr) return sq_throwerror(vm, "Pass an instance of a child class of GameInfo to RegisterGame"); GameInfo *info = (GameInfo *)instance; SQInteger res = ScriptInfo::Constructor(vm, info); @@ -82,7 +80,7 @@ template <> const char *GetClassName() { return "GSInfo"; } } /* Remove the link to the real instance, else it might get deleted by RegisterGame() */ - sq_setinstanceup(vm, 2, NULL); + sq_setinstanceup(vm, 2, nullptr); /* Register the Game to the base system */ info->GetScanner()->RegisterScript(info); return 0; @@ -91,7 +89,7 @@ template <> const char *GetClassName() { return "GSInfo"; } GameInfo::GameInfo() : min_loadable_version(0), is_developer_only(false), - api_version(NULL) + api_version(nullptr) { } diff --git a/src/game/game_info.hpp b/src/game/game_info.hpp index f4fc5ed86b..cfa900767c 100644 --- a/src/game/game_info.hpp +++ b/src/game/game_info.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. @@ -40,7 +38,7 @@ public: */ const char *GetAPIVersion() const { return this->api_version; } - /* virtual */ bool IsDeveloperOnly() const { return this->is_developer_only; } + bool IsDeveloperOnly() const override { return this->is_developer_only; } private: int min_loadable_version; ///< The Game can load savegame data if the version is equal or greater than this. @@ -51,7 +49,7 @@ private: /** All static information from an Game library like name, version, etc. */ class GameLibrary : public ScriptInfo { public: - GameLibrary() : ScriptInfo(), category(NULL) {}; + GameLibrary() : ScriptInfo(), category(nullptr) {}; ~GameLibrary(); /** diff --git a/src/game/game_instance.cpp b/src/game/game_instance.cpp index e2b3775110..57b2213ea9 100644 --- a/src/game/game_instance.cpp +++ b/src/game/game_instance.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. @@ -64,6 +62,7 @@ #include "../script/api/game/game_rail.hpp.sq" #include "../script/api/game/game_railtypelist.hpp.sq" #include "../script/api/game/game_road.hpp.sq" +#include "../script/api/game/game_roadtypelist.hpp.sq" #include "../script/api/game/game_sign.hpp.sq" #include "../script/api/game/game_signlist.hpp.sq" #include "../script/api/game/game_station.hpp.sq" @@ -174,6 +173,7 @@ void GameInstance::RegisterAPI() SQGSRail_Register(this->engine); SQGSRailTypeList_Register(this->engine); SQGSRoad_Register(this->engine); + SQGSRoadTypeList_Register(this->engine); SQGSSign_Register(this->engine); SQGSSignList_Register(this->engine); SQGSStation_Register(this->engine); @@ -239,10 +239,10 @@ void GameInstance::Died() ShowAIDebugWindow(OWNER_DEITY); const GameInfo *info = Game::GetInfo(); - if (info != NULL) { + if (info != nullptr) { ShowErrorMessage(STR_ERROR_AI_PLEASE_REPORT_CRASH, INVALID_STRING_ID, WL_WARNING); - if (info->GetURL() != NULL) { + if (info->GetURL() != nullptr) { ScriptLog::Info("Please report the error to the following URL:"); ScriptLog::Info(info->GetURL()); } @@ -255,11 +255,13 @@ void GameInstance::Died() * @param tile The tile on which the command was executed. * @param p1 p1 as given to DoCommandPInternal. * @param p2 p2 as given to DoCommandPInternal. + * @param cmd cmd as given to DoCommandPInternal. */ -void CcGame(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) +void CcGame(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) { - Game::GetGameInstance()->DoCommandCallback(result, tile, p1, p2); - Game::GetGameInstance()->Continue(); + if (Game::GetGameInstance()->DoCommandCallback(result, tile, p1, p2, cmd)) { + Game::GetGameInstance()->Continue(); + } } CommandCallback *GameInstance::GetDoCommandCallback() diff --git a/src/game/game_instance.hpp b/src/game/game_instance.hpp index 08ce344247..7b3b12b379 100644 --- a/src/game/game_instance.hpp +++ b/src/game/game_instance.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. @@ -25,14 +23,14 @@ public: */ void Initialize(class GameInfo *info); - /* virtual */ int GetSetting(const char *name); - /* virtual */ ScriptInfo *FindLibrary(const char *library, int version); + int GetSetting(const char *name) override; + ScriptInfo *FindLibrary(const char *library, int version) override; private: - /* virtual */ void RegisterAPI(); - /* virtual */ void Died(); - /* virtual */ CommandCallback *GetDoCommandCallback(); - /* virtual */ void LoadDummyScript() {} + void RegisterAPI() override; + void Died() override; + CommandCallback *GetDoCommandCallback() override; + void LoadDummyScript() override {} }; #endif /* GAME_INSTANCE_HPP */ diff --git a/src/game/game_scanner.cpp b/src/game/game_scanner.cpp index 38afdd1357..68efa350c2 100644 --- a/src/game/game_scanner.cpp +++ b/src/game/game_scanner.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. @@ -35,14 +33,14 @@ void GameScannerInfo::RegisterAPI(class Squirrel *engine) GameInfo *GameScannerInfo::FindInfo(const char *nameParam, int versionParam, bool force_exact_match) { - if (this->info_list.size() == 0) return NULL; - if (nameParam == NULL) return NULL; + if (this->info_list.size() == 0) return nullptr; + if (nameParam == nullptr) return nullptr; char game_name[1024]; strecpy(game_name, nameParam, lastof(game_name)); strtolower(game_name); - GameInfo *info = NULL; + GameInfo *info = nullptr; int version = -1; if (versionParam == -1) { @@ -51,7 +49,7 @@ GameInfo *GameScannerInfo::FindInfo(const char *nameParam, int versionParam, boo /* If we didn't find a match Game script, maybe the user included a version */ char *e = strrchr(game_name, '.'); - if (e == NULL) return NULL; + if (e == nullptr) return nullptr; *e = '\0'; e++; versionParam = atoi(e); @@ -106,7 +104,7 @@ GameLibrary *GameScannerLibrary::FindLibrary(const char *library, int version) /* Check if the library + version exists */ ScriptInfoList::iterator iter = this->info_list.find(library_name); - if (iter == this->info_list.end()) return NULL; + if (iter == this->info_list.end()) return nullptr; return static_cast((*iter).second); } diff --git a/src/game/game_scanner.hpp b/src/game/game_scanner.hpp index 071d19d38d..6c96bccfdf 100644 --- a/src/game/game_scanner.hpp +++ b/src/game/game_scanner.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. @@ -16,44 +14,44 @@ class GameScannerInfo : public ScriptScanner { public: - /* virtual */ void Initialize(); + void Initialize() override; /** * Check if we have a game by name and version available in our list. * @param nameParam The name of the game script. * @param versionParam The version of the game script, or -1 if you want the latest. * @param force_exact_match Only match name+version, never latest. - * @return NULL if no match found, otherwise the game script that matched. + * @return nullptr if no match found, otherwise the game script that matched. */ class GameInfo *FindInfo(const char *nameParam, int versionParam, bool force_exact_match); protected: - /* virtual */ void GetScriptName(ScriptInfo *info, char *name, const char *last); - /* virtual */ const char *GetFileName() const { return PATHSEP "info.nut"; } - /* virtual */ Subdirectory GetDirectory() const { return GAME_DIR; } - /* virtual */ const char *GetScannerName() const { return "Game Scripts"; } - /* virtual */ void RegisterAPI(class Squirrel *engine); + void GetScriptName(ScriptInfo *info, char *name, const char *last) override; + const char *GetFileName() const override { return PATHSEP "info.nut"; } + Subdirectory GetDirectory() const override { return GAME_DIR; } + const char *GetScannerName() const override { return "Game Scripts"; } + void RegisterAPI(class Squirrel *engine) override; }; class GameScannerLibrary : public ScriptScanner { public: - /* virtual */ void Initialize(); + void Initialize() override; /** * Find a library in the pool. * @param library The library name to find. * @param version The version the library should have. - * @return The library if found, NULL otherwise. + * @return The library if found, nullptr otherwise. */ class GameLibrary *FindLibrary(const char *library, int version); protected: - /* virtual */ void GetScriptName(ScriptInfo *info, char *name, const char *last); - /* virtual */ const char *GetFileName() const { return PATHSEP "library.nut"; } - /* virtual */ Subdirectory GetDirectory() const { return GAME_LIBRARY_DIR; } - /* virtual */ const char *GetScannerName() const { return "GS Libraries"; } - /* virtual */ void RegisterAPI(class Squirrel *engine); + void GetScriptName(ScriptInfo *info, char *name, const char *last) override; + const char *GetFileName() const override { return PATHSEP "library.nut"; } + Subdirectory GetDirectory() const override { return GAME_LIBRARY_DIR; } + const char *GetScannerName() const override { return "GS Libraries"; } + void RegisterAPI(class Squirrel *engine) override; }; #endif /* GAME_SCANNER_HPP */ diff --git a/src/game/game_text.cpp b/src/game/game_text.cpp index a32e5b41d7..64281c60cb 100644 --- a/src/game/game_text.cpp +++ b/src/game/game_text.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. @@ -23,6 +21,7 @@ #include "table/strings.h" #include +#include #include "../safeguards.h" @@ -62,11 +61,11 @@ void NORETURN CDECL strgen_fatal(const char *s, ...) /** * Create a new container for language strings. * @param language The language name. - * @param end If not NULL, terminate \a language at this position. + * @param end If not nullptr, terminate \a language at this position. */ LanguageStrings::LanguageStrings(const char *language, const char *end) { - this->language = stredup(language, end != NULL ? end - 1 : NULL); + this->language = stredup(language, end != nullptr ? end - 1 : nullptr); } /** Free everything. */ @@ -78,36 +77,31 @@ LanguageStrings::~LanguageStrings() /** * Read all the raw language strings from the given file. * @param file The file to read from. - * @return The raw strings, or NULL upon error. + * @return The raw strings, or nullptr upon error. */ -LanguageStrings *ReadRawLanguageStrings(const char *file) +std::unique_ptr ReadRawLanguageStrings(const char *file) { - LanguageStrings *ret = NULL; - FILE *fh = NULL; try { size_t to_read; - fh = FioFOpenFile(file, "rb", GAME_DIR, &to_read); - if (fh == NULL) { - return NULL; - } + FILE *fh = FioFOpenFile(file, "rb", GAME_DIR, &to_read); + if (fh == nullptr) return nullptr; + + FileCloser fhClose(fh); const char *langname = strrchr(file, PATHSEPCHAR); - if (langname == NULL) { + if (langname == nullptr) { langname = file; } else { langname++; } /* Check for invalid empty filename */ - if (*langname == '.' || *langname == 0) { - fclose(fh); - return NULL; - } + if (*langname == '.' || *langname == 0) return nullptr; - ret = new LanguageStrings(langname, strchr(langname, '.')); + std::unique_ptr ret(new LanguageStrings(langname, strchr(langname, '.'))); char buffer[2048]; - while (to_read != 0 && fgets(buffer, sizeof(buffer), fh) != NULL) { + while (to_read != 0 && fgets(buffer, sizeof(buffer), fh) != nullptr) { size_t len = strlen(buffer); /* Remove trailing spaces/newlines from the string. */ @@ -115,7 +109,7 @@ LanguageStrings *ReadRawLanguageStrings(const char *file) while (i > 0 && (buffer[i - 1] == '\r' || buffer[i - 1] == '\n' || buffer[i - 1] == ' ')) i--; buffer[i] = '\0'; - *ret->lines.Append() = stredup(buffer, buffer + to_read - 1); + ret->lines.emplace_back(buffer, i); if (len > to_read) { to_read = 0; @@ -124,20 +118,17 @@ LanguageStrings *ReadRawLanguageStrings(const char *file) } } - fclose(fh); return ret; } catch (...) { - if (fh != NULL) fclose(fh); - delete ret; - return NULL; + return nullptr; } } /** A reader that simply reads using fopen. */ struct StringListReader : StringReader { - const char * const *p; ///< The current location of the iteration. - const char * const *end; ///< The end of the iteration. + StringList::const_iterator p; ///< The current location of the iteration. + StringList::const_iterator end; ///< The end of the iteration. /** * Create the reader. @@ -146,16 +137,16 @@ struct StringListReader : StringReader { * @param master Are we reading the master file? * @param translation Are we reading a translation? */ - StringListReader(StringData &data, const LanguageStrings *strings, bool master, bool translation) : - StringReader(data, strings->language, master, translation), p(strings->lines.Begin()), end(strings->lines.End()) + StringListReader(StringData &data, const LanguageStrings &strings, bool master, bool translation) : + StringReader(data, strings.language, master, translation), p(strings.lines.begin()), end(strings.lines.end()) { } - /* virtual */ char *ReadLine(char *buffer, const char *last) + char *ReadLine(char *buffer, const char *last) override { - if (this->p == this->end) return NULL; + if (this->p == this->end) return nullptr; - strecpy(buffer, *this->p, last); + strecpy(buffer, this->p->c_str(), last); this->p++; return buffer; @@ -164,13 +155,13 @@ struct StringListReader : StringReader { /** Class for writing an encoded language. */ struct TranslationWriter : LanguageWriter { - StringList *strings; ///< The encoded strings. + StringList &strings; ///< The encoded strings. /** * Writer for the encoded data. * @param strings The string table to add the strings to. */ - TranslationWriter(StringList *strings) : strings(strings) + TranslationWriter(StringList &strings) : strings(strings) { } @@ -191,28 +182,25 @@ struct TranslationWriter : LanguageWriter { void Write(const byte *buffer, size_t length) { - char *dest = MallocT(length + 1); - memcpy(dest, buffer, length); - dest[length] = '\0'; - *this->strings->Append() = dest; + this->strings.emplace_back((const char *)buffer, length); } }; /** Class for writing the string IDs. */ struct StringNameWriter : HeaderWriter { - StringList *strings; ///< The string names. + StringList &strings; ///< The string names. /** * Writer for the string names. * @param strings The string table to add the strings to. */ - StringNameWriter(StringList *strings) : strings(strings) + StringNameWriter(StringList &strings) : strings(strings) { } void WriteStringID(const char *name, int stringid) { - if (stringid == (int)this->strings->Length()) *this->strings->Append() = stredup(name); + if (stringid == (int)this->strings.size()) this->strings.emplace_back(name); } void Finalise(const StringData &data) @@ -242,11 +230,14 @@ public: this->FileScanner::Scan(".txt", directory, false); } - /* virtual */ bool AddFile(const char *filename, size_t basepath_length, const char *tar_filename) + bool AddFile(const char *filename, size_t basepath_length, const char *tar_filename) override { if (strcmp(filename, exclude) == 0) return true; - *gs->raw_strings.Append() = ReadRawLanguageStrings(filename); + auto ls = ReadRawLanguageStrings(filename); + if (ls == nullptr) return false; + + gs->raw_strings.push_back(std::move(ls)); return true; } }; @@ -261,15 +252,18 @@ GameStrings *LoadTranslations() char filename[512]; strecpy(filename, info->GetMainScript(), lastof(filename)); char *e = strrchr(filename, PATHSEPCHAR); - if (e == NULL) return NULL; + if (e == nullptr) return nullptr; e++; // Make 'e' point after the PATHSEPCHAR strecpy(e, "lang" PATHSEP "english.txt", lastof(filename)); - if (!FioCheckFileExists(filename, GAME_DIR)) return NULL; + if (!FioCheckFileExists(filename, GAME_DIR)) return nullptr; + + auto ls = ReadRawLanguageStrings(filename); + if (ls == nullptr) return nullptr; GameStrings *gs = new GameStrings(); try { - *gs->raw_strings.Append() = ReadRawLanguageStrings(filename); + gs->raw_strings.push_back(std::move(ls)); /* Scan for other language files */ LanguageScanner scanner(gs, filename); @@ -278,7 +272,7 @@ GameStrings *LoadTranslations() const char *tar_filename = info->GetTarFile(); TarList::iterator iter; - if (tar_filename != NULL && (iter = _tar_list[GAME_DIR].find(tar_filename)) != _tar_list[GAME_DIR].end()) { + if (tar_filename != nullptr && (iter = _tar_list[GAME_DIR].find(tar_filename)) != _tar_list[GAME_DIR].end()) { /* The main script is in a tar file, so find all files that * are in the same tar and add them to the langfile scanner. */ TarFileList::iterator tar; @@ -301,37 +295,37 @@ GameStrings *LoadTranslations() return gs; } catch (...) { delete gs; - return NULL; + return nullptr; } } /** Compile the language. */ void GameStrings::Compile() { - StringData data(1); - StringListReader master_reader(data, this->raw_strings[0], true, false); + StringData data(32); + StringListReader master_reader(data, *this->raw_strings[0], true, false); master_reader.ParseFile(); if (_errors != 0) throw std::exception(); this->version = data.Version(); - StringNameWriter id_writer(&this->string_names); + StringNameWriter id_writer(this->string_names); id_writer.WriteHeader(data); - for (LanguageStrings **p = this->raw_strings.Begin(); p != this->raw_strings.End(); p++) { + for (const auto &p : this->raw_strings) { data.FreeTranslation(); - StringListReader translation_reader(data, *p, false, strcmp((*p)->language, "english") != 0); + StringListReader translation_reader(data, *p, false, strcmp(p->language, "english") != 0); translation_reader.ParseFile(); if (_errors != 0) throw std::exception(); - LanguageStrings *compiled = *this->compiled_strings.Append() = new LanguageStrings((*p)->language); - TranslationWriter writer(&compiled->lines); + this->compiled_strings.emplace_back(new LanguageStrings(p->language)); + TranslationWriter writer(this->compiled_strings.back()->lines); writer.WriteLang(data); } } /** The currently loaded game strings. */ -GameStrings *_current_data = NULL; +GameStrings *_current_data = nullptr; /** * Get the string pointer of a particular game string. @@ -340,8 +334,8 @@ GameStrings *_current_data = NULL; */ const char *GetGameStringPtr(uint id) { - if (id >= _current_data->cur_language->lines.Length()) return GetStringPtr(STR_UNDEFINED); - return _current_data->cur_language->lines[id]; + if (id >= _current_data->cur_language->lines.size()) return GetStringPtr(STR_UNDEFINED); + return _current_data->cur_language->lines[id].c_str(); } /** @@ -352,7 +346,7 @@ void RegisterGameTranslation(Squirrel *engine) { delete _current_data; _current_data = LoadTranslations(); - if (_current_data == NULL) return; + if (_current_data == nullptr) return; HSQUIRRELVM vm = engine->GetVM(); sq_pushroottable(vm); @@ -360,10 +354,11 @@ void RegisterGameTranslation(Squirrel *engine) if (SQ_FAILED(sq_get(vm, -2))) return; int idx = 0; - for (const char * const *p = _current_data->string_names.Begin(); p != _current_data->string_names.End(); p++, idx++) { - sq_pushstring(vm, *p, -1); + for (const auto &p : _current_data->string_names) { + sq_pushstring(vm, p.c_str(), -1); sq_pushinteger(vm, idx); sq_rawset(vm, -3); + idx++; } sq_pop(vm, 2); @@ -376,24 +371,24 @@ void RegisterGameTranslation(Squirrel *engine) */ void ReconsiderGameScriptLanguage() { - if (_current_data == NULL) return; + if (_current_data == nullptr) return; char temp[MAX_PATH]; strecpy(temp, _current_language->file, lastof(temp)); /* Remove the extension */ char *l = strrchr(temp, '.'); - assert(l != NULL); + assert(l != nullptr); *l = '\0'; /* Skip the path */ char *language = strrchr(temp, PATHSEPCHAR); - assert(language != NULL); + assert(language != nullptr); language++; - for (LanguageStrings **p = _current_data->compiled_strings.Begin(); p != _current_data->compiled_strings.End(); p++) { - if (strcmp((*p)->language, language) == 0) { - _current_data->cur_language = *p; + for (auto &p : _current_data->compiled_strings) { + if (strcmp(p->language, language) == 0) { + _current_data->cur_language = p; return; } } diff --git a/src/game/game_text.hpp b/src/game/game_text.hpp index 14da7d9b2e..20cccff54c 100644 --- a/src/game/game_text.hpp +++ b/src/game/game_text.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. @@ -23,18 +21,18 @@ struct LanguageStrings { const char *language; ///< Name of the language (base filename). StringList lines; ///< The lines of the file to pass into the parser/encoder. - LanguageStrings(const char *language, const char *end = NULL); + LanguageStrings(const char *language, const char *end = nullptr); ~LanguageStrings(); }; /** Container for all the game strings. */ struct GameStrings { - uint version; ///< The version of the language strings. - LanguageStrings *cur_language; ///< The current (compiled) language. + uint version; ///< The version of the language strings. + std::shared_ptr cur_language; ///< The current (compiled) language. - AutoDeleteSmallVector raw_strings; ///< The raw strings per language, first must be English/the master language!. - AutoDeleteSmallVector compiled_strings; ///< The compiled strings per language, first must be English/the master language!. - StringList string_names; ///< The names of the compiled strings. + 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. void Compile(); }; diff --git a/src/gamelog.cpp b/src/gamelog.cpp index 29910d7ad1..b325dc7fd3 100644 --- a/src/gamelog.cpp +++ b/src/gamelog.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. @@ -34,9 +32,9 @@ extern byte _sl_minor_version; ///< the minor savegame version, DO NOT USE! static GamelogActionType _gamelog_action_type = GLAT_NONE; ///< action to record if anything changes -LoggedAction *_gamelog_action = NULL; ///< first logged action +LoggedAction *_gamelog_action = nullptr; ///< first logged action uint _gamelog_actions = 0; ///< number of actions -static LoggedAction *_current_action = NULL; ///< current action we are logging, NULL when there is no action active +static LoggedAction *_current_action = nullptr; ///< current action we are logging, nullptr when there is no action active /** @@ -81,9 +79,9 @@ void GamelogStopAction() { assert(_gamelog_action_type != GLAT_NONE); // nobody should try to stop if there is no action in progress - bool print = _current_action != NULL; + bool print = _current_action != nullptr; - _current_action = NULL; + _current_action = nullptr; _gamelog_action_type = GLAT_NONE; if (print) GamelogPrintDebug(5); @@ -114,9 +112,9 @@ void GamelogReset() assert(_gamelog_action_type == GLAT_NONE); GamelogFree(_gamelog_action, _gamelog_actions); - _gamelog_action = NULL; + _gamelog_action = nullptr; _gamelog_actions = 0; - _current_action = NULL; + _current_action = nullptr; } /** @@ -132,18 +130,18 @@ static char *PrintGrfInfo(char *buf, const char *last, uint grfid, const uint8 * { char txt[40]; - if (md5sum != NULL) { + if (md5sum != nullptr) { md5sumToString(txt, lastof(txt), md5sum); buf += seprintf(buf, last, "GRF ID %08X, checksum %s", BSWAP32(grfid), txt); } else { buf += seprintf(buf, last, "GRF ID %08X", BSWAP32(grfid)); } - if (gc != NULL) { + if (gc != nullptr) { buf += seprintf(buf, last, ", filename: %s (md5sum matches)", gc->filename); } else { gc = FindGRFConfig(grfid, FGCM_ANY); - if (gc != NULL) { + if (gc != nullptr) { buf += seprintf(buf, last, ", filename: %s (matches GRFID only)", gc->filename); } else { buf += seprintf(buf, last, ", unknown GRF"); @@ -178,6 +176,7 @@ struct GRFPresence{ bool was_missing; ///< Grf was missing during some gameload in the past GRFPresence(const GRFConfig *gc) : gc(gc), was_missing(false) {} + GRFPresence() = default; }; typedef SmallMap GrfIDMapping; @@ -272,7 +271,7 @@ void GamelogPrint(GamelogPrintProc *proc) case GLCT_GRFREM: { 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, NULL, gm != grf_names.End() ? gm->second.gc : NULL); + buf = PrintGrfInfo(buf, lastof(buffer), lc->grfrem.grfid, nullptr, gm != grf_names.End() ? gm->second.gc : nullptr); if (gm == grf_names.End()) { buf += seprintf(buf, lastof(buffer), ". Gamelog inconsistency: GrfID was never added!"); } else { @@ -298,7 +297,7 @@ void GamelogPrint(GamelogPrintProc *proc) case GLCT_GRFPARAM: { 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, NULL, gm != grf_names.End() ? gm->second.gc : NULL); + buf = PrintGrfInfo(buf, lastof(buffer), lc->grfparam.grfid, nullptr, gm != grf_names.End() ? gm->second.gc : nullptr); if (gm == grf_names.End()) buf += seprintf(buf, lastof(buffer), ". Gamelog inconsistency: GrfID was never added!"); break; } @@ -307,7 +306,7 @@ void GamelogPrint(GamelogPrintProc *proc) 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" ); - buf = PrintGrfInfo(buf, lastof(buffer), lc->grfmove.grfid, NULL, gm != grf_names.End() ? gm->second.gc : NULL); + buf = PrintGrfInfo(buf, lastof(buffer), lc->grfmove.grfid, nullptr, gm != grf_names.End() ? gm->second.gc : nullptr); if (gm == grf_names.End()) buf += seprintf(buf, lastof(buffer), ". Gamelog inconsistency: GrfID was never added!"); break; } @@ -320,7 +319,7 @@ void GamelogPrint(GamelogPrintProc *proc) buf += seprintf(buf, lastof(buffer), "Rail vehicle changes length outside a depot: GRF ID %08X, internal ID 0x%X", BSWAP32(lc->grfbug.grfid), (uint)lc->grfbug.data); break; } - buf = PrintGrfInfo(buf, lastof(buffer), lc->grfbug.grfid, NULL, gm != grf_names.End() ? gm->second.gc : NULL); + buf = PrintGrfInfo(buf, lastof(buffer), lc->grfbug.grfid, nullptr, gm != grf_names.End() ? gm->second.gc : nullptr); if (gm == grf_names.End()) buf += seprintf(buf, lastof(buffer), ". Gamelog inconsistency: GrfID was never added!"); break; } @@ -371,21 +370,21 @@ void GamelogPrintDebug(int level) /** * Allocates new LoggedChange and new LoggedAction if needed. - * If there is no action active, NULL is returned. + * If there is no action active, nullptr is returned. * @param ct type of change - * @return new LoggedChange, or NULL if there is no action active + * @return new LoggedChange, or nullptr if there is no action active */ static LoggedChange *GamelogChange(GamelogChangeType ct) { - if (_current_action == NULL) { - if (_gamelog_action_type == GLAT_NONE) return NULL; + if (_current_action == nullptr) { + if (_gamelog_action_type == GLAT_NONE) return nullptr; _gamelog_action = ReallocT(_gamelog_action, _gamelog_actions + 1); _current_action = &_gamelog_action[_gamelog_actions++]; _current_action->at = _gamelog_action_type; _current_action->tick = _tick_counter; - _current_action->change = NULL; + _current_action->change = nullptr; _current_action->changes = 0; } @@ -415,7 +414,7 @@ void GamelogEmergency() */ bool GamelogTestEmergency() { - const LoggedChange *emergency = NULL; + const LoggedChange *emergency = nullptr; const LoggedAction *laend = &_gamelog_action[_gamelog_actions]; for (const LoggedAction *la = _gamelog_action; la != laend; la++) { @@ -425,7 +424,7 @@ bool GamelogTestEmergency() } } - return (emergency != NULL); + return (emergency != nullptr); } /** @@ -436,7 +435,7 @@ void GamelogRevision() assert(_gamelog_action_type == GLAT_START || _gamelog_action_type == GLAT_LOAD); LoggedChange *lc = GamelogChange(GLCT_REVISION); - if (lc == NULL) return; + if (lc == nullptr) return; memset(lc->revision.text, 0, sizeof(lc->revision.text)); strecpy(lc->revision.text, GetGamelogRevisionString(), lastof(lc->revision.text)); @@ -453,7 +452,7 @@ void GamelogMode() assert(_gamelog_action_type == GLAT_START || _gamelog_action_type == GLAT_LOAD || _gamelog_action_type == GLAT_CHEAT); LoggedChange *lc = GamelogChange(GLCT_MODE); - if (lc == NULL) return; + if (lc == nullptr) return; lc->mode.mode = _game_mode; lc->mode.landscape = _settings_game.game_creation.landscape; @@ -467,7 +466,7 @@ void GamelogOldver() assert(_gamelog_action_type == GLAT_LOAD); LoggedChange *lc = GamelogChange(GLCT_OLDVER); - if (lc == NULL) return; + if (lc == nullptr) return; lc->oldver.type = _savegame_type; lc->oldver.version = (_savegame_type == SGT_OTTD ? ((uint32)_sl_version << 8 | _sl_minor_version) : _ttdp_version); @@ -484,7 +483,7 @@ void GamelogSetting(const char *name, int32 oldval, int32 newval) assert(_gamelog_action_type == GLAT_SETTING); LoggedChange *lc = GamelogChange(GLCT_SETTING); - if (lc == NULL) return; + if (lc == nullptr) return; lc->setting.name = stredup(name); lc->setting.oldval = oldval; @@ -498,7 +497,7 @@ void GamelogSetting(const char *name, int32 oldval, int32 newval) */ void GamelogTestRevision() { - const LoggedChange *rev = NULL; + const LoggedChange *rev = nullptr; const LoggedAction *laend = &_gamelog_action[_gamelog_actions]; for (const LoggedAction *la = _gamelog_action; la != laend; la++) { @@ -508,7 +507,7 @@ void GamelogTestRevision() } } - if (rev == NULL || strcmp(rev->revision.text, GetGamelogRevisionString()) != 0 || + if (rev == nullptr || strcmp(rev->revision.text, GetGamelogRevisionString()) != 0 || rev->revision.modified != _openttd_revision_modified || rev->revision.newgrf != _openttd_newgrf_version) { GamelogRevision(); @@ -521,7 +520,7 @@ void GamelogTestRevision() */ void GamelogTestMode() { - const LoggedChange *mode = NULL; + const LoggedChange *mode = nullptr; const LoggedAction *laend = &_gamelog_action[_gamelog_actions]; for (const LoggedAction *la = _gamelog_action; la != laend; la++) { @@ -531,7 +530,7 @@ void GamelogTestMode() } } - if (mode == NULL || mode->mode.mode != _game_mode || mode->mode.landscape != _settings_game.game_creation.landscape) GamelogMode(); + if (mode == nullptr || mode->mode.mode != _game_mode || mode->mode.landscape != _settings_game.game_creation.landscape) GamelogMode(); } @@ -546,7 +545,7 @@ static void GamelogGRFBug(uint32 grfid, byte bug, uint64 data) assert(_gamelog_action_type == GLAT_GRFBUG); LoggedChange *lc = GamelogChange(GLCT_GRFBUG); - if (lc == NULL) return; + if (lc == nullptr) return; lc->grfbug.data = data; lc->grfbug.grfid = grfid; @@ -602,7 +601,7 @@ void GamelogGRFRemove(uint32 grfid) assert(_gamelog_action_type == GLAT_LOAD || _gamelog_action_type == GLAT_GRF); LoggedChange *lc = GamelogChange(GLCT_GRFREM); - if (lc == NULL) return; + if (lc == nullptr) return; lc->grfrem.grfid = grfid; } @@ -618,7 +617,7 @@ void GamelogGRFAdd(const GRFConfig *newg) if (!IsLoggableGrfConfig(newg)) return; LoggedChange *lc = GamelogChange(GLCT_GRFADD); - if (lc == NULL) return; + if (lc == nullptr) return; lc->grfadd = newg->ident; } @@ -633,7 +632,7 @@ void GamelogGRFCompatible(const GRFIdentifier *newg) assert(_gamelog_action_type == GLAT_LOAD || _gamelog_action_type == GLAT_GRF); LoggedChange *lc = GamelogChange(GLCT_GRFCOMPAT); - if (lc == NULL) return; + if (lc == nullptr) return; lc->grfcompat = *newg; } @@ -648,7 +647,7 @@ static void GamelogGRFMove(uint32 grfid, int32 offset) assert(_gamelog_action_type == GLAT_GRF); LoggedChange *lc = GamelogChange(GLCT_GRFMOVE); - if (lc == NULL) return; + if (lc == nullptr) return; lc->grfmove.grfid = grfid; lc->grfmove.offset = offset; @@ -664,7 +663,7 @@ static void GamelogGRFParameters(uint32 grfid) assert(_gamelog_action_type == GLAT_GRF); LoggedChange *lc = GamelogChange(GLCT_GRFPARAM); - if (lc == NULL) return; + if (lc == nullptr) return; lc->grfparam.grfid = grfid; } @@ -678,7 +677,7 @@ void GamelogGRFAddList(const GRFConfig *newg) { assert(_gamelog_action_type == GLAT_START || _gamelog_action_type == GLAT_LOAD); - for (; newg != NULL; newg = newg->next) { + for (; newg != nullptr; newg = newg->next) { GamelogGRFAdd(newg); } } @@ -696,14 +695,14 @@ struct GRFList { static GRFList *GenerateGRFList(const GRFConfig *grfc) { uint n = 0; - for (const GRFConfig *g = grfc; g != NULL; g = g->next) { + for (const GRFConfig *g = grfc; g != nullptr; g = g->next) { if (IsLoggableGrfConfig(g)) n++; } GRFList *list = (GRFList*)MallocT(sizeof(GRFList) + n * sizeof(GRFConfig*)); list->n = 0; - for (const GRFConfig *g = grfc; g != NULL; g = g->next) { + for (const GRFConfig *g = grfc; g != nullptr; g = g->next) { if (IsLoggableGrfConfig(g)) list->grf[list->n++] = g; } diff --git a/src/gamelog.h b/src/gamelog.h index 83694e3ea8..0f21fe0f1b 100644 --- a/src/gamelog.h +++ b/src/gamelog.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/gamelog_internal.h b/src/gamelog_internal.h index 261a8cd579..2b5c6ed0a1 100644 --- a/src/gamelog_internal.h +++ b/src/gamelog_internal.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/genworld.cpp b/src/genworld.cpp index 25d6a7bd9d..c76fe309d9 100644 --- a/src/genworld.cpp +++ b/src/genworld.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. @@ -34,6 +32,7 @@ #include "game/game.hpp" #include "game/game_instance.hpp" #include "string_func.h" +#include "thread.h" #include "safeguards.h" @@ -81,8 +80,8 @@ static void CleanupGeneration() /* Show all vital windows again, because we have hidden them */ if (_gw.threaded && _game_mode != GM_MENU) ShowVitalWindows(); SetModalProgress(false); - _gw.proc = NULL; - _gw.abortp = NULL; + _gw.proc = nullptr; + _gw.abortp = nullptr; _gw.threaded = false; DeleteWindowByClass(WC_MODAL_PROGRESS); @@ -93,14 +92,15 @@ static void CleanupGeneration() /** * The internal, real, generate function. */ -static void _GenerateWorld(void *) +static void _GenerateWorld() { /* Make sure everything is done via OWNER_NONE. */ - Backup _cur_company(_current_company, OWNER_NONE, FILE_LINE); + Backup _cur_company(_current_company, OWNER_NONE, FILE_LINE); + std::unique_lock lock(_modal_progress_work_mutex, std::defer_lock); try { _generating_world = true; - _modal_progress_work_mutex->BeginCritical(); + lock.lock(); if (_network_dedicated) DEBUG(net, 1, "Generating map, please wait..."); /* Set the Random() seed to generation_seed so we produce the same map with the same seed */ if (_settings_game.game_creation.generation_seed == GENERATE_NEW_SEED) _settings_game.game_creation.generation_seed = _settings_newgame.game_creation.generation_seed = InteractiveRandom(); @@ -133,11 +133,17 @@ static void _GenerateWorld(void *) GenerateLandscape(_gw.mode); GenerateClearTile(); - /* only generate towns, tree and industries in newgame mode. */ + /* Only generate towns, tree and industries in newgame mode. */ if (_game_mode != GM_EDITOR) { if (!GenerateTowns(_settings_game.economy.town_layout)) { _cur_company.Restore(); HandleGeneratingWorldAbortion(); + BasePersistentStorageArray::SwitchMode(PSM_LEAVE_GAMELOOP); + if (_network_dedicated) { + /* Exit the game to prevent a return to main menu. */ + DEBUG(net, 0, "Generating map failed, aborting"); + _exit_game = true; + } return; } GenerateIndustries(); @@ -169,7 +175,7 @@ static void _GenerateWorld(void *) if (_game_mode != GM_EDITOR) { Game::StartNew(); - if (Game::GetInstance() != NULL) { + if (Game::GetInstance() != nullptr) { SetGeneratingWorldProgress(GWP_RUNSCRIPT, 2500); _generating_world = true; for (i = 0; i < 2500; i++) { @@ -190,11 +196,11 @@ static void _GenerateWorld(void *) SetGeneratingWorldProgress(GWP_GAME_START, 1); /* Call any callback */ - if (_gw.proc != NULL) _gw.proc(); + if (_gw.proc != nullptr) _gw.proc(); IncreaseGeneratingWorldProgress(GWP_GAME_START); CleanupGeneration(); - _modal_progress_work_mutex->EndCritical(); + lock.unlock(); ShowNewGRFError(); @@ -210,7 +216,6 @@ static void _GenerateWorld(void *) BasePersistentStorageArray::SwitchMode(PSM_LEAVE_GAMELOOP, true); if (_cur_company.IsValid()) _cur_company.Restore(); _generating_world = false; - _modal_progress_work_mutex->EndCritical(); throw; } } @@ -241,17 +246,15 @@ void GenerateWorldSetAbortCallback(GWAbortProc *proc) */ void WaitTillGeneratedWorld() { - if (_gw.thread == NULL) return; + if (!_gw.thread.joinable()) return; - _modal_progress_work_mutex->EndCritical(); - _modal_progress_paint_mutex->EndCritical(); + _modal_progress_work_mutex.unlock(); + _modal_progress_paint_mutex.unlock(); _gw.quit_thread = true; - _gw.thread->Join(); - delete _gw.thread; - _gw.thread = NULL; + _gw.thread.join(); _gw.threaded = false; - _modal_progress_work_mutex->BeginCritical(); - _modal_progress_paint_mutex->BeginCritical(); + _modal_progress_work_mutex.lock(); + _modal_progress_paint_mutex.lock(); } /** @@ -279,11 +282,11 @@ void HandleGeneratingWorldAbortion() /* Clean up - in SE create an empty map, otherwise, go to intro menu */ _switch_mode = (_game_mode == GM_EDITOR) ? SM_EDITOR : SM_MENU; - if (_gw.abortp != NULL) _gw.abortp(); + if (_gw.abortp != nullptr) _gw.abortp(); CleanupGeneration(); - if (_gw.thread != NULL) _gw.thread->Exit(); + if (_gw.thread.joinable() && _gw.thread.get_id() == std::this_thread::get_id()) throw OTTDThreadExitSignal(); SwitchToMode(_switch_mode); } @@ -303,7 +306,7 @@ void GenerateWorld(GenWorldMode mode, uint size_x, uint size_y, bool reset_setti _gw.size_y = size_y; SetModalProgress(true); _gw.abort = false; - _gw.abortp = NULL; + _gw.abortp = nullptr; _gw.lc = _local_company; _gw.quit_thread = false; _gw.threaded = true; @@ -325,18 +328,14 @@ void GenerateWorld(GenWorldMode mode, uint size_x, uint size_y, bool reset_setti SetupColoursAndInitialWindow(); SetObjectToPlace(SPR_CURSOR_ZZZ, PAL_NONE, HT_NONE, WC_MAIN_WINDOW, 0); - if (_gw.thread != NULL) { - _gw.thread->Join(); - delete _gw.thread; - _gw.thread = NULL; - } + if (_gw.thread.joinable()) _gw.thread.join(); - if (!VideoDriver::GetInstance()->HasGUI() || !ThreadObject::New(&_GenerateWorld, NULL, &_gw.thread, "ottd:genworld")) { + if (!UseThreadedModelProgress() || !VideoDriver::GetInstance()->HasGUI() || !StartNewThread(&_gw.thread, "ottd:genworld", &_GenerateWorld)) { DEBUG(misc, 1, "Cannot create genworld thread, reverting to single-threaded mode"); _gw.threaded = false; - _modal_progress_work_mutex->EndCritical(); - _GenerateWorld(NULL); - _modal_progress_work_mutex->BeginCritical(); + _modal_progress_work_mutex.unlock(); + _GenerateWorld(); + _modal_progress_work_mutex.lock(); return; } @@ -350,7 +349,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) != NULL) { + if (FindWindowById(WC_MAIN_WINDOW, 0) != nullptr) { ScrollMainWindowToTile(TileXY(MapSizeX() / 2, MapSizeY() / 2), true); } } diff --git a/src/genworld.h b/src/genworld.h index 1b1c806e09..8014797125 100644 --- a/src/genworld.h +++ b/src/genworld.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. @@ -13,6 +11,7 @@ #define GENWORLD_H #include "company_type.h" +#include /** Constants related to world generation */ enum LandscapeGenerator { @@ -59,9 +58,9 @@ struct GenWorldInfo { CompanyID lc; ///< The local_company before generating uint size_x; ///< X-size of the map uint size_y; ///< Y-size of the map - GWDoneProc *proc; ///< Proc that is called when done (can be NULL) - GWAbortProc *abortp; ///< Proc that is called when aborting (can be NULL) - class ThreadObject *thread; ///< The thread we are in (can be NULL) + GWDoneProc *proc; ///< Proc that is called when done (can be nullptr) + GWAbortProc *abortp; ///< Proc that is called when aborting (can be nullptr) + std::thread thread; ///< The thread we are in (joinable if a thread was created) }; /** Current stage of world generation process */ diff --git a/src/genworld_gui.cpp b/src/genworld_gui.cpp index 76aa7a5452..aafb993af0 100644 --- a/src/genworld_gui.cpp +++ b/src/genworld_gui.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. @@ -263,14 +261,14 @@ static void LandscapeGenerationCallback(Window *w, bool confirmed) if (confirmed) StartGeneratingLandscape((GenerateLandscapeWindowMode)w->window_number); } -static DropDownList *BuildMapsizeDropDown() +static DropDownList BuildMapsizeDropDown() { - DropDownList *list = new DropDownList(); + DropDownList list; for (uint i = MIN_MAP_SIZE_BITS; i <= MAX_MAP_SIZE_BITS; i++) { DropDownListParamStringItem *item = new DropDownListParamStringItem(STR_JUST_INT, i, false); item->SetParam(0, 1LL << i); - *list->Append() = item; + list.emplace_back(item); } return list; @@ -313,7 +311,7 @@ struct GenerateLandscapeWindow : public Window { } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { switch (widget) { case WID_GL_START_DATE_TEXT: SetDParam(0, ConvertYMDToDate(_settings_newgame.game_creation.starting_year, 0, 1)); break; @@ -374,7 +372,7 @@ struct GenerateLandscapeWindow : public Window { * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; /* Update the climate buttons */ @@ -421,9 +419,9 @@ struct GenerateLandscapeWindow : public Window { } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { - const StringID *strs = NULL; + const StringID *strs = nullptr; switch (widget) { case WID_GL_MAX_HEIGHTLEVEL_TEXT: SetDParam(0, MAX_TILE_HEIGHT); @@ -493,7 +491,7 @@ struct GenerateLandscapeWindow : public Window { default: return; } - if (strs != NULL) { + if (strs != nullptr) { while (*strs != INVALID_STRING_ID) { *size = maxdim(*size, GetStringBoundingBox(*strs++)); } @@ -502,7 +500,7 @@ struct GenerateLandscapeWindow : public Window { size->height = max(size->height, (uint)(FONT_HEIGHT_NORMAL + WD_DROPDOWNTEXT_TOP + WD_DROPDOWNTEXT_BOTTOM)); } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { switch (widget) { case WID_GL_HEIGHTMAP_NAME_TEXT: { @@ -512,7 +510,7 @@ struct GenerateLandscapeWindow : public Window { } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_GL_TEMPERATE: @@ -687,7 +685,7 @@ struct GenerateLandscapeWindow : public Window { } } - virtual void OnTimeout() + void OnTimeout() override { static const int raise_widgets[] = {WID_GL_MAX_HEIGHTLEVEL_DOWN, WID_GL_MAX_HEIGHTLEVEL_UP, WID_GL_START_DATE_DOWN, WID_GL_START_DATE_UP, WID_GL_SNOW_LEVEL_UP, WID_GL_SNOW_LEVEL_DOWN, WIDGET_LIST_END}; for (const int *widget = raise_widgets; *widget != WIDGET_LIST_END; widget++) { @@ -698,7 +696,7 @@ struct GenerateLandscapeWindow : public Window { } } - virtual void OnDropdownSelect(int widget, int index) + void OnDropdownSelect(int widget, int index) override { switch (widget) { case WID_GL_MAPSIZE_X_PULLDOWN: _settings_newgame.game_creation.map_x = index; break; @@ -742,10 +740,10 @@ struct GenerateLandscapeWindow : public Window { this->InvalidateData(); } - virtual void OnQueryTextFinished(char *str) + void OnQueryTextFinished(char *str) override { /* Was 'cancel' pressed? */ - if (str == NULL) return; + if (str == nullptr) return; int32 value; if (!StrEmpty(str)) { @@ -792,14 +790,14 @@ struct GenerateLandscapeWindow : public Window { }; static WindowDesc _generate_landscape_desc( - WDP_CENTER, NULL, 0, 0, + WDP_CENTER, nullptr, 0, 0, WC_GENERATE_LANDSCAPE, WC_NONE, 0, _nested_generate_landscape_widgets, lengthof(_nested_generate_landscape_widgets) ); static WindowDesc _heightmap_load_desc( - WDP_CENTER, NULL, 0, 0, + WDP_CENTER, nullptr, 0, 0, WC_GENERATE_LANDSCAPE, WC_NONE, 0, _nested_heightmap_load_widgets, lengthof(_nested_heightmap_load_widgets) @@ -872,7 +870,7 @@ struct CreateScenarioWindow : public Window this->LowerWidget(_settings_newgame.game_creation.landscape + WID_CS_TEMPERATE); } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { switch (widget) { case WID_CS_START_DATE_TEXT: @@ -893,7 +891,7 @@ struct CreateScenarioWindow : public Window } } - virtual void OnPaint() + void OnPaint() override { this->SetWidgetDisabledState(WID_CS_START_DATE_DOWN, _settings_newgame.game_creation.starting_year <= MIN_YEAR); this->SetWidgetDisabledState(WID_CS_START_DATE_UP, _settings_newgame.game_creation.starting_year >= MAX_YEAR); @@ -908,7 +906,7 @@ struct CreateScenarioWindow : public Window this->DrawWidgets(); } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { StringID str = STR_JUST_INT; switch (widget) { @@ -936,7 +934,7 @@ struct CreateScenarioWindow : public Window size->height = GetMinSizing(NWST_BUTTON, size->height); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_CS_TEMPERATE: @@ -1001,7 +999,7 @@ struct CreateScenarioWindow : public Window } } - virtual void OnTimeout() + void OnTimeout() override { static const int raise_widgets[] = {WID_CS_START_DATE_DOWN, WID_CS_START_DATE_UP, WID_CS_FLAT_LAND_HEIGHT_DOWN, WID_CS_FLAT_LAND_HEIGHT_UP, WIDGET_LIST_END}; for (const int *widget = raise_widgets; *widget != WIDGET_LIST_END; widget++) { @@ -1012,7 +1010,7 @@ struct CreateScenarioWindow : public Window } } - virtual void OnDropdownSelect(int widget, int index) + void OnDropdownSelect(int widget, int index) override { switch (widget) { case WID_CS_MAPSIZE_X_PULLDOWN: _settings_newgame.game_creation.map_x = index; break; @@ -1021,7 +1019,7 @@ struct CreateScenarioWindow : public Window this->SetDirty(); } - virtual void OnQueryTextFinished(char *str) + void OnQueryTextFinished(char *str) override { if (!StrEmpty(str)) { int32 value = atoi(str); @@ -1101,7 +1099,7 @@ static const NWidgetPart _nested_create_scenario_widgets[] = { }; static WindowDesc _create_scenario_desc( - WDP_CENTER, NULL, 0, 0, + WDP_CENTER, nullptr, 0, 0, WC_GENERATE_LANDSCAPE, WC_NONE, 0, _nested_create_scenario_widgets, lengthof(_nested_create_scenario_widgets) @@ -1129,7 +1127,7 @@ static const NWidgetPart _nested_generate_progress_widgets[] = { static WindowDesc _generate_progress_desc( - WDP_CENTER, NULL, 0, 0, + WDP_CENTER, nullptr, 0, 0, WC_MODAL_PROGRESS, WC_NONE, 0, _nested_generate_progress_widgets, lengthof(_nested_generate_progress_widgets) @@ -1178,7 +1176,7 @@ struct GenerateProgressWindow : public Window { this->InitNested(); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_GP_ABORT: @@ -1193,7 +1191,7 @@ struct GenerateProgressWindow : public Window { } } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_GP_PROGRESS_BAR: { @@ -1214,7 +1212,7 @@ struct GenerateProgressWindow : public Window { } } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { switch (widget) { case WID_GP_PROGRESS_BAR: @@ -1312,10 +1310,10 @@ static void _SetGeneratingWorldProgress(GenWorldProgress cls, uint progress, uin * paint thread. The 'other' thread already has the paint thread rights so * this ensures us that we are waiting until the paint thread is done * before we reacquire the mapgen rights */ - _modal_progress_work_mutex->EndCritical(); - _modal_progress_paint_mutex->BeginCritical(); - _modal_progress_work_mutex->BeginCritical(); - _modal_progress_paint_mutex->EndCritical(); + _modal_progress_work_mutex.unlock(); + _modal_progress_paint_mutex.lock(); + _modal_progress_work_mutex.lock(); + _modal_progress_paint_mutex.unlock(); _gws.timer = _realtime_tick; } diff --git a/src/gfx.cpp b/src/gfx.cpp index 5ba8f0dc62..caf07ff2ac 100644 --- a/src/gfx.cpp +++ b/src/gfx.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. @@ -21,6 +19,7 @@ #include "network/network_func.h" #include "window_func.h" #include "newgrf_debug.h" +#include "thread.h" #include "table/palettes.h" #include "table/string_colours.h" @@ -50,20 +49,20 @@ bool _exit_game; bool _restart_game; GameMode _game_mode; SwitchMode _switch_mode; ///< The next mainloop command. -PauseModeByte _pause_mode; +PauseMode _pause_mode; Palette _cur_palette; static byte _stringwidth_table[FS_END][224]; ///< Cache containing width of often used characters. @see GetCharacterWidth() DrawPixelInfo *_cur_dpi; byte _colour_gradient[COLOUR_END][8]; -static void GfxMainBlitterViewport(const Sprite *sprite, int x, int y, BlitterMode mode, const SubSprite *sub = NULL, SpriteID sprite_id = SPR_CURSOR_MOUSE); -static void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode, const SubSprite *sub = NULL, SpriteID sprite_id = SPR_CURSOR_MOUSE, ZoomLevel zoom = ZOOM_LVL_NORMAL); +static void GfxMainBlitterViewport(const Sprite *sprite, int x, int y, BlitterMode mode, const SubSprite *sub = nullptr, SpriteID sprite_id = SPR_CURSOR_MOUSE); +static void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode, const SubSprite *sub = nullptr, SpriteID sprite_id = SPR_CURSOR_MOUSE, ZoomLevel zoom = ZOOM_LVL_NORMAL); static ReusableBuffer _cursor_backup; -ZoomLevelByte _gui_zoom; ///< GUI Zoom level -ZoomLevelByte _font_zoom; ///< Font Zoom level +ZoomLevel _gui_zoom; ///< GUI Zoom level +ZoomLevel _font_zoom; ///< Font Zoom level /** * The rect for repaint. @@ -80,7 +79,7 @@ static const uint DIRTY_BLOCK_HEIGHT = 8; static const uint DIRTY_BLOCK_WIDTH = 64; static uint _dirty_bytes_per_line = 0; -static byte *_dirty_blocks = NULL; +static byte *_dirty_blocks = nullptr; extern uint _dirty_block_colour; void GfxScroll(int left, int top, int width, int height, int xo, int yo) @@ -91,9 +90,7 @@ void GfxScroll(int left, int top, int width, int height, int xo, int yo) if (_cursor.visible) UndrawMouseCursor(); -#ifdef ENABLE_NETWORK if (_networking) NetworkUndrawChatMessage(); -#endif /* ENABLE_NETWORK */ blitter->ScrollBuffer(_screen.dst_ptr, left, top, width, height, xo, yo); /* This part of the screen is now dirty. */ @@ -162,6 +159,144 @@ void GfxFillRect(int left, int top, int right, int bottom, int colour, FillRectM } } +typedef std::pair LineSegment; + +/** + * Make line segments from a polygon defined by points, translated by an offset. + * Entirely horizontal lines (start and end at same Y coordinate) are skipped, as they are irrelevant to scanline conversion algorithms. + * Generated line segments always have the lowest Y coordinate point first, i.e. original direction is lost. + * @param shape The polygon to convert. + * @param offset Offset vector subtracted from all coordinates in the shape. + * @return Vector of undirected line segments. + */ +static std::vector MakePolygonSegments(const std::vector &shape, Point offset) +{ + std::vector segments; + if (shape.size() < 3) return segments; // fewer than 3 will always result in an empty polygon + segments.reserve(shape.size()); + + /* Connect first and last point by having initial previous point be the last */ + Point prev = shape.back(); + prev.x -= offset.x; + prev.y -= offset.y; + for (Point pt : shape) { + pt.x -= offset.x; + pt.y -= offset.y; + /* Create segments for all non-horizontal lines in the polygon. + * The segments always have lowest Y coordinate first. */ + if (prev.y > pt.y) { + segments.emplace_back(pt, prev); + } else if (prev.y < pt.y) { + segments.emplace_back(prev, pt); + } + prev = pt; + } + + return segments; +} + +/** + * Fill a polygon with colour. + * The odd-even winding rule is used, i.e. self-intersecting polygons will have holes in them. + * Left and top edges are inclusive, right and bottom edges are exclusive. + * @note For rectangles the GfxFillRect function will be faster. + * @pre dpi->zoom == ZOOM_LVL_NORMAL + * @param shape List of points on the polygon. + * @param colour An 8 bit palette index (FILLRECT_OPAQUE and FILLRECT_CHECKER) or a recolour spritenumber (FILLRECT_RECOLOUR). + * @param mode + * FILLRECT_OPAQUE: Fill the polygon with the specified colour. + * FILLRECT_CHECKER: Fill every other pixel with the specified colour, in a checkerboard pattern. + * FILLRECT_RECOLOUR: Apply a recolour sprite to every pixel in the polygon. + */ +void GfxFillPolygon(const std::vector &shape, int colour, FillRectMode mode) +{ + Blitter *blitter = BlitterFactory::GetCurrentBlitter(); + const DrawPixelInfo *dpi = _cur_dpi; + if (dpi->zoom != ZOOM_LVL_NORMAL) return; + + std::vector segments = MakePolygonSegments(shape, Point{ dpi->left, dpi->top }); + + /* Remove segments appearing entirely above or below the clipping area. */ + segments.erase(std::remove_if(segments.begin(), segments.end(), [dpi](const LineSegment &s) { return s.second.y <= 0 || s.first.y >= dpi->height; }), segments.end()); + + /* Check that this wasn't an empty shape (all points on a horizontal line or outside clipping.) */ + if (segments.empty()) return; + + /* Sort the segments by first point Y coordinate. */ + std::sort(segments.begin(), segments.end(), [](const LineSegment &a, const LineSegment &b) { return a.first.y < b.first.y; }); + + /* Segments intersecting current scanline. */ + std::vector active; + /* Intersection points with a scanline. + * Kept outside loop to avoid repeated re-allocations. */ + std::vector intersections; + /* Normal, reasonable polygons don't have many intersections per scanline. */ + active.reserve(4); + intersections.reserve(4); + + /* Scan through the segments and paint each scanline. */ + int y = segments.front().first.y; + std::vector::iterator nextseg = segments.begin(); + while (!active.empty() || nextseg != segments.end()) { + /* Clean up segments that have ended. */ + active.erase(std::remove_if(active.begin(), active.end(), [y](const LineSegment &s) { return s.second.y == y; }), active.end()); + + /* Activate all segments starting on this scanline. */ + while (nextseg != segments.end() && nextseg->first.y == y) { + active.push_back(*nextseg); + ++nextseg; + } + + /* Check clipping. */ + if (y < 0) { + ++y; + continue; + } + if (y >= dpi->height) return; + + /* Intersect scanline with all active segments. */ + intersections.clear(); + for (const LineSegment &s : active) { + const int sdx = s.second.x - s.first.x; + const int sdy = s.second.y - s.first.y; + const int ldy = y - s.first.y; + const int x = s.first.x + sdx * ldy / sdy; + intersections.push_back(x); + } + + /* Fill between pairs of intersections. */ + std::sort(intersections.begin(), intersections.end()); + for (size_t i = 1; i < intersections.size(); i += 2) { + /* Check clipping. */ + const int x1 = max(0, intersections[i - 1]); + const int x2 = min(intersections[i], dpi->width); + if (x2 < 0) continue; + if (x1 >= dpi->width) continue; + + /* Fill line y from x1 to x2. */ + void *dst = blitter->MoveTo(dpi->dst_ptr, x1, y); + switch (mode) { + default: // FILLRECT_OPAQUE + blitter->DrawRect(dst, x2 - x1, 1, (uint8)colour); + break; + case FILLRECT_RECOLOUR: + blitter->DrawColourMappingRect(dst, x2 - x1, 1, GB(colour, 0, PALETTE_WIDTH)); + break; + case FILLRECT_CHECKER: + /* Fill every other pixel, offset such that the sum of filled pixels' X and Y coordinates is odd. + * This creates a checkerboard effect. */ + for (int x = (x1 + y) & 1; x < x2 - x1; x += 2) { + blitter->SetPixel(dst, x, 0, (uint8)colour); + } + break; + } + } + + /* Next line */ + ++y; + } +} + /** * Check line clipping by using a linear equation and draw the visible part of * the line given by x/y and x2/y2. @@ -218,7 +353,7 @@ static inline void GfxDoDrawLine(void *video, int x, int y, int x2, int y2, int * work the blitter has to do by shortening the effective line segment. * However, in order to get that right and prevent the flickering effects * of rounding errors so much additional code has to be run here that in - * the general case the effect is not noticable. */ + * the general case the effect is not noticeable. */ blitter->DrawLine(video, x, y, x2, y2, screen_width, screen_height, colour, width, dash); } @@ -324,7 +459,7 @@ static void SetColourRemap(TextColour colour) * would be invisible at best, but it actually makes it illegible. */ bool no_shade = (colour & TC_NO_SHADE) != 0 || colour == TC_BLACK; bool raw_colour = (colour & TC_IS_PALETTE_COLOUR) != 0; - colour &= ~(TC_NO_SHADE | TC_IS_PALETTE_COLOUR); + colour &= ~(TC_NO_SHADE | TC_IS_PALETTE_COLOUR | TC_FORCED); _string_colourremap[1] = raw_colour ? (byte)colour : _string_colourmap[colour]; _string_colourremap[2] = no_shade ? 0 : 1; @@ -346,12 +481,12 @@ static void SetColourRemap(TextColour colour) * @return In case of left or center alignment the right most pixel we have drawn to. * In case of right alignment the left most pixel we have drawn to. */ -static int DrawLayoutLine(const ParagraphLayouter::Line *line, int y, int left, int right, StringAlignment align, bool underline, bool truncation) +static int DrawLayoutLine(const ParagraphLayouter::Line &line, int y, int left, int right, StringAlignment align, bool underline, bool truncation) { - if (line->CountRuns() == 0) return 0; + if (line.CountRuns() == 0) return 0; - int w = line->GetWidth(); - int h = line->GetLeading(); + int w = line.GetWidth(); + int h = line.GetLeading(); /* * The following is needed for truncation. @@ -373,7 +508,7 @@ static int DrawLayoutLine(const ParagraphLayouter::Line *line, int y, int left, truncation &= max_w < w; // Whether we need to do truncation. int dot_width = 0; // Cache for the width of the dot. - const Sprite *dot_sprite = NULL; // Cache for the sprite of the dot. + const Sprite *dot_sprite = nullptr; // Cache for the sprite of the dot. if (truncation) { /* @@ -382,7 +517,7 @@ static int DrawLayoutLine(const ParagraphLayouter::Line *line, int y, int left, * another size would be chosen it won't have truncated too little for * the truncation dots. */ - FontCache *fc = ((const Font*)line->GetVisualRun(0)->GetFont())->fc; + FontCache *fc = ((const Font*)line.GetVisualRun(0).GetFont())->fc; GlyphID dot_glyph = fc->MapCharToGlyph('.'); dot_width = fc->GetGlyphWidth(dot_glyph); dot_sprite = fc->GetGlyph(dot_glyph); @@ -427,9 +562,9 @@ static int DrawLayoutLine(const ParagraphLayouter::Line *line, int y, int left, TextColour colour = TC_BLACK; bool draw_shadow = false; - for (int run_index = 0; run_index < line->CountRuns(); run_index++) { - const ParagraphLayouter::VisualRun *run = line->GetVisualRun(run_index); - const Font *f = (const Font*)run->GetFont(); + for (int run_index = 0; run_index < line.CountRuns(); run_index++) { + const ParagraphLayouter::VisualRun &run = line.GetVisualRun(run_index); + const Font *f = (const Font*)run.GetFont(); FontCache *fc = f->fc; colour = f->colour; @@ -441,15 +576,15 @@ static int DrawLayoutLine(const ParagraphLayouter::Line *line, int y, int left, draw_shadow = fc->GetDrawGlyphShadow() && (colour & TC_NO_SHADE) == 0 && colour != TC_BLACK; - for (int i = 0; i < run->GetGlyphCount(); i++) { - GlyphID glyph = run->GetGlyphs()[i]; + for (int i = 0; i < run.GetGlyphCount(); i++) { + GlyphID glyph = run.GetGlyphs()[i]; /* Not a valid glyph (empty) */ if (glyph == 0xFFFF) continue; - int begin_x = (int)run->GetPositions()[i * 2] + left - offset_x; - int end_x = (int)run->GetPositions()[i * 2 + 2] + left - offset_x - 1; - int top = (int)run->GetPositions()[i * 2 + 1] + y; + int begin_x = (int)run.GetPositions()[i * 2] + left - offset_x; + int end_x = (int)run.GetPositions()[i * 2 + 2] + left - offset_x - 1; + int top = (int)run.GetPositions()[i * 2 + 1] + y; /* Truncated away. */ if (truncation && (begin_x < min_x || end_x > max_x)) continue; @@ -493,7 +628,8 @@ static int DrawLayoutLine(const ParagraphLayouter::Line *line, int y, int left, * @param right The right most position to draw on. * @param top The top most position to draw on. * @param str String to draw. - * @param colour Colour used for drawing the string, see DoDrawString() for details + * @param colour Colour used for drawing the string, for details see _string_colourmap in + * table/palettes.h or docs/ottd-colourtext-palette.png or the enum TextColour in gfx_type.h * @param align The alignment of the string when drawing left-to-right. In the * case a right-to-left language is chosen this is inverted so it * will be drawn in the right direction. @@ -516,9 +652,9 @@ int DrawString(int left, int right, int top, const char *str, TextColour colour, } Layouter layout(str, INT32_MAX, colour, fontsize); - if (layout.Length() == 0) return 0; + if (layout.size() == 0) return 0; - return DrawLayoutLine(*layout.Begin(), top, left, right, align, underline, true); + return DrawLayoutLine(*layout.front(), top, left, right, align, underline, true); } /** @@ -528,7 +664,8 @@ int DrawString(int left, int right, int top, const char *str, TextColour colour, * @param right The right most position to draw on. * @param top The top most position to draw on. * @param str String to draw. - * @param colour Colour used for drawing the string, see DoDrawString() for details + * @param colour Colour used for drawing the string, for details see _string_colourmap in + * table/palettes.h or docs/ottd-colourtext-palette.png or the enum TextColour in gfx_type.h * @param align The alignment of the string when drawing left-to-right. In the * case a right-to-left language is chosen this is inverted so it * will be drawn in the right direction. @@ -581,7 +718,7 @@ int GetStringLineCount(StringID str, int maxw) GetString(buffer, str, lastof(buffer)); Layouter layout(buffer, maxw); - return layout.Length(); + return (uint)layout.size(); } /** @@ -616,7 +753,8 @@ Dimension GetStringMultiLineBoundingBox(const char *str, const Dimension &sugges * @param top The top most position to draw on. * @param bottom The bottom most position to draw on. * @param str String to draw. - * @param colour Colour used for drawing the string, see DoDrawString() for details + * @param colour Colour used for drawing the string, for details see _string_colourmap in + * table/palettes.h or docs/ottd-colourtext-palette.png or the enum TextColour in gfx_type.h * @param align The horizontal and vertical alignment of the string. * @param underline Whether to underline all strings * @param fontsize The size of the initial characters. @@ -654,15 +792,14 @@ int DrawStringMultiLine(int left, int right, int top, int bottom, const char *st int last_line = top; int first_line = bottom; - for (const ParagraphLayouter::Line **iter = layout.Begin(); iter != layout.End(); iter++) { - const ParagraphLayouter::Line *line = *iter; + for (const auto &line : layout) { int line_height = line->GetLeading(); if (y >= top && y < bottom) { last_line = y + line_height; if (first_line > y) first_line = y; - DrawLayoutLine(line, y, left, right, align, underline, false); + DrawLayoutLine(*line, y, left, right, align, underline, false); } y += line_height; } @@ -678,7 +815,8 @@ int DrawStringMultiLine(int left, int right, int top, int bottom, const char *st * @param top The top most position to draw on. * @param bottom The bottom most position to draw on. * @param str String to draw. - * @param colour Colour used for drawing the string, see DoDrawString() for details + * @param colour Colour used for drawing the string, for details see _string_colourmap in + * table/palettes.h or docs/ottd-colourtext-palette.png or the enum TextColour in gfx_type.h * @param align The horizontal and vertical alignment of the string. * @param underline Whether to underline all strings * @param fontsize The size of the initial characters. @@ -741,11 +879,11 @@ Point GetCharPosInString(const char *str, const char *ch, FontSize start_fontsiz * @param str String to test. * @param x Position relative to the start of the string. * @param start_fontsize Font size to start the text with. - * @return Pointer to the character at the position or NULL if there is no character at the position. + * @return Pointer to the character at the position or nullptr if there is no character at the position. */ const char *GetCharAtPosition(const char *str, int x, FontSize start_fontsize) { - if (x < 0) return NULL; + if (x < 0) return nullptr; Layouter layout(str, INT32_MAX, TC_FROMSTRING, start_fontsize); return layout.GetCharAtPosition(x); @@ -756,7 +894,8 @@ const char *GetCharAtPosition(const char *str, int x, FontSize start_fontsize) * @param c Character (glyph) to draw * @param x X position to draw character * @param y Y position to draw character - * @param colour Colour to use, see DoDrawString() for details + * @param colour Colour to use, for details see _string_colourmap in + * table/palettes.h or docs/ottd-colourtext-palette.png or the enum TextColour in gfx_type.h */ void DrawCharCentered(WChar c, int x, int y, TextColour colour) { @@ -775,7 +914,7 @@ Dimension GetSpriteSize(SpriteID sprid, Point *offset, ZoomLevel zoom) { const Sprite *sprite = GetSprite(sprid, ST_NORMAL); - if (offset != NULL) { + if (offset != nullptr) { offset->x = UnScaleByZoom(sprite->x_offs, zoom); offset->y = UnScaleByZoom(sprite->y_offs, zoom); } @@ -925,7 +1064,7 @@ static void GfxBlitter(const Sprite * const sprite, int x, int y, BlitterMode mo x += sprite->x_offs; y += sprite->y_offs; - if (sub == NULL) { + if (sub == nullptr) { /* No clipping. */ bp.skip_left = 0; bp.skip_top = 0; @@ -1019,7 +1158,7 @@ static void GfxBlitter(const Sprite * const sprite, int x, int y, BlitterMode mo if (topleft <= clicked && clicked <= bottomright) { uint offset = (((size_t)clicked - (size_t)topleft) / (blitter->GetScreenDepth() / 8)) % bp.pitch; if (offset < (uint)bp.width) { - _newgrf_debug_sprite_picker.sprites.Include(sprite_id); + include(_newgrf_debug_sprite_picker.sprites, sprite_id); } } } @@ -1062,7 +1201,7 @@ void DoPaletteAnimations() uint i; uint j; - if (blitter != NULL && blitter->UsePaletteAnimation() == Blitter::PALETTE_ANIMATION_NONE) { + if (blitter != nullptr && blitter->UsePaletteAnimation() == Blitter::PALETTE_ANIMATION_NONE) { palette_animation_counter = 0; } @@ -1147,7 +1286,7 @@ void DoPaletteAnimations() if (j >= EPV_CYCLES_GLITTER_WATER) j -= EPV_CYCLES_GLITTER_WATER; } - if (blitter != NULL && blitter->UsePaletteAnimation() == Blitter::PALETTE_ANIMATION_NONE) { + if (blitter != nullptr && blitter->UsePaletteAnimation() == Blitter::PALETTE_ANIMATION_NONE) { palette_animation_counter = old_tc; } else { if (memcmp(old_val, &_cur_palette.palette[PALETTE_ANIM_START], sizeof(old_val)) != 0 && _cur_palette.count_dirty == 0) { @@ -1256,7 +1395,7 @@ void ScreenSizeChanged() void UndrawMouseCursor() { /* Don't undraw the mouse cursor if the screen is not ready */ - if (_screen.dst_ptr == NULL) return; + if (_screen.dst_ptr == nullptr) return; if (_cursor.visible) { Blitter *blitter = BlitterFactory::GetCurrentBlitter(); @@ -1269,7 +1408,7 @@ void UndrawMouseCursor() void DrawMouseCursor() { /* Don't draw the mouse cursor if the screen is not ready */ - if (_screen.dst_ptr == NULL) return; + if (_screen.dst_ptr == nullptr) return; Blitter *blitter = BlitterFactory::GetCurrentBlitter(); @@ -1339,9 +1478,7 @@ void RedrawScreenRect(int left, int top, int right, int bottom) } } -#ifdef ENABLE_NETWORK if (_networking) NetworkUndrawChatMessage(); -#endif /* ENABLE_NETWORK */ DrawOverlappedWindowForAll(left, top, right, bottom); @@ -1364,8 +1501,8 @@ void DrawDirtyBlocks() if (HasModalProgress()) { /* We are generating the world, so release our rights to the map and * painting while we are waiting a bit. */ - _modal_progress_paint_mutex->EndCritical(); - _modal_progress_work_mutex->EndCritical(); + _modal_progress_paint_mutex.unlock(); + _modal_progress_work_mutex.unlock(); /* Wait a while and update _realtime_tick so we are given the rights */ if (!IsFirstModalProgressLoop()) CSleep(MODAL_PROGRESS_REDRAW_TIMEOUT); @@ -1373,9 +1510,9 @@ void DrawDirtyBlocks() /* Modal progress thread may need blitter access while we are waiting for it. */ VideoDriver::GetInstance()->ReleaseBlitterLock(); - _modal_progress_paint_mutex->BeginCritical(); + _modal_progress_paint_mutex.lock(); VideoDriver::GetInstance()->AcquireBlitterLock(); - _modal_progress_work_mutex->BeginCritical(); + _modal_progress_work_mutex.lock(); /* When we ended with the modal progress, do not draw the blocks. * Simply let the next run do so, otherwise we would be loading @@ -1633,7 +1770,7 @@ static void SwitchAnimatedCursor() { const AnimCursor *cur = _cursor.animate_cur; - if (cur == NULL || cur->sprite == AnimCursor::LAST) cur = _cursor.animate_list; + if (cur == nullptr || cur->sprite == AnimCursor::LAST) cur = _cursor.animate_list; SetCursorSprite(cur->sprite, _cursor.sprite_seq[0].pal); @@ -1683,7 +1820,7 @@ void SetMouseCursor(CursorID sprite, PaletteID pal) void SetAnimatedMouseCursor(const AnimCursor *table) { _cursor.animate_list = table; - _cursor.animate_cur = NULL; + _cursor.animate_cur = nullptr; _cursor.sprite_seq[0].pal = PAL_NONE; SwitchAnimatedCursor(); } @@ -1724,7 +1861,7 @@ bool CursorVars::UpdateCursorPosition(int x, int y, bool queued_warp) if (this->delta.x != 0 || this->delta.y != 0) { /* Trigger warp. * Note: We also trigger warping again, if there is already a pending warp. - * This makes it more tolerant about the OS or other software inbetween + * This makes it more tolerant about the OS or other software in between * botchering the warp. */ this->queued_warp = queued_warp; need_warp = true; @@ -1746,22 +1883,15 @@ bool ChangeResInGame(int width, int height) bool ToggleFullScreen(bool fs) { bool result = VideoDriver::GetInstance()->ToggleFullscreen(fs); - if (_fullscreen != fs && _num_resolutions == 0) { + if (_fullscreen != fs && _resolutions.empty()) { DEBUG(driver, 0, "Could not find a suitable fullscreen resolution"); } return result; } -static int CDECL compare_res(const Dimension *pa, const Dimension *pb) +void SortResolutions() { - int x = pa->width - pb->width; - if (x != 0) return x; - return pa->height - pb->height; -} - -void SortResolutions(int count) -{ - QSortT(_resolutions, count, &compare_res); + std::sort(_resolutions.begin(), _resolutions.end()); } diff --git a/src/gfx_func.h b/src/gfx_func.h index 95ba2d3cd1..ac13e2fe5d 100644 --- a/src/gfx_func.h +++ b/src/gfx_func.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. @@ -31,7 +29,7 @@ * VideoDriver::MakeDirty and it is truncated back to an empty rectangle. At some * later point (which is uninteresting, too) the video driver * repaints all these saved rectangle instead of the whole screen and drop the - * rectangle informations. Then a new round begins by marking objects "dirty". + * rectangle information. Then a new round begins by marking objects "dirty". * * @see VideoDriver::MakeDirty * @see _invalid_rect @@ -70,16 +68,14 @@ extern Point _right_button_down_pos; extern DrawPixelInfo _screen; extern bool _screen_disable_anim; ///< Disable palette animation (important for 32bpp-anim blitter during giant screenshot) -extern int _num_resolutions; -extern Dimension _resolutions[100]; +extern std::vector _resolutions; extern Dimension _cur_resolution; extern Palette _cur_palette; ///< Current palette void HandleKeypress(uint keycode, WChar key); -void HandleTextInput(const char *str, bool marked = false, const char *caret = NULL, const char *insert_location = NULL, const char *replacement_end = NULL); +void HandleTextInput(const char *str, bool marked = false, const char *caret = nullptr, const char *insert_location = nullptr, const char *replacement_end = nullptr); void HandleCtrlChanged(); void HandleMouseEvents(); -void CSleep(int milliseconds); void UpdateWindows(); void DrawMouseCursor(); @@ -93,12 +89,12 @@ static const int DRAW_STRING_BUFFER = 2048; 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 = NULL, ZoomLevel zoom = ZOOM_LVL_GUI); -void DrawSpriteViewport(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub = NULL); -void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub = NULL, ZoomLevel zoom = ZOOM_LVL_GUI); -void DrawSpriteCentered(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub = NULL, ZoomLevel zoom = ZOOM_LVL_GUI); -void DrawSpriteCenteredRect(SpriteID img, PaletteID pal, int left, int top, int right, int bottom, const SubSprite *sub = NULL, ZoomLevel zoom = ZOOM_LVL_GUI); -void DrawSpriteCenteredRect(SpriteID img, PaletteID pal, const Rect &r, const SubSprite *sub = NULL, ZoomLevel zoom = ZOOM_LVL_GUI); +Dimension GetSpriteSize(SpriteID sprid, Point *offset = nullptr, ZoomLevel zoom = ZOOM_LVL_GUI); +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 DrawSpriteCentered(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub = nullptr, ZoomLevel zoom = ZOOM_LVL_GUI); +void DrawSpriteCenteredRect(SpriteID img, PaletteID pal, int left, int top, int right, int bottom, const SubSprite *sub = nullptr, ZoomLevel zoom = ZOOM_LVL_GUI); +void DrawSpriteCenteredRect(SpriteID img, PaletteID pal, const Rect &r, const SubSprite *sub = nullptr, ZoomLevel zoom = ZOOM_LVL_GUI); /** How to align the to-be drawn text. */ enum StringAlignment { @@ -126,6 +122,7 @@ int DrawStringMultiLine(int left, int right, int top, int bottom, StringID str, void DrawCharCentered(uint32 c, int x, int y, TextColour colour); void GfxFillRect(int left, int top, int right, int bottom, int colour, FillRectMode mode = FILLRECT_OPAQUE); +void GfxFillPolygon(const std::vector &shape, int colour, FillRectMode mode = FILLRECT_OPAQUE); 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); @@ -170,7 +167,7 @@ void SetAnimatedMouseCursor(const AnimCursor *table); void CursorTick(); void UpdateCursorSize(); bool ChangeResInGame(int w, int h); -void SortResolutions(int count); +void SortResolutions(); bool ToggleFullScreen(bool fs); /* gfx.cpp */ @@ -263,7 +260,14 @@ static const uint8 PC_VERY_LIGHT_YELLOW = 0x45; ///< Almost-white yel static const uint8 PC_GREEN = 0xD0; ///< Green palette colour. +static const uint8 PC_VERY_DARK_BLUE = 0x9A; ///< Almost-black blue palette colour. static const uint8 PC_DARK_BLUE = 0x9D; ///< Dark blue palette colour. static const uint8 PC_LIGHT_BLUE = 0x98; ///< Light blue palette colour. +static const uint8 PC_ROUGH_LAND = 0x52; ///< Dark green palette colour for rough land. +static const uint8 PC_GRASS_LAND = 0x54; ///< Dark green palette colour for grass land. +static const uint8 PC_BARE_LAND = 0x37; ///< Brown palette colour for bare land. +static const uint8 PC_FIELDS = 0x25; ///< Light brown palette colour for fields. +static const uint8 PC_TREES = 0x57; ///< Green palette colour for trees. +static const uint8 PC_WATER = 0xC9; ///< Dark blue palette colour for water. #endif /* GFX_FUNC_H */ diff --git a/src/gfx_layout.cpp b/src/gfx_layout.cpp index c65ead90e1..f093a53863 100644 --- a/src/gfx_layout.cpp +++ b/src/gfx_layout.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. @@ -17,9 +15,9 @@ #include "table/control_codes.h" -#ifdef WITH_ICU_LAYOUT +#ifdef WITH_ICU_LX #include -#endif /* WITH_ICU_LAYOUT */ +#endif /* WITH_ICU_LX */ #ifdef WITH_UNISCRIBE #include "os/windows/string_uniscribe.h" @@ -50,7 +48,7 @@ Font::Font(FontSize size, TextColour colour) : assert(size < FS_END); } -#ifdef WITH_ICU_LAYOUT +#ifdef WITH_ICU_LX /* Implementation details of LEFontInstance */ le_int32 Font::getUnitsPerEM() const @@ -124,7 +122,7 @@ le_bool Font::getGlyphPoint(LEGlyphID glyph, le_int32 pointNumber, LEPoint &poin /** * Wrapper for doing layouts with ICU. */ -class ICUParagraphLayout : public AutoDeleteSmallVector, public ParagraphLayouter { +class ICUParagraphLayout : public ParagraphLayouter { icu::ParagraphLayout *p; ///< The actual ICU paragraph layout. public: /** Visual run contains data about the bit of text with the same font. */ @@ -134,33 +132,33 @@ public: public: ICUVisualRun(const icu::ParagraphLayout::VisualRun *vr) : vr(vr) { } - const Font *GetFont() const { return (const Font*)vr->getFont(); } - int GetGlyphCount() const { return vr->getGlyphCount(); } - const GlyphID *GetGlyphs() const { return vr->getGlyphs(); } - const float *GetPositions() const { return vr->getPositions(); } - int GetLeading() const { return vr->getLeading(); } - const int *GetGlyphToCharMap() const { return vr->getGlyphToCharMap(); } + const Font *GetFont() const override { return (const Font*)vr->getFont(); } + int GetGlyphCount() const override { return vr->getGlyphCount(); } + const GlyphID *GetGlyphs() const override { return vr->getGlyphs(); } + const float *GetPositions() const override { return vr->getPositions(); } + int GetLeading() const override { return vr->getLeading(); } + const int *GetGlyphToCharMap() const override { return vr->getGlyphToCharMap(); } }; /** A single line worth of VisualRuns. */ - class ICULine : public AutoDeleteSmallVector, public ParagraphLayouter::Line { + class ICULine : public std::vector, public ParagraphLayouter::Line { icu::ParagraphLayout::Line *l; ///< The actual ICU line. public: ICULine(icu::ParagraphLayout::Line *l) : l(l) { for (int i = 0; i < l->countRuns(); i++) { - *this->Append() = new ICUVisualRun(l->getVisualRun(i)); + this->emplace_back(l->getVisualRun(i)); } } - ~ICULine() { delete l; } + ~ICULine() override { delete l; } - int GetLeading() const { return l->getLeading(); } - int GetWidth() const { return l->getWidth(); } - int CountRuns() const { return l->countRuns(); } - const ParagraphLayouter::VisualRun *GetVisualRun(int run) const { return *this->Get(run); } + int GetLeading() const override { return l->getLeading(); } + int GetWidth() const override { return l->getWidth(); } + int CountRuns() const override { return l->countRuns(); } + const ParagraphLayouter::VisualRun &GetVisualRun(int run) const override { return this->at(run); } - int GetInternalCharLength(WChar c) const + int GetInternalCharLength(WChar c) const override { /* ICU uses UTF-16 internally which means we need to account for surrogate pairs. */ return Utf8CharLen(c) < 4 ? 1 : 2; @@ -168,13 +166,13 @@ public: }; ICUParagraphLayout(icu::ParagraphLayout *p) : p(p) { } - ~ICUParagraphLayout() { delete p; } - void Reflow() { p->reflow(); } + ~ICUParagraphLayout() override { delete p; } + void Reflow() override { p->reflow(); } - ParagraphLayouter::Line *NextLine(int max_width) + std::unique_ptr NextLine(int max_width) override { icu::ParagraphLayout::Line *l = p->nextLine(max_width); - return l == NULL ? NULL : new ICULine(l); + return std::unique_ptr(l == nullptr ? nullptr : new ICULine(l)); } }; @@ -196,22 +194,22 @@ public: /* ICU's ParagraphLayout cannot handle empty strings, so fake one. */ buff[0] = ' '; length = 1; - fontMapping.End()[-1].first++; + fontMapping.back().first++; } /* Fill ICU's FontRuns with the right data. */ - icu::FontRuns runs(fontMapping.Length()); - for (FontMap::iterator iter = fontMapping.Begin(); iter != fontMapping.End(); iter++) { - runs.add(iter->second, iter->first); + icu::FontRuns runs(fontMapping.size()); + for (auto &pair : fontMapping) { + runs.add(pair.second, pair.first); } LEErrorCode status = LE_NO_ERROR; /* ParagraphLayout does not copy "buff", so it must stay valid. * "runs" is copied according to the ICU source, but the documentation does not specify anything, so this might break somewhen. */ - icu::ParagraphLayout *p = new icu::ParagraphLayout(buff, length, &runs, NULL, NULL, NULL, _current_text_dir == TD_RTL ? UBIDI_DEFAULT_RTL : UBIDI_DEFAULT_LTR, false, status); + icu::ParagraphLayout *p = new icu::ParagraphLayout(buff, length, &runs, nullptr, nullptr, nullptr, _current_text_dir == TD_RTL ? 1 : 0, false, status); if (status != LE_NO_ERROR) { delete p; - return NULL; + return nullptr; } return new ICUParagraphLayout(p); @@ -226,7 +224,7 @@ public: return length; } }; -#endif /* WITH_ICU_LAYOUT */ +#endif /* WITH_ICU_LX */ /*** Paragraph layout ***/ /** @@ -234,7 +232,7 @@ public: * visual runs. * * One constructs this class with the text that needs to be split into - * lines. Then nextLine is called with the maximum width until NULL is + * lines. Then nextLine is called with the maximum width until nullptr is * returned. Each nextLine call creates VisualRuns which contain the * length of text that are to be drawn with the same font. In other * words, the result of this class is a list of sub strings with their @@ -259,24 +257,25 @@ public: public: FallbackVisualRun(Font *font, const WChar *chars, int glyph_count, int x); - ~FallbackVisualRun(); - const Font *GetFont() const; - int GetGlyphCount() const; - const GlyphID *GetGlyphs() const; - const float *GetPositions() const; - int GetLeading() const; - const int *GetGlyphToCharMap() const; + FallbackVisualRun(FallbackVisualRun &&other) noexcept; + ~FallbackVisualRun() override; + const Font *GetFont() const override; + int GetGlyphCount() const override; + const GlyphID *GetGlyphs() const override; + const float *GetPositions() const override; + int GetLeading() const override; + const int *GetGlyphToCharMap() const override; }; /** A single line worth of VisualRuns. */ - class FallbackLine : public AutoDeleteSmallVector, public ParagraphLayouter::Line { + class FallbackLine : public std::vector, public ParagraphLayouter::Line { public: - int GetLeading() const; - int GetWidth() const; - int CountRuns() const; - const ParagraphLayouter::VisualRun *GetVisualRun(int run) const; + int GetLeading() const override; + int GetWidth() const override; + int CountRuns() const override; + const ParagraphLayouter::VisualRun &GetVisualRun(int run) const override; - int GetInternalCharLength(WChar c) const { return 1; } + int GetInternalCharLength(WChar c) const override { return 1; } }; const WChar *buffer_begin; ///< Begin of the buffer. @@ -284,8 +283,8 @@ public: FontMap &runs; ///< The fonts we have to use for this paragraph. FallbackParagraphLayout(WChar *buffer, int length, FontMap &runs); - void Reflow(); - const ParagraphLayouter::Line *NextLine(int max_width); + void Reflow() override; + std::unique_ptr NextLine(int max_width) override; }; /** @@ -350,6 +349,18 @@ FallbackParagraphLayout::FallbackVisualRun::FallbackVisualRun(Font *font, const } } +/** Move constructor for visual runs.*/ +FallbackParagraphLayout::FallbackVisualRun::FallbackVisualRun(FallbackVisualRun &&other) noexcept : font(other.font), glyph_count(other.glyph_count) +{ + this->positions = other.positions; + this->glyph_to_char = other.glyph_to_char; + this->glyphs = other.glyphs; + + other.positions = nullptr; + other.glyph_to_char = nullptr; + other.glyphs = nullptr; +} + /** Free all data. */ FallbackParagraphLayout::FallbackVisualRun::~FallbackVisualRun() { @@ -419,8 +430,8 @@ int FallbackParagraphLayout::FallbackVisualRun::GetLeading() const int FallbackParagraphLayout::FallbackLine::GetLeading() const { int leading = 0; - for (const FallbackVisualRun * const *run = this->Begin(); run != this->End(); run++) { - leading = max(leading, (*run)->GetLeading()); + for (const auto &run : *this) { + leading = max(leading, run.GetLeading()); } return leading; @@ -432,15 +443,15 @@ int FallbackParagraphLayout::FallbackLine::GetLeading() const */ int FallbackParagraphLayout::FallbackLine::GetWidth() const { - if (this->Length() == 0) return 0; + if (this->size() == 0) return 0; /* * The last X position of a run contains is the end of that run. * Since there is no left-to-right support, taking this value of * the last run gives us the end of the line and thus the width. */ - const ParagraphLayouter::VisualRun *run = this->GetVisualRun(this->CountRuns() - 1); - return (int)run->GetPositions()[run->GetGlyphCount() * 2]; + const auto &run = this->GetVisualRun(this->CountRuns() - 1); + return (int)run.GetPositions()[run.GetGlyphCount() * 2]; } /** @@ -449,16 +460,16 @@ int FallbackParagraphLayout::FallbackLine::GetWidth() const */ int FallbackParagraphLayout::FallbackLine::CountRuns() const { - return this->Length(); + return (uint)this->size(); } /** * Get a specific visual run. * @return The visual run. */ -const ParagraphLayouter::VisualRun *FallbackParagraphLayout::FallbackLine::GetVisualRun(int run) const +const ParagraphLayouter::VisualRun &FallbackParagraphLayout::FallbackLine::GetVisualRun(int run) const { - return *this->Get(run); + return this->at(run); } /** @@ -483,27 +494,27 @@ void FallbackParagraphLayout::Reflow() /** * Construct a new line with a maximum width. * @param max_width The maximum width of the string. - * @return A Line, or NULL when at the end of the paragraph. + * @return A Line, or nullptr when at the end of the paragraph. */ -const ParagraphLayouter::Line *FallbackParagraphLayout::NextLine(int max_width) +std::unique_ptr FallbackParagraphLayout::NextLine(int max_width) { /* Simple idea: * - split a line at a newline character, or at a space where we can break a line. * - split for a visual run whenever a new line happens, or the font changes. */ - if (this->buffer == NULL) return NULL; + if (this->buffer == nullptr) return nullptr; - FallbackLine *l = new FallbackLine(); + std::unique_ptr l(new FallbackLine()); if (*this->buffer == '\0') { /* Only a newline. */ - this->buffer = NULL; - *l->Append() = new FallbackVisualRun(this->runs.Begin()->second, this->buffer, 0, 0); + this->buffer = nullptr; + l->emplace_back(this->runs.front().second, this->buffer, 0, 0); return l; } int offset = this->buffer - this->buffer_begin; - FontMap::iterator iter = this->runs.Begin(); + FontMap::iterator iter = this->runs.data(); while (iter->first <= offset) { iter++; assert(iter != this->runs.End()); @@ -513,7 +524,7 @@ const ParagraphLayouter::Line *FallbackParagraphLayout::NextLine(int max_width) const WChar *next_run = this->buffer_begin + iter->first; const WChar *begin = this->buffer; - const WChar *last_space = NULL; + const WChar *last_space = nullptr; const WChar *last_char; int width = 0; for (;;) { @@ -521,20 +532,20 @@ const ParagraphLayouter::Line *FallbackParagraphLayout::NextLine(int max_width) last_char = this->buffer; if (c == '\0') { - this->buffer = NULL; + this->buffer = nullptr; break; } if (this->buffer == next_run) { int w = l->GetWidth(); - *l->Append() = new FallbackVisualRun(iter->second, begin, this->buffer - begin, w); + l->emplace_back(iter->second, begin, this->buffer - begin, w); iter++; assert(iter != this->runs.End()); next_run = this->buffer_begin + iter->first; begin = this->buffer; - last_space = NULL; + last_space = nullptr; } if (IsWhitespace(c)) last_space = this->buffer; @@ -548,11 +559,11 @@ const ParagraphLayouter::Line *FallbackParagraphLayout::NextLine(int max_width) if (width == char_width) { /* The character is wider than allowed width; don't know * what to do with this case... bail out! */ - this->buffer = NULL; + this->buffer = nullptr; return l; } - if (last_space == NULL) { + if (last_space == nullptr) { /* No space has been found. Just terminate at our current * location. This usually happens for languages that do not * require spaces in strings, like Chinese, Japanese and @@ -572,9 +583,9 @@ const ParagraphLayouter::Line *FallbackParagraphLayout::NextLine(int max_width) this->buffer++; } - if (l->Length() == 0 || last_char - begin != 0) { + if (l->size() == 0 || last_char - begin != 0) { int w = l->GetWidth(); - *l->Append() = new FallbackVisualRun(iter->second, begin, last_char - begin, w); + l->emplace_back(iter->second, begin, last_char - begin, w); } return l; } @@ -582,7 +593,7 @@ const ParagraphLayouter::Line *FallbackParagraphLayout::NextLine(int max_width) /** * Helper for getting a ParagraphLayouter of the given type. * - * @note In case no ParagraphLayouter could be constructed, line.layout will be NULL. + * @note In case no ParagraphLayouter could be constructed, line.layout will be nullptr. * @param line The cache item to store our layouter in. * @param str The string to create a layouter for. * @param state The state of the font and color. @@ -591,7 +602,7 @@ const ParagraphLayouter::Line *FallbackParagraphLayout::NextLine(int max_width) template static inline void GetLayouter(Layouter::LineCacheItem &line, const char *&str, FontState &state) { - if (line.buffer != NULL) free(line.buffer); + if (line.buffer != nullptr) free(line.buffer); typename T::CharType *buff_begin = MallocT(DRAW_STRING_BUFFER); const typename T::CharType *buffer_last = buff_begin + DRAW_STRING_BUFFER; @@ -600,7 +611,7 @@ static inline void GetLayouter(Layouter::LineCacheItem &line, const char *&str, Font *f = Layouter::GetFont(state.fontsize, state.cur_colour); line.buffer = buff_begin; - fontMapping.Clear(); + fontMapping.clear(); /* * Go through the whole string while adding Font instances to the font map @@ -666,7 +677,7 @@ Layouter::Layouter(const char *str, int maxw, TextColour colour, FontSize fontsi } LineCacheItem& line = GetCachedParagraphLayout(str, lineend - str, state); - if (line.layout != NULL) { + if (line.layout != nullptr) { /* Line is in cache */ str = lineend + 1; state = line.state_after; @@ -674,13 +685,13 @@ Layouter::Layouter(const char *str, int maxw, TextColour colour, FontSize fontsi } else { /* Line is new, layout it */ FontState old_state = state; -#if defined(WITH_ICU_LAYOUT) || defined(WITH_UNISCRIBE) || defined(WITH_COCOA) +#if defined(WITH_ICU_LX) || defined(WITH_UNISCRIBE) || defined(WITH_COCOA) const char *old_str = str; #endif -#ifdef WITH_ICU_LAYOUT +#ifdef WITH_ICU_LX GetLayouter(line, str, state); - if (line.layout == NULL) { + if (line.layout == nullptr) { static bool warned = false; if (!warned) { DEBUG(misc, 0, "ICU layouter bailed on the font. Falling back to the fallback layouter"); @@ -693,9 +704,9 @@ Layouter::Layouter(const char *str, int maxw, TextColour colour, FontSize fontsi #endif #ifdef WITH_UNISCRIBE - if (line.layout == NULL) { + if (line.layout == nullptr) { GetLayouter(line, str, state); - if (line.layout == NULL) { + if (line.layout == nullptr) { state = old_state; str = old_str; } @@ -703,26 +714,26 @@ Layouter::Layouter(const char *str, int maxw, TextColour colour, FontSize fontsi #endif #ifdef WITH_COCOA - if (line.layout == NULL) { + if (line.layout == nullptr) { GetLayouter(line, str, state); - if (line.layout == NULL) { + if (line.layout == nullptr) { state = old_state; str = old_str; } } #endif - if (line.layout == NULL) { + if (line.layout == nullptr) { GetLayouter(line, str, state); } } - /* Copy all lines into a local cache so we can reuse them later on more easily. */ - const ParagraphLayouter::Line *l; - while ((l = line.layout->NextLine(maxw)) != NULL) { - *this->Append() = l; + /* Move all lines into a local cache so we can reuse them later on more easily. */ + for (;;) { + auto l = line.layout->NextLine(maxw); + if (l == nullptr) break; + this->push_back(std::move(l)); } - } while (c != '\0'); } @@ -733,9 +744,9 @@ Layouter::Layouter(const char *str, int maxw, TextColour colour, FontSize fontsi Dimension Layouter::GetBounds() { Dimension d = { 0, 0 }; - for (const ParagraphLayouter::Line **l = this->Begin(); l != this->End(); l++) { - d.width = max(d.width, (*l)->GetWidth()); - d.height += (*l)->GetLeading(); + for (const auto &l : *this) { + d.width = max(d.width, l->GetWidth()); + d.height += l->GetLeading(); } return d; } @@ -757,12 +768,12 @@ Point Layouter::GetCharPosition(const char *ch) const size_t len = Utf8Decode(&c, str); if (c == '\0' || c == '\n') break; str += len; - index += (*this->Begin())->GetInternalCharLength(c); + index += this->front()->GetInternalCharLength(c); } if (str == ch) { /* Valid character. */ - const ParagraphLayouter::Line *line = *this->Begin(); + const auto &line = this->front(); /* Pointer to the end-of-string/line marker? Return total line width. */ if (*ch == '\0' || *ch == '\n') { @@ -772,12 +783,12 @@ Point Layouter::GetCharPosition(const char *ch) const /* Scan all runs until we've found our code point index. */ for (int run_index = 0; run_index < line->CountRuns(); run_index++) { - const ParagraphLayouter::VisualRun *run = line->GetVisualRun(run_index); + const ParagraphLayouter::VisualRun &run = line->GetVisualRun(run_index); - for (int i = 0; i < run->GetGlyphCount(); i++) { + for (int i = 0; i < run.GetGlyphCount(); i++) { /* Matching glyph? Return position. */ - if ((size_t)run->GetGlyphToCharMap()[i] == index) { - Point p = { (int)run->GetPositions()[i * 2], (int)run->GetPositions()[i * 2 + 1] }; + if ((size_t)run.GetGlyphToCharMap()[i] == index) { + Point p = { (int)run.GetPositions()[i * 2], (int)run.GetPositions()[i * 2 + 1] }; return p; } } @@ -791,25 +802,25 @@ Point Layouter::GetCharPosition(const char *ch) const /** * Get the character that is at a position. * @param x Position in the string. - * @return Pointer to the character at the position or NULL if no character is at the position. + * @return Pointer to the character at the position or nullptr if no character is at the position. */ const char *Layouter::GetCharAtPosition(int x) const { - const ParagraphLayouter::Line *line = *this->Begin(); + const auto &line = this->front(); for (int run_index = 0; run_index < line->CountRuns(); run_index++) { - const ParagraphLayouter::VisualRun *run = line->GetVisualRun(run_index); + const ParagraphLayouter::VisualRun &run = line->GetVisualRun(run_index); - for (int i = 0; i < run->GetGlyphCount(); i++) { + for (int i = 0; i < run.GetGlyphCount(); i++) { /* Not a valid glyph (empty). */ - if (run->GetGlyphs()[i] == 0xFFFF) continue; + if (run.GetGlyphs()[i] == 0xFFFF) continue; - int begin_x = (int)run->GetPositions()[i * 2]; - int end_x = (int)run->GetPositions()[i * 2 + 2]; + int begin_x = (int)run.GetPositions()[i * 2]; + int end_x = (int)run.GetPositions()[i * 2 + 2]; if (IsInsideMM(x, begin_x, end_x)) { /* Found our glyph, now convert to UTF-8 string index. */ - size_t index = run->GetGlyphToCharMap()[i]; + size_t index = run.GetGlyphToCharMap()[i]; size_t cur_idx = 0; for (const char *str = this->string; *str != '\0'; ) { @@ -822,7 +833,7 @@ const char *Layouter::GetCharAtPosition(int x) const } } - return NULL; + return nullptr; } /** @@ -834,7 +845,7 @@ Font *Layouter::GetFont(FontSize size, TextColour colour) if (it != fonts[size].End()) return it->second; Font *f = new Font(size, colour); - *fonts[size].Append() = FontColourMap::Pair(colour, f); + fonts[size].emplace_back(colour, f); return f; } @@ -844,10 +855,10 @@ Font *Layouter::GetFont(FontSize size, TextColour colour) */ void Layouter::ResetFontCache(FontSize size) { - for (FontColourMap::iterator it = fonts[size].Begin(); it != fonts[size].End(); ++it) { - delete it->second; + for (auto &pair : fonts[size]) { + delete pair.second; } - fonts[size].Clear(); + fonts[size].clear(); /* We must reset the linecache since it references the just freed fonts */ ResetLineCache(); @@ -870,7 +881,7 @@ void Layouter::ResetFontCache(FontSize size) */ Layouter::LineCacheItem &Layouter::GetCachedParagraphLayout(const char *str, size_t len, const FontState &state) { - if (linecache == NULL) { + if (linecache == nullptr) { /* Create linecache on first access to avoid trouble with initialisation order of static variables. */ linecache = new LineCache(); } @@ -886,7 +897,7 @@ Layouter::LineCacheItem &Layouter::GetCachedParagraphLayout(const char *str, siz */ void Layouter::ResetLineCache() { - if (linecache != NULL) linecache->clear(); + if (linecache != nullptr) linecache->clear(); } /** @@ -894,7 +905,7 @@ void Layouter::ResetLineCache() */ void Layouter::ReduceLineCache() { - if (linecache != NULL) { + if (linecache != nullptr) { /* TODO LRU cache would be fancy, but not exactly necessary */ if (linecache->size() > 4096) ResetLineCache(); } diff --git a/src/gfx_layout.h b/src/gfx_layout.h index 94cbac073a..4854be6e55 100644 --- a/src/gfx_layout.h +++ b/src/gfx_layout.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. @@ -21,12 +19,12 @@ #include #include -#ifdef WITH_ICU_LAYOUT +#ifdef WITH_ICU_LX #include "layout/ParagraphLayout.h" #define ICU_FONTINSTANCE : public icu::LEFontInstance -#else /* WITH_ICU_LAYOUT */ +#else /* WITH_ICU_LX */ #define ICU_FONTINSTANCE -#endif /* WITH_ICU_LAYOUT */ +#endif /* WITH_ICU_LX */ /** * Text drawing parameters, which can change while drawing a line, but are kept between multiple parts @@ -48,7 +46,7 @@ struct FontState { inline void SetColour(TextColour c) { assert(c >= TC_BLUE && c <= TC_BLACK); - this->cur_colour = c; + if ((this->cur_colour & TC_FORCED) == 0) this->cur_colour = c; } /** @@ -89,7 +87,7 @@ public: Font(FontSize size, TextColour colour); -#ifdef WITH_ICU_LAYOUT +#ifdef WITH_ICU_LX /* Implementation details of LEFontInstance */ le_int32 getUnitsPerEM() const; @@ -105,7 +103,7 @@ public: LEGlyphID mapCharToGlyph(LEUnicode32 ch) const; void getGlyphAdvance(LEGlyphID glyph, LEPoint &advance) const; le_bool getGlyphPoint(LEGlyphID glyph, le_int32 pointNumber, LEPoint &point) const; -#endif /* WITH_ICU_LAYOUT */ +#endif /* WITH_ICU_LX */ }; /** Mapping from index to font. */ @@ -137,12 +135,12 @@ public: virtual int GetLeading() const = 0; virtual int GetWidth() const = 0; virtual int CountRuns() const = 0; - virtual const VisualRun *GetVisualRun(int run) const = 0; + virtual const VisualRun &GetVisualRun(int run) const = 0; virtual int GetInternalCharLength(WChar c) const = 0; }; virtual void Reflow() = 0; - virtual const Line *NextLine(int max_width) = 0; + virtual std::unique_ptr NextLine(int max_width) = 0; }; /** @@ -150,7 +148,7 @@ public: * * It also accounts for the memory allocations and frees. */ -class Layouter : public AutoDeleteSmallVector { +class Layouter : public std::vector> { const char *string; ///< Pointer to the original string. /** Key into the linecache */ @@ -177,7 +175,7 @@ public: FontState state_after; ///< Font state after the line. ParagraphLayouter *layout; ///< Layout of the line. - LineCacheItem() : buffer(NULL), layout(NULL) {} + LineCacheItem() : buffer(nullptr), layout(nullptr) {} ~LineCacheItem() { delete layout; free(buffer); } }; private: diff --git a/src/gfx_type.h b/src/gfx_type.h index 7eeddb4078..6fca2228df 100644 --- a/src/gfx_type.h +++ b/src/gfx_type.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. @@ -269,6 +267,7 @@ enum TextColour { TC_IS_PALETTE_COLOUR = 0x100, ///< Colour value is already a real palette colour index, not an index of a StringColour. TC_NO_SHADE = 0x200, ///< Do not add shading to this text colour. + TC_FORCED = 0x400, ///< Ignore colour changes from strings. }; DECLARE_ENUM_AS_BIT_SET(TextColour) @@ -294,7 +293,7 @@ enum PaletteType { }; /** Types of sprites that might be loaded */ -enum SpriteType { +enum SpriteType : byte { ST_NORMAL = 0, ///< The most basic (normal) sprite ST_MAPGEN = 1, ///< Special sprite for the map generator ST_FONT = 2, ///< A sprite used for fonts diff --git a/src/gfxinit.cpp b/src/gfxinit.cpp index 3613ce0d86..86dc868e6b 100644 --- a/src/gfxinit.cpp +++ b/src/gfxinit.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. @@ -120,7 +118,7 @@ static void LoadGrfFileIndexed(const char *filename, const SpriteID *index_tbl, */ void CheckExternalFiles() { - if (BaseGraphics::GetUsedSet() == NULL || BaseSounds::GetUsedSet() == NULL) return; + if (BaseGraphics::GetUsedSet() == nullptr || BaseSounds::GetUsedSet() == nullptr) return; const GraphicsSet *used_set = BaseGraphics::GetUsedSet(); @@ -265,7 +263,7 @@ static bool SwitchNewGRFBlitter() */ uint depth_wanted_by_base = BaseGraphics::GetUsedSet()->blitter == BLT_32BPP ? 32 : 8; uint depth_wanted_by_grf = _support8bpp == S8BPP_NONE ? 32 : 8; - for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) { + for (GRFConfig *c = _grfconfig; c != nullptr; c = c->next) { if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND || HasBit(c->flags, GCF_INIT_ONLY)) continue; if (c->palette & GRFP_BLT_32BPP) depth_wanted_by_grf = 32; } @@ -307,18 +305,18 @@ static bool SwitchNewGRFBlitter() VideoDriver::GetInstance()->ReleaseBlitterLock(); return false; } - if (BlitterFactory::GetBlitterFactory(repl_blitter) == NULL) continue; + if (BlitterFactory::GetBlitterFactory(repl_blitter) == nullptr) continue; DEBUG(misc, 1, "Switching blitter from '%s' to '%s'... ", cur_blitter, repl_blitter); Blitter *new_blitter = BlitterFactory::SelectBlitter(repl_blitter); - if (new_blitter == NULL) NOT_REACHED(); + if (new_blitter == nullptr) NOT_REACHED(); DEBUG(misc, 1, "Successfully switched to %s.", repl_blitter); break; } if (!VideoDriver::GetInstance()->AfterBlitterChange()) { /* Failed to switch blitter, let's hope we can return to the old one. */ - if (BlitterFactory::SelectBlitter(cur_blitter) == NULL || !VideoDriver::GetInstance()->AfterBlitterChange()) usererror("Failed to reinitialize video driver. Specify a fixed blitter in the config"); + if (BlitterFactory::SelectBlitter(cur_blitter) == nullptr || !VideoDriver::GetInstance()->AfterBlitterChange()) usererror("Failed to reinitialize video driver. Specify a fixed blitter in the config"); } VideoDriver::GetInstance()->ReleaseBlitterLock(); @@ -362,7 +360,7 @@ bool GraphicsSet::FillSetDetails(IniFile *ini, const char *path, const char *ful /* Get optional blitter information. */ item = metadata->GetItem("blitter", false); - this->blitter = (item != NULL && *item->value == '3') ? BLT_32BPP : BLT_8BPP; + this->blitter = (item != nullptr && *item->value == '3') ? BLT_32BPP : BLT_8BPP; } return ret; } @@ -380,7 +378,7 @@ bool GraphicsSet::FillSetDetails(IniFile *ini, const char *path, const char *ful { size_t size = 0; FILE *f = FioFOpenFile(file->filename, "rb", subdir, &size); - if (f == NULL) return MD5File::CR_NO_FILE; + if (f == nullptr) return MD5File::CR_NO_FILE; size_t max = GRFGetSizeOfDataSection(f); @@ -404,7 +402,7 @@ MD5File::ChecksumResult MD5File::CheckMD5(Subdirectory subdir, size_t max_size) size_t size; FILE *f = FioFOpenFile(this->filename, "rb", subdir, &size); - if (f == NULL) return CR_NO_FILE; + if (f == nullptr) return CR_NO_FILE; size = min(size, max_size); @@ -434,14 +432,14 @@ template template /* static */ bool BaseMedia::DetermineBestSet() { - if (BaseMedia::used_set != NULL) return true; + if (BaseMedia::used_set != nullptr) return true; - const Tbase_set *best = NULL; - for (const Tbase_set *c = BaseMedia::available_sets; c != NULL; c = c->next) { + const Tbase_set *best = nullptr; + for (const Tbase_set *c = BaseMedia::available_sets; c != nullptr; c = c->next) { /* Skip unusable sets */ if (c->GetNumMissing() != 0) continue; - if (best == NULL || + if (best == nullptr || (best->fallback && !c->fallback) || best->valid_files < c->valid_files || (best->valid_files == c->valid_files && ( @@ -452,7 +450,7 @@ template } BaseMedia::used_set = best; - return BaseMedia::used_set != NULL; + return BaseMedia::used_set != nullptr; } template diff --git a/src/gfxinit.h b/src/gfxinit.h index 5bf0bff5ca..76f19135c3 100644 --- a/src/gfxinit.h +++ b/src/gfxinit.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/goal.cpp b/src/goal.cpp index f7aae350e5..9c9441e9ee 100644 --- a/src/goal.cpp +++ b/src/goal.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. @@ -79,7 +77,7 @@ CommandCost CmdCreateGoal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 case GT_STORY_PAGE: { if (!StoryPage::IsValidID(p2)) return CMD_ERROR; - CompanyByte story_company = StoryPage::Get(p2)->company; + CompanyID story_company = StoryPage::Get(p2)->company; if (company == INVALID_COMPANY ? story_company != INVALID_COMPANY : story_company != INVALID_COMPANY && story_company != company) return CMD_ERROR; break; } @@ -93,7 +91,7 @@ CommandCost CmdCreateGoal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 g->dst = p2; g->company = company; g->text = stredup(text); - g->progress = NULL; + g->progress = nullptr; g->completed = false; if (g->company == INVALID_COMPANY) { @@ -187,7 +185,7 @@ CommandCost CmdSetGoalProgress(TileIndex tile, DoCommandFlag flags, uint32 p1, u Goal *g = Goal::Get(p1); free(g->progress); if (StrEmpty(text)) { - g->progress = NULL; + g->progress = nullptr; } else { g->progress = stredup(text); } @@ -236,10 +234,11 @@ CommandCost CmdSetGoalCompleted(TileIndex tile, DoCommandFlag flags, uint32 p1, * @param flags type of operation * @param p1 various bitstuffed elements * - p1 = (bit 0 - 15) - Unique ID to use for this question. - * - p1 = (bit 16 - 23) - Company or client for which this question is. - * - p1 = (bit 24 - 25) - Question type. - * - p1 = (bit 31) - Question target: 0 - company, 1 - client. - * @param p2 Buttons of the question. + * - p1 = (bit 16 - 31) - Company or client for which this question is. + * @param p2 various bitstuffed elements + * - p2 = (bit 0 - 17) - Buttons of the question. + * - p2 = (bit 29 - 30) - Question type. + * - p2 = (bit 31) - Question target: 0 - company, 1 - client. * @param text Text of the question. * @return the cost of this operation or an error */ @@ -247,37 +246,31 @@ CommandCost CmdGoalQuestion(TileIndex tile, DoCommandFlag flags, uint32 p1, uint { uint16 uniqueid = (GoalType)GB(p1, 0, 16); CompanyID company = (CompanyID)GB(p1, 16, 8); -#ifdef ENABLE_NETWORK - ClientIndex client = (ClientIndex)GB(p1, 16, 8); -#endif - byte type = GB(p1, 24, 2); - bool is_client = HasBit(p1, 31); + ClientID client = (ClientID)GB(p1, 16, 16); + + assert_compile(GOAL_QUESTION_BUTTON_COUNT < 29); + uint32 button_mask = GB(p2, 0, GOAL_QUESTION_BUTTON_COUNT); + byte type = GB(p2, 29, 2); + bool is_client = HasBit(p2, 31); if (_current_company != OWNER_DEITY) return CMD_ERROR; if (StrEmpty(text)) return CMD_ERROR; if (is_client) { -#ifdef ENABLE_NETWORK - if (!NetworkClientInfo::IsValidID(client)) return CMD_ERROR; -#else - return CMD_ERROR; -#endif + if (NetworkClientInfo::GetByClientID(client) == nullptr) return CMD_ERROR; } else { if (company != INVALID_COMPANY && !Company::IsValidID(company)) return CMD_ERROR; } - if (CountBits(p2) < 1 || CountBits(p2) > 3) return CMD_ERROR; - if (p2 >= (1 << GOAL_QUESTION_BUTTON_COUNT)) return CMD_ERROR; + if (CountBits(button_mask) < 1 || CountBits(button_mask) > 3) return CMD_ERROR; if (type >= GOAL_QUESTION_TYPE_COUNT) return CMD_ERROR; if (flags & DC_EXEC) { if (is_client) { -#ifdef ENABLE_NETWORK - if (NetworkClientInfo::Get(client)->client_id != _network_own_client_id) return CommandCost(); -#endif + if (client != _network_own_client_id) return CommandCost(); } else { if (company == INVALID_COMPANY && !Company::IsValidID(_local_company)) return CommandCost(); if (company != INVALID_COMPANY && company != _local_company) return CommandCost(); } - ShowGoalQuestion(uniqueid, type, p2, text); + ShowGoalQuestion(uniqueid, type, button_mask, text); } return CommandCost(); diff --git a/src/goal_base.h b/src/goal_base.h index 7453196c8e..ceeb0ef933 100644 --- a/src/goal_base.h +++ b/src/goal_base.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. @@ -21,12 +19,12 @@ extern GoalPool _goal_pool; /** Struct about goals, current and completed */ struct Goal : GoalPool::PoolItem<&_goal_pool> { - CompanyByte company; ///< Goal is for a specific company; INVALID_COMPANY if it is global - GoalTypeByte type; ///< Type of the goal - GoalTypeID dst; ///< Index of type - char *text; ///< Text of the goal. - char *progress; ///< Progress text of the goal. - bool completed; ///< Is the goal completed or not? + CompanyID company; ///< Goal is for a specific company; INVALID_COMPANY if it is global + GoalType type; ///< Type of the goal + GoalTypeID dst; ///< Index of type + char *text; ///< Text of the goal. + char *progress; ///< Progress text of the goal. + bool completed; ///< Is the goal completed or not? /** * We need an (empty) constructor so struct isn't zeroed (as C++ standard states) @@ -34,12 +32,9 @@ struct Goal : GoalPool::PoolItem<&_goal_pool> { inline Goal() { } /** - * (Empty) destructor has to be defined else operator delete might be called with NULL parameter + * (Empty) destructor has to be defined else operator delete might be called with nullptr parameter */ inline ~Goal() { free(this->text); free(this->progress); } }; -#define FOR_ALL_GOALS_FROM(var, start) FOR_ALL_ITEMS_FROM(Goal, goal_index, var, start) -#define FOR_ALL_GOALS(var) FOR_ALL_GOALS_FROM(var, 0) - #endif /* GOAL_BASE_H */ diff --git a/src/goal_gui.cpp b/src/goal_gui.cpp index ee4d8170e1..7a77b30146 100644 --- a/src/goal_gui.cpp +++ b/src/goal_gui.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. @@ -50,7 +48,7 @@ struct GoalListWindow : public Window { this->OnInvalidateData(0); } - /* virtual */ void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { if (widget != WID_GOAL_CAPTION) return; @@ -62,14 +60,13 @@ struct GoalListWindow : public Window { } } - /* virtual */ void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { if (widget != WID_GOAL_LIST) return; int y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_GOAL_LIST, WD_FRAMERECT_TOP); int num = 0; - const Goal *s; - FOR_ALL_GOALS(s) { + for (const Goal *s : Goal::Iterate()) { if (s->company == INVALID_COMPANY) { y--; if (y == 0) { @@ -88,7 +85,7 @@ struct GoalListWindow : public Window { y -= 2; // "Company specific goals:" line. if (y < 0) return; - FOR_ALL_GOALS(s) { + for (const Goal *s : Goal::Iterate()) { if (s->company == this->window_number) { y--; if (y == 0) { @@ -160,8 +157,7 @@ struct GoalListWindow : public Window { /* Count number of (non) awarded goals. */ uint num_global = 0; uint num_company = 0; - const Goal *s; - FOR_ALL_GOALS(s) { + for (const Goal *s : Goal::Iterate()) { if (s->company == INVALID_COMPANY) { num_global++; } else if (s->company == this->window_number) { @@ -177,7 +173,7 @@ struct GoalListWindow : public Window { return 3 + num_global + num_company; } - /* virtual */ void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { if (widget != WID_GOAL_LIST) return; Dimension d = maxdim(GetStringBoundingBox(STR_GOALS_GLOBAL_TITLE), GetStringBoundingBox(STR_GOALS_COMPANY_TITLE)); @@ -209,8 +205,7 @@ struct GoalListWindow : public Window { bool rtl = _current_text_dir == TD_RTL; uint num = 0; - const Goal *s; - FOR_ALL_GOALS(s) { + for (const Goal *s : Goal::Iterate()) { if (global_section ? s->company == INVALID_COMPANY : (s->company == this->window_number && s->company != INVALID_COMPANY)) { if (IsInsideMM(pos, 0, cap)) { switch (column) { @@ -223,7 +218,7 @@ struct GoalListWindow : public Window { } case GC_PROGRESS: - if (s->progress != NULL) { + if (s->progress != nullptr) { SetDParamStr(0, s->progress); StringID str = s->completed ? STR_GOALS_PROGRESS_COMPLETE : STR_GOALS_PROGRESS; int progress_x = x; @@ -272,7 +267,7 @@ struct GoalListWindow : public Window { DrawPartialGoalList(pos, cap, x, y, right, progress_col_width, false, column); } - /* virtual */ void OnPaint() + void OnPaint() override { this->DrawWidgets(); @@ -280,9 +275,8 @@ struct GoalListWindow : public Window { /* Calculate progress column width. */ uint max_width = 0; - Goal *s; - FOR_ALL_GOALS(s) { - if (s->progress != NULL) { + for (const Goal *s : Goal::Iterate()) { + if (s->progress != nullptr) { SetDParamStr(0, s->progress); StringID str = s->completed ? STR_GOALS_PROGRESS_COMPLETE : STR_GOALS_PROGRESS; uint str_width = GetStringBoundingBox(str).width; @@ -299,7 +293,7 @@ struct GoalListWindow : public Window { } - /* virtual */ void OnResize() + void OnResize() override { this->vscroll->SetCapacityFromWidget(this, WID_GOAL_LIST); } @@ -309,7 +303,7 @@ struct GoalListWindow : public Window { * @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. */ - /* virtual */ void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; this->vscroll->SetCount(this->CountLines()); @@ -388,7 +382,7 @@ struct GoalQuestionWindow : public Window { free(this->question); } - /* virtual */ void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { switch (widget) { case WID_GQ_CAPTION: @@ -409,7 +403,7 @@ struct GoalQuestionWindow : public Window { } } - /* virtual */ void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_GQ_BUTTON_1: @@ -429,7 +423,7 @@ struct GoalQuestionWindow : public Window { } } - /* virtual */ void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { if (widget != WID_GQ_QUESTION) return; @@ -437,7 +431,7 @@ struct GoalQuestionWindow : public Window { size->height = GetStringHeight(STR_JUST_RAW_STRING, size->width) + WD_PAR_VSEP_WIDE; } - /* virtual */ void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { if (widget != WID_GQ_QUESTION) return; @@ -473,7 +467,7 @@ static const NWidgetPart _nested_goal_question_widgets[] = { }; static WindowDesc _goal_question_list_desc( - WDP_CENTER, NULL, 0, 0, + WDP_CENTER, nullptr, 0, 0, WC_GOAL_QUESTION, WC_NONE, WDF_CONSTRUCTION, _nested_goal_question_widgets, lengthof(_nested_goal_question_widgets) diff --git a/src/goal_type.h b/src/goal_type.h index aa9dee349d..b422e14d99 100644 --- a/src/goal_type.h +++ b/src/goal_type.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. @@ -18,7 +16,7 @@ static const uint32 GOAL_QUESTION_BUTTON_COUNT = 18; ///< Amount of buttons avai static const byte GOAL_QUESTION_TYPE_COUNT = 4; ///< Amount of question types. /** Types of goal destinations */ -enum GoalType { +enum GoalType : byte { GT_NONE, ///< Destination is not linked GT_TILE, ///< Destination is a tile GT_INDUSTRY, ///< Destination is an industry @@ -26,7 +24,6 @@ enum GoalType { GT_COMPANY, ///< Destination is a company GT_STORY_PAGE, ///< Destination is a story page }; -typedef SimpleTinyEnumT GoalTypeByte; ///< The GoalType packed into a byte for savegame purposes. 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 diff --git a/src/graph_gui.cpp b/src/graph_gui.cpp index e36f64e760..ce85aab084 100644 --- a/src/graph_gui.cpp +++ b/src/graph_gui.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. @@ -56,7 +54,7 @@ struct GraphLegendWindow : Window { } } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { if (!IsInsideMM(widget, WID_GL_FIRST_COMPANY, MAX_COMPANIES + WID_GL_FIRST_COMPANY)) return; @@ -74,7 +72,7 @@ struct GraphLegendWindow : Window { DrawString(r.left + (rtl ? (uint)WD_FRAMERECT_LEFT : (d.width + 4)), r.right - (rtl ? (d.width + 4) : (uint)WD_FRAMERECT_RIGHT), r.top + (r.bottom - r.top + 1 - FONT_HEIGHT_NORMAL) / 2, STR_COMPANY_NAME_COMPANY_NUM, HasBit(_legend_excluded_companies, cid) ? TC_BLACK : TC_WHITE); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { if (!IsInsideMM(widget, WID_GL_FIRST_COMPANY, MAX_COMPANIES + WID_GL_FIRST_COMPANY)) return; @@ -93,7 +91,7 @@ struct GraphLegendWindow : Window { * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; if (Company::IsValidID(data)) return; @@ -486,7 +484,7 @@ protected: } public: - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { if (widget != this->graph_widget) return; @@ -522,7 +520,7 @@ public: size->height = max(size->height, size->width / 3); } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { if (widget != this->graph_widget) return; @@ -534,13 +532,13 @@ public: return INVALID_DATAPOINT; } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { /* Clicked on legend? */ if (widget == WID_CV_KEY_BUTTON) ShowGraphLegend(); } - virtual void OnGameTick() + void OnGameTick() override { this->UpdateStatistics(false); } @@ -550,7 +548,7 @@ public: * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; this->UpdateStatistics(true); @@ -570,8 +568,7 @@ public: } byte nums = 0; - const Company *c; - FOR_ALL_COMPANIES(c) { + for (const Company *c : Company::Iterate()) { nums = min(this->num_vert_lines, max(nums, c->num_valid_stat_ent)); } @@ -595,8 +592,8 @@ public: int numd = 0; for (CompanyID k = COMPANY_FIRST; k < MAX_COMPANIES; k++) { - c = Company::GetIfValid(k); - if (c != NULL) { + const Company *c = Company::GetIfValid(k); + if (c != nullptr) { this->colours[numd] = _colour_gradient[c->colour][6]; for (int j = this->num_on_x_axis, i = 0; --j >= 0;) { this->cost[numd][i] = (j >= c->num_valid_stat_ent) ? INVALID_DATAPOINT : GetGraphData(c, j); @@ -622,7 +619,7 @@ struct OperatingProfitGraphWindow : BaseGraphWindow { this->InitializeWindow(window_number); } - virtual OverflowSafeInt64 GetGraphData(const Company *c, int j) + OverflowSafeInt64 GetGraphData(const Company *c, int j) override { return c->old_economy[j].income + c->old_economy[j].expenses; } @@ -673,7 +670,7 @@ struct IncomeGraphWindow : BaseGraphWindow { this->InitializeWindow(window_number); } - virtual OverflowSafeInt64 GetGraphData(const Company *c, int j) + OverflowSafeInt64 GetGraphData(const Company *c, int j) override { return c->old_economy[j].income; } @@ -722,7 +719,7 @@ struct DeliveredCargoGraphWindow : BaseGraphWindow { this->InitializeWindow(window_number); } - virtual OverflowSafeInt64 GetGraphData(const Company *c, int j) + OverflowSafeInt64 GetGraphData(const Company *c, int j) override { return c->old_economy[j].delivered_cargo.GetSum(); } @@ -771,12 +768,12 @@ struct PerformanceHistoryGraphWindow : BaseGraphWindow { this->InitializeWindow(window_number); } - virtual OverflowSafeInt64 GetGraphData(const Company *c, int j) + OverflowSafeInt64 GetGraphData(const Company *c, int j) override { return c->old_economy[j].performance_history; } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { if (widget == WID_PHG_DETAILED_PERFORMANCE) ShowPerformanceRatingDetail(); this->BaseGraphWindow::OnClick(pt, widget, click_count); @@ -827,7 +824,7 @@ struct CompanyValueGraphWindow : BaseGraphWindow { this->InitializeWindow(window_number); } - virtual OverflowSafeInt64 GetGraphData(const Company *c, int j) + OverflowSafeInt64 GetGraphData(const Company *c, int j) override { return c->old_economy[j].company_value; } @@ -904,7 +901,7 @@ struct PaymentRatesGraphWindow : BaseGraphWindow { } } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { if (widget != WID_CPR_MATRIX) { BaseGraphWindow::UpdateWidgetSize(widget, size, padding, fill, resize); @@ -927,7 +924,7 @@ struct PaymentRatesGraphWindow : BaseGraphWindow { resize->height = this->line_height; } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { if (widget != WID_CPR_MATRIX) { BaseGraphWindow::DrawWidget(r, widget); @@ -964,7 +961,7 @@ struct PaymentRatesGraphWindow : BaseGraphWindow { } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_CPR_ENABLE_CARGOES: @@ -1005,12 +1002,12 @@ struct PaymentRatesGraphWindow : BaseGraphWindow { } } - virtual void OnResize() + void OnResize() override { this->vscroll->SetCapacityFromWidget(this, WID_CPR_MATRIX); } - virtual void OnGameTick() + void OnGameTick() override { /* Override default OnGameTick */ } @@ -1020,13 +1017,13 @@ struct PaymentRatesGraphWindow : BaseGraphWindow { * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; this->OnHundredthTick(); } - virtual void OnHundredthTick() + void OnHundredthTick() override { this->UpdateExcludedData(); @@ -1138,21 +1135,20 @@ private: { if (!this->companies.NeedRebuild()) return; - this->companies.Clear(); + this->companies.clear(); - const Company *c; - FOR_ALL_COMPANIES(c) { - *this->companies.Append() = c; + for (const Company *c : Company::Iterate()) { + this->companies.push_back(c); } - this->companies.Compact(); + this->companies.shrink_to_fit(); this->companies.RebuildDone(); } /** Sort the company league by performance history */ - static int CDECL PerformanceSorter(const Company * const *c1, const Company * const *c2) + static bool PerformanceSorter(const Company * const &c1, const Company * const &c2) { - return (*c2)->old_economy[0].performance_history - (*c1)->old_economy[0].performance_history; + return c2->old_economy[0].performance_history < c1->old_economy[0].performance_history; } public: @@ -1163,7 +1159,7 @@ public: this->companies.NeedResort(); } - virtual void OnPaint() + void OnPaint() override { this->BuildCompanyList(); this->companies.Sort(&PerformanceSorter); @@ -1171,7 +1167,7 @@ public: this->DrawWidgets(); } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { if (widget != WID_CL_BACKGROUND) return; @@ -1184,7 +1180,7 @@ public: 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.Length(); i++) { + 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); @@ -1198,7 +1194,7 @@ public: } } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { if (widget != WID_CL_BACKGROUND) return; @@ -1223,8 +1219,7 @@ public: this->line_height = max(d.height + 2, FONT_HEIGHT_NORMAL); this->icon_y_offset = Center(1, this->line_height, d.height); - const Company *c; - FOR_ALL_COMPANIES(c) { + for (const Company *c : Company::Iterate()) { SetDParam(0, c->index); SetDParam(1, c->index); SetDParam(2, _performance_titles[widest_title]); @@ -1238,7 +1233,7 @@ public: } - virtual void OnGameTick() + void OnGameTick() override { if (this->companies.NeedResort()) { this->SetDirty(); @@ -1250,7 +1245,7 @@ public: * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + 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 */ @@ -1303,8 +1298,7 @@ struct PerformanceRatingDetailWindow : Window { { /* Update all company stats with the current data * (this is because _score_info is not saved to a savegame) */ - Company *c; - FOR_ALL_COMPANIES(c) { + for (Company *c : Company::Iterate()) { UpdateCompanyRatingAndValue(c, false); } @@ -1320,7 +1314,7 @@ struct PerformanceRatingDetailWindow : Window { uint score_detail_left; uint score_detail_right; - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_PRD_SCORE_FIRST: @@ -1378,7 +1372,7 @@ struct PerformanceRatingDetailWindow : Window { } } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { /* No need to draw when there's nothing to draw */ if (this->company == INVALID_COMPANY) return; @@ -1457,7 +1451,7 @@ struct PerformanceRatingDetailWindow : Window { } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { /* Check which button is clicked */ if (IsInsideMM(widget, WID_PRD_COMPANY_FIRST, WID_PRD_COMPANY_LAST + 1)) { @@ -1471,7 +1465,7 @@ struct PerformanceRatingDetailWindow : Window { } } - virtual void OnGameTick() + void OnGameTick() override { /* Update the company score every 5 days */ if (--this->timeout == 0) { @@ -1485,7 +1479,7 @@ struct PerformanceRatingDetailWindow : Window { * @param data the company ID of the company that is going to be removed * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; /* Disable the companies who are not active */ @@ -1501,8 +1495,7 @@ struct PerformanceRatingDetailWindow : Window { } if (this->company == INVALID_COMPANY) { - const Company *c; - FOR_ALL_COMPANIES(c) { + for (const Company *c : Company::Iterate()) { this->company = c->index; break; } diff --git a/src/graph_gui.h b/src/graph_gui.h index acc23421f4..8338878c01 100644 --- a/src/graph_gui.h +++ b/src/graph_gui.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/ground_vehicle.cpp b/src/ground_vehicle.cpp index 6fd8d77106..74095fc576 100644 --- a/src/ground_vehicle.cpp +++ b/src/ground_vehicle.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. @@ -28,9 +26,9 @@ void GroundVehicle::PowerChanged() uint32 total_power = 0; uint32 max_te = 0; uint32 number_of_parts = 0; - uint16 max_track_speed = v->GetDisplayMaxSpeed(); + uint16 max_track_speed = this->vcache.cached_max_speed; // Max track speed in internal units. - for (const T *u = v; u != NULL; u = u->Next()) { + for (const T *u = v; u != nullptr; u = u->Next()) { uint32 current_power = u->GetPower() + u->GetPoweredPartPower(u); total_power += current_power; @@ -83,7 +81,7 @@ void GroundVehicle::CargoChanged() assert(this->First() == this); uint32 weight = 0; - for (T *u = T::From(this); u != NULL; u = u->Next()) { + for (T *u = T::From(this); u != nullptr; u = u->Next()) { uint32 current_weight = u->GetWeight(); weight += current_weight; /* Slope steepness is in percent, result in N. */ @@ -116,7 +114,7 @@ int GroundVehicle::GetAcceleration() const /* Power is stored in HP, we need it in watts. * Each vehicle can have U16 power, 128 vehicles, HP -> watt - * and km/h to m/s conversion below result in a maxium of + * and km/h to m/s conversion below result in a maximum of * about 1.1E11, way more than 4.3E9 of int32. */ int64 power = this->gcache.cached_power * 746ll; @@ -198,7 +196,7 @@ bool GroundVehicle::IsChainInDepot() const if (!IsDepotTypeTile(v->tile, (TransportType)Type) || v->cur_speed != 0) return false; /* Check whether the rest is also already trying to enter the depot. */ - for (; v != NULL; v = v->Next()) { + for (; v != nullptr; v = v->Next()) { if (!v->T::IsInDepot() || v->tile != this->tile) return false; } diff --git a/src/ground_vehicle.hpp b/src/ground_vehicle.hpp index 56b97875fc..af6e25c806 100644 --- a/src/ground_vehicle.hpp +++ b/src/ground_vehicle.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. @@ -36,7 +34,7 @@ struct GroundVehicleCache { uint16 cached_axle_resistance; ///< Resistance caused by the axles of the vehicle (valid only for the first engine). /* Cached acceleration values, recalculated on load and each time a vehicle is added to/removed from the consist. */ - uint16 cached_max_track_speed; ///< Maximum consist speed limited by track type (valid only for the first engine). + uint16 cached_max_track_speed; ///< Maximum consist speed (in internal units) limited by track type (valid only for the first engine). uint32 cached_power; ///< Total power of the consist (valid only for the first engine). uint32 cached_air_drag; ///< Air drag coefficient of the vehicle (valid only for the first engine). @@ -92,17 +90,17 @@ struct GroundVehicle : public SpecializedVehicle { void PowerChanged(); void CargoChanged(); int GetAcceleration() const; - bool IsChainInDepot() const; + bool IsChainInDepot() const override; /** * Common code executed for crashed ground vehicles * @param flooded was this vehicle flooded? * @return number of victims */ - /* virtual */ uint Crash(bool flooded) + uint Crash(bool flooded) override { /* Crashed vehicles aren't going up or down */ - for (T *v = T::From(this); v != NULL; v = v->Next()) { + for (T *v = T::From(this); v != nullptr; v = v->Next()) { ClrBit(v->gv_flags, GVF_GOINGUP_BIT); ClrBit(v->gv_flags, GVF_GOINGDOWN_BIT); } @@ -117,7 +115,7 @@ struct GroundVehicle : public SpecializedVehicle { { int64 incl = 0; - for (const T *u = T::From(this); u != NULL; u = u->Next()) { + for (const T *u = T::From(this); u != nullptr; u = u->Next()) { if (HasBit(u->gv_flags, GVF_GOINGUP_BIT)) { incl += u->gcache.cached_slope_resistance; } else if (HasBit(u->gv_flags, GVF_GOINGDOWN_BIT)) { diff --git a/src/group.h b/src/group.h index ea4f7e130e..aeb7f581a8 100644 --- a/src/group.h +++ b/src/group.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. @@ -65,15 +63,17 @@ struct GroupStatistics { /** Group data. */ struct Group : GroupPool::PoolItem<&_group_pool> { - char *name; ///< Group Name - OwnerByte owner; ///< Group Owner - VehicleTypeByte vehicle_type; ///< Vehicle type of the group + char *name; ///< Group Name + Owner owner; ///< Group Owner + VehicleType vehicle_type; ///< Vehicle type of the group - bool replace_protection; ///< If set to true, the global autoreplace have no effect on the group - Livery livery; ///< Custom colour scheme for vehicles in this group - GroupStatistics statistics; ///< NOSAVE: Statistics and caches on the vehicles in the group. + bool replace_protection; ///< If set to true, the global autoreplace have no effect on the group + Livery livery; ///< Custom colour scheme for vehicles in this group + GroupStatistics statistics; ///< NOSAVE: Statistics and caches on the vehicles in the group. - GroupID parent; ///< Parent group + bool folded; ///< NOSAVE: Is this group folded in the group view? + + GroupID parent; ///< Parent group Group(CompanyID owner = INVALID_COMPANY); ~Group(); @@ -95,11 +95,11 @@ static inline bool IsAllGroupID(GroupID id_g) return id_g == ALL_GROUP; } -#define FOR_ALL_GROUPS_FROM(var, start) FOR_ALL_ITEMS_FROM(Group, group_index, var, start) -#define FOR_ALL_GROUPS(var) FOR_ALL_GROUPS_FROM(var, 0) - 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); void SetTrainGroupID(Train *v, GroupID grp); void UpdateTrainGroupID(Train *v); diff --git a/src/group_cmd.cpp b/src/group_cmd.cpp index bd99aa1272..497d74d68b 100644 --- a/src/group_cmd.cpp +++ b/src/group_cmd.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. @@ -103,8 +101,7 @@ void GroupStatistics::Clear() /* static */ void GroupStatistics::UpdateAfterLoad() { /* Set up the engine count for all companies */ - Company *c; - FOR_ALL_COMPANIES(c) { + for (Company *c : Company::Iterate()) { for (VehicleType type = VEH_BEGIN; type < VEH_COMPANY_END; type++) { c->group_all[type].Clear(); c->group_default[type].Clear(); @@ -112,20 +109,18 @@ void GroupStatistics::Clear() } /* Recalculate */ - Group *g; - FOR_ALL_GROUPS(g) { + for (Group *g : Group::Iterate()) { g->statistics.Clear(); } - const Vehicle *v; - FOR_ALL_VEHICLES(v) { + for (const Vehicle *v : Vehicle::Iterate()) { if (!v->IsEngineCountable()) continue; GroupStatistics::CountEngine(v, 1); if (v->IsPrimaryVehicle()) GroupStatistics::CountVehicle(v, 1); } - FOR_ALL_COMPANIES(c) { + for (const Company *c : Company::Iterate()) { GroupStatistics::UpdateAutoreplace(c->index); } } @@ -185,8 +180,7 @@ void GroupStatistics::Clear() /* static */ void GroupStatistics::UpdateProfits() { /* Set up the engine count for all companies */ - Company *c; - FOR_ALL_COMPANIES(c) { + for (Company *c : Company::Iterate()) { for (VehicleType type = VEH_BEGIN; type < VEH_COMPANY_END; type++) { c->group_all[type].ClearProfits(); c->group_default[type].ClearProfits(); @@ -194,13 +188,11 @@ void GroupStatistics::Clear() } /* Recalculate */ - Group *g; - FOR_ALL_GROUPS(g) { + for (Group *g : Group::Iterate()) { g->statistics.ClearProfits(); } - const Vehicle *v; - FOR_ALL_VEHICLES(v) { + for (const Vehicle *v : Vehicle::Iterate()) { if (v->IsPrimaryVehicle() && v->age > VEHICLE_PROFIT_MIN_AGE) GroupStatistics::VehicleReachedProfitAge(v); } } @@ -219,13 +211,12 @@ void GroupStatistics::Clear() } /* Recalculate */ - Group *g; - FOR_ALL_GROUPS(g) { + for (Group *g : Group::Iterate()) { if (g->owner != company) continue; g->statistics.ClearAutoreplace(); } - for (EngineRenewList erl = c->engine_renew_list; erl != NULL; erl = erl->next) { + for (EngineRenewList erl = c->engine_renew_list; erl != nullptr; erl = erl->next) { const Engine *e = Engine::Get(erl->from); GroupStatistics &stats = GroupStatistics::Get(company, erl->group_id, e->type); if (!stats.autoreplace_defined) { @@ -274,18 +265,16 @@ const Livery *GetParentLivery(const Group *g) void PropagateChildLivery(const Group *g) { /* Company colour data is indirectly cached. */ - Vehicle *v; - FOR_ALL_VEHICLES(v) { + for (Vehicle *v : Vehicle::Iterate()) { if (v->group_id == g->index && (!v->IsGroundVehicle() || v->IsFrontEngine())) { - for (Vehicle *u = v; u != NULL; u = u->Next()) { + for (Vehicle *u = v; u != nullptr; u = u->Next()) { u->colourmap = PAL_NONE; u->InvalidateNewGRFCache(); } } } - Group *cg; - FOR_ALL_GROUPS(cg) { + for (Group *cg : Group::Iterate()) { if (cg->parent == g->index) { if (!HasBit(cg->livery.in_use, 0)) cg->livery.colour1 = g->livery.colour1; if (!HasBit(cg->livery.in_use, 1)) cg->livery.colour2 = g->livery.colour2; @@ -298,6 +287,7 @@ void PropagateChildLivery(const Group *g) Group::Group(Owner owner) { this->owner = owner; + this->folded = false; } Group::~Group() @@ -323,7 +313,7 @@ CommandCost CmdCreateGroup(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 if (!Group::CanAllocateItem()) return CMD_ERROR; const Group *pg = Group::GetIfValid(GB(p2, 0, 16)); - if (pg != NULL) { + if (pg != nullptr) { if (pg->owner != _current_company) return CMD_ERROR; if (pg->vehicle_type != vt) return CMD_ERROR; } @@ -334,7 +324,7 @@ CommandCost CmdCreateGroup(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 g->vehicle_type = vt; g->parent = INVALID_GROUP; - if (pg == NULL) { + if (pg == nullptr) { const Company *c = Company::Get(_current_company); g->livery.colour1 = c->livery[LS_DEFAULT].colour1; g->livery.colour2 = c->livery[LS_DEFAULT].colour2; @@ -367,14 +357,13 @@ CommandCost CmdCreateGroup(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 CommandCost CmdDeleteGroup(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { Group *g = Group::GetIfValid(p1); - if (g == NULL || g->owner != _current_company) return CMD_ERROR; + if (g == nullptr || g->owner != _current_company) return CMD_ERROR; /* Remove all vehicles from the group */ DoCommand(0, p1, 0, flags, CMD_REMOVE_ALL_VEHICLES_GROUP); /* Delete sub-groups */ - Group *gp; - FOR_ALL_GROUPS(gp) { + for (const Group *gp : Group::Iterate()) { if (gp->parent == g->index) { DoCommand(0, gp->index, 0, flags, CMD_DELETE_GROUP); } @@ -387,10 +376,9 @@ CommandCost CmdDeleteGroup(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 /* If we set an autoreplace for the group we delete, remove it. */ if (_current_company < MAX_COMPANIES) { Company *c; - EngineRenew *er; c = Company::Get(_current_company); - FOR_ALL_ENGINE_RENEWS(er) { + for (EngineRenew *er : EngineRenew::Iterate()) { if (er->group_id == g->index) RemoveEngineReplacementForCompany(c, er->from, g->index, flags); } } @@ -423,7 +411,7 @@ CommandCost CmdDeleteGroup(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 CommandCost CmdAlterGroup(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { Group *g = Group::GetIfValid(GB(p1, 0, 16)); - if (g == NULL || g->owner != _current_company) return CMD_ERROR; + if (g == nullptr || g->owner != _current_company) return CMD_ERROR; if (!HasBit(p1, 16)) { /* Rename group */ @@ -437,23 +425,23 @@ CommandCost CmdAlterGroup(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 /* Delete the old name */ free(g->name); /* Assign the new one */ - g->name = reset ? NULL : stredup(text); + g->name = reset ? nullptr : stredup(text); } } else { /* Set group parent */ const Group *pg = Group::GetIfValid(GB(p2, 0, 16)); - if (pg != NULL) { + if (pg != nullptr) { if (pg->owner != _current_company) return CMD_ERROR; if (pg->vehicle_type != g->vehicle_type) return CMD_ERROR; /* Ensure request parent isn't child of group. * This is the only place that infinite loops are prevented. */ - if (GroupIsInGroup(pg->index, g->index)) return CMD_ERROR; + if (GroupIsInGroup(pg->index, g->index)) return_cmd_error(STR_ERROR_GROUP_CAN_T_SET_PARENT_RECURSION); } if (flags & DC_EXEC) { - g->parent = (pg == NULL) ? INVALID_GROUP : pg->index; + g->parent = (pg == nullptr) ? INVALID_GROUP : pg->index; GroupStatistics::UpdateAutoreplace(g->owner); if (g->livery.in_use == 0) { @@ -497,7 +485,7 @@ static void AddVehicleToGroup(Vehicle *v, GroupID new_g) case VEH_AIRCRAFT: if (v->IsEngineCountable()) UpdateNumEngineGroup(v, v->group_id, new_g); v->group_id = new_g; - for (Vehicle *u = v; u != NULL; u = u->Next()) { + for (Vehicle *u = v; u != nullptr; u = u->Next()) { u->colourmap = PAL_NONE; u->InvalidateNewGRFCache(); u->UpdateViewport(true); @@ -525,7 +513,7 @@ CommandCost CmdAddVehicleGroup(TileIndex tile, DoCommandFlag flags, uint32 p1, u Vehicle *v = Vehicle::GetIfValid(GB(p2, 0, 20)); GroupID new_g = p1; - if (v == NULL || (!Group::IsValidID(new_g) && !IsDefaultGroupID(new_g) && new_g != NEW_GROUP)) return CMD_ERROR; + if (v == nullptr || (!Group::IsValidID(new_g) && !IsDefaultGroupID(new_g) && new_g != NEW_GROUP)) return CMD_ERROR; if (Group::IsValidID(new_g)) { Group *g = Group::Get(new_g); @@ -536,7 +524,7 @@ CommandCost CmdAddVehicleGroup(TileIndex tile, DoCommandFlag flags, uint32 p1, u if (new_g == NEW_GROUP) { /* Create new group. */ - CommandCost ret = CmdCreateGroup(0, flags, v->type, 0, NULL); + CommandCost ret = CmdCreateGroup(0, flags, v->type, INVALID_GROUP, nullptr); if (ret.Failed()) return ret; new_g = _new_group_id; @@ -547,7 +535,7 @@ CommandCost CmdAddVehicleGroup(TileIndex tile, DoCommandFlag flags, uint32 p1, u if (HasBit(p2, 31)) { /* Add vehicles in the shared order list as well. */ - for (Vehicle *v2 = v->FirstShared(); v2 != NULL; v2 = v2->NextShared()) { + for (Vehicle *v2 = v->FirstShared(); v2 != nullptr; v2 = v2->NextShared()) { if (v2->group_id != new_g) AddVehicleToGroup(v2, new_g); } } @@ -582,16 +570,14 @@ CommandCost CmdAddSharedVehicleGroup(TileIndex tile, DoCommandFlag flags, uint32 if (!Group::IsValidID(id_g) || !IsCompanyBuildableVehicleType(type)) return CMD_ERROR; if (flags & DC_EXEC) { - Vehicle *v; - /* Find the first front engine which belong to the group id_g * then add all shared vehicles of this front engine to the group id_g */ - FOR_ALL_VEHICLES(v) { + for (const Vehicle *v : Vehicle::Iterate()) { if (v->type == type && v->IsPrimaryVehicle()) { if (v->group_id != id_g) continue; /* For each shared vehicles add it to the group */ - for (Vehicle *v2 = v->FirstShared(); v2 != NULL; v2 = v2->NextShared()) { + for (Vehicle *v2 = v->FirstShared(); v2 != nullptr; v2 = v2->NextShared()) { if (v2->group_id != id_g) DoCommand(tile, id_g, v2->index, flags, CMD_ADD_VEHICLE_GROUP, text); } } @@ -619,13 +605,11 @@ CommandCost CmdRemoveAllVehiclesGroup(TileIndex tile, DoCommandFlag flags, uint3 GroupID old_g = p1; Group *g = Group::GetIfValid(old_g); - if (g == NULL || g->owner != _current_company) return CMD_ERROR; + if (g == nullptr || g->owner != _current_company) return CMD_ERROR; if (flags & DC_EXEC) { - Vehicle *v; - /* Find each Vehicle that belongs to the group old_g and add it to the default group */ - FOR_ALL_VEHICLES(v) { + for (const Vehicle *v : Vehicle::Iterate()) { if (v->IsPrimaryVehicle()) { if (v->group_id != old_g) continue; @@ -656,7 +640,7 @@ CommandCost CmdSetGroupLivery(TileIndex tile, DoCommandFlag flags, uint32 p1, ui bool primary = !HasBit(p2, 8); Colours colour = Extract(p2); - if (g == NULL || g->owner != _current_company) return CMD_ERROR; + if (g == nullptr || g->owner != _current_company) return CMD_ERROR; if (colour >= COLOUR_END && colour != INVALID_COLOUR) return CMD_ERROR; @@ -687,8 +671,7 @@ static void SetGroupReplaceProtection(Group *g, bool protect) { g->replace_protection = protect; - Group *pg; - FOR_ALL_GROUPS(pg) { + for (Group *pg : Group::Iterate()) { if (pg->parent == g->index) SetGroupReplaceProtection(pg, protect); } } @@ -708,7 +691,7 @@ static void SetGroupReplaceProtection(Group *g, bool protect) CommandCost CmdSetGroupReplaceProtection(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { Group *g = Group::GetIfValid(p1); - if (g == NULL || g->owner != _current_company) return CMD_ERROR; + if (g == nullptr || g->owner != _current_company) return CMD_ERROR; if (flags & DC_EXEC) { if (HasBit(p2, 1)) { @@ -749,7 +732,7 @@ void SetTrainGroupID(Train *v, GroupID new_g) assert(v->IsFrontEngine() || IsDefaultGroupID(new_g)); - for (Vehicle *u = v; u != NULL; u = u->Next()) { + for (Vehicle *u = v; u != nullptr; u = u->Next()) { if (u->IsEngineCountable()) UpdateNumEngineGroup(u, u->group_id, new_g); u->group_id = new_g; @@ -776,7 +759,7 @@ void UpdateTrainGroupID(Train *v) assert(v->IsFrontEngine() || v->IsFreeWagon()); GroupID new_g = v->IsFrontEngine() ? v->group_id : (GroupID)DEFAULT_GROUP; - for (Vehicle *u = v; u != NULL; u = u->Next()) { + for (Vehicle *u = v; u != nullptr; u = u->Next()) { if (u->IsEngineCountable()) UpdateNumEngineGroup(u, u->group_id, new_g); u->group_id = new_g; @@ -801,18 +784,66 @@ uint GetGroupNumEngines(CompanyID company, GroupID id_g, EngineID id_e) { uint count = 0; const Engine *e = Engine::Get(id_e); - const Group *g; - FOR_ALL_GROUPS(g) { + for (const Group *g : Group::Iterate()) { if (g->parent == id_g) count += GetGroupNumEngines(company, g->index, id_e); } return count + GroupStatistics::Get(company, id_g, e->type).num_engines[id_e]; } +/** + * Get the number of vehicles in 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 The number of vehicles in the group + */ +uint GetGroupNumVehicle(CompanyID company, GroupID id_g, VehicleType type) +{ + uint count = 0; + for (const Group *g : Group::Iterate()) { + if (g->parent == id_g) count += GetGroupNumVehicle(company, g->index, type); + } + return count + GroupStatistics::Get(company, id_g, type).num_vehicle; +} + +/** + * Get the number of vehicles above profit minimum age in 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 The number of vehicles above profit minimum age in the group + */ +uint GetGroupNumProfitVehicle(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); + } + return count + GroupStatistics::Get(company, id_g, type).num_profit_vehicle; +} + +/** + * Get last year's profit 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 + */ +Money GetGroupProfitLastYear(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); + } + return sum + GroupStatistics::Get(company, id_g, type).profit_last_year; +} + void RemoveAllGroupsForCompany(const CompanyID company) { - Group *g; - - FOR_ALL_GROUPS(g) { + for (Group *g : Group::Iterate()) { if (company == g->owner) delete g; } } diff --git a/src/group_gui.cpp b/src/group_gui.cpp index b9a5eabedc..7b5384ea8a 100644 --- a/src/group_gui.cpp +++ b/src/group_gui.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. @@ -102,6 +100,7 @@ class VehicleGroupWindow : public BaseVehicleListWindow { private: /* Columns in the group list */ enum ListColumns { + VGC_FOLD, ///< Fold / Unfold button. VGC_NAME, ///< Group name. VGC_PROTECT, ///< Autoreplace protect icon. VGC_AUTOREPLACE, ///< Autoreplace active icon. @@ -120,41 +119,48 @@ private: uint tiny_step_height; ///< Step height for the group list Scrollbar *group_sb; - SmallVector indents; ///< Indentation levels + std::vector indents; ///< Indentation levels Dimension column_size[VGC_END]; ///< Size of the columns in the group list. void AddChildren(GUIGroupList *source, GroupID parent, int indent) { - for (const Group **g = source->Begin(); g != source->End(); g++) { - if ((*g)->parent != parent) continue; - *this->groups.Append() = *g; - *this->indents.Append() = indent; - AddChildren(source, (*g)->index, indent + 1); + for (const Group *g : *source) { + if (g->parent != parent) continue; + this->groups.push_back(g); + this->indents.push_back(indent); + if (g->folded) { + /* Test if this group has children at all. If not, the folded flag should be cleared to avoid lingering unfold buttons in the list. */ + auto child = std::find_if(source->begin(), source->end(), [g](const Group *child){ return child->parent == g->index; }); + bool has_children = child != source->end(); + Group::Get(g->index)->folded = has_children; + } else { + AddChildren(source, g->index, indent + 1); + } } } /** Sort the groups by their name */ - static int CDECL GroupNameSorter(const Group * const *a, const Group * const *b) + static bool GroupNameSorter(const Group * const &a, const Group * const &b) { - static const Group *last_group[2] = { NULL, NULL }; + static const Group *last_group[2] = { nullptr, nullptr }; static char last_name[2][64] = { "", "" }; - if (*a != last_group[0]) { - last_group[0] = *a; - SetDParam(0, (*a)->index); + if (a != last_group[0]) { + last_group[0] = a; + SetDParam(0, a->index); GetString(last_name[0], STR_GROUP_NAME, lastof(last_name[0])); } - if (*b != last_group[1]) { - last_group[1] = *b; - SetDParam(0, (*b)->index); + if (b != last_group[1]) { + last_group[1] = b; + SetDParam(0, b->index); GetString(last_name[1], STR_GROUP_NAME, lastof(last_name[1])); } int r = strnatcmp(last_name[0], last_name[1]); // Sort by name (natural sorting). - if (r == 0) return (*a)->index - (*b)->index; - return r; + if (r == 0) return a->index < b->index; + return r < 0; } /** @@ -166,15 +172,14 @@ private: { if (!this->groups.NeedRebuild()) return; - this->groups.Clear(); - this->indents.Clear(); + this->groups.clear(); + this->indents.clear(); GUIGroupList list; - const Group *g; - FOR_ALL_GROUPS(g) { + for (const Group *g : Group::Iterate()) { if (g->owner == owner && g->vehicle_type == this->vli.vtype) { - *list.Append() = g; + list.push_back(g); } } @@ -183,7 +188,7 @@ private: AddChildren(&list, INVALID_GROUP, 0); - this->groups.Compact(); + this->groups.shrink_to_fit(); this->groups.RebuildDone(); } @@ -193,10 +198,13 @@ private: */ uint ComputeGroupInfoSize() { + this->column_size[VGC_FOLD] = maxdim(GetSpriteSize(SPR_CIRCLE_FOLDED), GetSpriteSize(SPR_CIRCLE_UNFOLDED)); + 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)); /* We consider the max average length of characters to be the one of "a" */ this->column_size[VGC_NAME].width = max(GetCharacterWidth(FS_NORMAL, 97) * (MAX_LENGTH_GROUP_NAME_CHARS - 4), this->column_size[VGC_NAME].width); - this->tiny_step_height = max(11U, this->column_size[VGC_NAME].height); + this->tiny_step_height = max(this->tiny_step_height, this->column_size[VGC_NAME].height); this->column_size[VGC_PROTECT] = GetSpriteSize(SPR_GROUP_REPLACE_PROTECT); this->tiny_step_height = max(this->tiny_step_height, this->column_size[VGC_PROTECT].height); @@ -213,14 +221,17 @@ private: } this->tiny_step_height = max(this->tiny_step_height, this->column_size[VGC_PROFIT].height); - SetDParamMaxValue(0, GroupStatistics::Get(this->vli.company, ALL_GROUP, this->vli.vtype).num_vehicle, 3, FS_SMALL); - this->column_size[VGC_NUMBER] = GetStringBoundingBox(STR_TINY_COMMA); + int num_vehicle = GetGroupNumVehicle(this->vli.company, ALL_GROUP, this->vli.vtype); + SetDParamMaxValue(0, num_vehicle, 3, FS_SMALL); + SetDParamMaxValue(1, num_vehicle, 3, FS_SMALL); + this->column_size[VGC_NUMBER] = GetStringBoundingBox(STR_GROUP_COUNT_WITH_SUBGROUP); this->tiny_step_height = max(this->tiny_step_height, this->column_size[VGC_NUMBER].height); this->tiny_step_height += WD_MATRIX_TOP; this->tiny_step_height = GetMinSizing(NWST_STEP, this->tiny_step_height); 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 + @@ -237,8 +248,9 @@ private: * @param g_id Group to list. * @param indent Indentation level. * @param protection Whether autoreplace protection is set. + * @param has_children Whether the group has children and should have a fold / unfold button. */ - void DrawGroupInfo(int y, int left, int right, GroupID g_id, int indent = 0, bool protection = false) const + void DrawGroupInfo(int y, int left, int right, GroupID g_id, int indent = 0, bool protection = false, bool has_children = false) const { /* Highlight the group if a vehicle is dragged over it */ if (g_id == this->group_over) { @@ -252,6 +264,12 @@ private: const GroupStatistics &stats = GroupStatistics::Get(this->vli.company, g_id, this->vli.vtype); 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; + 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); + } + /* draw group name */ StringID str; if (IsAllGroupID(g_id)) { @@ -262,7 +280,7 @@ private: SetDParam(0, g_id); str = STR_GROUP_NAME; } - int x = rtl ? right - WD_FRAMERECT_RIGHT - 8 - this->column_size[VGC_NAME].width + 1 : left + WD_FRAMERECT_LEFT + 8; + x = rtl ? x - 2 - this->column_size[VGC_NAME].width : x + 2 + 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 */ @@ -276,11 +294,13 @@ private: /* draw the profit icon */ x = rtl ? x - 2 - this->column_size[VGC_PROFIT].width : x + 2 + this->column_size[VGC_AUTOREPLACE].width; SpriteID spr; - if (stats.num_profit_vehicle == 0) { + 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) { spr = SPR_PROFIT_NA; - } else if (stats.profit_last_year < 0) { + } else if (profit_last_year < 0) { spr = SPR_PROFIT_NEGATIVE; - } else if (stats.profit_last_year < 10000 * stats.num_profit_vehicle) { // TODO magic number + } else if (profit_last_year < VEHICLE_PROFIT_THRESHOLD * num_profit_vehicle) { spr = SPR_PROFIT_SOME; } else { spr = SPR_PROFIT_LOT; @@ -289,8 +309,16 @@ private: /* 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; - SetDParam(0, stats.num_vehicle); - DrawString(x, x + this->column_size[VGC_NUMBER].width - 1, y + (this->tiny_step_height - this->column_size[VGC_NUMBER].height) / 2, STR_TINY_COMMA, colour, SA_RIGHT | SA_FORCE); + 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) { + SetDParam(0, num_vehicle); + DrawString(x, x + this->column_size[VGC_NUMBER].width - 1, y + (this->tiny_step_height - this->column_size[VGC_NUMBER].height) / 2, STR_TINY_COMMA, colour, SA_RIGHT | SA_FORCE); + } else { + SetDParam(0, num_vehicle); + SetDParam(1, num_vehicle_with_subgroups - num_vehicle); + DrawString(x, x + this->column_size[VGC_NUMBER].width - 1, y + (this->tiny_step_height - this->column_size[VGC_NUMBER].height) / 2, STR_GROUP_COUNT_WITH_SUBGROUP, colour, SA_RIGHT | SA_FORCE); + } } /** @@ -341,6 +369,7 @@ public: this->groups.ForceRebuild(); this->groups.NeedResort(); this->BuildGroupList(vli.company); + this->group_sb->SetCount((uint)this->groups.size()); this->GetWidget(WID_GL_CAPTION)->widget_data = STR_VEHICLE_LIST_TRAIN_CAPTION + this->vli.vtype; this->GetWidget(WID_GL_LIST_VEHICLE)->tool_tip = STR_VEHICLE_LIST_TRAIN_LIST_TOOLTIP + this->vli.vtype; @@ -360,7 +389,7 @@ public: *this->sorting = this->vehicles.GetListing(); } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_GL_LIST_GROUP: { @@ -424,7 +453,7 @@ public: * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + 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 */ @@ -448,7 +477,7 @@ public: this->SetDirty(); } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { switch (widget) { case WID_GL_AVAILABLE_VEHICLES: @@ -461,21 +490,21 @@ public: if (IsDefaultGroupID(this->vli.index) || IsAllGroupID(this->vli.index)) { SetDParam(0, STR_COMPANY_NAME); SetDParam(1, this->vli.company); - SetDParam(2, this->vehicles.Length()); - SetDParam(3, this->vehicles.Length()); + SetDParam(2, this->vehicles.size()); + SetDParam(3, this->vehicles.size()); } else { - const Group *g = Group::Get(this->vli.index); + uint num_vehicle = GetGroupNumVehicle(this->vli.company, this->vli.index, this->vli.vtype); SetDParam(0, STR_GROUP_NAME); - SetDParam(1, g->index); - SetDParam(2, g->statistics.num_vehicle); - SetDParam(3, g->statistics.num_vehicle); + SetDParam(1, this->vli.index); + SetDParam(2, num_vehicle); + SetDParam(3, num_vehicle); } break; } } - virtual void OnPaint() + void OnPaint() override { /* If we select the all vehicles, this->list will contain all vehicles of the owner * else this->list will contain all vehicles which belong to the selected group */ @@ -484,17 +513,17 @@ public: this->BuildGroupList(this->owner); - this->group_sb->SetCount(this->groups.Length()); - this->vscroll->SetCount(this->vehicles.Length()); + this->group_sb->SetCount((uint)this->groups.size()); + this->vscroll->SetCount((uint)this->vehicles.size()); /* The drop down menu is out, *but* it may not be used, retract it. */ - if (this->vehicles.Length() == 0 && this->IsWidgetLowered(WID_GL_MANAGE_VEHICLES_DROPDOWN)) { + if (this->vehicles.size() == 0 && this->IsWidgetLowered(WID_GL_MANAGE_VEHICLES_DROPDOWN)) { this->RaiseWidget(WID_GL_MANAGE_VEHICLES_DROPDOWN); HideDropDownMenu(this); } /* Disable all lists management button when the list is empty */ - this->SetWidgetsDisabledState(this->vehicles.Length() == 0 || _local_company != this->vli.company, + this->SetWidgetsDisabledState(this->vehicles.size() == 0 || _local_company != this->vli.company, WID_GL_STOP_ALL, WID_GL_START_ALL, WID_GL_MANAGE_VEHICLES_DROPDOWN, @@ -530,7 +559,7 @@ public: this->DrawWidgets(); } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { switch (widget) { case WID_GL_ALL_VEHICLES: @@ -545,7 +574,7 @@ public: Money this_year = 0; Money last_year = 0; uint32 occupancy = 0; - uint32 vehicle_count = this->vehicles.Length(); + size_t vehicle_count = this->vehicles.size(); for (uint i = 0; i < vehicle_count; i++) { const Vehicle *v = this->vehicles[i]; @@ -581,17 +610,17 @@ public: case WID_GL_LIST_GROUP: { int y1 = r.top + WD_FRAMERECT_TOP; - int max = min(this->group_sb->GetPosition() + this->group_sb->GetCapacity(), this->groups.Length()); + int max = min(this->group_sb->GetPosition() + this->group_sb->GetCapacity(), (uint)this->groups.size()); for (int i = this->group_sb->GetPosition(); i < max; ++i) { const Group *g = this->groups[i]; assert(g->owner == this->owner); - DrawGroupInfo(y1, r.left, r.right, g->index, this->indents[i] * LEVEL_WIDTH, g->replace_protection); + DrawGroupInfo(y1, r.left, r.right, g->index, this->indents[i] * LEVEL_WIDTH, g->replace_protection, g->folded || (i + 1 < (int)this->groups.size() && indents[i + 1] > this->indents[i])); y1 += this->tiny_step_height; } - if ((uint)this->group_sb->GetPosition() + this->group_sb->GetCapacity() > this->groups.Length()) { + if ((uint)this->group_sb->GetPosition() + this->group_sb->GetCapacity() > this->groups.size()) { DrawGroupInfo(y1, r.left, r.right, NEW_GROUP); } break; @@ -605,7 +634,7 @@ public: if (this->vli.index != ALL_GROUP) { /* Mark vehicles which are in sub-groups */ int y = r.top; - uint max = min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->vehicles.Length()); + uint max = min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), (uint)this->vehicles.size()); for (uint i = this->vscroll->GetPosition(); i < max; ++i) { const Vehicle *v = this->vehicles[i]; if (v->group_id != this->vli.index) { @@ -629,7 +658,7 @@ public: } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_GL_SORT_BY_ORDER: // Flip sorting method ascending/descending @@ -659,7 +688,34 @@ public: case WID_GL_LIST_GROUP: { // Matrix Group uint id_g = this->group_sb->GetScrolledRowFromWidget(pt.y, this, WID_GL_LIST_GROUP, 0, this->tiny_step_height); - if (id_g >= this->groups.Length()) return; + if (id_g >= this->groups.size()) return; + + if (groups[id_g]->folded || (id_g + 1 < this->groups.size() && this->indents[id_g + 1] > this->indents[id_g])) { + /* 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; + if (click_count > 1 || (pt.x >= x && pt.x < (int)(x + this->column_size[VGC_FOLD].width))) { + + GroupID g = this->vli.index; + if (!IsAllGroupID(g) && !IsDefaultGroupID(g)) { + do { + g = Group::Get(g)->parent; + if (g == groups[id_g]->index) { + this->vli.index = g; + break; + } + } while (g != INVALID_GROUP); + } + + Group::Get(groups[id_g]->index)->folded = !groups[id_g]->folded; + this->groups.ForceRebuild(); + + this->SetDirty(); + break; + } + } this->group_sel = this->vli.index = this->groups[id_g]->index; @@ -672,13 +728,17 @@ public: case WID_GL_LIST_VEHICLE: { // Matrix Vehicle uint id_v = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_GL_LIST_VEHICLE); - if (id_v >= this->vehicles.Length()) return; // click out of list bound + if (id_v >= this->vehicles.size()) return; // click out of list bound const Vehicle *v = this->vehicles[id_v]; if (VehicleClicked(v)) break; this->vehicle_sel = v->index; + if (_ctrl_pressed) { + this->SelectGroup(v->group_id); + } + SetObjectToPlaceWnd(SPR_CURSOR_MOUSE, PAL_NONE, HT_DRAG, this); SetMouseCursorVehicle(v, EIT_IN_LIST); _cursor.vehchain = true; @@ -711,8 +771,7 @@ public: break; case WID_GL_MANAGE_VEHICLES_DROPDOWN: { - DropDownList *list = this->BuildActionDropdownList(true, Group::IsValidID(this->vli.index)); - ShowDropDownList(this, list, 0, WID_GL_MANAGE_VEHICLES_DROPDOWN); + ShowDropDownList(this, this->BuildActionDropdownList(true, Group::IsValidID(this->vli.index)), 0, WID_GL_MANAGE_VEHICLES_DROPDOWN); break; } @@ -724,7 +783,7 @@ public: case WID_GL_REPLACE_PROTECTION: { const Group *g = Group::GetIfValid(this->vli.index); - if (g != NULL) { + if (g != nullptr) { DoCommandP(0, this->vli.index, (g->replace_protection ? 0 : 1) | (_ctrl_pressed << 1), CMD_SET_GROUP_REPLACE_PROTECTION); } break; @@ -738,7 +797,7 @@ public: switch (widget) { case WID_GL_ALL_VEHICLES: // All vehicles - case WID_GL_DEFAULT_VEHICLES: // Ungroupd vehicles + case WID_GL_DEFAULT_VEHICLES: // Ungrouped vehicles if (g->parent != INVALID_GROUP) { DoCommandP(0, this->group_sel | (1 << 16), INVALID_GROUP, CMD_ALTER_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_SET_PARENT)); } @@ -750,7 +809,7 @@ public: case WID_GL_LIST_GROUP: { // Matrix group uint id_g = this->group_sb->GetScrolledRowFromWidget(pt.y, this, WID_GL_LIST_GROUP, 0, this->tiny_step_height); - GroupID new_g = id_g >= this->groups.Length() ? INVALID_GROUP : this->groups[id_g]->index; + GroupID new_g = id_g >= this->groups.size() ? INVALID_GROUP : this->groups[id_g]->index; if (this->group_sel != new_g && g->parent != new_g) { DoCommandP(0, this->group_sel | (1 << 16), new_g, CMD_ALTER_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_SET_PARENT)); @@ -783,9 +842,9 @@ public: this->SetDirty(); uint id_g = this->group_sb->GetScrolledRowFromWidget(pt.y, this, WID_GL_LIST_GROUP, 0, this->tiny_step_height); - GroupID new_g = id_g >= this->groups.Length() ? NEW_GROUP : this->groups[id_g]->index; + GroupID new_g = id_g >= this->groups.size() ? NEW_GROUP : this->groups[id_g]->index; - DoCommandP(0, new_g, vindex | (_ctrl_pressed ? 1 << 31 : 0), CMD_ADD_VEHICLE_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_ADD_VEHICLE), new_g == NEW_GROUP ? CcAddVehicleNewGroup : NULL); + DoCommandP(0, new_g, vindex | (_ctrl_pressed ? 1 << 31 : 0), CMD_ADD_VEHICLE_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_ADD_VEHICLE), new_g == NEW_GROUP ? CcAddVehicleNewGroup : nullptr); break; } @@ -796,7 +855,7 @@ public: this->SetDirty(); uint id_v = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_GL_LIST_VEHICLE); - if (id_v >= this->vehicles.Length()) return; // click out of list bound + if (id_v >= this->vehicles.size()) return; // click out of list bound const Vehicle *v = this->vehicles[id_v]; if (!VehicleClicked(v) && vindex == v->index) { @@ -807,7 +866,7 @@ public: } } - virtual void OnDragDrop(Point pt, int widget) + void OnDragDrop(Point pt, int widget) override { if (this->vehicle_sel != INVALID_VEHICLE) OnDragDrop_Vehicle(pt, widget); if (this->group_sel != INVALID_GROUP) OnDragDrop_Group(pt, widget); @@ -815,19 +874,19 @@ public: _cursor.vehchain = false; } - virtual void OnQueryTextFinished(char *str) + void OnQueryTextFinished(char *str) override { - if (str != NULL) DoCommandP(0, this->group_rename, 0, CMD_ALTER_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_RENAME), NULL, str); + if (str != nullptr) DoCommandP(0, this->group_rename, 0, CMD_ALTER_GROUP | CMD_MSG(STR_ERROR_GROUP_CAN_T_RENAME), nullptr, str); this->group_rename = INVALID_GROUP; } - virtual void OnResize() + void OnResize() override { this->group_sb->SetCapacityFromWidget(this, WID_GL_LIST_GROUP); this->vscroll->SetCapacityFromWidget(this, WID_GL_LIST_VEHICLE); } - virtual void OnDropdownSelect(int widget, int index) + void OnDropdownSelect(int widget, int index) override { switch (widget) { case WID_GL_SORT_BY_DROPDOWN: @@ -835,7 +894,7 @@ public: break; case WID_GL_MANAGE_VEHICLES_DROPDOWN: - assert(this->vehicles.Length() != 0); + assert(this->vehicles.size() != 0); switch (index) { case ADI_REPLACE: // Replace window @@ -867,14 +926,14 @@ public: this->SetDirty(); } - virtual void OnGameTick() + void OnGameTick() override { if (this->groups.NeedResort() || this->vehicles.NeedResort()) { this->SetDirty(); } } - virtual void OnPlaceObjectAbort() + void OnPlaceObjectAbort() override { /* abort drag & drop */ this->vehicle_sel = INVALID_VEHICLE; @@ -883,7 +942,7 @@ public: this->SetWidgetDirty(WID_GL_LIST_VEHICLE); } - virtual void OnMouseDrag(Point pt, int widget) + void OnMouseDrag(Point pt, int widget) override { if (this->vehicle_sel == INVALID_VEHICLE && this->group_sel == INVALID_GROUP) return; @@ -896,7 +955,7 @@ public: case WID_GL_LIST_GROUP: { // ... the list of custom groups. uint id_g = this->group_sb->GetScrolledRowFromWidget(pt.y, this, WID_GL_LIST_GROUP, 0, this->tiny_step_height); - new_group_over = id_g >= this->groups.Length() ? NEW_GROUP : this->groups[id_g]->index; + new_group_over = id_g >= this->groups.size() ? NEW_GROUP : this->groups[id_g]->index; break; } } @@ -938,6 +997,36 @@ public: { if (this->vehicle_sel == vehicle) ResetObjectToPlace(); } + + /** + * Selects the specified group in the list + * + * @param g_id The ID of the group to be selected + */ + void SelectGroup(const GroupID g_id) + { + if (g_id == INVALID_GROUP || g_id == this->vli.index) return; + + this->vli.index = g_id; + if (g_id != ALL_GROUP && g_id != DEFAULT_GROUP) { + const Group *g = Group::Get(g_id); + int id_g = find_index(this->groups, g); + // The group's branch is maybe collapsed, so try to expand it + if (id_g == -1) { + for (auto pg = Group::GetIfValid(g->parent); pg != nullptr; pg = Group::GetIfValid(pg->parent)) { + pg->folded = false; + } + this->groups.ForceRebuild(); + this->BuildGroupList(this->owner); + this->group_sb->SetCount((uint)this->groups.size()); + id_g = find_index(this->groups, g); + } + this->group_sb->ScrollTowards(id_g); + } + this->vehicles.ForceRebuild(); + this->SetDirty(); + } + }; @@ -959,25 +1048,38 @@ static WindowDesc _train_group_desc( * Show the group window for the given company and vehicle type. * @param company The company to show the window for. * @param vehicle_type The type of vehicle to show it for. + * @param group The group to be selected. Defaults to INVALID_GROUP. + * @param need_existing_window Whether the existing window is needed. Defaults to false. */ -void ShowCompanyGroup(CompanyID company, VehicleType vehicle_type) +void ShowCompanyGroup(CompanyID company, VehicleType vehicle_type, GroupID group = INVALID_GROUP, bool need_existing_window = false) { if (!Company::IsValidID(company)) return; - WindowNumber num = VehicleListIdentifier(VL_GROUP_LIST, vehicle_type, company).Pack(); + const WindowNumber num = VehicleListIdentifier(VL_GROUP_LIST, vehicle_type, company).Pack(); + VehicleGroupWindow *w; if (vehicle_type == VEH_TRAIN) { - AllocateWindowDescFront(&_train_group_desc, num); + w = AllocateWindowDescFront(&_train_group_desc, num, need_existing_window); } else { _other_group_desc.cls = GetWindowClassForVehicleType(vehicle_type); - AllocateWindowDescFront(&_other_group_desc, num); + w = AllocateWindowDescFront(&_other_group_desc, num, need_existing_window); } + if (w != nullptr) w->SelectGroup(group); +} + +/** + * Show the group window for the given vehicle. + * @param v The vehicle to show the window for. + */ +void ShowCompanyGroupForVehicle(const Vehicle *v) +{ + ShowCompanyGroup(v->owner, v->type, v->group_id, true); } /** * Finds a group list window determined by vehicle type and owner * @param vt vehicle type * @param owner owner of groups - * @return pointer to VehicleGroupWindow, NULL if not found + * @return pointer to VehicleGroupWindow, nullptr if not found */ static inline VehicleGroupWindow *FindVehicleGroupWindow(VehicleType vt, Owner owner) { @@ -990,15 +1092,16 @@ static inline VehicleGroupWindow *FindVehicleGroupWindow(VehicleType vt, Owner o * @param tile Unused. * @param p1 Vehicle type. * @param p2 Unused. + * @param cmd Unused. * @see CmdCreateGroup */ -void CcCreateGroup(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) +void CcCreateGroup(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) { if (result.Failed()) return; assert(p1 <= VEH_AIRCRAFT); VehicleGroupWindow *w = FindVehicleGroupWindow((VehicleType)p1, _current_company); - if (w != NULL) w->ShowRenameGroupWindow(_new_group_id, true); + if (w != nullptr) w->ShowRenameGroupWindow(_new_group_id, true); } /** @@ -1007,13 +1110,14 @@ void CcCreateGroup(const CommandCost &result, TileIndex tile, uint32 p1, uint32 * @param tile Unused. * @param p1 Unused. * @param p2 Bit 0-19: Vehicle ID. + * @param cmd Unused. */ -void CcAddVehicleNewGroup(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) +void CcAddVehicleNewGroup(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) { if (result.Failed()) return; assert(Vehicle::IsValidID(GB(p2, 0, 20))); - CcCreateGroup(result, 0, Vehicle::Get(GB(p2, 0, 20))->type, 0); + CcCreateGroup(result, 0, Vehicle::Get(GB(p2, 0, 20))->type, 0, cmd); } /** @@ -1028,5 +1132,5 @@ void DeleteGroupHighlightOfVehicle(const Vehicle *v) if (_special_mouse_mode != WSM_DRAGDROP) return; VehicleGroupWindow *w = FindVehicleGroupWindow(v->type, v->owner); - if (w != NULL) w->UnselectVehicle(v->index); + if (w != nullptr) w->UnselectVehicle(v->index); } diff --git a/src/group_gui.h b/src/group_gui.h index 108d611e75..d42704663e 100644 --- a/src/group_gui.h +++ b/src/group_gui.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. @@ -15,7 +13,8 @@ #include "company_type.h" #include "vehicle_type.h" -void ShowCompanyGroup(CompanyID company, VehicleType veh); +void ShowCompanyGroup(CompanyID company, VehicleType veh, GroupID group = INVALID_GROUP, bool need_existing_window = false); +void ShowCompanyGroupForVehicle(const Vehicle *v); void DeleteGroupHighlightOfVehicle(const Vehicle *v); #endif /* GROUP_GUI_H */ diff --git a/src/group_type.h b/src/group_type.h index 530f31f1ea..d3a0487a61 100644 --- a/src/group_type.h +++ b/src/group_type.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/gui.h b/src/gui.h index 39f1ea661e..181472f555 100644 --- a/src/gui.h +++ b/src/gui.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/guitimer_func.h b/src/guitimer_func.h index 44ce042287..f37bd5dbbc 100644 --- a/src/guitimer_func.h +++ b/src/guitimer_func.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/heightmap.cpp b/src/heightmap.cpp index 17bdbbf610..fab93c9802 100644 --- a/src/heightmap.cpp +++ b/src/heightmap.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. @@ -47,7 +45,7 @@ static void ReadHeightmapPNGImageData(byte *map, png_structp png_ptr, png_infop { uint x, y; byte gray_palette[256]; - png_bytep *row_pointers = NULL; + png_bytep *row_pointers = nullptr; bool has_palette = png_get_color_type(png_ptr, info_ptr) == PNG_COLOR_TYPE_PALETTE; uint channels = png_get_channels(png_ptr, info_ptr); @@ -99,33 +97,33 @@ static void ReadHeightmapPNGImageData(byte *map, png_structp png_ptr, png_infop /** * Reads the heightmap and/or size of the heightmap from a PNG file. - * If map == NULL only the size of the PNG is read, otherwise a map + * If map == nullptr only the size of the PNG is read, otherwise a map * with grayscale pixels is allocated and assigned to *map. */ static bool ReadHeightmapPNG(const char *filename, uint *x, uint *y, byte **map) { FILE *fp; - png_structp png_ptr = NULL; - png_infop info_ptr = NULL; + png_structp png_ptr = nullptr; + png_infop info_ptr = nullptr; fp = FioFOpenFile(filename, "rb", HEIGHTMAP_DIR); - if (fp == NULL) { + if (fp == nullptr) { ShowErrorMessage(STR_ERROR_PNGMAP, STR_ERROR_PNGMAP_FILE_NOT_FOUND, WL_ERROR); return false; } - png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); - if (png_ptr == NULL) { + png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, nullptr, nullptr, nullptr); + if (png_ptr == nullptr) { ShowErrorMessage(STR_ERROR_PNGMAP, STR_ERROR_PNGMAP_MISC, WL_ERROR); fclose(fp); return false; } info_ptr = png_create_info_struct(png_ptr); - if (info_ptr == NULL || setjmp(png_jmpbuf(png_ptr))) { + if (info_ptr == nullptr || setjmp(png_jmpbuf(png_ptr))) { ShowErrorMessage(STR_ERROR_PNGMAP, STR_ERROR_PNGMAP_MISC, WL_ERROR); fclose(fp); - png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + png_destroy_read_struct(&png_ptr, &info_ptr, nullptr); return false; } @@ -134,14 +132,14 @@ static bool ReadHeightmapPNG(const char *filename, uint *x, uint *y, byte **map) /* Allocate memory and read image, without alpha or 16-bit samples * (result is either 8-bit indexed/grayscale or 24-bit RGB) */ png_set_packing(png_ptr); - png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_PACKING | PNG_TRANSFORM_STRIP_ALPHA | PNG_TRANSFORM_STRIP_16, NULL); + png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_PACKING | PNG_TRANSFORM_STRIP_ALPHA | PNG_TRANSFORM_STRIP_16, nullptr); /* Maps of wrong colour-depth are not used. * (this should have been taken care of by stripping alpha and 16-bit samples on load) */ if ((png_get_channels(png_ptr, info_ptr) != 1) && (png_get_channels(png_ptr, info_ptr) != 3) && (png_get_bit_depth(png_ptr, info_ptr) != 8)) { ShowErrorMessage(STR_ERROR_PNGMAP, STR_ERROR_PNGMAP_IMAGE_TYPE, WL_ERROR); fclose(fp); - png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + png_destroy_read_struct(&png_ptr, &info_ptr, nullptr); return false; } @@ -152,11 +150,11 @@ static bool ReadHeightmapPNG(const char *filename, uint *x, uint *y, byte **map) if ((uint64)width * height >= (size_t)-1) { ShowErrorMessage(STR_ERROR_PNGMAP, STR_ERROR_HEIGHTMAP_TOO_LARGE, WL_ERROR); fclose(fp); - png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + png_destroy_read_struct(&png_ptr, &info_ptr, nullptr); return false; } - if (map != NULL) { + if (map != nullptr) { *map = MallocT(width * height); ReadHeightmapPNGImageData(*map, png_ptr, info_ptr); } @@ -165,7 +163,7 @@ static bool ReadHeightmapPNG(const char *filename, uint *x, uint *y, byte **map) *y = height; fclose(fp); - png_destroy_read_struct(&png_ptr, &info_ptr, NULL); + png_destroy_read_struct(&png_ptr, &info_ptr, nullptr); return true; } @@ -180,7 +178,7 @@ static void ReadHeightmapBMPImageData(byte *map, BmpInfo *info, BmpData *data) uint x, y; byte gray_palette[256]; - if (data->palette != NULL) { + if (data->palette != nullptr) { uint i; bool all_gray = true; @@ -229,7 +227,7 @@ static void ReadHeightmapBMPImageData(byte *map, BmpInfo *info, BmpData *data) /** * Reads the heightmap and/or size of the heightmap from a BMP file. - * If map == NULL only the size of the BMP is read, otherwise a map + * If map == nullptr only the size of the BMP is read, otherwise a map * with grayscale pixels is allocated and assigned to *map. */ static bool ReadHeightmapBMP(const char *filename, uint *x, uint *y, byte **map) @@ -243,7 +241,7 @@ static bool ReadHeightmapBMP(const char *filename, uint *x, uint *y, byte **map) memset(&data, 0, sizeof(data)); f = FioFOpenFile(filename, "rb", HEIGHTMAP_DIR); - if (f == NULL) { + if (f == nullptr) { ShowErrorMessage(STR_ERROR_BMPMAP, STR_ERROR_PNGMAP_FILE_NOT_FOUND, WL_ERROR); return false; } @@ -265,7 +263,7 @@ static bool ReadHeightmapBMP(const char *filename, uint *x, uint *y, byte **map) return false; } - if (map != NULL) { + if (map != nullptr) { if (!BmpReadBitmap(&buffer, &info, &data)) { ShowErrorMessage(STR_ERROR_BMPMAP, STR_ERROR_BMPMAP_IMAGE_TYPE, WL_ERROR); fclose(f); @@ -449,7 +447,7 @@ void FixSlopes() * @param filename Name of the file to load. * @param[out] x Length of the image. * @param[out] y Height of the image. - * @param[in,out] map If not \c NULL, destination to store the loaded block of image data. + * @param[in,out] map If not \c nullptr, destination to store the loaded block of image data. * @return Whether loading was successful. */ static bool ReadHeightMap(DetailedFileType dft, const char *filename, uint *x, uint *y, byte **map) @@ -478,7 +476,7 @@ static bool ReadHeightMap(DetailedFileType dft, const char *filename, uint *x, u */ bool GetHeightmapDimensions(DetailedFileType dft, const char *filename, uint *x, uint *y) { - return ReadHeightMap(dft, filename, x, y, NULL); + return ReadHeightMap(dft, filename, x, y, nullptr); } /** @@ -491,7 +489,7 @@ bool GetHeightmapDimensions(DetailedFileType dft, const char *filename, uint *x, void LoadHeightmap(DetailedFileType dft, const char *filename) { uint x, y; - byte *map = NULL; + byte *map = nullptr; if (!ReadHeightMap(dft, filename, &x, &y, &map)) { free(map); diff --git a/src/heightmap.h b/src/heightmap.h index 67349df483..9c3e71bbee 100644 --- a/src/heightmap.h +++ b/src/heightmap.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/highscore.cpp b/src/highscore.cpp index 86e4f5ae88..d8fe348fe0 100644 --- a/src/highscore.cpp +++ b/src/highscore.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. @@ -17,7 +15,6 @@ #include "string_func.h" #include "strings_func.h" #include "table/strings.h" -#include "core/sort_func.hpp" #include "debug.h" #include "safeguards.h" @@ -79,9 +76,9 @@ int8 SaveHighScoreValue(const Company *c) } /** Sort all companies given their performance */ -static int CDECL HighScoreSorter(const Company * const *a, const Company * const *b) +static bool HighScoreSorter(const Company * const &a, const Company * const &b) { - return (*b)->old_economy[0].performance_history - (*a)->old_economy[0].performance_history; + return b->old_economy[0].performance_history < a->old_economy[0].performance_history; } /** @@ -90,15 +87,14 @@ static int CDECL HighScoreSorter(const Company * const *a, const Company * const */ int8 SaveHighScoreValueNetwork() { - const Company *c; const Company *cl[MAX_COMPANIES]; uint count = 0; int8 company = -1; /* Sort all active companies with the highest score first */ - FOR_ALL_COMPANIES(c) cl[count++] = c; + for (const Company *c : Company::Iterate()) cl[count++] = c; - QSortT(cl, count, &HighScoreSorter); + std::sort(std::begin(cl), std::begin(cl) + count, HighScoreSorter); { uint i; @@ -129,7 +125,7 @@ void SaveToHighScore() { FILE *fp = fopen(_highscore_file, "wb"); - if (fp != NULL) { + if (fp != nullptr) { uint i; HighScore *hs; @@ -159,7 +155,7 @@ void LoadFromHighScore() memset(_highscore_table, 0, sizeof(_highscore_table)); - if (fp != NULL) { + if (fp != nullptr) { uint i; HighScore *hs; diff --git a/src/highscore.h b/src/highscore.h index 5d4b919ee5..8993e83afa 100644 --- a/src/highscore.h +++ b/src/highscore.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/highscore_gui.cpp b/src/highscore_gui.cpp index c67aaa170b..68b823966f 100644 --- a/src/highscore_gui.cpp +++ b/src/highscore_gui.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. @@ -22,6 +20,7 @@ #include "company_base.h" #include "strings_func.h" #include "hotkeys.h" +#include "zoom_func.h" #include "widgets/highscore_widget.h" @@ -63,12 +62,12 @@ struct EndGameHighScoreBaseWindow : Window { return pt; } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { delete this; } - virtual EventState OnKeyPress(WChar key, uint16 keycode) + EventState OnKeyPress(WChar key, uint16 keycode) override { /* All keys are 'handled' by this window but we want to make * sure that 'quit' still works correctly. Not handling the @@ -129,13 +128,13 @@ struct EndGameWindow : EndGameHighScoreBaseWindow { ShowHighscoreTable(this->window_number, this->rank); } - virtual void OnPaint() + void OnPaint() override { this->SetupHighScoreEndWindow(); - Point pt = this->GetTopLeft(640, 480); + Point pt = this->GetTopLeft(ScaleGUITrad(640), ScaleGUITrad(480)); const Company *c = Company::GetIfValid(_local_company); - if (c == NULL) return; + if (c == nullptr) return; /* We need to get performance from last year because the image is shown * at the start of the new year when these things have already been copied */ @@ -143,11 +142,11 @@ struct EndGameWindow : EndGameHighScoreBaseWindow { SetDParam(0, c->index); SetDParam(1, c->index); SetDParam(2, EndGameGetPerformanceTitleFromValue(c->old_economy[0].performance_history)); - DrawStringMultiLine(pt.x + 15, pt.x + 640 - 25, pt.y + 90, pt.y + 160, STR_HIGHSCORE_PRESIDENT_OF_COMPANY_ACHIEVES_STATUS, TC_FROMSTRING, SA_CENTER); + 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); } else { SetDParam(0, c->index); SetDParam(1, EndGameGetPerformanceTitleFromValue(c->old_economy[0].performance_history)); - DrawStringMultiLine(pt.x + 36, pt.x + 640, pt.y + 140, pt.y + 206, STR_HIGHSCORE_COMPANY_ACHIEVES_STATUS, TC_FROMSTRING, SA_CENTER); + 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); } } }; @@ -177,29 +176,29 @@ struct HighScoreWindow : EndGameHighScoreBaseWindow { if (!_networking && !this->game_paused_by_player) DoCommandP(0, PM_PAUSED_NORMAL, 0, CMD_PAUSE); // unpause } - virtual void OnPaint() + void OnPaint() override { const HighScore *hs = _highscore_table[this->window_number]; this->SetupHighScoreEndWindow(); - Point pt = this->GetTopLeft(640, 480); + Point pt = this->GetTopLeft(ScaleGUITrad(640), ScaleGUITrad(480)); SetDParam(0, ORIGINAL_END_YEAR); - DrawStringMultiLine(pt.x + 70, pt.x + 570, pt.y, pt.y + 140, !_networking ? STR_HIGHSCORE_TOP_COMPANIES_WHO_REACHED : STR_HIGHSCORE_TOP_COMPANIES_NETWORK_GAME, TC_FROMSTRING, SA_CENTER); + 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); /* Draw Highscore peepz */ for (uint8 i = 0; i < lengthof(_highscore_table[0]); i++) { SetDParam(0, i + 1); - DrawString(pt.x + 40, pt.x + 600, pt.y + 140 + (i * 55), STR_HIGHSCORE_POSITION); + DrawString(pt.x + ScaleGUITrad(40), pt.x + ScaleGUITrad(600), pt.y + ScaleGUITrad(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 + 71, pt.x + 569, pt.y + 140 + (i * 55), STR_JUST_BIG_RAW_STRING, colour); + DrawString(pt.x + ScaleGUITrad(71), pt.x + ScaleGUITrad(569), pt.y + ScaleGUITrad(140 + i * 55), STR_JUST_BIG_RAW_STRING, colour); SetDParam(0, hs[i].title); SetDParam(1, hs[i].score); - DrawString(pt.x + 71, pt.x + 569, pt.y + 140 + FONT_HEIGHT_LARGE + (i * 55), STR_HIGHSCORE_STATS, colour); + DrawString(pt.x + ScaleGUITrad(71), pt.x + ScaleGUITrad(569), pt.y + ScaleGUITrad(140) + FONT_HEIGHT_LARGE + ScaleGUITrad(i * 55), STR_HIGHSCORE_STATS, colour); } } } @@ -210,14 +209,14 @@ static const NWidgetPart _nested_highscore_widgets[] = { }; static WindowDesc _highscore_desc( - WDP_MANUAL, NULL, 0, 0, + WDP_MANUAL, nullptr, 0, 0, WC_HIGHSCORE, WC_NONE, 0, _nested_highscore_widgets, lengthof(_nested_highscore_widgets) ); static WindowDesc _endgame_desc( - WDP_MANUAL, NULL, 0, 0, + WDP_MANUAL, nullptr, 0, 0, WC_ENDSCREEN, WC_NONE, 0, _nested_highscore_widgets, lengthof(_nested_highscore_widgets) diff --git a/src/hotkeys.cpp b/src/hotkeys.cpp index 12bd827fa5..d5cd90b3c5 100644 --- a/src/hotkeys.cpp +++ b/src/hotkeys.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. @@ -24,7 +22,7 @@ char *_hotkeys_file; * List of all HotkeyLists. * This is a pointer to ensure initialisation order with the various static HotkeyList instances. */ -static SmallVector *_hotkey_lists = NULL; +static std::vector *_hotkey_lists = nullptr; /** String representation of a keycode */ struct KeycodeNames { @@ -40,10 +38,15 @@ static const KeycodeNames _keycode_to_name[] = { {"META", WKC_META}, {"GLOBAL", WKC_GLOBAL_HOTKEY}, {"ESC", WKC_ESC}, - {"DEL", WKC_DELETE}, {"BACKSPACE", WKC_BACKSPACE}, + {"INS", WKC_INSERT}, + {"DEL", WKC_DELETE}, + {"PAGEUP", WKC_PAGEUP}, + {"PAGEDOWN", WKC_PAGEDOWN}, + {"END", WKC_END}, + {"HOME", WKC_HOME}, {"RETURN", WKC_RETURN}, - {"BACKQUOTE", WKC_BACKQUOTE}, + {"SPACE", WKC_SPACE}, {"F1", WKC_F1}, {"F2", WKC_F2}, {"F3", WKC_F3}, @@ -56,11 +59,24 @@ static const KeycodeNames _keycode_to_name[] = { {"F10", WKC_F10}, {"F11", WKC_F11}, {"F12", WKC_F12}, + {"BACKQUOTE", WKC_BACKQUOTE}, {"PAUSE", WKC_PAUSE}, - {"COMMA", WKC_COMMA}, - {"NUM_PLUS", WKC_NUM_PLUS}, + {"NUM_DIV", WKC_NUM_DIV}, + {"NUM_MUL", WKC_NUM_MUL}, {"NUM_MINUS", WKC_NUM_MINUS}, + {"NUM_PLUS", WKC_NUM_PLUS}, + {"NUM_ENTER", WKC_NUM_ENTER}, + {"NUM_DOT", WKC_NUM_DECIMAL}, + {"/", WKC_SLASH}, + {";", WKC_SEMICOLON}, {"=", WKC_EQUALS}, + {"[", WKC_L_BRACKET}, + {"\\", WKC_BACKSLASH}, + {"]", WKC_R_BRACKET}, + {"'", WKC_SINGLEQUOTE}, + {",", WKC_COMMA}, + {"COMMA", WKC_COMMA}, // legacy variant, should be below "," + {".", WKC_PERIOD}, {"-", WKC_MINUS}, }; @@ -203,7 +219,7 @@ const char *SaveKeycodes(const Hotkey *hotkey) { static char buf[128]; buf[0] = '\0'; - for (uint i = 0; i < hotkey->keycodes.Length(); i++) { + for (uint i = 0; i < hotkey->keycodes.size(); i++) { const char *str = KeycodeToString(hotkey->keycodes[i]); if (i > 0) strecat(buf, ",", lastof(buf)); strecat(buf, str, lastof(buf)); @@ -248,19 +264,19 @@ Hotkey::Hotkey(const uint16 *default_keycodes, const char *name, int num) : */ void Hotkey::AddKeycode(uint16 keycode) { - this->keycodes.Include(keycode); + include(this->keycodes, keycode); } HotkeyList::HotkeyList(const char *ini_group, Hotkey *items, GlobalHotkeyHandlerFunc global_hotkey_handler) : global_hotkey_handler(global_hotkey_handler), ini_group(ini_group), items(items) { - if (_hotkey_lists == NULL) _hotkey_lists = new SmallVector(); - *_hotkey_lists->Append() = this; + if (_hotkey_lists == nullptr) _hotkey_lists = new std::vector(); + _hotkey_lists->push_back(this); } HotkeyList::~HotkeyList() { - _hotkey_lists->Erase(_hotkey_lists->Find(this)); + _hotkey_lists->erase(std::find(_hotkey_lists->begin(), _hotkey_lists->end(), this)); } /** @@ -270,11 +286,11 @@ HotkeyList::~HotkeyList() void HotkeyList::Load(IniFile *ini) { IniGroup *group = ini->GetGroup(this->ini_group); - for (Hotkey *hotkey = this->items; hotkey->name != NULL; ++hotkey) { + for (Hotkey *hotkey = this->items; hotkey->name != nullptr; ++hotkey) { IniItem *item = group->GetItem(hotkey->name, false); - if (item != NULL) { - hotkey->keycodes.Clear(); - if (item->value != NULL) ParseHotkeys(hotkey, item->value); + if (item != nullptr) { + hotkey->keycodes.clear(); + if (item->value != nullptr) ParseHotkeys(hotkey, item->value); } } } @@ -286,7 +302,7 @@ void HotkeyList::Load(IniFile *ini) void HotkeyList::Save(IniFile *ini) const { IniGroup *group = ini->GetGroup(this->ini_group); - for (const Hotkey *hotkey = this->items; hotkey->name != NULL; ++hotkey) { + for (const Hotkey *hotkey = this->items; hotkey->name != nullptr; ++hotkey) { IniItem *item = group->GetItem(hotkey->name, true); item->SetValue(SaveKeycodes(hotkey)); } @@ -300,8 +316,10 @@ void HotkeyList::Save(IniFile *ini) const */ int HotkeyList::CheckMatch(uint16 keycode, bool global_only) const { - for (const Hotkey *list = this->items; list->name != NULL; ++list) { - if (list->keycodes.Contains(keycode | WKC_GLOBAL_HOTKEY) || (!global_only && list->keycodes.Contains(keycode))) { + for (const Hotkey *list = this->items; list->name != nullptr; ++list) { + auto begin = list->keycodes.begin(); + auto end = list->keycodes.end(); + if (std::find(begin, end, keycode | WKC_GLOBAL_HOTKEY) != end || (!global_only && std::find(begin, end, keycode) != end)) { return list->num; } } @@ -314,11 +332,11 @@ static void SaveLoadHotkeys(bool save) IniFile *ini = new IniFile(); ini->LoadFromDisk(_hotkeys_file, NO_DIRECTORY); - for (HotkeyList **list = _hotkey_lists->Begin(); list != _hotkey_lists->End(); ++list) { + for (HotkeyList *list : *_hotkey_lists) { if (save) { - (*list)->Save(ini); + list->Save(ini); } else { - (*list)->Load(ini); + list->Load(ini); } } @@ -341,11 +359,11 @@ void SaveHotkeysToConfig() void HandleGlobalHotkeys(WChar key, uint16 keycode) { - for (HotkeyList **list = _hotkey_lists->Begin(); list != _hotkey_lists->End(); ++list) { - if ((*list)->global_hotkey_handler == NULL) continue; + for (HotkeyList *list : *_hotkey_lists) { + if (list->global_hotkey_handler == nullptr) continue; - int hotkey = (*list)->CheckMatch(keycode, true); - if (hotkey >= 0 && ((*list)->global_hotkey_handler(hotkey) == ES_HANDLED)) return; + int hotkey = list->CheckMatch(keycode, true); + if (hotkey >= 0 && (list->global_hotkey_handler(hotkey) == ES_HANDLED)) return; } } diff --git a/src/hotkeys.h b/src/hotkeys.h index 25a489b3f3..59fec34570 100644 --- a/src/hotkeys.h +++ b/src/hotkeys.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. @@ -29,10 +27,10 @@ struct Hotkey { const char *name; int num; - SmallVector keycodes; + std::vector keycodes; }; -#define HOTKEY_LIST_END Hotkey((uint16)0, NULL, -1) +#define HOTKEY_LIST_END Hotkey((uint16)0, nullptr, -1) struct IniFile; @@ -42,7 +40,7 @@ struct IniFile; struct HotkeyList { typedef EventState (*GlobalHotkeyHandlerFunc)(int hotkey); - HotkeyList(const char *ini_group, Hotkey *items, GlobalHotkeyHandlerFunc global_hotkey_handler = NULL); + HotkeyList(const char *ini_group, Hotkey *items, GlobalHotkeyHandlerFunc global_hotkey_handler = nullptr); ~HotkeyList(); void Load(IniFile *ini); diff --git a/src/house.h b/src/house.h index c1cfe61041..7d3b8dc5e8 100644 --- a/src/house.h +++ b/src/house.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/house_type.h b/src/house_type.h index 9c9c41702c..c1623598b1 100644 --- a/src/house_type.h +++ b/src/house_type.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/industry.h b/src/industry.h index af0208b3cc..e82033dd13 100644 --- a/src/industry.h +++ b/src/industry.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. @@ -18,6 +16,7 @@ #include "industry_map.h" #include "industrytype.h" #include "tilearea_type.h" +#include "station_base.h" typedef Pool IndustryPool; @@ -41,6 +40,7 @@ enum ProductionLevels { struct Industry : IndustryPool::PoolItem<&_industry_pool> { TileArea location; ///< Location of the industry Town *town; ///< Nearest town + Station *neutral_station; ///< Associated neutral station CargoID produced_cargo[INDUSTRY_NUM_OUTPUTS]; ///< 16 production cargo slots uint16 produced_cargo_waiting[INDUSTRY_NUM_OUTPUTS]; ///< amount of cargo produced per cargo uint16 incoming_cargo_waiting[INDUSTRY_NUM_INPUTS]; ///< incoming cargo waiting to be processed @@ -54,23 +54,25 @@ struct Industry : IndustryPool::PoolItem<&_industry_pool> { uint16 last_month_transported[INDUSTRY_NUM_OUTPUTS]; ///< total units transported per cargo in the last full month uint16 counter; ///< used for animation and/or production (if available cargo) - IndustryType type; ///< type of industry. - OwnerByte owner; ///< owner of the industry. Which SHOULD always be (imho) OWNER_NONE - byte random_colour; ///< randomized colour of the industry, for display purpose - Year last_prod_year; ///< last year of production - byte was_cargo_delivered; ///< flag that indicate this has been the closest industry chosen for cargo delivery by a station. see DeliverGoodsToIndustry + IndustryType type; ///< type of industry. + Owner owner; ///< owner of the industry. Which SHOULD always be (imho) OWNER_NONE + byte random_colour; ///< randomized colour of the industry, for display purpose + Year last_prod_year; ///< last year of production + byte was_cargo_delivered; ///< flag that indicate this has been the closest industry chosen for cargo delivery by a station. see DeliverGoodsToIndustry - PartOfSubsidyByte part_of_subsidy; ///< NOSAVE: is this industry a source/destination of a subsidy? + PartOfSubsidy part_of_subsidy; ///< NOSAVE: is this industry a source/destination of a subsidy? + StationList stations_near; ///< NOSAVE: List of nearby stations. + mutable std::string cached_name; ///< NOSAVE: Cache of the resolved name of the industry - OwnerByte founder; ///< Founder of the industry - Date construction_date; ///< Date of the construction of the industry - uint8 construction_type; ///< Way the industry was constructed (@see IndustryConstructionType) + Owner founder; ///< Founder of the industry + Date construction_date; ///< Date of the construction of the industry + uint8 construction_type; ///< Way the industry was constructed (@see IndustryConstructionType) Date last_cargo_accepted_at[INDUSTRY_NUM_INPUTS]; ///< Last day each cargo type was accepted by this industry - byte selected_layout; ///< Which tile layout was used when creating the industry + byte selected_layout; ///< Which tile layout was used when creating the industry - uint16 random; ///< Random value used for randomisation of all kinds of things + uint16 random; ///< Random value used for randomisation of all kinds of things - PersistentStorage *psa; ///< Persistent storage for NewGRF industries. + PersistentStorage *psa; ///< Persistent storage for NewGRF industries. Industry(TileIndex tile = INVALID_TILE) : location(tile, 0, 0) {} ~Industry(); @@ -156,19 +158,27 @@ struct Industry : IndustryPool::PoolItem<&_industry_pool> { memset(&counts, 0, sizeof(counts)); } + inline const char *GetCachedName() const + { + if (this->cached_name.empty()) this->FillCachedName(); + return this->cached_name.c_str(); + } + +private: + void FillCachedName() const; + protected: static uint16 counts[NUM_INDUSTRYTYPES]; ///< Number of industries per type ingame }; +void ClearAllIndustryCachedNames(); + void PlantRandomFarmField(const Industry *i); void ReleaseDisastersTargetingIndustry(IndustryID); bool IsTileForestIndustry(TileIndex tile); -#define FOR_ALL_INDUSTRIES_FROM(var, start) FOR_ALL_ITEMS_FROM(Industry, industry_index, var, start) -#define FOR_ALL_INDUSTRIES(var) FOR_ALL_INDUSTRIES_FROM(var, 0) - /** Data for managing the number of industries of a single industry type. */ struct IndustryTypeBuildData { uint32 probability; ///< Relative probability of building this industry. @@ -199,4 +209,12 @@ struct IndustryBuildData { extern IndustryBuildData _industry_builder; + +/** Special values for the industry list window for the data parameter of #InvalidateWindowData. */ +enum IndustryDirectoryInvalidateWindowData { + IDIWD_FORCE_REBUILD, + IDIWD_PRODUCTION_CHANGE, + IDIWD_FORCE_RESORT, +}; + #endif /* INDUSTRY_H */ diff --git a/src/industry_cmd.cpp b/src/industry_cmd.cpp index 086f28abb6..dfc43500f9 100644 --- a/src/industry_cmd.cpp +++ b/src/industry_cmd.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. @@ -71,11 +69,15 @@ IndustryBuildData _industry_builder; ///< In-game manager of industries. */ void ResetIndustries() { - memset(&_industry_specs, 0, sizeof(_industry_specs)); - memcpy(&_industry_specs, &_origin_industry_specs, sizeof(_origin_industry_specs)); - - /* once performed, enable only the current climate industries */ for (IndustryType i = 0; i < NUM_INDUSTRYTYPES; i++) { + /* Reset the spec to default */ + if (i < lengthof(_origin_industry_specs)) { + _industry_specs[i] = _origin_industry_specs[i]; + } else { + _industry_specs[i] = IndustrySpec{}; + } + + /* Enable only the current climate industries */ _industry_specs[i].enabled = i < NEW_INDUSTRYOFFSET && HasBit(_origin_industry_specs[i].climate_availability, _settings_game.game_creation.landscape); } @@ -101,7 +103,7 @@ IndustryType GetIndustryType(TileIndex tile) assert(IsTileType(tile, MP_INDUSTRY)); const Industry *ind = Industry::GetByTile(tile); - assert(ind != NULL); + assert(ind != nullptr); return ind->type; } @@ -142,6 +144,8 @@ Industry::~Industry() * Also we must not decrement industry counts in that case. */ if (this->location.w == 0) return; + const bool has_neutral_station = this->neutral_station != nullptr; + TILE_AREA_LOOP(tile_cur, this->location) { if (IsTileType(tile_cur, MP_INDUSTRY)) { if (GetIndustryIndex(tile_cur) == this->index) { @@ -155,9 +159,15 @@ Industry::~Industry() } } + if (has_neutral_station) { + /* Remove possible docking tiles */ + TILE_AREA_LOOP(tile_cur, this->location) { + ClearDockingTilesCheckingNeighbours(tile_cur); + } + } + if (GetIndustrySpec(this->type)->behaviour & INDUSTRYBEH_PLANT_FIELDS) { - TileArea ta(this->location.tile - TileDiffXY(min(TileX(this->location.tile), 21), min(TileY(this->location.tile), 21)), 42, 42); - ta.ClampToMap(); + TileArea ta = TileArea(this->location.tile, 0, 0).Expand(21); /* Remove the farmland and convert it to regular tiles over time. */ TILE_AREA_LOOP(tile_cur, ta) { @@ -182,6 +192,10 @@ Industry::~Industry() DeleteSubsidyWith(ST_INDUSTRY, this->index); CargoPacket::InvalidateAllFrom(ST_INDUSTRY, this->index); + + for (Station *st : this->stations_near) { + st->industries_near.erase(this); + } } /** @@ -190,18 +204,17 @@ Industry::~Industry() */ void Industry::PostDestructor(size_t index) { - InvalidateWindowData(WC_INDUSTRY_DIRECTORY, 0, 0); - Station::RecomputeIndustriesNearForAll(); + InvalidateWindowData(WC_INDUSTRY_DIRECTORY, 0, IDIWD_FORCE_REBUILD); } /** * Return a random valid industry. - * @return random industry, NULL if there are no industries + * @return random industry, nullptr if there are no industries */ /* static */ Industry *Industry::GetRandom() { - if (Industry::GetNumItems() == 0) return NULL; + if (Industry::GetNumItems() == 0) return nullptr; int num = RandomRange((uint16)Industry::GetNumItems()); size_t index = MAX_UVALUE(size_t); @@ -313,7 +326,7 @@ static void DrawTile_Industry(TileInfo *ti) * DrawNewIndustry will return false if ever the resolver could not * find any sprite to display. So in this case, we will jump on the * substitute gfx instead. */ - if (indts->grf_prop.spritegroup[0] != NULL && DrawNewIndustryTile(ti, ind, gfx, indts)) { + if (indts->grf_prop.spritegroup[0] != nullptr && DrawNewIndustryTile(ti, ind, gfx, indts)) { return; } else { /* No sprite group (or no valid one) found, meaning no graphics associated. @@ -382,7 +395,7 @@ static Foundation GetFoundation_Industry(TileIndex tile, Slope tileh) */ if (gfx >= NEW_INDUSTRYTILEOFFSET) { const IndustryTileSpec *indts = GetIndustryTileSpec(gfx); - if (indts->grf_prop.spritegroup[0] != NULL && HasBit(indts->callback_mask, CBM_INDT_DRAW_FOUNDATIONS)) { + if (indts->grf_prop.spritegroup[0] != nullptr && HasBit(indts->callback_mask, CBM_INDT_DRAW_FOUNDATIONS)) { uint32 callback_res = GetIndustryTileCallback(CBID_INDTILE_DRAW_FOUNDATIONS, 0, 0, gfx, Industry::GetByTile(tile), tile); if (callback_res != CALLBACK_FAILED && !ConvertBooleanCallback(indts->grf_prop.grffile, CBID_INDTILE_DRAW_FOUNDATIONS, callback_res)) return FOUNDATION_NONE; } @@ -472,7 +485,7 @@ static void GetTileDesc_Industry(TileIndex tile, TileDesc *td) td->str = STR_LAI_TOWN_INDUSTRY_DESCRIPTION_UNDER_CONSTRUCTION; } - if (is->grf_prop.grffile != NULL) { + if (is->grf_prop.grffile != nullptr) { td->grf = GetGRFConfig(is->grf_prop.grffile->grfid)->GetName(); } } @@ -516,8 +529,6 @@ static bool TransportIndustryGoods(TileIndex tile) const IndustrySpec *indspec = GetIndustrySpec(i->type); bool moved_cargo = false; - StationFinder stations(i->location); - for (uint j = 0; j < lengthof(i->produced_cargo_waiting); j++) { uint cw = min(i->produced_cargo_waiting[j], 255); if (cw > indspec->minimal_cargo && i->produced_cargo[j] != CT_INVALID) { @@ -528,7 +539,7 @@ static bool TransportIndustryGoods(TileIndex tile) i->this_month_production[j] += cw; - uint am = MoveGoodsToStation(i->produced_cargo[j], cw, ST_INDUSTRY, i->index, stations.GetStations()); + uint am = MoveGoodsToStation(i->produced_cargo[j], cw, ST_INDUSTRY, i->index, &i->stations_near); i->this_month_transported[j] += am; moved_cargo |= (am != 0); @@ -798,7 +809,7 @@ static void TileLoopIndustry_BubbleGenerator(TileIndex tile) EV_BUBBLE ); - if (v != NULL) v->animation_substate = dir; + if (v != nullptr) v->animation_substate = dir; } static void TileLoop_Industry(TileIndex tile) @@ -1077,7 +1088,7 @@ static bool SearchLumberMillTrees(TileIndex tile, void *user_data) if (IsTileType(tile, MP_TREES) && GetTreeGrowth(tile) > 2) { ///< 3 and up means all fully grown trees /* found a tree */ - Backup cur_company(_current_company, OWNER_NONE, FILE_LINE); + Backup cur_company(_current_company, OWNER_NONE, FILE_LINE); _industry_sound_ctr = 1; _industry_sound_tile = tile; @@ -1105,7 +1116,7 @@ static void ChopLumberMillTrees(Industry *i) } TileIndex tile = i->location.tile; - if (CircularTileSearch(&tile, 40, SearchLumberMillTrees, NULL)) { // 40x40 tiles to search. + if (CircularTileSearch(&tile, 40, SearchLumberMillTrees, nullptr)) { // 40x40 tiles to search. i->produced_cargo_waiting[0] = min(0xffff, i->produced_cargo_waiting[0] + 45); // Found a tree, add according value to waiting cargo. } } @@ -1117,11 +1128,16 @@ static void ProduceIndustryGoods(Industry *i) /* play a sound? */ if ((i->counter & 0x3F) == 0) { uint32 r; - uint num; - if (Chance16R(1, 14, r) && (num = indsp->number_of_sounds) != 0 && _settings_client.sound.ambient) { - SndPlayTileFx( - (SoundFx)(indsp->random_sounds[((r >> 16) * num) >> 16]), - i->location.tile); + if (Chance16R(1, 14, r) && indsp->number_of_sounds != 0 && _settings_client.sound.ambient) { + for (size_t j = 0; j < lengthof(i->last_month_production); j++) { + if (i->last_month_production[j] > 0) { + /* Play sound since last month had production */ + SndPlayTileFx( + (SoundFx)(indsp->random_sounds[((r >> 16) * indsp->number_of_sounds) >> 16]), + i->location.tile); + break; + } + } } } @@ -1187,8 +1203,7 @@ void OnTick_Industry() if (_game_mode == GM_EDITOR) return; - Industry *i; - FOR_ALL_INDUSTRIES(i) { + for (Industry *i : Industry::Iterate()) { ProduceIndustryGoods(i); } } @@ -1218,6 +1233,29 @@ static CommandCost CheckNewIndustry_Forest(TileIndex tile) return CommandCost(); } +/** + * Check if a tile is within a distance from map edges, scaled by map dimensions independently. + * Each dimension is checked independently, and dimensions smaller than 256 are not scaled. + * @param tile Which tile to check distance of. + * @param maxdist Normal distance on a 256x256 map. + * @return True if the tile is near the map edge. + */ +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 (DistanceFromEdgeDir(tile, DIAGDIR_NE) < maxdist_x) return true; + if (DistanceFromEdgeDir(tile, DIAGDIR_NW) < maxdist_y) return true; + if (DistanceFromEdgeDir(tile, DIAGDIR_SW) < maxdist_x) return true; + if (DistanceFromEdgeDir(tile, DIAGDIR_SE) < maxdist_y) return true; + + return false; +} + /** * Check the conditions of #CHECK_REFINERY (Industry should be positioned near edge of the map). * @param tile %Tile to perform the checking. @@ -1226,7 +1264,8 @@ static CommandCost CheckNewIndustry_Forest(TileIndex tile) static CommandCost CheckNewIndustry_OilRefinery(TileIndex tile) { if (_game_mode == GM_EDITOR) return CommandCost(); - if (DistanceFromEdge(TILE_ADDXY(tile, 1, 1)) < _settings_game.game_creation.oil_refinery_limit) return CommandCost(); + + if (CheckScaledDistanceFromEdge(TILE_ADDXY(tile, 1, 1), _settings_game.game_creation.oil_refinery_limit)) return CommandCost(); return_cmd_error(STR_ERROR_CAN_ONLY_BE_POSITIONED); } @@ -1241,8 +1280,9 @@ extern bool _ignore_restrictions; static CommandCost CheckNewIndustry_OilRig(TileIndex tile) { if (_game_mode == GM_EDITOR && _ignore_restrictions) return CommandCost(); + if (TileHeight(tile) == 0 && - DistanceFromEdge(TILE_ADDXY(tile, 1, 1)) < _settings_game.game_creation.oil_refinery_limit) return CommandCost(); + CheckScaledDistanceFromEdge(TILE_ADDXY(tile, 1, 1), _settings_game.game_creation.oil_refinery_limit)) return CommandCost(); return_cmd_error(STR_ERROR_CAN_ONLY_BE_POSITIONED); } @@ -1338,11 +1378,11 @@ static CheckNewIndustryProc * const _check_new_industry_procs[CHECK_END] = { * Find a town for the industry, while checking for multiple industries in the same town. * @param tile Position of the industry to build. * @param type Industry type. - * @param[out] t Pointer to return town for the new industry, \c NULL is written if no good town can be found. + * @param[out] t Pointer to return town for the new industry, \c nullptr is written if no good town can be found. * @return Succeeded or failed command. * - * @pre \c *t != NULL - * @post \c *t points to a town on success, and \c NULL on failure. + * @pre \c *t != nullptr + * @post \c *t points to a town on success, and \c nullptr on failure. */ static CommandCost FindTownForIndustry(TileIndex tile, int type, Town **t) { @@ -1350,10 +1390,9 @@ static CommandCost FindTownForIndustry(TileIndex tile, int type, Town **t) if (_settings_game.economy.multiple_industry_per_town) return CommandCost(); - const Industry *i; - FOR_ALL_INDUSTRIES(i) { + for (const Industry *i : Industry::Iterate()) { if (i->type == (byte)type && i->town == *t) { - *t = NULL; + *t = nullptr; return_cmd_error(STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN); } } @@ -1381,8 +1420,8 @@ bool IsSlopeRefused(Slope current, Slope refused) /** * Are the tiles of the industry free? * @param tile Position to check. - * @param it Industry tiles table. - * @param itspec_index The index of the itsepc to build/fund + * @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 @@ -1390,14 +1429,14 @@ bool IsSlopeRefused(Slope current, Slope refused) * @param[out] custom_shape_check Perform custom check for the site. * @return Failed or succeeded command. */ -static CommandCost CheckIfIndustryTilesAreFree(TileIndex tile, const IndustryTileTable *it, uint itspec_index, int type, uint16 initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type, bool *custom_shape_check = NULL) +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) { bool refused_slope = false; bool custom_shape = false; - do { - IndustryGfx gfx = GetTranslatedIndustryTileID(it->gfx); - TileIndex cur_tile = TileAddWrap(tile, it->ti.x, it->ti.y); + for (const IndustryTileLayoutTile &it : layout) { + IndustryGfx gfx = GetTranslatedIndustryTileID(it.gfx); + TileIndex cur_tile = TileAddWrap(tile, it.ti.x, it.ti.y); if (!IsValidTile(cur_tile)) { return_cmd_error(STR_ERROR_SITE_UNSUITABLE); @@ -1422,7 +1461,7 @@ static CommandCost CheckIfIndustryTilesAreFree(TileIndex tile, const IndustryTil if (HasBit(its->callback_mask, CBM_INDT_SHAPE_CHECK)) { custom_shape = true; - CommandCost ret = PerformIndustryTileSlopeCheck(tile, cur_tile, its, type, gfx, itspec_index, initial_random_bits, founder, creation_type); + 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); @@ -1436,7 +1475,7 @@ 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); + Backup cur_company(_current_company, OWNER_TOWN, FILE_LINE); CommandCost ret = DoCommand(cur_tile, 0, 0, DC_NONE, CMD_LANDSCAPE_CLEAR); cur_company.Restore(); @@ -1448,9 +1487,9 @@ static CommandCost CheckIfIndustryTilesAreFree(TileIndex tile, const IndustryTil if (ret.Failed()) return ret; } } - } while ((++it)->ti.x != -0x80); + } - if (custom_shape_check != NULL) *custom_shape_check = custom_shape; + if (custom_shape_check != nullptr) *custom_shape_check = custom_shape; /* It is almost impossible to have a fully flat land in TG, so what we * do is that we check if we can make the land flat later on. See @@ -1512,18 +1551,17 @@ static bool CheckCanTerraformSurroundingTiles(TileIndex tile, uint height, int i * This function tries to flatten out the land below an industry, without * damaging the surroundings too much. */ -static bool CheckIfCanLevelIndustryPlatform(TileIndex tile, DoCommandFlag flags, const IndustryTileTable *it, int type) +static bool CheckIfCanLevelIndustryPlatform(TileIndex tile, DoCommandFlag flags, const IndustryTileLayout &layout, int type) { - const int MKEND = -0x80; // used for last element in an IndustryTileTable (see build_industry.h) int max_x = 0; int max_y = 0; /* Finds dimensions of largest variant of this industry */ - do { - if (it->gfx == 0xFF) continue; // FF been a marquer for a check on clear water, skip it - if (it->ti.x > max_x) max_x = it->ti.x; - if (it->ti.y > max_y) max_y = it->ti.y; - } while ((++it)->ti.x != MKEND); + for (const IndustryTileLayoutTile &it : layout) { + if (it.gfx == GFX_WATERTILE_SPECIALCHECK) continue; // watercheck tiles don't count for footprint size + if (it.ti.x > max_x) max_x = it.ti.x; + if (it.ti.y > max_y) max_y = it.ti.y; + } /* Remember level height */ uint h = TileHeight(tile); @@ -1532,6 +1570,8 @@ static bool CheckIfCanLevelIndustryPlatform(TileIndex tile, DoCommandFlag flags, /* Check that all tiles in area and surrounding are clear * this determines that there are no obstructing items */ + /* TileArea::Expand is not used here as we need to abort + * instead of clamping if the bounds cannot expanded. */ 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); @@ -1539,7 +1579,7 @@ static bool CheckIfCanLevelIndustryPlatform(TileIndex tile, DoCommandFlag flags, /* _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. */ - Backup cur_company(_current_company, OWNER_TOWN, FILE_LINE); + Backup cur_company(_current_company, OWNER_TOWN, FILE_LINE); TILE_AREA_LOOP(tile_walk, ta) { uint curh = TileHeight(tile_walk); @@ -1587,14 +1627,12 @@ static bool CheckIfCanLevelIndustryPlatform(TileIndex tile, DoCommandFlag flags, static CommandCost CheckIfFarEnoughFromConflictingIndustry(TileIndex tile, int type) { const IndustrySpec *indspec = GetIndustrySpec(type); - const Industry *i = NULL; /* On a large map with many industries, it may be faster to check an area. */ static const int dmax = 14; if (Industry::GetNumItems() > (size_t) (dmax * dmax * 2)) { - const int tx = TileX(tile); - const int ty = TileY(tile); - TileArea tile_area = TileArea(TileXY(max(0, tx - dmax), max(0, ty - dmax)), TileXY(min(MapMaxX(), tx + dmax), min(MapMaxY(), ty + dmax))); + const Industry* i = nullptr; + TileArea tile_area = TileArea(tile, 1, 1).Expand(dmax); TILE_AREA_LOOP(atile, tile_area) { if (GetTileType(atile) == MP_INDUSTRY) { const Industry *i2 = Industry::GetByTile(atile); @@ -1611,7 +1649,7 @@ static CommandCost CheckIfFarEnoughFromConflictingIndustry(TileIndex tile, int t return CommandCost(); } - FOR_ALL_INDUSTRIES(i) { + for (const Industry *i : Industry::Iterate()) { /* Within 14 tiles from another industry is considered close */ if (DistanceMax(tile, i->location.tile) > 14) continue; @@ -1644,18 +1682,49 @@ static void AdvertiseIndustryOpening(const Industry *ind) Game::NewEvent(new ScriptEventIndustryOpen(ind->index)); } +/** + * Populate an industry's list of nearby stations, and if it accepts any cargo, also + * add the industry to each station's nearby industry list. + * @param ind Industry + */ +static void PopulateStationsNearby(Industry *ind) +{ + if (ind->neutral_station != nullptr && !_settings_game.station.serve_neutral_industries) { + /* Industry has a neutral station. Use it and ignore any other nearby stations. */ + ind->stations_near.insert(ind->neutral_station); + ind->neutral_station->industries_near.clear(); + ind->neutral_station->industries_near.insert(ind); + return; + } + + /* Get our list of nearby stations. */ + FindStationsAroundTiles(ind->location, &ind->stations_near, false); + + /* Test if industry can accept cargo */ + uint cargo_index; + for (cargo_index = 0; cargo_index < lengthof(ind->accepts_cargo); cargo_index++) { + if (ind->accepts_cargo[cargo_index] != CT_INVALID) break; + } + if (cargo_index >= lengthof(ind->accepts_cargo)) return; + + /* Cargo is accepted, add industry to nearby stations nearby industry list. */ + for (Station *st : ind->stations_near) { + st->industries_near.insert(ind); + } +} + /** * Put an industry on the map. - * @param i Just allocated poolitem, mostly empty. - * @param tile North tile of the industry. - * @param type Type of the industry. - * @param it Industrylayout to build. - * @param layout Number of the layout. - * @param t Nearest town. - * @param founder Founder of the industry; OWNER_NONE in case of random construction. + * @param i Just allocated poolitem, mostly empty. + * @param tile North tile of the industry. + * @param type Type of the industry. + * @param layout Industrylayout to build. + * @param layout_index Number of the industry layout. + * @param t Nearest town. + * @param founder Founder of the industry; OWNER_NONE in case of random construction. * @param initial_random_bits Random bits for the industry. */ -static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, const IndustryTileTable *it, byte layout, Town *t, Owner founder, uint16 initial_random_bits) +static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, const IndustryTileLayout &layout, size_t layout_index, Town *t, Owner founder, uint16 initial_random_bits) { const IndustrySpec *indspec = GetIndustrySpec(type); @@ -1700,7 +1769,7 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, /* Adding 1 here makes it conform to specs of var44 of varaction2 for industries * 0 = created prior of newindustries * else, chosen layout + 1 */ - i->selected_layout = layout + 1; + i->selected_layout = (byte)(layout_index + 1); i->prod_level = PRODLEVEL_DEFAULT; @@ -1753,6 +1822,11 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, break; } CargoID cargo = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile); + /* Industries without "unlimited" cargo types support depend on the specific order/slots of cargo types. + * They need to be able to blank out specific slots without aborting the callback sequence, + * and solve this by returning undefined cargo indexes. Skip these. */ + if (cargo == CT_INVALID && !(indspec->behaviour & INDUSTRYBEH_CARGOTYPES_UNLIMITED)) continue; + /* Verify valid cargo */ if (std::find(indspec->accepts_cargo, endof(indspec->accepts_cargo), cargo) == endof(indspec->accepts_cargo)) { /* Cargo not in spec, error in NewGRF */ ErrorUnknownCallbackResult(indspec->grf_prop.grffile->grfid, CBID_INDUSTRY_INPUT_CARGO_TYPES, res); @@ -1780,6 +1854,9 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, break; } CargoID cargo = GetCargoTranslation(GB(res, 0, 8), indspec->grf_prop.grffile); + /* Allow older GRFs to skip slots. */ + if (cargo == CT_INVALID && !(indspec->behaviour & INDUSTRYBEH_CARGOTYPES_UNLIMITED)) continue; + /* Verify valid cargo */ if (std::find(indspec->produced_cargo, endof(indspec->produced_cargo), cargo) == endof(indspec->produced_cargo)) { /* Cargo not in spec, error in NewGRF */ ErrorUnknownCallbackResult(indspec->grf_prop.grffile->grfid, CBID_INDUSTRY_OUTPUT_CARGO_TYPES, res); @@ -1796,17 +1873,17 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, /* Plant the tiles */ - do { - TileIndex cur_tile = tile + ToTileIndexDiff(it->ti); + for (const IndustryTileLayoutTile &it : layout) { + TileIndex cur_tile = tile + ToTileIndexDiff(it.ti); - if (it->gfx != GFX_WATERTILE_SPECIALCHECK) { + if (it.gfx != GFX_WATERTILE_SPECIALCHECK) { i->location.Add(cur_tile); WaterClass wc = (IsWaterTile(cur_tile) ? GetWaterClass(cur_tile) : WATER_CLASS_INVALID); DoCommand(cur_tile, 0, 0, DC_EXEC | DC_NO_TEST_TOWN_RATING | DC_NO_MODIFY_TOWN_RATING, CMD_LANDSCAPE_CLEAR); - MakeIndustry(cur_tile, i->index, it->gfx, Random(), wc); + MakeIndustry(cur_tile, i->index, it.gfx, Random(), wc); if (_generating_world) { SetIndustryConstructionCounter(cur_tile, 3); @@ -1814,18 +1891,18 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, } /* it->gfx is stored in the map. But the translated ID cur_gfx is the interesting one */ - IndustryGfx cur_gfx = GetTranslatedIndustryTileID(it->gfx); + IndustryGfx cur_gfx = GetTranslatedIndustryTileID(it.gfx); const IndustryTileSpec *its = GetIndustryTileSpec(cur_gfx); if (its->animation.status != ANIM_STATUS_NO_ANIMATION) AddAnimatedTile(cur_tile); } - } while ((++it)->ti.x != -0x80); + } if (GetIndustrySpec(i->type)->behaviour & INDUSTRYBEH_PLANT_ON_BUILT) { for (uint j = 0; j != 50; j++) PlantRandomFarmField(i); } - InvalidateWindowData(WC_INDUSTRY_DIRECTORY, 0, 0); + InvalidateWindowData(WC_INDUSTRY_DIRECTORY, 0, IDIWD_FORCE_REBUILD); - Station::RecomputeIndustriesNearForAll(); + if (!_generating_world) PopulateStationsNearby(i); } /** @@ -1834,7 +1911,7 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, * @param type of industry to build * @param flags of operations to conduct * @param indspec pointer to industry specifications - * @param itspec_index the index of the itsepc to build/fund + * @param layout_index the index of the itsepc to build/fund * @param random_var8f random seed (possibly) used by industries * @param random_initial_bits The random bits the industry is going to have after construction. * @param founder Founder of the industry @@ -1842,40 +1919,40 @@ static void DoCreateNewIndustry(Industry *i, TileIndex tile, IndustryType type, * @param[out] ip Pointer to store newly created industry. * @return Succeeded or failed command. * - * @post \c *ip contains the newly created industry if all checks are successful and the \a flags request actual creation, else it contains \c NULL afterwards. + * @post \c *ip contains the newly created industry if all checks are successful and the \a flags request actual creation, else it contains \c nullptr afterwards. */ -static CommandCost CreateNewIndustryHelper(TileIndex tile, IndustryType type, DoCommandFlag flags, const IndustrySpec *indspec, uint itspec_index, uint32 random_var8f, uint16 random_initial_bits, Owner founder, IndustryAvailabilityCallType creation_type, Industry **ip) +static CommandCost CreateNewIndustryHelper(TileIndex tile, IndustryType type, DoCommandFlag flags, const IndustrySpec *indspec, size_t layout_index, uint32 random_var8f, uint16 random_initial_bits, Owner founder, IndustryAvailabilityCallType creation_type, Industry **ip) { - assert(itspec_index < indspec->num_table); - const IndustryTileTable *it = indspec->table[itspec_index]; + assert(layout_index < indspec->layouts.size()); + const IndustryTileLayout &layout = indspec->layouts[layout_index]; bool custom_shape_check = false; - *ip = NULL; + *ip = nullptr; - SmallVector object_areas(_cleared_object_areas); - CommandCost ret = CheckIfIndustryTilesAreFree(tile, it, itspec_index, type, random_initial_bits, founder, creation_type, &custom_shape_check); + std::vector object_areas(_cleared_object_areas); + CommandCost ret = CheckIfIndustryTilesAreFree(tile, layout, layout_index, type, random_initial_bits, founder, creation_type, &custom_shape_check); _cleared_object_areas = object_areas; if (ret.Failed()) return ret; if (HasBit(GetIndustrySpec(type)->callback_mask, CBM_IND_LOCATION)) { - ret = CheckIfCallBackAllowsCreation(tile, type, itspec_index, random_var8f, random_initial_bits, founder, creation_type); + ret = CheckIfCallBackAllowsCreation(tile, type, layout_index, random_var8f, random_initial_bits, founder, creation_type); } else { ret = _check_new_industry_procs[indspec->check_proc](tile); } 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, it, type)) { + !_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 = NULL; + Town *t = nullptr; ret = FindTownForIndustry(tile, type, &t); if (ret.Failed()) return ret; - assert(t != NULL); + assert(t != nullptr); ret = CheckIfIndustryIsAllowed(tile, type, t); if (ret.Failed()) return ret; @@ -1884,8 +1961,8 @@ static CommandCost CreateNewIndustryHelper(TileIndex tile, IndustryType type, Do if (flags & DC_EXEC) { *ip = new Industry(tile); - if (!custom_shape_check) CheckIfCanLevelIndustryPlatform(tile, DC_NO_WATER | DC_EXEC, it, type); - DoCreateNewIndustry(*ip, tile, type, it, itspec_index, t, founder, random_initial_bits); + if (!custom_shape_check) CheckIfCanLevelIndustryPlatform(tile, DC_NO_WATER | DC_EXEC, layout, type); + DoCreateNewIndustry(*ip, tile, type, layout, layout_index, t, founder, random_initial_bits); } return CommandCost(); @@ -1911,7 +1988,7 @@ CommandCost CmdBuildIndustry(TileIndex tile, DoCommandFlag flags, uint32 p1, uin const IndustrySpec *indspec = GetIndustrySpec(it); /* Check if the to-be built/founded industry is available for this climate. */ - if (!indspec->enabled || indspec->num_table == 0) return CMD_ERROR; + if (!indspec->enabled || indspec->layouts.empty()) return CMD_ERROR; /* If the setting for raw-material industries is not on, you cannot build raw-material industries. * Raw material industries are industries that do not accept cargo (at least for now) */ @@ -1927,15 +2004,15 @@ CommandCost CmdBuildIndustry(TileIndex tile, DoCommandFlag flags, uint32 p1, uin randomizer.SetSeed(p2); uint16 random_initial_bits = GB(p2, 0, 16); uint32 random_var8f = randomizer.Next(); - int num_layouts = indspec->num_table; + size_t num_layouts = indspec->layouts.size(); CommandCost ret = CommandCost(STR_ERROR_SITE_UNSUITABLE); const bool deity_prospect = _current_company == OWNER_DEITY && !HasBit(p1, 16); - Industry *ind = NULL; + 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); + 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. */ @@ -1946,9 +2023,9 @@ CommandCost CmdBuildIndustry(TileIndex tile, DoCommandFlag flags, uint32 p1, uin */ tile = RandomTile(); /* Start with a random layout */ - int layout = RandomRange(num_layouts); + size_t layout = RandomRange((uint32)num_layouts); /* Check now each layout, starting with the random one */ - for (int j = 0; j < num_layouts; j++) { + 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); if (ret.Succeeded()) break; @@ -1959,11 +2036,11 @@ CommandCost CmdBuildIndustry(TileIndex tile, DoCommandFlag flags, uint32 p1, uin cur_company.Restore(); } } else { - int layout = GB(p1, 8, 8); + size_t layout = GB(p1, 8, 8); if (layout >= num_layouts) return CMD_ERROR; /* Check subsequently each layout, starting with the given layout in p1 */ - for (int i = 0; i < num_layouts; i++) { + for (size_t i = 0; i < num_layouts; i++) { layout = (layout + 1) % num_layouts; ret = CreateNewIndustryHelper(tile, it, flags, indspec, layout, random_var8f, random_initial_bits, _current_company, _current_company == OWNER_DEITY ? IACT_RANDOMCREATION : IACT_USERCREATION, &ind); if (ret.Succeeded()) break; @@ -1973,7 +2050,7 @@ CommandCost CmdBuildIndustry(TileIndex tile, DoCommandFlag flags, uint32 p1, uin if (ret.Failed()) return ret; } - if ((flags & DC_EXEC) && ind != NULL && _game_mode != GM_EDITOR) { + if ((flags & DC_EXEC) && ind != nullptr && _game_mode != GM_EDITOR) { AdvertiseIndustryOpening(ind); } @@ -1986,7 +2063,7 @@ CommandCost CmdBuildIndustry(TileIndex tile, DoCommandFlag flags, uint32 p1, uin * @param tile The location to build the industry. * @param type The industry type to build. * @param creation_type The circumstances the industry is created under. - * @return the created industry or NULL if it failed. + * @return the created industry or nullptr if it failed. */ static Industry *CreateNewIndustry(TileIndex tile, IndustryType type, IndustryAvailabilityCallType creation_type) { @@ -1994,9 +2071,10 @@ static Industry *CreateNewIndustry(TileIndex tile, IndustryType type, IndustryAv uint32 seed = Random(); uint32 seed2 = Random(); - Industry *i = NULL; - CommandCost ret = CreateNewIndustryHelper(tile, type, DC_EXEC, indspec, RandomRange(indspec->num_table), seed, GB(seed2, 0, 16), OWNER_NONE, creation_type, &i); - assert(i != NULL || ret.Failed()); + Industry *i = nullptr; + size_t layout_index = RandomRange((uint32)indspec->layouts.size()); + CommandCost ret = CreateNewIndustryHelper(tile, type, DC_EXEC, indspec, layout_index, seed, GB(seed2, 0, 16), OWNER_NONE, creation_type, &i); + assert(i != nullptr || ret.Failed()); return i; } @@ -2010,7 +2088,7 @@ static uint32 GetScaledIndustryGenerationProbability(IndustryType it, bool *forc { const IndustrySpec *ind_spc = GetIndustrySpec(it); uint32 chance = ind_spc->appear_creation[_settings_game.game_creation.landscape] * 16; // * 16 to increase precision - if (!ind_spc->enabled || ind_spc->num_table == 0 || + if (!ind_spc->enabled || ind_spc->layouts.empty() || (_game_mode != GM_EDITOR && _settings_game.difficulty.industry_density == ID_FUND_ONLY) || (chance = GetIndustryProbabilityCallback(it, IACT_MAPGENERATION, chance)) == 0) { *force_at_least_one = false; @@ -2040,7 +2118,7 @@ static uint16 GetIndustryGamePlayProbability(IndustryType it, byte *min_number) const IndustrySpec *ind_spc = GetIndustrySpec(it); byte chance = ind_spc->appear_ingame[_settings_game.game_creation.landscape]; - if (!ind_spc->enabled || ind_spc->num_table == 0 || + if (!ind_spc->enabled || ind_spc->layouts.empty() || ((ind_spc->behaviour & INDUSTRYBEH_BEFORE_1950) && _cur_year > 1950) || ((ind_spc->behaviour & INDUSTRYBEH_AFTER_1960) && _cur_year < 1960) || (chance = GetIndustryProbabilityCallback(it, IACT_RANDOMCREATION, chance)) == 0) { @@ -2078,16 +2156,16 @@ static uint GetNumberOfIndustries() * than to try a few times before concluding it does not work. * @param type Industry type of the desired industry. * @param try_hard Try very hard to find a place. (Used to place at least one industry per type.) - * @return Pointer to created industry, or \c NULL if creation failed. + * @return Pointer to created industry, or \c nullptr if creation failed. */ static Industry *PlaceIndustry(IndustryType type, IndustryAvailabilityCallType creation_type, bool try_hard) { uint tries = try_hard ? 10000u : 2000u; for (; tries > 0; tries--) { Industry *ind = CreateNewIndustry(RandomTile(), type, creation_type); - if (ind != NULL) return ind; + if (ind != nullptr) return ind; } - return NULL; + return nullptr; } /** @@ -2097,7 +2175,7 @@ static Industry *PlaceIndustry(IndustryType type, IndustryAvailabilityCallType c */ static void PlaceInitialIndustry(IndustryType type, bool try_hard) { - Backup cur_company(_current_company, OWNER_NONE, FILE_LINE); + Backup cur_company(_current_company, OWNER_NONE, FILE_LINE); IncreaseGeneratingWorldProgress(GWP_INDUSTRY); PlaceIndustry(type, IACT_MAPGENERATION, try_hard); @@ -2241,6 +2319,21 @@ void Industry::RecomputeProductionMultipliers() } } +void Industry::FillCachedName() const +{ + char buf[256]; + int64 args_array[] = { this->index }; + StringParameters tmp_params(args_array); + char *end = GetStringWithArgs(buf, STR_INDUSTRY_NAME, &tmp_params, lastof(buf)); + this->cached_name.assign(buf, end); +} + +void ClearAllIndustryCachedNames() +{ + for (Industry *ind : Industry::Iterate()) { + ind->cached_name.clear(); + } +} /** * Set the #probability and #min_number fields for the industry type \a it for a running game. @@ -2353,7 +2446,7 @@ void IndustryBuildData::TryBuildNewIndustry() /* Try to create the industry. */ const Industry *ind = PlaceIndustry(it, IACT_RANDOMCREATION, false); - if (ind == NULL) { + if (ind == nullptr) { this->builddata[it].wait_count = this->builddata[it].max_wait + 1; // Compensate for decrementing below. this->builddata[it].max_wait = min(1000, this->builddata[it].max_wait + 2); } else { @@ -2430,15 +2523,10 @@ static void CanCargoServiceIndustry(CargoID cargo, Industry *ind, bool *c_accept */ static int WhoCanServiceIndustry(Industry *ind) { - /* Find all stations within reach of the industry */ - StationList stations; - FindStationsAroundTiles(ind->location, &stations); + if (ind->stations_near.size() == 0) return 0; // No stations found at all => nobody services - if (stations.Length() == 0) return 0; // No stations found at all => nobody services - - const Vehicle *v; int result = 0; - FOR_ALL_VEHICLES(v) { + for (const Vehicle *v : Vehicle::Iterate()) { /* Is it worthwhile to try this vehicle? */ if (v->owner != _local_company && result != 0) continue; @@ -2446,7 +2534,7 @@ static int WhoCanServiceIndustry(Industry *ind) bool c_accepts = false; bool c_produces = false; if (v->type == VEH_TRAIN && v->IsFrontEngine()) { - for (const Vehicle *u = v; u != NULL; u = u->Next()) { + for (const Vehicle *u = v; u != nullptr; u = u->Next()) { CanCargoServiceIndustry(u->cargo_type, ind, &c_accepts, &c_produces); } } else if (v->type == VEH_ROAD || v->type == VEH_SHIP || v->type == VEH_AIRCRAFT) { @@ -2465,12 +2553,12 @@ static int WhoCanServiceIndustry(Industry *ind) if (o->IsType(OT_GOTO_STATION) && !(o->GetUnloadType() & OUFB_TRANSFER)) { /* Vehicle visits a station to load or unload */ Station *st = Station::Get(o->GetDestination()); - assert(st != NULL); + assert(st != nullptr); /* Same cargo produced by industry is dropped here => not serviced by vehicle v */ if ((o->GetUnloadType() & OUFB_UNLOAD) && !c_accepts) break; - if (stations.Contains(st)) { + if (ind->stations_near.find(st) != ind->stations_near.end()) { if (v->owner == _local_company) return 2; // Company services industry result = 1; // Competitor services industry } @@ -2733,7 +2821,7 @@ void IndustryDailyLoop() return; // Nothing to do? get out } - Backup cur_company(_current_company, OWNER_NONE, FILE_LINE); + Backup cur_company(_current_company, OWNER_NONE, FILE_LINE); /* perform the required industry changes for the day */ @@ -2746,7 +2834,7 @@ void IndustryDailyLoop() _industry_builder.TryBuildNewIndustry(); } else { Industry *i = Industry::GetRandom(); - if (i != NULL) { + if (i != nullptr) { ChangeIndustryProduction(i, false); SetWindowDirty(WC_INDUSTRY_VIEW, i->index); } @@ -2756,17 +2844,16 @@ void IndustryDailyLoop() cur_company.Restore(); /* production-change */ - InvalidateWindowData(WC_INDUSTRY_DIRECTORY, 0, 1); + InvalidateWindowData(WC_INDUSTRY_DIRECTORY, 0, IDIWD_PRODUCTION_CHANGE); } void IndustryMonthlyLoop() { - Backup cur_company(_current_company, OWNER_NONE, FILE_LINE); + Backup cur_company(_current_company, OWNER_NONE, FILE_LINE); _industry_builder.MonthlyLoop(); - Industry *i; - FOR_ALL_INDUSTRIES(i) { + for (Industry *i : Industry::Iterate()) { UpdateIndustryStatistics(i); if (i->prod_level == PRODLEVEL_CLOSURE) { delete i; @@ -2779,7 +2866,7 @@ void IndustryMonthlyLoop() cur_company.Restore(); /* production-change */ - InvalidateWindowData(WC_INDUSTRY_DIRECTORY, 0, 1); + InvalidateWindowData(WC_INDUSTRY_DIRECTORY, 0, IDIWD_PRODUCTION_CHANGE); } @@ -2864,6 +2951,13 @@ bool IndustrySpec::UsesSmoothEconomy() const !(HasBit(this->callback_mask, CBM_IND_MONTHLYPROD_CHANGE) || HasBit(this->callback_mask, CBM_IND_PRODUCTION_CHANGE) || HasBit(this->callback_mask, CBM_IND_PROD_CHANGE_BUILD)); // production change callbacks } +IndustrySpec::~IndustrySpec() +{ + if (HasBit(this->cleanup_flag, CLEAN_RANDOMSOUNDS)) { + free(this->random_sounds); + } +} + static CommandCost TerraformTile_Industry(TileIndex tile, DoCommandFlag flags, int z_new, Slope tileh_new) { if (AutoslopeEnabled()) { @@ -2904,8 +2998,13 @@ extern const TileTypeProcs _tile_type_industry_procs = { AnimateTile_Industry, // animate_tile_proc TileLoop_Industry, // tile_loop_proc ChangeTileOwner_Industry, // change_tile_owner_proc - NULL, // add_produced_cargo_proc - NULL, // vehicle_enter_tile_proc + nullptr, // add_produced_cargo_proc + nullptr, // vehicle_enter_tile_proc GetFoundation_Industry, // get_foundation_proc TerraformTile_Industry, // terraform_tile_proc }; + +bool IndustryCompare::operator() (const Industry *lhs, const Industry *rhs) const +{ + return lhs->index < rhs->index; +} diff --git a/src/industry_gui.cpp b/src/industry_gui.cpp index 483094344e..870244d869 100644 --- a/src/industry_gui.cpp +++ b/src/industry_gui.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. @@ -76,7 +74,7 @@ static void ShowIndustryCargoesWindow(IndustryType id); * Gets the string to display after the cargo name (using callback 37) * @param cargo the cargo for which the suffix is requested, meaning depends on presence of flag 18 in prop 1A * @param cst the cargo suffix type (for which window is it requested). @see CargoSuffixType - * @param ind the industry (NULL if in fund window) + * @param ind the industry (nullptr if in fund window) * @param ind_type the industry type * @param indspec the industry spec * @param suffix is filled with the string to display @@ -138,7 +136,7 @@ enum CargoSuffixInOut { * Gets all strings to display after the cargoes of industries (using callback 37) * @param use_input get suffixes for output cargoes or input cargoes? * @param cst the cargo suffix type (for which window is it requested). @see CargoSuffixType - * @param ind the industry (NULL if in fund window) + * @param ind the industry (nullptr if in fund window) * @param ind_type the industry type * @param indspec the industry spec * @param cargoes array with cargotypes. for CT_INVALID no suffix will be determined @@ -183,23 +181,23 @@ static inline void GetAllCargoSuffixes(CargoSuffixInOut use_input, CargoSuffixTy } } -IndustryType _sorted_industry_types[NUM_INDUSTRYTYPES]; ///< Industry types sorted by name. +std::array _sorted_industry_types; ///< Industry types sorted by name. /** Sort industry types by their name. */ -static int CDECL IndustryTypeNameSorter(const IndustryType *a, const IndustryType *b) +static bool IndustryTypeNameSorter(const IndustryType &a, const IndustryType &b) { static char industry_name[2][64]; - const IndustrySpec *indsp1 = GetIndustrySpec(*a); + const IndustrySpec *indsp1 = GetIndustrySpec(a); GetString(industry_name[0], indsp1->name, lastof(industry_name[0])); - const IndustrySpec *indsp2 = GetIndustrySpec(*b); + const IndustrySpec *indsp2 = GetIndustrySpec(b); GetString(industry_name[1], indsp2->name, lastof(industry_name[1])); int r = strnatcmp(industry_name[0], industry_name[1]); // Sort by name (natural sorting). /* If the names are equal, sort by industry type. */ - return (r != 0) ? r : (*a - *b); + return (r != 0) ? r < 0 : (a < b); } /** @@ -213,7 +211,7 @@ void SortIndustryTypes() } /* Sort industry types by name. */ - QSortT(_sorted_industry_types, NUM_INDUSTRYTYPES, &IndustryTypeNameSorter); + std::sort(_sorted_industry_types.begin(), _sorted_industry_types.end(), IndustryTypeNameSorter); } /** @@ -222,8 +220,9 @@ void SortIndustryTypes() * @param tile Tile where the industry is placed. * @param p1 Additional data of the #CMD_BUILD_INDUSTRY command. * @param p2 Additional data of the #CMD_BUILD_INDUSTRY command. + * @param cmd Unused. */ -void CcBuildIndustry(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) +void CcBuildIndustry(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) { if (result.Succeeded()) return; @@ -300,8 +299,7 @@ class BuildIndustryWindow : public Window { * The tests performed after the enabled allow to load the industries * In the same way they are inserted by grf (if any) */ - for (uint i = 0; i < NUM_INDUSTRYTYPES; i++) { - IndustryType ind = _sorted_industry_types[i]; + for (IndustryType ind : _sorted_industry_types) { const IndustrySpec *indsp = GetIndustrySpec(ind); if (indsp->enabled) { /* Rule is that editor mode loads all industries. @@ -405,12 +403,12 @@ public: if (_thd.GetCallbackWnd() == this) this->OnPlaceObjectAbort(); } - virtual void OnInit() + void OnInit() override { this->SetupArrays(); } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_DPI_MATRIX_WIDGET: { @@ -440,7 +438,7 @@ public: CargoSuffix cargo_suffix[lengthof(indsp->accepts_cargo)]; /* Measure the accepted cargoes, if any. */ - GetAllCargoSuffixes(CARGOSUFFIX_IN, CST_FUND, NULL, this->index[i], indsp, indsp->accepts_cargo, cargo_suffix); + GetAllCargoSuffixes(CARGOSUFFIX_IN, CST_FUND, nullptr, this->index[i], 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); Dimension strdim = GetStringBoundingBox(cargostring.c_str()); if (strdim.width > max_minwidth) { @@ -450,7 +448,7 @@ public: d = maxdim(d, strdim); /* Measure the produced cargoes, if any. */ - GetAllCargoSuffixes(CARGOSUFFIX_OUT, CST_FUND, NULL, this->index[i], indsp, indsp->produced_cargo, cargo_suffix); + GetAllCargoSuffixes(CARGOSUFFIX_OUT, CST_FUND, nullptr, this->index[i], indsp, indsp->produced_cargo, cargo_suffix); cargostring = this->MakeCargoListString(indsp->produced_cargo, cargo_suffix, lengthof(indsp->produced_cargo), STR_INDUSTRY_VIEW_PRODUCES_N_CARGO); strdim = GetStringBoundingBox(cargostring.c_str()); if (strdim.width > max_minwidth) { @@ -479,7 +477,7 @@ public: } } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { switch (widget) { case WID_DPI_FUND_WIDGET: @@ -496,7 +494,7 @@ public: } } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { switch (widget) { case WID_DPI_MATRIX_WIDGET: { @@ -555,18 +553,18 @@ public: CargoSuffix cargo_suffix[lengthof(indsp->accepts_cargo)]; /* Draw the accepted cargoes, if any. Otherwise, will print "Nothing". */ - GetAllCargoSuffixes(CARGOSUFFIX_IN, CST_FUND, NULL, this->selected_type, indsp, indsp->accepts_cargo, cargo_suffix); + 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.c_str()); /* Draw the produced cargoes, if any. Otherwise, will print "Nothing". */ - GetAllCargoSuffixes(CARGOSUFFIX_OUT, CST_FUND, NULL, this->selected_type, indsp, indsp->produced_cargo, cargo_suffix); + 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.c_str()); /* Get the additional purchase info text, if it has not already been queried. */ if (HasBit(indsp->callback_mask, CBM_IND_FUND_MORE_TEXT)) { - uint16 callback_res = GetIndustryCallback(CBID_INDUSTRY_FUND_MORE_TEXT, 0, 0, NULL, this->selected_type, INVALID_TILE); + uint16 callback_res = GetIndustryCallback(CBID_INDUSTRY_FUND_MORE_TEXT, 0, 0, nullptr, this->selected_type, INVALID_TILE); if (callback_res != CALLBACK_FAILED && callback_res != 0x400) { if (callback_res > 0x400) { ErrorUnknownCallbackResult(indsp->grf_prop.grffile->grfid, CBID_INDUSTRY_FUND_MORE_TEXT, callback_res); @@ -585,7 +583,7 @@ public: } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_DPI_MATRIX_WIDGET: { @@ -593,12 +591,12 @@ public: if (y < this->count) { // Is it within the boundaries of available data? this->selected_index = y; this->selected_type = this->index[y]; - const IndustrySpec *indsp = (this->selected_type == INVALID_INDUSTRYTYPE) ? NULL : GetIndustrySpec(this->selected_type); + const IndustrySpec *indsp = (this->selected_type == INVALID_INDUSTRYTYPE) ? nullptr : GetIndustrySpec(this->selected_type); this->SetDirty(); if (_thd.GetCallbackWnd() == this && - ((_game_mode != GM_EDITOR && _settings_game.construction.raw_industry_construction == 2 && indsp != NULL && indsp->IsRawIndustry()) || + ((_game_mode != GM_EDITOR && _settings_game.construction.raw_industry_construction == 2 && indsp != nullptr && indsp->IsRawIndustry()) || this->selected_type == INVALID_INDUSTRYTYPE || !this->enabled[this->selected_index])) { /* Reset the button state if going to prospecting or "build many industries" */ @@ -639,13 +637,13 @@ public: } } - virtual void OnResize() + void OnResize() override { /* Adjust the number of items in the matrix depending of the resize */ this->vscroll->SetCapacityFromWidget(this, WID_DPI_MATRIX_WIDGET); } - virtual void OnPlaceObject(Point pt, TileIndex tile) + void OnPlaceObject(Point pt, TileIndex tile) override { VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_SINGLE_TILE); MoveAllWindowsOffScreen(); @@ -666,6 +664,7 @@ public: /* We do not need to protect ourselves against "Random Many Industries" in this mode */ const IndustrySpec *indsp = GetIndustrySpec(this->selected_type); uint32 seed = InteractiveRandom(); + uint32 layout_index = InteractiveRandomRange((uint32)indsp->layouts.size()); if (_game_mode == GM_EDITOR) { /* Show error if no town exists at all */ @@ -675,25 +674,25 @@ public: return; } - Backup cur_company(_current_company, OWNER_NONE, FILE_LINE); + Backup cur_company(_current_company, OWNER_NONE, FILE_LINE); _generating_world = true; _ignore_restrictions = true; - DoCommandP(end_tile, (InteractiveRandomRange(indsp->num_table) << 8) | this->selected_type, seed, + DoCommandP(end_tile, (layout_index << 8) | this->selected_type, seed, CMD_BUILD_INDUSTRY | CMD_MSG(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY), &CcBuildIndustry); cur_company.Restore(); _ignore_restrictions = false; _generating_world = false; } else { - success = DoCommandP(end_tile, (InteractiveRandomRange(indsp->num_table) << 8) | this->selected_type, seed, CMD_BUILD_INDUSTRY | CMD_MSG(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY)); + success = DoCommandP(end_tile, (layout_index << 8) | this->selected_type, seed, CMD_BUILD_INDUSTRY | CMD_MSG(STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY)); } /* If an industry has been built, just reset the cursor and the system */ if (success && !_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); } - virtual void OnGameTick() + void OnGameTick() override { if (!this->timer_enabled) return; if (--this->callback_timer == 0) { @@ -716,12 +715,12 @@ public: } } - virtual void OnTimeout() + void OnTimeout() override { this->RaiseButtons(); } - virtual void OnPlaceObjectAbort() + void OnPlaceObjectAbort() override { MoveAllHiddenWindowsBackToScreen(); this->RaiseButtons(); @@ -732,13 +731,13 @@ public: * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; this->SetupArrays(); - const IndustrySpec *indsp = (this->selected_type == INVALID_INDUSTRYTYPE) ? NULL : GetIndustrySpec(this->selected_type); - if (indsp == NULL) this->enabled[this->selected_index] = _settings_game.difficulty.industry_density != ID_FUND_ONLY; + const IndustrySpec *indsp = (this->selected_type == INVALID_INDUSTRYTYPE) ? nullptr : GetIndustrySpec(this->selected_type); + if (indsp == nullptr) this->enabled[this->selected_index] = _settings_game.difficulty.industry_density != ID_FUND_ONLY; this->SetButtons(); } }; @@ -807,7 +806,7 @@ public: this->InvalidateData(); } - virtual void OnPaint() + void OnPaint() override { this->DrawWidgets(); @@ -946,17 +945,17 @@ public: return y + WD_FRAMERECT_BOTTOM; } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { if (widget == WID_IV_CAPTION) SetDParam(0, this->window_number); } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { if (widget == WID_IV_INFO) size->height = this->info_height; } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_IV_INFO: { @@ -1063,16 +1062,16 @@ public: } } - virtual void OnTimeout() + void OnTimeout() override { this->clicked_line = IL_NONE; this->clicked_button = 0; this->SetDirty(); } - virtual void OnResize() + void OnResize() override { - if (this->viewport != NULL) { + if (this->viewport != nullptr) { NWidgetViewport *nvp = this->GetWidget(WID_IV_VIEWPORT); nvp->UpdateViewportCoordinates(this); @@ -1080,7 +1079,7 @@ public: } } - virtual void OnQueryTextFinished(char *str) + void OnQueryTextFinished(char *str) override { if (StrEmpty(str)) return; @@ -1106,7 +1105,7 @@ public: * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; const Industry *i = Industry::Get(this->window_number); @@ -1118,12 +1117,12 @@ public: } } - virtual bool IsNewGRFInspectable() const + bool IsNewGRFInspectable() const override { return ::IsNewGRFInspectable(GSF_INDUSTRIES, this->window_number); } - virtual void ShowNewGRFInspectWindow() const + void ShowNewGRFInspectWindow() const override { ::ShowNewGRFInspectWindow(GSF_INDUSTRIES, this->window_number); } @@ -1192,6 +1191,8 @@ static const NWidgetPart _nested_industry_directory_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_ID_DROPDOWN_ORDER), SetSizingType(NWST_STEP), 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(), 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(), @@ -1203,7 +1204,68 @@ static const NWidgetPart _nested_industry_directory_widgets[] = { EndContainer(), }; -typedef GUIList GUIIndustryList; +typedef GUIList &> GUIIndustryList; + +/** Special cargo filter criteria */ +enum CargoFilterSpecialType { + CF_ANY = CT_NO_REFIT, ///< Show all industries (i.e. no filtering) + CF_NONE = CT_INVALID, ///< Show only industries which do not produce/accept cargo +}; + +/** Cargo filter functions */ +/** + * Check whether an industry accepts and produces a certain cargo pair. + * @param industry The industry whose cargoes will being checked. + * @param cargoes The accepted and produced cargo pair to look for. + * @return bool Whether the given cargoes accepted and produced by the industry. + */ +static bool CDECL CargoFilter(const Industry * const *industry, const std::pair &cargoes) +{ + auto accepted_cargo = cargoes.first; + auto produced_cargo = cargoes.second; + + bool accepted_cargo_matches; + + switch (accepted_cargo) { + case CF_ANY: + accepted_cargo_matches = true; + break; + + case CF_NONE: + accepted_cargo_matches = std::all_of(std::begin((*industry)->accepts_cargo), std::end((*industry)->accepts_cargo), [](CargoID cargo) { + return cargo == CT_INVALID; + }); + break; + + default: + const auto &ac = (*industry)->accepts_cargo; + accepted_cargo_matches = std::find(std::begin(ac), std::end(ac), accepted_cargo) != std::end(ac); + break; + } + + bool produced_cargo_matches; + + switch (produced_cargo) { + case CF_ANY: + produced_cargo_matches = true; + break; + + case CF_NONE: + produced_cargo_matches = std::all_of(std::begin((*industry)->produced_cargo), std::end((*industry)->produced_cargo), [](CargoID cargo) { + return cargo == CT_INVALID; + }); + break; + + default: + const auto &pc = (*industry)->produced_cargo; + produced_cargo_matches = std::find(std::begin(pc), std::end(pc), produced_cargo) != std::end(pc); + break; + } + + return accepted_cargo_matches && produced_cargo_matches; +} + +static GUIIndustryList::FilterFunction * const _filter_funcs[] = { &CargoFilter }; /** @@ -1213,7 +1275,6 @@ class IndustryDirectoryWindow : public Window { protected: /* Runtime saved values */ static Listing last_sorting; - static const Industry *last_industry; /* Constants for sorting stations */ static const StringID sorter_names[]; @@ -1222,25 +1283,105 @@ protected: GUIIndustryList industries; Scrollbar *vscroll; + CargoID cargo_filter[NUM_CARGO + 2]; ///< Available cargo filters; CargoID or CF_ANY or CF_NONE + StringID cargo_filter_texts[NUM_CARGO + 3]; ///< Texts for filter_cargo, terminated by INVALID_STRING_ID + CargoID produced_cargo_filter_criteria; ///< Selected produced cargo filter + CargoID accepted_cargo_filter_criteria; ///< Selected accepted cargo filter + + /** + * Set cargo filter list item index. + * @param index The index of the cargo to be set + */ + void SetProducedCargoFilterIndex(int index) + { + if (this->produced_cargo_filter_criteria != index) { + this->produced_cargo_filter_criteria = index; + /* deactivate filter if criteria is 'Show All', activate it otherwise */ + bool is_filtering_necessary = this->cargo_filter[this->produced_cargo_filter_criteria] != CF_ANY || this->cargo_filter[this->accepted_cargo_filter_criteria] != CF_ANY; + + this->industries.SetFilterState(is_filtering_necessary); + this->industries.SetFilterType(0); + this->industries.ForceRebuild(); + } + } + + /** + * Set cargo filter list item index. + * @param index The index of the cargo to be set + */ + void SetAcceptedCargoFilterIndex(int index) + { + if (this->accepted_cargo_filter_criteria != index) { + this->accepted_cargo_filter_criteria = index; + /* deactivate filter if criteria is 'Show All', activate it otherwise */ + bool is_filtering_necessary = this->cargo_filter[this->produced_cargo_filter_criteria] != CF_ANY || this->cargo_filter[this->accepted_cargo_filter_criteria] != CF_ANY; + + this->industries.SetFilterState(is_filtering_necessary); + this->industries.SetFilterType(0); + this->industries.ForceRebuild(); + } + } + + /** + * Populate the filter list and set the cargo filter criteria. + */ + void SetCargoFilterArray() + { + uint filter_items = 0; + + /* Add item for disabling filtering. */ + this->cargo_filter[filter_items] = CF_ANY; + this->cargo_filter_texts[filter_items] = STR_INDUSTRY_DIRECTORY_FILTER_ALL_TYPES; + this->produced_cargo_filter_criteria = filter_items; + this->accepted_cargo_filter_criteria = filter_items; + filter_items++; + + /* Add item for industries not producing anything, e.g. power plants */ + this->cargo_filter[filter_items] = CF_NONE; + this->cargo_filter_texts[filter_items] = STR_INDUSTRY_DIRECTORY_FILTER_NONE; + filter_items++; + + /* Collect available cargo types for filtering. */ + const CargoSpec *cs; + FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) { + 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->industries.SetFilterFuncs(_filter_funcs); + + bool is_filtering_necessary = this->cargo_filter[this->produced_cargo_filter_criteria] != CF_ANY || this->cargo_filter[this->accepted_cargo_filter_criteria] != CF_ANY; + + this->industries.SetFilterState(is_filtering_necessary); + } + /** (Re)Build industries list */ void BuildSortIndustriesList() { if (this->industries.NeedRebuild()) { - this->industries.Clear(); + this->industries.clear(); - const Industry *i; - FOR_ALL_INDUSTRIES(i) { - *this->industries.Append() = i; + for (const Industry *i : Industry::Iterate()) { + this->industries.push_back(i); } - this->industries.Compact(); + this->industries.shrink_to_fit(); this->industries.RebuildDone(); - this->vscroll->SetCount(this->industries.Length()); // Update scrollbar as well. } - if (!this->industries.Sort()) return; - IndustryDirectoryWindow::last_industry = NULL; // Reset name sorter sort cache - this->SetWidgetDirty(WID_ID_INDUSTRY_LIST); // Set the modified widget dirty + auto filter = std::make_pair(this->cargo_filter[this->accepted_cargo_filter_criteria], + this->cargo_filter[this->produced_cargo_filter_criteria]); + + this->industries.Filter(filter); + this->industries.Sort(); + + this->vscroll->SetCount((uint)this->industries.size()); // Update scrollbar as well. + + this->SetDirty(); } /** @@ -1276,52 +1417,42 @@ protected: } /** Sort industries by name */ - static int CDECL IndustryNameSorter(const Industry * const *a, const Industry * const *b) + static bool IndustryNameSorter(const Industry * const &a, const Industry * const &b) { - static char buf_cache[96]; - static char buf[96]; - - SetDParam(0, (*a)->index); - GetString(buf, STR_INDUSTRY_NAME, lastof(buf)); - - if (*b != last_industry) { - last_industry = *b; - SetDParam(0, (*b)->index); - GetString(buf_cache, STR_INDUSTRY_NAME, lastof(buf_cache)); - } - - return strnatcmp(buf, buf_cache); // Sort by name (natural sorting). + int r = strnatcmp(a->GetCachedName(), b->GetCachedName()); // Sort by name (natural sorting). + if (r == 0) return a->index < b->index; + return r < 0; } /** Sort industries by type and name */ - static int CDECL IndustryTypeSorter(const Industry * const *a, const Industry * const *b) + static bool IndustryTypeSorter(const Industry * const &a, const Industry * const &b) { int it_a = 0; - while (it_a != NUM_INDUSTRYTYPES && (*a)->type != _sorted_industry_types[it_a]) it_a++; + while (it_a != NUM_INDUSTRYTYPES && a->type != _sorted_industry_types[it_a]) it_a++; int it_b = 0; - while (it_b != NUM_INDUSTRYTYPES && (*b)->type != _sorted_industry_types[it_b]) it_b++; + while (it_b != NUM_INDUSTRYTYPES && b->type != _sorted_industry_types[it_b]) it_b++; int r = it_a - it_b; - return (r == 0) ? IndustryNameSorter(a, b) : r; + return (r == 0) ? IndustryNameSorter(a, b) : r < 0; } /** Sort industries by production and name */ - static int CDECL IndustryProductionSorter(const Industry * const *a, const Industry * const *b) + static bool IndustryProductionSorter(const Industry * const &a, const Industry * const &b) { uint prod_a = 0, prod_b = 0; - for (uint i = 0; i < lengthof((*a)->produced_cargo); i++) { - if ((*a)->produced_cargo[i] != CT_INVALID) prod_a += (*a)->last_month_production[i]; - if ((*b)->produced_cargo[i] != CT_INVALID) prod_b += (*b)->last_month_production[i]; + for (uint i = 0; i < lengthof(a->produced_cargo); i++) { + if (a->produced_cargo[i] != CT_INVALID) prod_a += a->last_month_production[i]; + if (b->produced_cargo[i] != CT_INVALID) prod_b += b->last_month_production[i]; } int r = prod_a - prod_b; - return (r == 0) ? IndustryTypeSorter(a, b) : r; + return (r == 0) ? IndustryTypeSorter(a, b) : r < 0; } /** Sort industries by transported cargo and name */ - static int CDECL IndustryTransportedCargoSorter(const Industry * const *a, const Industry * const *b) + static bool IndustryTransportedCargoSorter(const Industry * const &a, const Industry * const &b) { - int r = GetCargoTransportedSortValue(*a) - GetCargoTransportedSortValue(*b); - return (r == 0) ? IndustryNameSorter(a, b) : r; + int r = GetCargoTransportedSortValue(a) - GetCargoTransportedSortValue(b); + return (r == 0) ? IndustryNameSorter(a, b) : r < 0; } /** @@ -1340,25 +1471,53 @@ protected: static CargoSuffix cargo_suffix[lengthof(i->produced_cargo)]; GetAllCargoSuffixes(CARGOSUFFIX_OUT, CST_DIR, i, i->type, indsp, i->produced_cargo, cargo_suffix); - /* Industry productions */ + /* Get industry productions (CargoID, production, suffix, transported) */ + typedef std::tuple CargoInfo; + std::vector cargos; + for (byte j = 0; j < lengthof(i->produced_cargo); j++) { if (i->produced_cargo[j] == CT_INVALID) continue; - SetDParam(p++, i->produced_cargo[j]); - SetDParam(p++, i->last_month_production[j]); - SetDParamStr(p++, cargo_suffix[j].text); + cargos.emplace_back(i->produced_cargo[j], i->last_month_production[j], cargo_suffix[j].text, ToPercent8(i->last_month_pct_transported[j])); } - /* Transported productions */ - for (byte j = 0; j < lengthof(i->produced_cargo); j++) { - if (i->produced_cargo[j] == CT_INVALID) continue; - SetDParam(p++, ToPercent8(i->last_month_pct_transported[j])); + /* Sort by descending production, then descending transported */ + std::sort(cargos.begin(), cargos.end(), [](const CargoInfo a, const CargoInfo b) { + if (std::get<1>(a) != std::get<1>(b)) return std::get<1>(a) > std::get<1>(b); + return std::get<3>(a) > std::get<3>(b); + }); + + /* If the produced cargo filter is active then move the filtered cargo to the beginning of the list, + * because this is the one the player interested in, and that way it is not hidden in the 'n' more cargos */ + const CargoID cid = this->cargo_filter[this->produced_cargo_filter_criteria]; + if (cid != CF_ANY && cid != CF_NONE) { + auto filtered_ci = std::find_if(cargos.begin(), cargos.end(), [cid](const CargoInfo& ci) -> bool { + return std::get<0>(ci) == cid; + }); + if (filtered_ci != cargos.end()) { + std::rotate(cargos.begin(), filtered_ci, filtered_ci + 1); + } } + /* Display first 3 cargos */ + for (size_t j = 0; j < min(3, cargos.size()); j++) { + CargoInfo ci = cargos[j]; + SetDParam(p++, STR_INDUSTRY_DIRECTORY_ITEM_INFO); + SetDParam(p++, std::get<0>(ci)); + SetDParam(p++, std::get<1>(ci)); + SetDParamStr(p++, std::get<2>(ci)); + SetDParam(p++, std::get<3>(ci)); + } + + /* Undisplayed cargos if any */ + SetDParam(p++, cargos.size() - 3); + /* Drawing the right string */ - switch (p) { - case 1: return STR_INDUSTRY_DIRECTORY_ITEM_NOPROD; - case 5: return STR_INDUSTRY_DIRECTORY_ITEM; - default: return STR_INDUSTRY_DIRECTORY_ITEM_TWO; + switch (cargos.size()) { + case 0: return STR_INDUSTRY_DIRECTORY_ITEM_NOPROD; + case 1: return STR_INDUSTRY_DIRECTORY_ITEM_PROD1; + case 2: return STR_INDUSTRY_DIRECTORY_ITEM_PROD2; + case 3: return STR_INDUSTRY_DIRECTORY_ITEM_PROD3; + default: return STR_INDUSTRY_DIRECTORY_ITEM_PRODMORE; } } @@ -1381,12 +1540,29 @@ public: this->last_sorting = this->industries.GetListing(); } - virtual void SetStringParameters(int widget) const + void OnInit() override { - if (widget == WID_ID_DROPDOWN_CRITERIA) SetDParam(0, IndustryDirectoryWindow::sorter_names[this->industries.SortType()]); + this->SetCargoFilterArray(); } - virtual void DrawWidget(const Rect &r, int widget) const + void SetStringParameters(int widget) const override + { + switch (widget) { + case WID_ID_DROPDOWN_CRITERIA: + SetDParam(0, IndustryDirectoryWindow::sorter_names[this->industries.SortType()]); + break; + + case WID_ID_FILTER_BY_ACC_CARGO: + SetDParam(0, this->cargo_filter_texts[this->accepted_cargo_filter_criteria]); + break; + + case WID_ID_FILTER_BY_PROD_CARGO: + SetDParam(0, this->cargo_filter_texts[this->produced_cargo_filter_criteria]); + break; + } + } + + void DrawWidget(const Rect &r, int widget) const override { switch (widget) { case WID_ID_DROPDOWN_ORDER: @@ -1396,12 +1572,21 @@ public: case WID_ID_INDUSTRY_LIST: { int n = 0; int y = Center(r.top, this->resize.step_height); - if (this->industries.Length() == 0) { + if (this->industries.size() == 0) { DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_INDUSTRY_DIRECTORY_NONE); break; } - for (uint i = this->vscroll->GetPosition(); i < this->industries.Length(); i++) { - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, this->GetIndustryString(this->industries[i])); + TextColour tc; + const CargoID acf_cid = this->cargo_filter[this->accepted_cargo_filter_criteria]; + for (uint i = this->vscroll->GetPosition(); i < this->industries.size(); i++) { + tc = TC_FROMSTRING; + if (acf_cid != CF_ANY && acf_cid != CF_NONE) { + Industry *ind = const_cast(this->industries[i]); + if (IndustryTemporarilyRefusesCargo(ind, acf_cid)) { + tc = TC_GREY | TC_FORCED; + } + } + DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, this->GetIndustryString(this->industries[i]), tc); y += this->resize.step_height; if (++n == this->vscroll->GetCapacity()) break; // max number of industries in 1 window @@ -1411,7 +1596,7 @@ public: } } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_ID_DROPDOWN_ORDER: { @@ -1435,7 +1620,7 @@ public: case WID_ID_INDUSTRY_LIST: { Dimension d = GetStringBoundingBox(STR_INDUSTRY_DIRECTORY_NONE); - for (uint i = 0; i < this->industries.Length(); i++) { + for (uint i = 0; i < this->industries.size(); i++) { d = maxdim(d, GetStringBoundingBox(this->GetIndustryString(this->industries[i]))); } resize->height = d.height = GetMinSizing(NWST_STEP, d.height); @@ -1449,7 +1634,7 @@ public: } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_ID_DROPDOWN_ORDER: @@ -1461,9 +1646,17 @@ public: ShowDropDownMenu(this, IndustryDirectoryWindow::sorter_names, this->industries.SortType(), WID_ID_DROPDOWN_CRITERIA, 0, 0); break; + case WID_ID_FILTER_BY_ACC_CARGO: // Cargo filter dropdown + ShowDropDownMenu(this, this->cargo_filter_texts, this->accepted_cargo_filter_criteria, WID_ID_FILTER_BY_ACC_CARGO, 0, 0); + break; + + case WID_ID_FILTER_BY_PROD_CARGO: // Cargo filter dropdown + ShowDropDownMenu(this, this->cargo_filter_texts, this->produced_cargo_filter_criteria, WID_ID_FILTER_BY_PROD_CARGO, 0, 0); + break; + case WID_ID_INDUSTRY_LIST: { uint p = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_ID_INDUSTRY_LIST, WD_FRAMERECT_TOP); - if (p < this->industries.Length()) { + if (p < this->industries.size()) { if (_ctrl_pressed) { ShowExtraViewPortWindow(this->industries[p]->location.tile); } else { @@ -1475,26 +1668,43 @@ public: } } - virtual void OnDropdownSelect(int widget, int index) + void OnDropdownSelect(int widget, int index) override { - if (this->industries.SortType() != index) { - this->industries.SetSortType(index); - this->BuildSortIndustriesList(); + switch (widget) { + case WID_ID_DROPDOWN_CRITERIA: { + if (this->industries.SortType() != index) { + this->industries.SetSortType(index); + this->BuildSortIndustriesList(); + } + break; + } + + case WID_ID_FILTER_BY_ACC_CARGO: { + this->SetAcceptedCargoFilterIndex(index); + this->BuildSortIndustriesList(); + break; + } + + case WID_ID_FILTER_BY_PROD_CARGO: { + this->SetProducedCargoFilterIndex(index); + this->BuildSortIndustriesList(); + break; + } } } - virtual void OnResize() + void OnResize() override { this->vscroll->SetCapacityFromWidget(this, WID_ID_INDUSTRY_LIST); } - virtual void OnPaint() + void OnPaint() override { if (this->industries.NeedRebuild()) this->BuildSortIndustriesList(); this->DrawWidgets(); } - virtual void OnHundredthTick() + void OnHundredthTick() override { this->industries.ForceResort(); this->BuildSortIndustriesList(); @@ -1505,19 +1715,26 @@ public: * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + 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->industries.ForceRebuild(); - } else { - this->industries.ForceResort(); + switch (data) { + case IDIWD_FORCE_REBUILD: + /* This needs to be done in command-scope to enforce rebuilding before resorting invalid data */ + this->industries.ForceRebuild(); + break; + + case IDIWD_PRODUCTION_CHANGE: + if (this->industries.SortType() == 2) this->industries.ForceResort(); + break; + + default: + this->industries.ForceResort(); + break; } } }; Listing IndustryDirectoryWindow::last_sorting = {false, 0}; -const Industry *IndustryDirectoryWindow::last_industry = NULL; /* Available station sorting functions. */ GUIIndustryList::SortFunction * const IndustryDirectoryWindow::sorter_funcs[] = { @@ -1922,8 +2139,8 @@ struct CargoesField { /** * Decide which cargo was clicked at in a #CFT_CARGO field. - * @param left Left industry neighbour if available (else \c NULL should be supplied). - * @param right Right industry neighbour if available (else \c NULL should be supplied). + * @param left Left industry neighbour if available (else \c nullptr should be supplied). + * @param right Right industry neighbour if available (else \c nullptr should be supplied). * @param pt Click position in the cargo field. * @return Cargo clicked at, or #INVALID_CARGO if none. */ @@ -1953,7 +2170,7 @@ struct CargoesField { /* row = 0 -> at first horizontal row, row = 1 -> second horizontal row, 2 = 3rd horizontal row. */ if (col == 0) { if (this->u.cargo.supp_cargoes[row] != INVALID_CARGO) return this->u.cargo.vertical_cargoes[this->u.cargo.supp_cargoes[row]]; - if (left != NULL) { + if (left != nullptr) { if (left->type == CFT_INDUSTRY) return left->u.industry.other_produced[row]; if (left->type == CFT_CARGO_LABEL && !left->u.cargo_label.left_align) return left->u.cargo_label.cargoes[row]; } @@ -1961,7 +2178,7 @@ struct CargoesField { } if (col == this->u.cargo.num_cargoes) { if (this->u.cargo.cust_cargoes[row] != INVALID_CARGO) return this->u.cargo.vertical_cargoes[this->u.cargo.cust_cargoes[row]]; - if (right != NULL) { + if (right != nullptr) { if (right->type == CFT_INDUSTRY) return right->u.industry.other_accepted[row]; if (right->type == CFT_CARGO_LABEL && right->u.cargo_label.left_align) return right->u.cargo_label.cargoes[row]; } @@ -2179,7 +2396,7 @@ next_cargo: ; struct IndustryCargoesWindow : public Window { static const int HOR_TEXT_PADDING, VERT_TEXT_PADDING; - typedef SmallVector Fields; + typedef std::vector Fields; Fields fields; ///< Fields to display in the #WID_IC_PANEL. uint ind_cargo; ///< If less than #NUM_INDUSTRYTYPES, an industry type, else a cargo id + NUM_INDUSTRYTYPES. @@ -2196,7 +2413,7 @@ struct IndustryCargoesWindow : public Window { this->OnInvalidateData(id); } - virtual void OnInit() + void OnInit() override { /* Initialize static CargoesField size variables. */ Dimension d = GetStringBoundingBox(STR_INDUSTRY_CARGOES_PRODUCERS); @@ -2243,7 +2460,7 @@ struct IndustryCargoesWindow : public Window { CargoesField::cargo_field_width = CargoesField::HOR_CARGO_BORDER_SPACE * 2 + CargoesField::HOR_CARGO_WIDTH * CargoesField::max_cargoes + CargoesField::HOR_CARGO_SPACE * (CargoesField::max_cargoes - 1); } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_IC_PANEL: @@ -2262,7 +2479,7 @@ struct IndustryCargoesWindow : public Window { CargoesFieldType type; ///< Type of field. - virtual void SetStringParameters (int widget) const + void SetStringParameters (int widget) const override { if (widget != WID_IC_CAPTION) return; @@ -2438,13 +2655,14 @@ struct IndustryCargoesWindow : public Window { _displayed_industries.reset(); _displayed_industries.set(it); - this->fields.Clear(); - CargoesRow *row = this->fields.Append(); - 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); + this->fields.clear(); + /*C++17: CargoesRow &row = */ this->fields.emplace_back(); + CargoesRow &row = this->fields.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); const IndustrySpec *central_sp = GetIndustrySpec(it); bool houses_supply = HousesCanSupply(central_sp->accepts_cargo, lengthof(central_sp->accepts_cargo)); @@ -2454,12 +2672,13 @@ struct IndustryCargoesWindow : public Window { int num_cust = CountMatchingAcceptingIndustries(central_sp->produced_cargo, lengthof(central_sp->produced_cargo)) + houses_accept; int num_indrows = max(3, max(num_supp, num_cust)); // One is needed for the 'it' industry, and 2 for the cargo labels. for (int i = 0; i < num_indrows; i++) { - CargoesRow *row = this->fields.Append(); - row->columns[0].MakeEmpty(CFT_EMPTY); - row->columns[1].MakeCargo(central_sp->accepts_cargo, lengthof(central_sp->accepts_cargo)); - row->columns[2].MakeEmpty(CFT_EMPTY); - row->columns[3].MakeCargo(central_sp->produced_cargo, lengthof(central_sp->produced_cargo)); - row->columns[4].MakeEmpty(CFT_EMPTY); + /*C++17: CargoesRow &row = */ this->fields.emplace_back(); + CargoesRow &row = this->fields.back(); + row.columns[0].MakeEmpty(CFT_EMPTY); + row.columns[1].MakeCargo(central_sp->accepts_cargo, lengthof(central_sp->accepts_cargo)); + row.columns[2].MakeEmpty(CFT_EMPTY); + row.columns[3].MakeCargo(central_sp->produced_cargo, lengthof(central_sp->produced_cargo)); + row.columns[4].MakeEmpty(CFT_EMPTY); } /* Add central industry. */ int central_row = 1 + num_indrows / 2; @@ -2516,13 +2735,14 @@ struct IndustryCargoesWindow : public Window { this->ind_cargo = cid + NUM_INDUSTRYTYPES; _displayed_industries.reset(); - this->fields.Clear(); - CargoesRow *row = this->fields.Append(); - 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); + this->fields.clear(); + /*C++17: CargoesRow &row = */ this->fields.emplace_back(); + CargoesRow &row = this->fields.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); bool houses_supply = HousesCanSupply(&cid, 1); bool houses_accept = HousesCanAccept(&cid, 1); @@ -2530,12 +2750,13 @@ struct IndustryCargoesWindow : public Window { int num_cust = CountMatchingAcceptingIndustries(&cid, 1) + houses_accept; int num_indrows = max(num_supp, num_cust); for (int i = 0; i < num_indrows; i++) { - CargoesRow *row = this->fields.Append(); - row->columns[0].MakeEmpty(CFT_EMPTY); - row->columns[1].MakeCargo(&cid, 1); - row->columns[2].MakeEmpty(CFT_EMPTY); - row->columns[3].MakeEmpty(CFT_EMPTY); - row->columns[4].MakeEmpty(CFT_EMPTY); + /*C++17: CargoesRow &row = */ this->fields.emplace_back(); + CargoesRow &row = this->fields.back(); + row.columns[0].MakeEmpty(CFT_EMPTY); + row.columns[1].MakeCargo(&cid, 1); + row.columns[2].MakeEmpty(CFT_EMPTY); + row.columns[3].MakeEmpty(CFT_EMPTY); + row.columns[4].MakeEmpty(CFT_EMPTY); } this->fields[num_indrows].MakeCargoLabel(0, false); // Add cargo labels at the left bottom. @@ -2581,7 +2802,7 @@ struct IndustryCargoesWindow : public Window { * - data = NUM_INDUSTRYTYPES: Stop sending updates to the smallmap window. * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; if (data == NUM_INDUSTRYTYPES) { @@ -2596,7 +2817,7 @@ struct IndustryCargoesWindow : public Window { this->ComputeIndustryDisplay(data); } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { if (widget != WID_IC_PANEL) return; @@ -2613,7 +2834,7 @@ struct IndustryCargoesWindow : public Window { const NWidgetBase *nwp = this->GetWidget(WID_IC_PANEL); int vpos = -this->vscroll->GetPosition() * nwp->resize_y; - for (uint i = 0; i < this->fields.Length(); i++) { + for (uint i = 0; i < this->fields.size(); i++) { int row_height = (i == 0) ? CargoesField::small_height : CargoesField::normal_height; if (vpos + row_height >= 0) { int xpos = left_pos; @@ -2655,7 +2876,7 @@ struct IndustryCargoesWindow : public Window { if (pt.y < vpos) return false; int row = (pt.y - vpos) / CargoesField::normal_height; // row is relative to row 1. - if (row + 1 >= (int)this->fields.Length()) return false; + if (row + 1 >= (int)this->fields.size()) return false; vpos = pt.y - vpos - row * CargoesField::normal_height; // Position in the row + 1 field row++; // rebase row to match index of this->fields. @@ -2684,7 +2905,7 @@ struct IndustryCargoesWindow : public Window { return true; } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_IC_PANEL: { @@ -2698,8 +2919,8 @@ struct IndustryCargoesWindow : public Window { break; case CFT_CARGO: { - CargoesField *lft = (fieldxy.x > 0) ? this->fields[fieldxy.y].columns + fieldxy.x - 1 : NULL; - CargoesField *rgt = (fieldxy.x < 4) ? this->fields[fieldxy.y].columns + fieldxy.x + 1 : NULL; + CargoesField *lft = (fieldxy.x > 0) ? this->fields[fieldxy.y].columns + fieldxy.x - 1 : nullptr; + CargoesField *rgt = (fieldxy.x < 4) ? this->fields[fieldxy.y].columns + fieldxy.x + 1 : nullptr; CargoID cid = fld->CargoClickedAt(lft, rgt, xy); if (cid != INVALID_CARGO) this->ComputeCargoDisplay(cid); break; @@ -2723,46 +2944,41 @@ struct IndustryCargoesWindow : public Window { if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); if (this->IsWidgetLowered(WID_IC_NOTIFY)) { - if (FindWindowByClass(WC_SMALLMAP) == NULL) ShowSmallMap(); + if (FindWindowByClass(WC_SMALLMAP) == nullptr) ShowSmallMap(); this->NotifySmallmap(); } break; case WID_IC_CARGO_DROPDOWN: { - DropDownList *lst = new DropDownList; + DropDownList lst; const CargoSpec *cs; FOR_ALL_SORTED_STANDARD_CARGOSPECS(cs) { - *lst->Append() = new DropDownListStringItem(cs->name, cs->Index(), false); + lst.emplace_back(new DropDownListStringItem(cs->name, cs->Index(), false)); } - if (lst->Length() == 0) { - delete lst; - break; + if (!lst.empty()) { + int selected = (this->ind_cargo >= NUM_INDUSTRYTYPES) ? (int)(this->ind_cargo - NUM_INDUSTRYTYPES) : -1; + ShowDropDownList(this, std::move(lst), selected, WID_IC_CARGO_DROPDOWN, 0, true); } - int selected = (this->ind_cargo >= NUM_INDUSTRYTYPES) ? (int)(this->ind_cargo - NUM_INDUSTRYTYPES) : -1; - ShowDropDownList(this, lst, selected, WID_IC_CARGO_DROPDOWN, 0, true); break; } case WID_IC_IND_DROPDOWN: { - DropDownList *lst = new DropDownList; - for (uint i = 0; i < NUM_INDUSTRYTYPES; i++) { - IndustryType ind = _sorted_industry_types[i]; + DropDownList lst; + for (IndustryType ind : _sorted_industry_types) { const IndustrySpec *indsp = GetIndustrySpec(ind); if (!indsp->enabled) continue; - *lst->Append() = new DropDownListStringItem(indsp->name, ind, false); + lst.emplace_back(new DropDownListStringItem(indsp->name, ind, false)); } - if (lst->Length() == 0) { - delete lst; - break; + if (!lst.empty()) { + int selected = (this->ind_cargo < NUM_INDUSTRYTYPES) ? (int)this->ind_cargo : -1; + ShowDropDownList(this, std::move(lst), selected, WID_IC_IND_DROPDOWN, 0, true); } - int selected = (this->ind_cargo < NUM_INDUSTRYTYPES) ? (int)this->ind_cargo : -1; - ShowDropDownList(this, lst, selected, WID_IC_IND_DROPDOWN, 0, true); break; } } } - virtual void OnDropdownSelect(int widget, int index) + void OnDropdownSelect(int widget, int index) override { if (index < 0) return; @@ -2777,7 +2993,7 @@ struct IndustryCargoesWindow : public Window { } } - bool OnTooltip(Point pt, int widget, TooltipCloseCondition close_cond) + bool OnTooltip(Point pt, int widget, TooltipCloseCondition close_cond) override { if (widget != WID_IC_PANEL) return false; @@ -2788,8 +3004,8 @@ struct IndustryCargoesWindow : public Window { CargoID cid = INVALID_CARGO; switch (fld->type) { case CFT_CARGO: { - CargoesField *lft = (fieldxy.x > 0) ? this->fields[fieldxy.y].columns + fieldxy.x - 1 : NULL; - CargoesField *rgt = (fieldxy.x < 4) ? this->fields[fieldxy.y].columns + fieldxy.x + 1 : NULL; + CargoesField *lft = (fieldxy.x > 0) ? this->fields[fieldxy.y].columns + fieldxy.x - 1 : nullptr; + CargoesField *rgt = (fieldxy.x < 4) ? this->fields[fieldxy.y].columns + fieldxy.x + 1 : nullptr; cid = fld->CargoClickedAt(lft, rgt, xy); break; } @@ -2801,7 +3017,7 @@ struct IndustryCargoesWindow : public Window { case CFT_INDUSTRY: if (fld->u.industry.ind_type < NUM_INDUSTRYTYPES && (this->ind_cargo >= NUM_INDUSTRYTYPES || fieldxy.x != 2)) { - GuiShowTooltips(this, STR_INDUSTRY_CARGOES_INDUSTRY_TOOLTIP, 0, NULL, close_cond); + GuiShowTooltips(this, STR_INDUSTRY_CARGOES_INDUSTRY_TOOLTIP, 0, nullptr, close_cond); } return true; @@ -2819,7 +3035,7 @@ struct IndustryCargoesWindow : public Window { return false; } - virtual void OnResize() + void OnResize() override { this->vscroll->SetCapacityFromWidget(this, WID_IC_PANEL); } @@ -2835,10 +3051,10 @@ const int IndustryCargoesWindow::VERT_TEXT_PADDING = 5; ///< Vertical padding ar static void ShowIndustryCargoesWindow(IndustryType id) { if (id >= NUM_INDUSTRYTYPES) { - for (uint i = 0; i < NUM_INDUSTRYTYPES; i++) { - const IndustrySpec *indsp = GetIndustrySpec(_sorted_industry_types[i]); + for (IndustryType ind : _sorted_industry_types) { + const IndustrySpec *indsp = GetIndustrySpec(ind); if (indsp->enabled) { - id = _sorted_industry_types[i]; + id = ind; break; } } @@ -2846,7 +3062,7 @@ static void ShowIndustryCargoesWindow(IndustryType id) } Window *w = BringWindowToFrontById(WC_INDUSTRY_CARGOES, 0); - if (w != NULL) { + if (w != nullptr) { w->InvalidateData(id); return; } diff --git a/src/industry_map.h b/src/industry_map.h index 9d2e3de211..1cdf90e59a 100644 --- a/src/industry_map.h +++ b/src/industry_map.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/industry_type.h b/src/industry_type.h index 9a8a469017..cac99043e0 100644 --- a/src/industry_type.h +++ b/src/industry_type.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/industrytype.h b/src/industrytype.h index cd451fa777..ec4f8f85df 100644 --- a/src/industrytype.h +++ b/src/industrytype.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. @@ -12,6 +10,8 @@ #ifndef INDUSTRYTYPE_H #define INDUSTRYTYPE_H +#include +#include #include "map_type.h" #include "slope_type.h" #include "industry_type.h" @@ -22,7 +22,6 @@ enum IndustryCleanupType { CLEAN_RANDOMSOUNDS, ///< Free the dynamically allocated sounds table - CLEAN_TILELAYOUT, ///< Free the dynamically allocated tile layout structure }; /** Available types of industry lifetimes. */ @@ -92,17 +91,20 @@ enum IndustryTileSpecialFlags { }; DECLARE_ENUM_AS_BIT_SET(IndustryTileSpecialFlags) -struct IndustryTileTable { +/** Definition of one tile in an industry tile layout */ +struct IndustryTileLayoutTile { TileIndexDiffC ti; IndustryGfx gfx; }; +/** A complete tile layout for an industry is a list of tiles */ +using IndustryTileLayout = std::vector; + /** * Defines the data structure for constructing industry. */ struct IndustrySpec { - const IndustryTileTable * const *table; ///< List of the tiles composing the industry - byte num_table; ///< Number of elements in the table + std::vector layouts; ///< List of possible tile layouts for the industry uint8 cost_multiplier; ///< Base construction cost multiplier. uint32 removal_cost_multiplier; ///< Base removal cost multiplier. uint32 prospecting_chance; ///< Chance prospecting succeeds @@ -142,6 +144,8 @@ struct IndustrySpec { Money GetConstructionCost() const; Money GetRemovalCost() const; bool UsesSmoothEconomy() const; + + ~IndustrySpec(); }; /** @@ -179,7 +183,7 @@ extern IndustryTileSpec _industry_tile_specs[NUM_INDUSTRYTILES]; /* industry_gui.cpp */ void SortIndustryTypes(); /* Industry types sorted alphabetically by name. */ -extern IndustryType _sorted_industry_types[NUM_INDUSTRYTYPES]; +extern std::array _sorted_industry_types; /** * Do industry gfx ID translation for NewGRFs. diff --git a/src/ini.cpp b/src/ini.cpp index ae0750ffd1..042f5f6e97 100644 --- a/src/ini.cpp +++ b/src/ini.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. @@ -29,7 +27,7 @@ /** * Create a new ini file with given group names. - * @param list_group_names A \c NULL terminated list with group names that should be loaded as lists instead of variables. @see IGT_LIST + * @param list_group_names A \c nullptr terminated list with group names that should be loaded as lists instead of variables. @see IGT_LIST */ IniFile::IniFile(const char * const *list_group_names) : IniLoadFile(list_group_names) { @@ -52,23 +50,23 @@ bool IniFile::SaveToDisk(const char *filename) strecpy(file_new, filename, lastof(file_new)); strecat(file_new, ".new", lastof(file_new)); FILE *f = fopen(file_new, "w"); - if (f == NULL) return false; + if (f == nullptr) return false; - for (const IniGroup *group = this->group; group != NULL; group = group->next) { + for (const IniGroup *group = this->group; group != nullptr; group = group->next) { if (group->comment) fputs(group->comment, f); fprintf(f, "[%s]\n", group->name); - for (const IniItem *item = group->item; item != NULL; item = item->next) { - if (item->comment != NULL) fputs(item->comment, f); + for (const IniItem *item = group->item; item != nullptr; item = item->next) { + if (item->comment != nullptr) fputs(item->comment, f); /* protect item->name with quotes if needed */ - if (strchr(item->name, ' ') != NULL || + if (strchr(item->name, ' ') != nullptr || item->name[0] == '[') { fprintf(f, "\"%s\"", item->name); } else { fprintf(f, "%s", item->name); } - fprintf(f, " = %s\n", item->value == NULL ? "" : item->value); + fprintf(f, " = %s\n", item->value == nullptr ? "" : item->value); } } if (this->comment) fputs(this->comment, f); diff --git a/src/ini_load.cpp b/src/ini_load.cpp index 389dcab031..dd72831308 100644 --- a/src/ini_load.cpp +++ b/src/ini_load.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. @@ -23,7 +21,7 @@ * @param name the name of the item * @param last the last element of the name of the item */ -IniItem::IniItem(IniGroup *parent, const char *name, const char *last) : next(NULL), value(NULL), comment(NULL) +IniItem::IniItem(IniGroup *parent, const char *name, const char *last) : next(nullptr), value(nullptr), comment(nullptr) { this->name = stredup(name, last); str_validate(this->name, this->name + strlen(this->name)); @@ -58,7 +56,7 @@ void IniItem::SetValue(const char *value) * @param name the name of the group * @param last the last element of the name of the group */ -IniGroup::IniGroup(IniLoadFile *parent, const char *name, const char *last) : next(NULL), type(IGT_VARIABLES), item(NULL), comment(NULL) +IniGroup::IniGroup(IniLoadFile *parent, const char *name, const char *last) : next(nullptr), type(IGT_VARIABLES), item(nullptr), comment(nullptr) { this->name = stredup(name, last); str_validate(this->name, this->name + strlen(this->name)); @@ -67,16 +65,16 @@ IniGroup::IniGroup(IniLoadFile *parent, const char *name, const char *last) : ne *parent->last_group = this; parent->last_group = &this->next; - if (parent->list_group_names != NULL) { - for (uint i = 0; parent->list_group_names[i] != NULL; i++) { + if (parent->list_group_names != nullptr) { + for (uint i = 0; parent->list_group_names[i] != nullptr; i++) { if (strcmp(this->name, parent->list_group_names[i]) == 0) { this->type = IGT_LIST; return; } } } - if (parent->seq_group_names != NULL) { - for (uint i = 0; parent->seq_group_names[i] != NULL; i++) { + if (parent->seq_group_names != nullptr) { + for (uint i = 0; parent->seq_group_names[i] != nullptr; i++) { if (strcmp(this->name, parent->seq_group_names[i]) == 0) { this->type = IGT_SEQUENCE; return; @@ -100,18 +98,18 @@ IniGroup::~IniGroup() * and create is true it creates a new item. * @param name name of the item to find. * @param create whether to create an item when not found or not. - * @return the requested item or NULL if not found. + * @return the requested item or nullptr if not found. */ IniItem *IniGroup::GetItem(const char *name, bool create) { - for (IniItem *item = this->item; item != NULL; item = item->next) { + for (IniItem *item = this->item; item != nullptr; item = item->next) { if (strcmp(item->name, name) == 0) return item; } - if (!create) return NULL; + if (!create) return nullptr; /* otherwise make a new one */ - return new IniItem(this, name, NULL); + return new IniItem(this, name, nullptr); } /** @@ -120,18 +118,18 @@ IniItem *IniGroup::GetItem(const char *name, bool create) void IniGroup::Clear() { delete this->item; - this->item = NULL; + this->item = nullptr; this->last_item = &this->item; } /** * Construct a new in-memory Ini file representation. - * @param list_group_names A \c NULL terminated list with group names that should be loaded as lists instead of variables. @see IGT_LIST - * @param seq_group_names A \c NULL terminated list with group names that should be loaded as lists of names. @see IGT_SEQUENCE + * @param list_group_names A \c nullptr terminated list with group names that should be loaded as lists instead of variables. @see IGT_LIST + * @param seq_group_names A \c nullptr terminated list with group names that should be loaded as lists of names. @see IGT_SEQUENCE */ IniLoadFile::IniLoadFile(const char * const *list_group_names, const char * const *seq_group_names) : - group(NULL), - comment(NULL), + group(nullptr), + comment(nullptr), list_group_names(list_group_names), seq_group_names(seq_group_names) { @@ -151,20 +149,20 @@ IniLoadFile::~IniLoadFile() * @param name name of the group to find. * @param len the maximum length of said name (\c 0 means length of the string). * @param create_new Allow creation of group if it does not exist. - * @return The requested group if it exists or was created, else \c NULL. + * @return The requested group if it exists or was created, else \c nullptr. */ IniGroup *IniLoadFile::GetGroup(const char *name, size_t len, bool create_new) { if (len == 0) len = strlen(name); /* does it exist already? */ - for (IniGroup *group = this->group; group != NULL; group = group->next) { + for (IniGroup *group = this->group; group != nullptr; group = group->next) { if (!strncmp(group->name, name, len) && group->name[len] == 0) { return group; } } - if (!create_new) return NULL; + if (!create_new) return nullptr; /* otherwise make a new one */ IniGroup *group = new IniGroup(this, name, name + len - 1); @@ -179,19 +177,19 @@ IniGroup *IniLoadFile::GetGroup(const char *name, size_t len, bool create_new) void IniLoadFile::RemoveGroup(const char *name) { size_t len = strlen(name); - IniGroup *prev = NULL; + IniGroup *prev = nullptr; IniGroup *group; /* does it exist already? */ - for (group = this->group; group != NULL; prev = group, group = group->next) { + for (group = this->group; group != nullptr; prev = group, group = group->next) { if (strncmp(group->name, name, len) == 0) { break; } } - if (group == NULL) return; + if (group == nullptr) return; - if (prev != NULL) { + if (prev != nullptr) { prev->next = prev->next->next; if (this->last_group == &group->next) this->last_group = &prev->next; } else { @@ -199,7 +197,7 @@ void IniLoadFile::RemoveGroup(const char *name) if (this->last_group == &group->next) this->last_group = &this->group; } - group->next = NULL; + group->next = nullptr; delete group; } @@ -214,15 +212,15 @@ void IniLoadFile::LoadFromDisk(const char *filename, Subdirectory subdir) assert(this->last_group == &this->group); char buffer[1024]; - IniGroup *group = NULL; + IniGroup *group = nullptr; - char *comment = NULL; + char *comment = nullptr; uint comment_size = 0; uint comment_alloc = 0; size_t end; FILE *in = this->OpenFile(filename, subdir, &end); - if (in == NULL) return; + if (in == nullptr) return; end += ftell(in); @@ -238,7 +236,7 @@ void IniLoadFile::LoadFromDisk(const char *filename, Subdirectory subdir) *e = '\0'; /* Skip comments and empty lines outside IGT_SEQUENCE groups. */ - if ((group == NULL || group->type != IGT_SEQUENCE) && (*s == '#' || *s == ';' || *s == '\0')) { + if ((group == nullptr || group->type != IGT_SEQUENCE) && (*s == '#' || *s == ';' || *s == '\0')) { uint ns = comment_size + (e - s + 1); uint a = comment_alloc; /* add to comment */ @@ -267,7 +265,7 @@ void IniLoadFile::LoadFromDisk(const char *filename, Subdirectory subdir) group->comment = stredup(comment, comment + comment_size - 1); comment_size = 0; } - } else if (group != NULL) { + } else if (group != nullptr) { if (group->type == IGT_SEQUENCE) { /* A sequence group, use the line as item name without further interpretation. */ IniItem *item = new IniItem(group, buffer, e - 1); @@ -305,9 +303,9 @@ void IniLoadFile::LoadFromDisk(const char *filename, Subdirectory subdir) if (e > t && e[-1] == '\"') e--; *e = '\0'; - /* If the value was not quoted and empty, it must be NULL */ - item->value = (!quoted && e == t) ? NULL : stredup(t); - if (item->value != NULL) str_validate(item->value, item->value + strlen(item->value)); + /* If the value was not quoted and empty, it must be nullptr */ + item->value = (!quoted && e == t) ? nullptr : stredup(t); + if (item->value != nullptr) str_validate(item->value, item->value + strlen(item->value)); } else { /* it's an orphan item */ this->ReportFileError("ini: '", buffer, "' outside of group"); diff --git a/src/ini_type.h b/src/ini_type.h index 9bd47fd4e5..679969efda 100644 --- a/src/ini_type.h +++ b/src/ini_type.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. @@ -28,7 +26,7 @@ struct IniItem { char *value; ///< The value of this item char *comment; ///< The comment associated with this item - IniItem(struct IniGroup *parent, const char *name, const char *last = NULL); + IniItem(struct IniGroup *parent, const char *name, const char *last = nullptr); ~IniItem(); void SetValue(const char *value); @@ -43,7 +41,7 @@ struct IniGroup { char *name; ///< name of group char *comment; ///< comment for group - IniGroup(struct IniLoadFile *parent, const char *name, const char *last = NULL); + IniGroup(struct IniLoadFile *parent, const char *name, const char *last = nullptr); ~IniGroup(); IniItem *GetItem(const char *name, bool create); @@ -55,10 +53,10 @@ struct IniLoadFile { IniGroup *group; ///< the first group in the ini IniGroup **last_group; ///< the last group in the ini char *comment; ///< last comment in file - const char * const *list_group_names; ///< NULL terminated list with group names that are lists - const char * const *seq_group_names; ///< NULL terminated list with group names that are sequences. + const char * const *list_group_names; ///< nullptr terminated list with group names that are lists + const char * const *seq_group_names; ///< nullptr terminated list with group names that are sequences. - IniLoadFile(const char * const *list_group_names = NULL, const char * const *seq_group_names = NULL); + IniLoadFile(const char * const *list_group_names = nullptr, const char * const *seq_group_names = nullptr); virtual ~IniLoadFile(); IniGroup *GetGroup(const char *name, size_t len = 0, bool create_new = true); @@ -71,7 +69,7 @@ struct IniLoadFile { * @param filename Name of the INI file. * @param subdir The subdir to load the file from. * @param[out] size Size of the opened file. - * @return File handle of the opened file, or \c NULL. + * @return File handle of the opened file, or \c nullptr. */ virtual FILE *OpenFile(const char *filename, Subdirectory subdir, size_t *size) = 0; @@ -86,7 +84,7 @@ struct IniLoadFile { /** Ini file that supports both loading and saving. */ struct IniFile : IniLoadFile { - IniFile(const char * const *list_group_names = NULL); + IniFile(const char * const *list_group_names = nullptr); bool SaveToDisk(const char *filename); diff --git a/src/intro_gui.cpp b/src/intro_gui.cpp index d0ac774027..5e7ffc4252 100644 --- a/src/intro_gui.cpp +++ b/src/intro_gui.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. @@ -50,7 +48,7 @@ struct SelectGameWindow : public Window { * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; this->SetWidgetLoweredState(WID_SGI_TEMPERATE_LANDSCAPE, _settings_newgame.game_creation.landscape == LT_TEMPERATE); @@ -59,7 +57,7 @@ struct SelectGameWindow : public Window { this->SetWidgetLoweredState(WID_SGI_TOYLAND_LANDSCAPE, _settings_newgame.game_creation.landscape == LT_TOYLAND); } - virtual void OnInit() + void OnInit() override { bool missing_sprites = _missing_extra_graphics > 0 && !IsReleasedVersion(); missing_sprites = false; @@ -72,7 +70,7 @@ struct SelectGameWindow : public Window { this->GetWidget(WID_SGI_TRANSLATION_SELECTION)->SetDisplayedPlane(missing_lang ? 0 : SZSP_NONE); } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { switch (widget) { case WID_SGI_BASESET: @@ -87,7 +85,7 @@ struct SelectGameWindow : public Window { } } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { StringID str = 0; switch (widget) { @@ -116,13 +114,11 @@ struct SelectGameWindow : public Window { } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { -#ifdef ENABLE_NETWORK /* Do not create a network server when you (just) have closed one of the game * creation/load windows for the network server. */ if (IsInsideMM(widget, WID_SGI_GENERATE_GAME, WID_SGI_EDIT_SCENARIO + 1)) _is_network_server = false; -#endif /* ENABLE_NETWORK */ switch (widget) { case WID_SGI_GENERATE_GAME: @@ -277,7 +273,7 @@ static const NWidgetPart _nested_select_game_widgets[] = { }; static WindowDesc _select_game_desc( - WDP_CENTER, NULL, 0, 0, + WDP_CENTER, nullptr, 0, 0, WC_SELECT_GAME, WC_NONE, 0, _nested_select_game_widgets, lengthof(_nested_select_game_widgets) @@ -299,27 +295,19 @@ void AskExitGame() SetDParam(0, STR_OSNAME_WINDOWS); #elif defined(__APPLE__) SetDParam(0, STR_OSNAME_OSX); -#elif defined(__BEOS__) - SetDParam(0, STR_OSNAME_BEOS); #elif defined(__HAIKU__) SetDParam(0, STR_OSNAME_HAIKU); -#elif defined(__MORPHOS__) - SetDParam(0, STR_OSNAME_MORPHOS); -#elif defined(__AMIGA__) - SetDParam(0, STR_OSNAME_AMIGAOS); #elif defined(__OS2__) SetDParam(0, STR_OSNAME_OS2); #elif defined(SUNOS) SetDParam(0, STR_OSNAME_SUNOS); -#elif defined(DOS) - SetDParam(0, STR_OSNAME_DOS); #else SetDParam(0, STR_OSNAME_UNIX); #endif ShowQuery( STR_QUIT_CAPTION, STR_QUIT_ARE_YOU_SURE_YOU_WANT_TO_EXIT_OPENTTD, - NULL, + nullptr, AskExitGameCallback ); } @@ -338,7 +326,7 @@ void AskExitToGameMenu() ShowQuery( STR_ABANDON_GAME_CAPTION, (_game_mode != GM_EDITOR) ? STR_ABANDON_GAME_QUERY : STR_ABANDON_SCENARIO_QUERY, - NULL, + nullptr, AskExitToGameMenuCallback ); } diff --git a/src/landscape.cpp b/src/landscape.cpp index b36f5c8842..e97d9cff03 100644 --- a/src/landscape.cpp +++ b/src/landscape.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. @@ -82,12 +80,12 @@ extern const byte _slope_to_sprite_offset[32] = { /** * Description of the snow line throughout the year. * - * If it is \c NULL, a static snowline height is used, as set by \c _settings_game.game_creation.snow_line_height. + * If it is \c nullptr, a static snowline height is used, as set by \c _settings_game.game_creation.snow_line_height. * Otherwise it points to a table loaded from a newGRF file that describes the variable snowline. * @ingroup SnowLineGroup * @see GetSnowLine() GameCreationSettings */ -static SnowLine *_snow_line = NULL; +static SnowLine *_snow_line = nullptr; /** * Map 2D viewport or smallmap coordinate to 3D world or tile coordinate. @@ -104,7 +102,7 @@ static SnowLine *_snow_line = NULL; */ Point InverseRemapCoords2(int x, int y, bool clamp_to_map, bool *clamped) { - if (clamped != NULL) *clamped = false; // Not clamping yet. + if (clamped != nullptr) *clamped = false; // Not clamping yet. /* Initial x/y world coordinate is like if the landscape * was completely flat on height 0. */ @@ -122,7 +120,7 @@ Point InverseRemapCoords2(int x, int y, bool clamp_to_map, bool *clamped) Point old_pt = pt; pt.x = Clamp(pt.x, -extra_tiles * TILE_SIZE, max_x); pt.y = Clamp(pt.y, -extra_tiles * TILE_SIZE, max_y); - if (clamped != NULL) *clamped = (pt.x != old_pt.x) || (pt.y != old_pt.y); + if (clamped != nullptr) *clamped = (pt.x != old_pt.x) || (pt.y != old_pt.y); } /* Now find the Z-world coordinate by fix point iteration. @@ -147,7 +145,7 @@ Point InverseRemapCoords2(int x, int y, bool clamp_to_map, bool *clamped) Point old_pt = pt; pt.x = Clamp(pt.x, min_coord, max_x); pt.y = Clamp(pt.y, min_coord, max_y); - if (clamped != NULL) *clamped = *clamped || (pt.x != old_pt.x) || (pt.y != old_pt.y); + if (clamped != nullptr) *clamped = *clamped || (pt.x != old_pt.x) || (pt.y != old_pt.y); } return pt; @@ -352,8 +350,8 @@ int GetSlopePixelZ(int x, int y) * Return world \c z coordinate of a given point of a tile, * also for tiles outside the map (virtual "black" tiles). * - * @param x World X coordinate in tile "units", may be ouside the map. - * @param y World Y coordinate in tile "units", may be ouside the map. + * @param x World X coordinate in tile "units", may be outside the map. + * @param y World Y coordinate in tile "units", may be outside the map. * @return World Z coordinate at tile ground level, including slopes and foundations. */ int GetSlopePixelZOutsideMap(int x, int y) @@ -418,7 +416,7 @@ void GetSlopePixelZOnEdge(Slope tileh, DiagDirection edge, int *z1, int *z2) * If a tile does not have a foundation, the function returns the same as GetTileSlope. * * @param tile The tile of interest. - * @param z returns the z of the foundation slope. (Can be NULL, if not needed) + * @param z returns the z of the foundation slope. (Can be nullptr, if not needed) * @return The slope on top of the foundation. */ Slope GetFoundationSlope(TileIndex tile, int *z) @@ -426,7 +424,7 @@ Slope GetFoundationSlope(TileIndex tile, int *z) Slope tileh = GetTileSlope(tile, z); Foundation f = _tile_type_procs[GetTileType(tile)]->get_foundation_proc(tile, tileh); uint z_inc = ApplyFoundationToSlope(f, &tileh); - if (z != NULL) *z += z_inc; + if (z != nullptr) *z += z_inc; return tileh; } @@ -572,7 +570,7 @@ void DrawFoundation(TileInfo *ti, Foundation f) 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 != NULL) DeleteAnimatedTile(tile); + if (_tile_type_procs[GetTileType(tile)]->animate_tile_proc != nullptr) DeleteAnimatedTile(tile); MakeClear(tile, CLEAR_GRASS, _generating_world ? 3 : 0); MarkTileDirtyByTile(tile); @@ -616,7 +614,7 @@ void GetTileDesc(TileIndex tile, TileDesc *td) */ bool IsSnowLineSet() { - return _snow_line != NULL; + return _snow_line != nullptr; } /** @@ -645,7 +643,7 @@ void SetSnowLine(byte table[SNOW_LINE_MONTHS][SNOW_LINE_DAYS]) */ byte GetSnowLine() { - if (_snow_line == NULL) return _settings_game.game_creation.snow_line_height; + if (_snow_line == nullptr) return _settings_game.game_creation.snow_line_height; YearMonthDay ymd; ConvertDateToYMD(_date, &ymd); @@ -659,7 +657,7 @@ byte GetSnowLine() */ byte HighestSnowLine() { - return _snow_line == NULL ? _settings_game.game_creation.snow_line_height : _snow_line->highest_value; + return _snow_line == nullptr ? _settings_game.game_creation.snow_line_height : _snow_line->highest_value; } /** @@ -669,7 +667,7 @@ byte HighestSnowLine() */ byte LowestSnowLine() { - return _snow_line == NULL ? _settings_game.game_creation.snow_line_height : _snow_line->lowest_value; + return _snow_line == nullptr ? _settings_game.game_creation.snow_line_height : _snow_line->lowest_value; } /** @@ -679,7 +677,7 @@ byte LowestSnowLine() void ClearSnowLine() { free(_snow_line); - _snow_line = NULL; + _snow_line = nullptr; } /** @@ -702,8 +700,8 @@ CommandCost CmdLandscapeClear(TileIndex tile, DoCommandFlag flags, uint32 p1, ui cost.AddCost(GetWaterClass(tile) == WATER_CLASS_CANAL ? _price[PR_CLEAR_CANAL] : _price[PR_CLEAR_WATER]); } - Company *c = (flags & (DC_AUTO | DC_BANKRUPT)) ? NULL : Company::GetIfValid(_current_company); - if (c != NULL && (int)GB(c->clear_limit, 16, 16) < 1) { + Company *c = (flags & (DC_AUTO | DC_BANKRUPT)) ? nullptr : Company::GetIfValid(_current_company); + if (c != nullptr && (int)GB(c->clear_limit, 16, 16) < 1) { return_cmd_error(STR_ERROR_CLEARING_LIMIT_REACHED); } @@ -711,7 +709,7 @@ CommandCost CmdLandscapeClear(TileIndex tile, DoCommandFlag flags, uint32 p1, ui /* If this tile was the first tile which caused object destruction, always * pass it on to the tile_type_proc. That way multiple test runs and the exec run stay consistent. */ - if (coa != NULL && coa->first_tile != tile) { + if (coa != nullptr && coa->first_tile != tile) { /* If this tile belongs to an object which was already cleared via another tile, pretend it has been * already removed. * However, we need to check stuff, which is not the same for all object tiles. (e.g. being on water or not) */ @@ -725,7 +723,7 @@ CommandCost CmdLandscapeClear(TileIndex tile, DoCommandFlag flags, uint32 p1, ui } if (flags & DC_EXEC) { - if (c != NULL) c->clear_limit -= 1 << 16; + if (c != nullptr) c->clear_limit -= 1 << 16; if (do_clear) DoClearSquare(tile); } return cost; @@ -750,8 +748,8 @@ CommandCost CmdClearArea(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 CommandCost last_error = CMD_ERROR; bool had_success = false; - const Company *c = (flags & (DC_AUTO | DC_BANKRUPT)) ? NULL : Company::GetIfValid(_current_company); - int limit = (c == NULL ? INT32_MAX : GB(c->clear_limit, 16, 16)); + 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 = HasBit(p2, 0) ? (TileIterator *)new DiagonalTileIterator(tile, p1) : new OrthogonalTileIterator(tile, p1); for (; *iter != INVALID_TILE; ++(*iter)) { @@ -761,7 +759,7 @@ CommandCost CmdClearArea(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 last_error = ret; /* We may not clear more tiles. */ - if (c != NULL && GB(c->clear_limit, 16, 16) < 1) break; + if (c != nullptr && GB(c->clear_limit, 16, 16) < 1) break; continue; } @@ -862,7 +860,7 @@ 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); - if (templ == NULL) usererror("Map generator sprites could not be loaded"); + if (templ == nullptr) usererror("Map generator sprites could not be loaded"); uint x = r & MapMaxX(); uint y = (r >> MapLogX()) & MapMaxY(); @@ -1065,7 +1063,7 @@ static bool MakeLake(TileIndex tile, void *user_data) MakeRiver(tile, Random()); /* Remove desert directly around the river tile. */ TileIndex t = tile; - CircularTileSearch(&t, RIVER_OFFSET_DESERT_DISTANCE, RiverModifyDesertZone, NULL); + CircularTileSearch(&t, RIVER_OFFSET_DESERT_DISTANCE, RiverModifyDesertZone, nullptr); return false; } } @@ -1132,12 +1130,12 @@ 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 != NULL; path = path->parent) { + for (PathNode *path = ¤t->path; path != nullptr; path = path->parent) { TileIndex tile = path->node.tile; if (!IsWaterTile(tile)) { MakeRiver(tile, Random()); /* Remove desert directly around the river tile. */ - CircularTileSearch(&tile, RIVER_OFFSET_DESERT_DISTANCE, RiverModifyDesertZone, NULL); + CircularTileSearch(&tile, RIVER_OFFSET_DESERT_DISTANCE, RiverModifyDesertZone, nullptr); } } } @@ -1249,7 +1247,7 @@ static bool FlowRiver(TileIndex spring, TileIndex begin) end = lakeCenter; MakeRiver(lakeCenter, Random()); /* Remove desert directly around the river tile. */ - CircularTileSearch(&lakeCenter, RIVER_OFFSET_DESERT_DISTANCE, RiverModifyDesertZone, NULL); + CircularTileSearch(&lakeCenter, RIVER_OFFSET_DESERT_DISTANCE, RiverModifyDesertZone, nullptr); lakeCenter = end; uint range = RandomRange(8) + 3; CircularTileSearch(&lakeCenter, range, MakeLake, &height); @@ -1280,7 +1278,7 @@ static void CreateRivers() IncreaseGeneratingWorldProgress(GWP_RIVER); for (int tries = 0; tries < 128; tries++) { TileIndex t = RandomTile(); - if (!CircularTileSearch(&t, 8, FindSpring, NULL)) continue; + if (!CircularTileSearch(&t, 8, FindSpring, nullptr)) continue; if (FlowRiver(t, t)) break; } } diff --git a/src/landscape.h b/src/landscape.h index 43d9e5f2e6..850ab482b4 100644 --- a/src/landscape.h +++ b/src/landscape.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. @@ -36,7 +34,7 @@ byte LowestSnowLine(); void ClearSnowLine(); int GetSlopeZInCorner(Slope tileh, Corner corner); -Slope GetFoundationSlope(TileIndex tile, int *z = NULL); +Slope GetFoundationSlope(TileIndex tile, int *z = nullptr); uint GetPartialPixelZ(int x, int y, Slope corners); int GetSlopePixelZ(int x, int y); @@ -62,12 +60,12 @@ static inline int GetSlopePixelZInCorner(Slope tileh, Corner corner) * If a tile does not have a foundation, the function returns the same as GetTilePixelSlope. * * @param tile The tile of interest. - * @param z returns the z of the foundation slope. (Can be NULL, if not needed) + * @param z returns the z of the foundation slope. (Can be nullptr, if not needed) * @return The slope on top of the foundation. */ static inline Slope GetFoundationPixelSlope(TileIndex tile, int *z) { - assert(z != NULL); + assert(z != nullptr); Slope s = GetFoundationSlope(tile, z); *z *= TILE_HEIGHT; return s; @@ -117,7 +115,7 @@ static inline Point InverseRemapCoords(int x, int y) return pt; } -Point InverseRemapCoords2(int x, int y, bool clamp_to_map = false, bool *clamped = NULL); +Point InverseRemapCoords2(int x, int y, bool clamp_to_map = false, bool *clamped = nullptr); uint ApplyFoundationToSlope(Foundation f, Slope *s); /** diff --git a/src/landscape_type.h b/src/landscape_type.h index 0742a32bbf..80b541bea4 100644 --- a/src/landscape_type.h +++ b/src/landscape_type.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/lang/afrikaans.txt b/src/lang/afrikaans.txt index 1a7376de1f..29f60b9bde 100644 --- a/src/lang/afrikaans.txt +++ b/src/lang/afrikaans.txt @@ -11,8 +11,6 @@ ##gender male -# $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. # 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. @@ -473,9 +471,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Skakel terminaal STR_ABOUT_MENU_AI_DEBUG :AI/Spel skript ontfout STR_ABOUT_MENU_SCREENSHOT :Skermskoot -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Ten volle vergrote skermskoot -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Basiese groote skermskoot -STR_ABOUT_MENU_GIANT_SCREENSHOT :Hele kaart Skermkiekie (Ctrl+G) STR_ABOUT_MENU_ABOUT_OPENTTD :Oor 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :"Sprite" rigter STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :skakel beperkte bokse @@ -645,9 +640,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Op Bestelling 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Musiek Volume STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Effek Volume -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}MIN -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}MAKS -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -859,6 +851,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}Nuwe {STRING} nou beskikbaar! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} aanvaar nie meer {STRING} nie STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} aanvaar nie meer {STRING} of {STRING} nie STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} aanvaar nou {STRING} @@ -1685,7 +1678,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Vragver STR_CONFIG_SETTING_AI :{ORANGE}Mededingers STR_CONFIG_SETTING_AI_NPC :{ORANGE}Rekenaar spelers -STR_CONFIG_SETTING_PATHFINDER_OPF :Oorspronklik STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Aanbevole) @@ -1768,13 +1760,9 @@ STR_QUIT_NO :{BLACK}Nee # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -2402,6 +2390,7 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Bou tonn STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Skakel bou/verwydering van pad konstruksie STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Skakel bou/verwyder vir tremweg konstruksie + # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Pad Depot Oriëntering STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}Kies pad voertuig depot orientasie @@ -3261,8 +3250,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}{COMPANY STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Spoorstukke: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Seine STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Padstukke: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Pad -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Tremweg STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Waterteëls: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Kanale STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Stasies: @@ -3273,8 +3260,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Nywerhede STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Geen - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% vervoer) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% vervoer) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Nywerheidsname - klik op 'n naam om skerm na nywerheid te skuif. Ctrl+klik maak 'n nuwe venster vir die nywerheid oop @@ -3336,6 +3321,7 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Ongegroepeerde STR_GROUP_DEFAULT_SHIPS :Ongegroepeerde skepe STR_GROUP_DEFAULT_AIRCRAFTS :Ongegroepeerde vliegtuig + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Groepe - klik op 'n groep om alle voertuie in hierdie groep te lys. Sleep en los om te rangskik volgens hiërargie. STR_GROUP_CREATE_TOOLTIP :{BLACK}Klik om groep te skep STR_GROUP_DELETE_TOOLTIP :{BLACK}Vee uit die gekose groep @@ -3357,10 +3343,13 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Nuwe Elektries STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Nuwe monospoor voertuie STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Nuwe Maglev Voertuie -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Spoorweg Voertuie STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Nuwe Pad Voertuie + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Spoorweg Voertuie STR_BUY_VEHICLE_SHIP_CAPTION :Nuwe Skepe STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Nuwe Vliegtuig +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Koste: {GOLD}{CURRENCY_LONG}{BLACK} Gewig: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Spoed: {GOLD}{VELOCITY}{BLACK} Krag: {GOLD}{POWER} @@ -3393,11 +3382,13 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Koop Voe STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Bou skip STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Koop vliegtuig + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Koop die gekose lokomotief/wa. Shift+klik vir kwotasie STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Koop die gekose voertuig. Shift+klik vir kwotasie STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Koop die gekose skip. Shift+klik vir kwotasie STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Koop die gekose vliegtuig. Shift+klik vir kwotasie + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Hernoem STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Hernoem STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Hernoem @@ -3506,13 +3497,16 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}U staan # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Boodskap van voertuig fabrikant STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Ons het sopas 'n nuwe {STRING} ontwerp, sal jy belangstel om hierdie voertuig eksklusief vir 'n jaar te gebruik. Hierdie word gedoen om te kyk hoe die voertuig doen voordat hy wereld wyd in produksie gesit word? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :spoorweg lokomotief -STR_ENGINE_PREVIEW_ROAD_VEHICLE :padvoertuig -STR_ENGINE_PREVIEW_AIRCRAFT :vliegtuig -STR_ENGINE_PREVIEW_SHIP :skip STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :monospoor lokomotief STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :maglev lokomotief +STR_ENGINE_PREVIEW_ROAD_VEHICLE :padvoertuig + +STR_ENGINE_PREVIEW_AIRCRAFT :vliegtuig +STR_ENGINE_PREVIEW_SHIP :skip + STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Koste: {CURRENCY_LONG} Massa: {WEIGHT_SHORT}{}Spoed: {VELOCITY} Krag: {POWER}{}Loopkoste: {CURRENCY_LONG}/jr{}Kapasitiet: {CARGO_LONG} STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Koste: {CURRENCY_LONG} Gewig: {WEIGHT_SHORT}{}Spoed: {VELOCITY} Krag: {POWER} Maks. Treg Krag: {6:FORCE}{}Lopende Koste: {4:CURRENCY_LONG}/jaar{}Kapasitiet: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Koste: {CURRENCY_LONG} Maks. Spoed: {VELOCITY}{}Kapasiteit: {CARGO_LONG}{}Lopende Koste: {CURRENCY_LONG}/jaar @@ -3553,6 +3547,7 @@ STR_REPLACE_ELRAIL_VEHICLES :Elektriese trei STR_REPLACE_MONORAIL_VEHICLES :Monospoor voertuie STR_REPLACE_MAGLEV_VEHICLES :Maglev Voertuie + STR_REPLACE_REMOVE_WAGON :{BLACK}Wa verwydering: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Maak autovervanging die lengte van 'n trein dieselfde hou deur verwydering waens (deur voor te begin), indien die enjin vervanging die trein langer sal maak @@ -4000,6 +3995,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Kies bel STR_AI_LIST_CANCEL :{BLACK}Kanseleer STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Moenie skrif verander nie + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parameters STR_AI_SETTINGS_CAPTION_AI :AI @@ -4271,7 +4267,7 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Moet eer STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Geen geskikte treinspoor STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Moet eers spoor verwyder STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Pad is een rigting of geblok -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Vlak kruisings word nie toegelaat vir die spoor tipe nie +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Vlak kruisings word nie toegelaat vir die spoor tipe nie STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Kan nie seinligte hier bou nie... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Kan nie spore hier bou nie... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Kan nie spore hier verwyder nie... diff --git a/src/lang/arabic_egypt.txt b/src/lang/arabic_egypt.txt index c95ca0aa87..0ac4914a75 100644 --- a/src/lang/arabic_egypt.txt +++ b/src/lang/arabic_egypt.txt @@ -10,8 +10,6 @@ ##grflangid 0x14 -# $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. # 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. @@ -282,7 +280,7 @@ STR_SORT_BY_TIMETABLE_DELAY :تاخير جد STR_SORT_BY_FACILITY :نوع المحطة STR_SORT_BY_RATING_MAX :اعلى نسبة شحن STR_SORT_BY_RATING_MIN :اقل نسبة شحن -STR_SORT_BY_ENGINE_ID :نوع المحرك (قياسي( +STR_SORT_BY_ENGINE_ID :نوع المحرك (قياسي) STR_SORT_BY_COST :التكلفة STR_SORT_BY_POWER :الطاقة STR_SORT_BY_TRACTIVE_EFFORT :قوة الجذب @@ -448,9 +446,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :توقل كونسول STR_ABOUT_MENU_AI_DEBUG :مكتشف اخطاء الذكاء الصناعي STR_ABOUT_MENU_SCREENSHOT :صورة من الشاشة - Ctrl-S - -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :صورة للشاشة مصغرة -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :تقريب الشاشة القياسي -STR_ABOUT_MENU_GIANT_SCREENSHOT :صورة كبيرة لكامل الخريطة -Ctrl-G - STR_ABOUT_MENU_ABOUT_OPENTTD :حول 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :موائم العفريتات STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :اضهار /اخفاء مربح الحوارات/الخيارات @@ -619,9 +614,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}معدل2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}مستوى الصوت STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}مؤثرات الصوت -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}منخفض -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}مرتفع -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}----- @@ -827,6 +819,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}جديد {STRING} الآن متاح ! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} لم تعد تقبل {STRING} STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION}لم تعد تقبل {STRING} او {STRING} STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} الآن تقبل {STRING} @@ -1147,7 +1140,7 @@ STR_CONFIG_SETTING_INDUSTRY_DENSITY :الكثافة STR_CONFIG_SETTING_INDUSTRY_DENSITY_HELPTEXT :إختر مقدار الصناعات التي يجب تكوينها وعلى اي مستوى يجب ان تكون خلال اللعبة STR_CONFIG_SETTING_SNOWLINE_HEIGHT :ارتفاع خط الثلج: {STRING} STR_CONFIG_SETTING_SNOWLINE_HEIGHT_HELPTEXT :تحكم على اي ارتفاع يبدأ نزول الثلج في المناطق القطبية,تؤثر الثلوج على مستوى تطور القطاع الصناعي ونمو المدن -STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN :خشونة التضاريس (صفر التكوين فقط ) :({STRING} +STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN :خشونة التضاريس: {STRING} STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_HELPTEXT :(TerraGenesis only)إختر تكرار الهضبات: الاراض المستويه تحتوي على البضع منها,هضبات موزعه عرضيا اكثر,الاراض الوعرة تحتوي الكثير من الهضاب,التي من الممكن ان تكون متكررة STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_VERY_SMOOTH :ناعم جدا STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_SMOOTH :ناعم @@ -1369,7 +1362,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :توزيع ال STR_CONFIG_SETTING_AI :{ORANGE}المتنافسين STR_CONFIG_SETTING_AI_NPC :{ORANGE} لاعبين الحاسوب -STR_CONFIG_SETTING_PATHFINDER_OPF :اصلي STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(مفضل) @@ -1440,13 +1432,9 @@ STR_QUIT_NO :{BLACK}لا # Supported OSes STR_OSNAME_WINDOWS :ويندوز -STR_OSNAME_DOS :دوس STR_OSNAME_UNIX :يونكس STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :بي او اس STR_OSNAME_HAIKU :هايكو -STR_OSNAME_MORPHOS :مورف او اس -STR_OSNAME_AMIGAOS :اميقا STR_OSNAME_OS2 :او اس/2 STR_OSNAME_SUNOS :صن @@ -1946,7 +1934,7 @@ STR_RAIL_TOOLBAR_MAGLEV_CONSTRUCTION_CAPTION :بناء الس STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}بناء سكة حديد STR_RAIL_TOOLBAR_TOOLTIP_BUILD_AUTORAIL :{BLACK}بناء سكة القطار باستخدام البناء التلقائي -STR_RAIL_TOOLBAR_TOOLTIP_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}بناء ورشة قطارات (لصيانة و شراء القطارات). +STR_RAIL_TOOLBAR_TOOLTIP_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}بناء ورشة قطارات (لصيانة و شراء القطارات) STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL_TO_WAYPOINT :{BLACK}غير السكة الى نقطة عبور STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_STATION :{BLACK}بناء محطة قطار. مفتاح كنترول يسمح بضم المحطات STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_SIGNALS :{BLACK}بناء إشارات السكك الحديدية. @@ -2028,7 +2016,7 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION :{BLACK}بناء STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOROAD :{BLACK}بناء الطرق باستخدام النظام الآلي STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOTRAM :{BLACK}بناء سكة القطار باستخدام النظام الآلي STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}بناء ورشة صيانة لعربات الطرق (لشراء و صيانة العربات). -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAM_VEHICLE_DEPOT :{BLACK}بناء ورشة لصيانة عربات الترام (لشراء و صيانة عربات الترام). +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAM_VEHICLE_DEPOT :{BLACK}بناء ورشة لصيانة عربات الترام (لشراء و صيانة عربات الترام) STR_ROAD_TOOLBAR_TOOLTIP_BUILD_BUS_STATION :{BLACK}بناء محطة باصات STR_ROAD_TOOLBAR_TOOLTIP_BUILD_PASSENGER_TRAM_STATION :{BLACK}بناء محطة ركاب ترام. STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRUCK_LOADING_BAY :{BLACK}بناء محطة تحميل عربات. مفتاح كنترول يسمح بمجاورة المحطات. @@ -2041,6 +2029,7 @@ 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}بدل بناء / ازالة طرق الترام + # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}اتجاه ورشة الصيانة STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}اختر اتجاة ورشة صيانة العربات @@ -2590,7 +2579,8 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}ادخل # Town directory window STR_TOWN_DIRECTORY_CAPTION :{WHITE}مدن/ بلدات STR_TOWN_DIRECTORY_NONE :{ORANGE}-بدون- -STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ) {COMMA}) +STR_TOWN_DIRECTORY_TOWN :{ORANGE}{RLE}{TOWN}{BLACK} {RLM}({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{RLE}{TOWN}{YELLOW} (مدينة){BLACK} {RLM}({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}اسم المدينة - اضغط على الاسم لتوسيط الشاشة عليها. اضغط + كنترول لفتح شاشة عرض جديدة للضاحية. STR_TOWN_POPULATION :{BLACK}سكان العالم: {COMMA} @@ -2678,7 +2668,7 @@ STR_STATION_LIST_STATION :{YELLOW}{STATIO STR_STATION_LIST_WAYPOINT :{YELLOW}{WAYPOINT} STR_STATION_LIST_NONE :{YELLOW}- بدون - STR_STATION_LIST_SELECT_ALL_FACILITIES :{BLACK}اختر جميع المرافق -STR_STATION_LIST_SELECT_ALL_TYPES :{BLACK}اختر كل انواع الشحن (حتى غير المنتظرة( +STR_STATION_LIST_SELECT_ALL_TYPES :{BLACK}اختر كل انواع الشحن (حتى غير المنتظرة) STR_STATION_LIST_NO_WAITING_CARGO :{BLACK}لا يوجد اي شحنة منتظرة # Station view window @@ -2802,8 +2792,6 @@ STR_BUY_COMPANY_MESSAGE :{WHITE}نحن # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}صناعات STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}-بدون- -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW}({COMMA}% صدرت) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW}({COMMA}%/{COMMA}% صدرت) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}اسماء المصانع - اضغط على اسم المصنع لتوسيط الشاشة عليه. اضغط + كنترول لفتح شاشة عرض جديدة لمنطقة المصنع. @@ -2864,6 +2852,7 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :لاتنتمي STR_GROUP_DEFAULT_SHIPS :مركبة لاتنتمي لأي مجموعة STR_GROUP_DEFAULT_AIRCRAFTS :طائرة لاتنتمي لأي مجموعة + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}المجموعات: اضغط على اي مجموعة لعرض مركباتها . اسحب للترتيب . STR_GROUP_CREATE_TOOLTIP :{BLACK}أضغط لإنشاء مجموعة STR_GROUP_DELETE_TOOLTIP :{BLACK}أحذف المجموعة المختارة @@ -2885,10 +2874,13 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :عربات قط STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :عربات قطار احادي جديدة STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :عربات قطار ممغنط جديدة -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :عربات قطار STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :عربات جديدة + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :عربات قطار STR_BUY_VEHICLE_SHIP_CAPTION :سفن جديدة STR_BUY_VEHICLE_AIRCRAFT_CAPTION :طائرة جديدة +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK} التكلفة: {GOLD}{CURRENCY_LONG}{BLACK} الوزن: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}السرعة: {GOLD}{VELOCITY}{BLACK} الطاقة: {GOLD}{POWER} @@ -2897,7 +2889,7 @@ STR_PURCHASE_INFO_SPEED_OCEAN :{BLACK}السر STR_PURCHASE_INFO_SPEED_CANAL :{BLACK}السرعة في القناة/النهر: {GOLD}{VELOCITY} STR_PURCHASE_INFO_RUNNINGCOST :{BLACK}تكلفة التشغيل: {GOLD}{CURRENCY_LONG}/ سنة STR_PURCHASE_INFO_CAPACITY :{BLACK}السعة: {GOLD}{CARGO_LONG} {STRING} -STR_PURCHASE_INFO_REFITTABLE :)قابل لتغيير( +STR_PURCHASE_INFO_REFITTABLE :(قابل لتغيي) STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}تصميم: {GOLD}{NUM}{BLACK} العمر الافتراضي: {GOLD}{COMMA} سنة STR_PURCHASE_INFO_RELIABILITY :{BLACK}الاعتمادية القصوى: {GOLD}{COMMA}% STR_PURCHASE_INFO_COST :{BLACK}التكلفة: {GOLD}{CURRENCY_LONG} @@ -2920,11 +2912,13 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}شراء STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}شراء سفينة STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}شراء طائرة + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}شراء العربة الموضحة STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}شراء العربة STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}شراء السفينة المختارة STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}اشتر الطائرة المختارة + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}اعادة تسمية STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}أعد التسمية STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}تسمية @@ -3021,13 +3015,16 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}أنت # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}رسالة من المصنعين STR_ENGINE_PREVIEW_MESSAGE :{GOLD}قد صممنا موديل جديد من {STRING} - هل ترغب في استخدام سنة حصري لهذه المركبة, لنستطيع تقييمها للأستخدام العام + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :قاطرة سكة حديد -STR_ENGINE_PREVIEW_ROAD_VEHICLE :مركبة -STR_ENGINE_PREVIEW_AIRCRAFT :طائرة -STR_ENGINE_PREVIEW_SHIP :سفينة STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :قاطرة سكة قطار احادية STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :قاطرة سكة قطار ممغنطة +STR_ENGINE_PREVIEW_ROAD_VEHICLE :مركبة + +STR_ENGINE_PREVIEW_AIRCRAFT :طائرة +STR_ENGINE_PREVIEW_SHIP :سفينة + STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK} التكلفة: {CURRENCY_LONG} الوزن: {WEIGHT_SHORT}{} السرعة: {VELOCITY} الطاقة: {POWER}{} كلفة التشغيل: {CURRENCY_LONG} / سنة{} السعة: {CARGO_LONG} STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}التكلفة {CURRENCY_LONG} الوزن {WEIGHT_SHORT}{}السرعة {VELOCITY} Power: {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} / سنة @@ -3061,6 +3058,7 @@ STR_REPLACE_ELRAIL_VEHICLES :سكة حديد STR_REPLACE_MONORAIL_VEHICLES :عربات احادية السكة STR_REPLACE_MAGLEV_VEHICLES :مركبات ممغنطة + STR_REPLACE_REMOVE_WAGON :{BLACK} إزالة العربات: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK} المحافظة على طول القطار بازالة عربات ابتداء من المقدمة عند التبديل - عندما يكون التبدل ينتج قطارا اطول. @@ -3193,7 +3191,7 @@ STR_VEHICLE_DETAILS_TRAIN_TOTAL_CARGO_TOOLTIP :{BLACK} عرض STR_VEHICLE_DETAILS_TRAIN_ARTICULATED_RV_CAPACITY :{BLACK}السعة: {LTBLUE} # Vehicle refit -STR_REFIT_CAPTION :{WHITE}{VEHICLE} )تغيير( +STR_REFIT_CAPTION :{WHITE}{VEHICLE} (تغيير) STR_REFIT_TITLE :{GOLD}اختر نوع الحمولة ... STR_REFIT_NEW_CAPACITY_COST_OF_REFIT :{BLACK}السعة الجديدة: {GOLD}{CARGO_LONG}{}{BLACK}تكلفة التغيير: {RED}{CURRENCY_LONG} STR_REFIT_NEW_CAPACITY_COST_OF_AIRCRAFT_REFIT :{BLACK}السعة الجديدة: {GOLD}{CARGO_LONG}, {GOLD}{CARGO_LONG}{}{BLACK}تكلفة اعادة التهيئة: {RED}{CURRENCY_LONG} @@ -3415,7 +3413,7 @@ STR_TIMETABLE_RESET_LATENESS :{BLACK}اعد STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{BLACK}عدل وقت التاخير للعداد حتى تصل المركبة في الوقت المحدد STR_TIMETABLE_AUTOFILL :{BLACK}تهيئة تلقائية -STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}املأ الجدولة تلقائيا بقيم الرحلة التالية (مفتاح كنترول لمحاولة ابقائ وقت الانتظار). +STR_TIMETABLE_AUTOFILL_TOOLTIP :{BLACK}مفتاح كنترول لمحاولة ابقائ وقت الانتظار (املأ الجدولة تلقائيا بقيم الرحلة التالية) STR_TIMETABLE_EXPECTED :{BLACK}متوقع STR_TIMETABLE_SCHEDULED :{BLACK}مجدول @@ -3483,6 +3481,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK} اخت STR_AI_LIST_CANCEL :{BLACK} الغاء STR_AI_LIST_CANCEL_TOOLTIP :{BLACK} لا تغير الذكاء الصناعي + # AI Parameters STR_AI_SETTINGS_CLOSE :{BLACK} اغلاق STR_AI_SETTINGS_RESET :{BLACK} اعادة ضبط @@ -3735,7 +3734,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 :{WHITE}التقاطع المتعدد غير متاح لهذا النوع من السكك +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}التقاطع المتعدد غير متاح لهذا النوع من السكك STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}تعذر بناء اﻹشارات هنا... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}تعذر بناء السكه الحديديه هنا... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}تعذر إزاله السكه الحديديه من هنا... diff --git a/src/lang/basque.txt b/src/lang/basque.txt index d22da6cdec..512aeef1a9 100644 --- a/src/lang/basque.txt +++ b/src/lang/basque.txt @@ -10,8 +10,6 @@ ##grflangid 0x21 -# $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. # 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. @@ -466,9 +464,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Konsola aktibatu STR_ABOUT_MENU_AI_DEBUG :IA/Joko script-aren garbitzailea STR_ABOUT_MENU_SCREENSHOT :Pantailan dagoenaren argazkia hartu (Ctrl+S) -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Pantailan dagoenaren argazkia hartu zoom-a guztiz erabiliz -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :zoom lehenetsikoarekin pantaila-argazkia -STR_ABOUT_MENU_GIANT_SCREENSHOT :Mapa osoaren argazkia hartu (Ctrl+G) STR_ABOUT_MENU_ABOUT_OPENTTD :'OpenTTD'-ri buruz STR_ABOUT_MENU_SPRITE_ALIGNER :"Sprit" lerrokatzailea STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Kaxen neurriak aldatu @@ -638,9 +633,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Pertsonalizatua 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Musikaren Bolumena STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Efektuen Bolumena -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}MIN -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}MAX -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -848,6 +840,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}{STRING} berri bat orain erabilgarri! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} ez du gehiago {STRING} onartzen STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} ez du gehiago {STRING} edo {STRING} onartzen STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} orain {STRING} onartzen du @@ -1598,7 +1591,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Zama ba STR_CONFIG_SETTING_AI :{ORANGE}Lehiakideak STR_CONFIG_SETTING_AI_NPC :{ORANGE}Ordenagailu jokalariak -STR_CONFIG_SETTING_PATHFINDER_OPF :Jatorrizkoa STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Gomendatua) @@ -1680,13 +1672,9 @@ STR_QUIT_NO :{BLACK}Ez # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -2305,6 +2293,7 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Tranbia STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Errepidea ezabatu STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Tranbia ezabatu + # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Errepide gordailuen norabidea STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}Aukeratu errepide biltokien norabidea @@ -3149,8 +3138,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}{COMPANY STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Trenbide sailak: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Seinaleak STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Errepide sailak: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Errepidea -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Tranbia sailak STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Urbide sailak: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Kanalak STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Geltokiak: @@ -3161,8 +3148,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Idustriak STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Ezer ez - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} (%{COMMA} garraiatua) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} (%{COMMA}/%{COMMA} garraiatua) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Industria izenak - Klikatu izenean ikuspegi nagusia industrian kokatzeko. Ktrl+Klik ikuspegi lehio berri bat irekitzen du industriaren kokapenarekin @@ -3224,6 +3209,7 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Taldeetan ez da STR_GROUP_DEFAULT_SHIPS :Taldeetan ez dauden itsasontziak STR_GROUP_DEFAULT_AIRCRAFTS :Taldeetan ez dauden hegazkinak + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Taldeak - Taldean klikatu taldearen ibilgailuak zerrendatzeko STR_GROUP_CREATE_TOOLTIP :{BLACK}Klikatu taldea sortzeko STR_GROUP_DELETE_TOOLTIP :{BLACK}Aukeratutako taldea ezabatu @@ -3244,10 +3230,13 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Tren elektriko STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Monorail tren berriak STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Tren magnetiko berriak -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Tren berriak STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Errepide ibilgailu berriak + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Tren berriak STR_BUY_VEHICLE_SHIP_CAPTION :Itsasontzi berriak STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Hegazkin berriak +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Kosteak: {GOLD}{CURRENCY_LONG}{BLACK} Pisua: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Abiadura: {GOLD}{VELOCITY}{BLACK} Potentzia: {GOLD}{POWER} @@ -3280,11 +3269,13 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Ibilgail STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Itsasontia erosi STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Hegazkina erosi + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Aukeratuta dagoen ibilgailua erosi. Shift+Klik gutxi gora beherako kostea erakutsi STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Aukeratuta dagoen ibilgailua erosi. Shift+Klik gutxi gora beherako kostea erakutsi STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Aukeratuta dagoen itsasontzia erosi. Shift+Klik gutxi gora beherako kostea erakutsi STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Aukeratuta dagoen hegazkina erosi. Shift+Klik gutxi gora beherako kostea erakutsi + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Berrizendatu STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Berrizendatu STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Berrizendatu @@ -3389,13 +3380,16 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Gordail # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Ibilgailu frabrikaren mezua STR_ENGINE_PREVIEW_MESSAGE :{GOLD}{STRING} berria diesinatu dugu - Nahiko zenuke ibilgailu honen urte baterako erabilera esklusiboa izatea? Bere funtzionamendua ikusi ahalko genuke publiko egin aurretik. + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :Lokomotora -STR_ENGINE_PREVIEW_ROAD_VEHICLE :Errepide ibilgailua -STR_ENGINE_PREVIEW_AIRCRAFT :Hegazkina -STR_ENGINE_PREVIEW_SHIP :Itsasontzia STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :Monorail lokomotora STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :Lokomotora magnetikoa +STR_ENGINE_PREVIEW_ROAD_VEHICLE :Errepide ibilgailua + +STR_ENGINE_PREVIEW_AIRCRAFT :Hegazkina +STR_ENGINE_PREVIEW_SHIP :Itsasontzia + STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Kostea: {CURRENCY_LONG} Pisua: {WEIGHT_SHORT}{}Pisua: {VELOCITY} Potentzia: {POWER}{}Mantenimendua: {CURRENCY_LONG}/urtero{}Edukiera: {CARGO_LONG} STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Kostua: {CURRENCY_LONG} Pisua: {WEIGHT_SHORT}{}Abiadura: {VELOCITY} Potentzia: {POWER} Gehienezko trakzioa: {6:FORCE}{}Mantinemendua: {4:CURRENCY_LONG}/urtero{}Edukiera: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Kostea: {CURRENCY_LONG} Gehienezko abiadura: {VELOCITY}{}Edukiera: {CARGO_LONG}{}Mantenimendua: {CURRENCY_LONG}/urtero @@ -3434,6 +3428,7 @@ STR_REPLACE_ELRAIL_VEHICLES :Tren ibilgailu STR_REPLACE_MONORAIL_VEHICLES :Monorail trenak STR_REPLACE_MAGLEV_VEHICLES :Tren magnetikoak + STR_REPLACE_REMOVE_WAGON :{BLACK}Bagoiak ezabatu: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Ordezkatze automatikoari agindu trenaren luzera errespetatzea, bagoiak ezabatuz luzera handitzen badute (trenaren hasierako bagoietik hasita) @@ -3875,6 +3870,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Piztutak 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 STR_AI_SETTINGS_CAPTION_AI :IA @@ -4143,7 +4139,7 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Lehendab STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Ez dago trenbide egokirik STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Lehendabizi trenbidea ezabatu STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Errepidea norabide bakarrekoa da edo blokeatua dago -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Ezin dira maila bereko pasaguneak egin trenbide mota honetan +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Ezin dira maila bereko pasaguneak egin trenbide mota honetan STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Ezin da seinalerik hemen eraiki... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Ezin da trenbiderik hemen eraiki... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Ezin da hemengo trenbidea ezabatu... diff --git a/src/lang/belarusian.txt b/src/lang/belarusian.txt index 9928e3254b..ac54c6ebb1 100644 --- a/src/lang/belarusian.txt +++ b/src/lang/belarusian.txt @@ -12,8 +12,6 @@ ##case m f n p nom gen dat acc abl pre -# $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. # 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. @@ -785,9 +783,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Кансоль STR_ABOUT_MENU_AI_DEBUG :Наладка штучнага інтэлекту (ШІ/AI) / скрыптоў STR_ABOUT_MENU_SCREENSHOT :Здымак экрана (Ctrl+S) -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Здымак экрана ў макс. набліжэньні -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Павялiчаны здымак экрана па змоўчаньнi -STR_ABOUT_MENU_GIANT_SCREENSHOT :Здымак усёй мапы (Ctrl+G) STR_ABOUT_MENU_ABOUT_OPENTTD :Аб гульні OpenTTD STR_ABOUT_MENU_SPRITE_ALIGNER :Выраўноўваньне спрайтаў STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Пераключыць абмежавальныя рамкі @@ -957,9 +952,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Уласны 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Гучнасьць музыкі STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Гучнасьць эфэктаў -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}МІН -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}МАКС -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -1175,6 +1167,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}З'явіўся новы {STRING}! — {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} больш не прымае {STRING.acc} STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} больш не прымае {STRING.acc} ды {STRING.acc} STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} цяпер прымае {STRING.acc} @@ -2009,7 +2002,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Раз STR_CONFIG_SETTING_AI :{ORANGE}Канкурэнты STR_CONFIG_SETTING_AI_NPC :{ORANGE}Кампутарныя гульцы -STR_CONFIG_SETTING_PATHFINDER_OPF :арыґінальны STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(рэкамэндуецца) @@ -2093,13 +2085,9 @@ STR_QUIT_NO :{BLACK}Не # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -2744,6 +2732,7 @@ 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}Будаўніцтва/выдаленьне трамвайных каляінаў + # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Кірунак гаража STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}Выберыце кірунак гаража @@ -3610,8 +3599,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Iнфр STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Чыгуначныя элемэнты: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Сыґналы STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Дарожныя элемэнты: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Дарогi -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Трамваi STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Водныя клеткi: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Каналы STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Станцыi: @@ -3622,8 +3609,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Прамысловасьць STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Няма - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% перавезена) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% перавезена) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Сьпіс прадпрыемстваў: пстрычка па назьве паказвае прадпрыемства ў асноўным вакне. Ctrl+клік - у дадатковым вакне. @@ -3688,6 +3673,7 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Бяз груп STR_GROUP_DEFAULT_SHIPS :Бяз групы STR_GROUP_DEFAULT_AIRCRAFTS :Бяз групы + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Ґрупы — клікніце па назьве ґрупы, каб убачыць сьпіс транспарту ў гэтай ґрупе. Націсьніце ды перацягвайце ґрупы, каб упарадкаваць гіерархію. STR_GROUP_CREATE_TOOLTIP :{BLACK}Стварыць групу STR_GROUP_DELETE_TOOLTIP :{BLACK}Выдаліць выбраную групу @@ -3713,10 +3699,13 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Новы эле STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Новы монарэйкавы цягнік STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Новы маґнітарэйкавы цягнік -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Новы цягнiк STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Новы аўтамабiль + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Новы цягнiк STR_BUY_VEHICLE_SHIP_CAPTION :Новы карабель STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Новы авiятранспарт +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Кошт: {GOLD}{CURRENCY_LONG}{BLACK} Вага: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Хуткасьць: {GOLD}{VELOCITY}{BLACK} Магутнасьць: {GOLD}{POWER} @@ -3750,11 +3739,13 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Купі STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Купіць STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Купіць + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Набыць абраны лякаматыў/ваґон. Shift+пстрычка — ацэнка кошту набыцьця. STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Набыць абраны аўтамабіль. Shift+пстрычка — ацэнка кошту набыцьця. STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Набыць абраны карабель. Shift+пстрычка — ацэнка кошту набыцьця. STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Набыць абраны авіятранспарт. Shift+пстрычка — ацэнка кошту набыцьця. + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Перайменаваць STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Перайменаваць STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Перайменаваць @@ -3863,18 +3854,10 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Уве # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Паведамленьне ад вытворцы транспарту STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Мы стварылі новую мадэль {STRING.gen}. Цi зацікаўлены Вы ў яе гадавым эксклюзіўным выкарыстаньні для праверкі перад запускам у масавую вытворчасьць? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :{G=m}чыгуначны лякаматыў STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE.gen :чыгуначнага лакаматыва STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE.acc :чыгуначны лякаматыў -STR_ENGINE_PREVIEW_ROAD_VEHICLE :{G=m}аўтамабiль -STR_ENGINE_PREVIEW_ROAD_VEHICLE.gen :аўтамабiля -STR_ENGINE_PREVIEW_ROAD_VEHICLE.acc :аўтамабіль -STR_ENGINE_PREVIEW_AIRCRAFT :{G=m}авiятранспарт -STR_ENGINE_PREVIEW_AIRCRAFT.gen :авiятранспарту -STR_ENGINE_PREVIEW_AIRCRAFT.acc :авіятранспарт -STR_ENGINE_PREVIEW_SHIP :{G=m}карабель -STR_ENGINE_PREVIEW_SHIP.gen :карабля -STR_ENGINE_PREVIEW_SHIP.acc :карабель STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :{G=m}монарэйкавы лякаматыў STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE.gen :монарэйкавага лякаматыва STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE.acc :монарэйкавы лякаматыў @@ -3882,6 +3865,17 @@ STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :{G=m}маґні STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE.gen :магнiтарэйкавага лякаматыва STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE.acc :магнітарэйкавы лякаматыў +STR_ENGINE_PREVIEW_ROAD_VEHICLE :{G=m}аўтамабiль +STR_ENGINE_PREVIEW_ROAD_VEHICLE.gen :аўтамабiля +STR_ENGINE_PREVIEW_ROAD_VEHICLE.acc :аўтамабіль + +STR_ENGINE_PREVIEW_AIRCRAFT :{G=m}авiятранспарт +STR_ENGINE_PREVIEW_AIRCRAFT.gen :авiятранспарту +STR_ENGINE_PREVIEW_AIRCRAFT.acc :авіятранспарт +STR_ENGINE_PREVIEW_SHIP :{G=m}карабель +STR_ENGINE_PREVIEW_SHIP.gen :карабля +STR_ENGINE_PREVIEW_SHIP.acc :карабель + STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Кошт: {CURRENCY_LONG} Вага: {WEIGHT_SHORT}{}Хуткасьць: {VELOCITY} Магутнасьць: {POWER}{}Кошт абслуг.: {CURRENCY_LONG}/год{}Ёмістасьць: {CARGO_LONG} STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Кошт: {CURRENCY_LONG} Вага: {WEIGHT_SHORT}{}Хуткасьць: {VELOCITY} Магутнасьць: {POWER} Макс. ЦН: {6:FORCE}{}Кошт абслуг.: {4:CURRENCY_LONG}/год{}Ёмістасьць: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Кошт: {CURRENCY_LONG} Макс. хуткасьць: {VELOCITY}{}Ёмістасьць: {CARGO_LONG}{}Кошт абслуг.: {CURRENCY_LONG}/год @@ -3935,6 +3929,7 @@ STR_REPLACE_ELRAIL_VEHICLES :Чыгунач STR_REPLACE_MONORAIL_VEHICLES :Монарэйкавыя ТС STR_REPLACE_MAGLEV_VEHICLES :Маґнітныя ТС + STR_REPLACE_REMOVE_WAGON :{BLACK}Выдаленьне ваґонаў: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Дазволіць пры аўтазамене захоўваць даўжыню цягнікоў шляхам выдаленьня ваґонаў (пачынаючы з галавы цягніка), калі пры аўтазамене лякаматыва павялічыцца даўжыня цягніка. @@ -4384,6 +4379,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Выбр STR_AI_LIST_CANCEL :{BLACK}Скасаваць STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Не змяняць скрыпт + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}Параметры {STRING} STR_AI_SETTINGS_CAPTION_AI :ШI @@ -4586,7 +4582,6 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... гэ STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... няправільны кірунак дарогі STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... на прахадных прыпынках нельга рабіць павароты STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... на прахадных прыпынках нельга рабіць скрыжаваньнi -STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... дарога аднабаковая ці заблакавана # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Немагчыма выдаліць частку станцыi... @@ -4656,7 +4651,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 :{WHITE}Праз гэты від рэйкаў забаронена будаваць пераезды +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Праз гэты від рэйкаў забаронена будаваць пераезды STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Тут немагчыма паставіць сьветлафор... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Тут немагчыма пракласьцi рэйкі... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Не атрымалася выдаліць чыгунку... diff --git a/src/lang/brazilian_portuguese.txt b/src/lang/brazilian_portuguese.txt index 7abcb2bf9e..0eb77a531d 100644 --- a/src/lang/brazilian_portuguese.txt +++ b/src/lang/brazilian_portuguese.txt @@ -11,8 +11,6 @@ ##gender m f -# $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. # 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. @@ -473,9 +471,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Alternar console STR_ABOUT_MENU_AI_DEBUG :Depurar IA/Script do jogo STR_ABOUT_MENU_SCREENSHOT :Captura de tela -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Ampliado em captura de tela -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Captura de tela em ampliação padrão -STR_ABOUT_MENU_GIANT_SCREENSHOT :Captura de tela do mapa inteiro STR_ABOUT_MENU_SHOW_FRAMERATE :Exibir taxa de quadros STR_ABOUT_MENU_ABOUT_OPENTTD :Sobre 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Alinhador de "sprites" @@ -646,9 +641,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Personalizado 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Volume da Música STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Volume dos Efeitos -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}MIN -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}MAX -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -865,6 +857,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}Nov{G o a} {STRING} já está disponível! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} não aceita mais {STRING} STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} não aceita mais {STRING} ou {STRING} STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} agora aceita {STRING} @@ -1700,7 +1693,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Distrib STR_CONFIG_SETTING_AI :{ORANGE}Oponentes STR_CONFIG_SETTING_AI_NPC :{ORANGE}Computadores -STR_CONFIG_SETTING_PATHFINDER_OPF :Original STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Recomendado) @@ -1784,13 +1776,9 @@ STR_QUIT_NO :{BLACK}Não # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -2419,6 +2407,7 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Construi STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Alternar construir/remover para contrução rodoviária STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Alternar construir/remover linhas de bonde e sinais + # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Orientação da Garagem STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}Selecionar a orientação da garagem @@ -3320,8 +3309,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Infraest STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Partes de ferrovias: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Sinais STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Partes de rodovias: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Rodovia -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Linha de bonde STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Partes d'água: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Canais STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Estações: @@ -3332,8 +3319,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Indústrias STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Nenhum - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% transportado) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% transportado) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Nomes das indústrias - clique no nome para centralizar a visçao principal na indústria. Ctrl+Clique abre uma nova janela na localização da indústria @@ -3398,6 +3383,7 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Automóveis sem STR_GROUP_DEFAULT_SHIPS :Embarcações sem grupo STR_GROUP_DEFAULT_AIRCRAFTS :Aeronaves sem grupo + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Grupos - Clique em um grupo para listar seus veículos. Clique e arraste para organizar a hierarquia. STR_GROUP_CREATE_TOOLTIP :{BLACK}Clique para criar um grupo STR_GROUP_DELETE_TOOLTIP :{BLACK}Remove o grupo selecionado @@ -3423,10 +3409,13 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Nova Locomotiva STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Nova Locomotiva Monotrilho STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Nova Locomotiva Maglev -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Trens STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Novos Automóveis + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Trens STR_BUY_VEHICLE_SHIP_CAPTION :Novas Embarcações STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Nova Aeronave +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Preço: {GOLD}{CURRENCY_LONG}{BLACK} Peso: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Velocidade: {GOLD}{VELOCITY}{BLACK} Potência: {GOLD}{POWER} @@ -3460,11 +3449,13 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Comprar STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Comprar Embarcação STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Comprar Aeronave + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Compra o veículo ferroviário selecionado. Shift+Clique mostra preço estimado sem a compra STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Compra o veículo selecionado. Shift+Clique mostra preço estimado sem a compra STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Compra a embarcação selecionada. Shift+Clique mostra preço estimado sem a compra STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Compra a aeronave selecionada. Shift+Clique mostra o preço estimado sem a compra + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Renomear STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Renomear STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Renomear @@ -3573,13 +3564,16 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Você e # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Mensagem de um fabricante de veículos STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Projetamos um novo {STRING} - estaria interessado em um ano de exclusividade do uso deste veículo, de modo a que possamos avaliar a sua performance antes de o disponibilizar para todos ? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :locomotiva ferroviária -STR_ENGINE_PREVIEW_ROAD_VEHICLE :automóvel -STR_ENGINE_PREVIEW_AIRCRAFT :aeronave -STR_ENGINE_PREVIEW_SHIP :embarcação STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :locomotiva monotrilho STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :locomotiva maglev +STR_ENGINE_PREVIEW_ROAD_VEHICLE :automóvel + +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_MAX_SPEED_CAP_RUNCOST :{BLACK}Preço: {CURRENCY_LONG} Vel. Max.: {VELOCITY}{}Capacidade: {CARGO_LONG}{}Custo de manuteção: {CURRENCY_LONG}/ano @@ -3625,6 +3619,7 @@ STR_REPLACE_ELRAIL_VEHICLES :Locomotivas El STR_REPLACE_MONORAIL_VEHICLES :Monotrilho STR_REPLACE_MAGLEV_VEHICLES :Maglevs + STR_REPLACE_REMOVE_WAGON :{BLACK}Remoção de vagões: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Faz autosubstituição manter o tamanho do trem removendo vagões (começando pela frente), se ao substituir a locomotiva o trem ficar maior @@ -4074,6 +4069,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Selecion STR_AI_LIST_CANCEL :{BLACK}Cancelar STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Não mudar o script + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parâmetros STR_AI_SETTINGS_CAPTION_AI :{G=f}IA @@ -4276,7 +4272,6 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... é u STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... rua na direção errada STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... paradas "drive-thru" não podem ter esquinas STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... paradas "drive-thru" não podem ter junções -STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... rua é mão única ou está bloqueada # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Impossível remover parte da estação... @@ -4346,7 +4341,7 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Remova o STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Tipo de linha não apropriado STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Remova a ferrovia antes STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Rua é mão única ou está bloqueada -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Cruzamentos de nível não são permitidos para esse tipo de trilho +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Cruzamentos de nível não são permitidos para esse tipo de trilho STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Impossível construir sinais aqui... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Impossível construir ferrovia aqui... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Impossível remover a ferrovia daqui... diff --git a/src/lang/bulgarian.txt b/src/lang/bulgarian.txt index b6a787df7e..0907f9b212 100644 --- a/src/lang/bulgarian.txt +++ b/src/lang/bulgarian.txt @@ -12,8 +12,6 @@ ##case m f n p -# $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. # 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. @@ -191,6 +189,7 @@ STR_COLOUR_ORANGE :Оранжев STR_COLOUR_BROWN :Кафяво STR_COLOUR_GREY :Сиво STR_COLOUR_WHITE :Бяло +STR_COLOUR_DEFAULT :По подразбиране # Units used in OpenTTD STR_UNITS_VELOCITY_IMPERIAL :{COMMA} мил{P я и}/ч @@ -236,6 +235,7 @@ STR_TOOLTIP_FILTER_CRITERIA :{BLACK}Избе STR_BUTTON_SORT_BY :{BLACK}Сортирай по STR_BUTTON_LOCATION :{BLACK}Позиция STR_BUTTON_RENAME :{BLACK}Преименувай +STR_BUTTON_CATCHMENT :{BLACK}Покритие STR_TOOLTIP_CLOSE_WINDOW :{BLACK}Затвори прозореца STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Заглавие на прозорец - преместване на прозореца с мишката @@ -462,6 +462,7 @@ STR_TOOLBAR_SOUND_MUSIC :Звук/муз ############ range for message menu starts STR_NEWS_MENU_LAST_MESSAGE_NEWS_REPORT :Последно съобщение/новини STR_NEWS_MENU_MESSAGE_HISTORY_MENU :История на съобщенията +STR_NEWS_MENU_DELETE_ALL_MESSAGES :Изтрий всички съобщения ############ range ends here ############ range for about menu starts @@ -470,9 +471,7 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Показване/скриване на конзола STR_ABOUT_MENU_AI_DEBUG :ИИ дебъг STR_ABOUT_MENU_SCREENSHOT :Screenshot -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Напълно увеличен в кадъра. -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Увеличение по подразбиране -STR_ABOUT_MENU_GIANT_SCREENSHOT :Огромен Screenshot +STR_ABOUT_MENU_SHOW_FRAMERATE :Показване на честотата на кадрите STR_ABOUT_MENU_ABOUT_OPENTTD :Относно 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Подравнител на спрайтове STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Активиране слепване на прозорците @@ -642,9 +641,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Персонален 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Сила на музиката STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Сила на ефектите -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}MIN -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}MAX -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -704,11 +700,13 @@ STR_SMALLMAP_TYPE_OWNERS :Собстве STR_SMALLMAP_TOOLTIP_SHOW_LAND_CONTOURS_ON_MAP :{BLACK}Покажи земните контури на картата STR_SMALLMAP_TOOLTIP_SHOW_VEHICLES_ON_MAP :{BLACK}Покажи превозните средства STR_SMALLMAP_TOOLTIP_SHOW_INDUSTRIES_ON_MAP :{BLACK}Покажи индустриите на картата +STR_SMALLMAP_TOOLTIP_SHOW_LINK_STATS_ON_MAP :{BLACK}Покажи на картата потока на товарите STR_SMALLMAP_TOOLTIP_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Покажи транспортните маршрути на картата STR_SMALLMAP_TOOLTIP_SHOW_VEGETATION_ON_MAP :{BLACK}Покажи растителността на картата STR_SMALLMAP_TOOLTIP_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Покажи собствениците на земя на картата STR_SMALLMAP_TOOLTIP_INDUSTRY_SELECTION :{BLACK}Натисни върху вид индустрия за превключване на показването.Click on an industry type to toggle displaying it. Ctrl деактивира всички освен избраната. Ctrl отново за активиране на всички STR_SMALLMAP_TOOLTIP_COMPANY_SELECTION :{BLACK}Натисни върху компания за показване/скриване на нейната собственост. Ctrl деактивира всички компании освен избраната. Ctrl отново за активиране на всички компании +STR_SMALLMAP_TOOLTIP_CARGO_SELECTION :{BLACK}Кликнете върху товара, за да превключите показването на неговите данни. Ctrl+Click изключва всички товари без текущо избрания. Направете отново Ctrl+Click въху него, за да включите отново всички товари STR_SMALLMAP_LEGENDA_ROADS :{TINY_FONT}{BLACK}Пътища STR_SMALLMAP_LEGENDA_RAILROADS :{TINY_FONT}{BLACK}ЖП @@ -850,6 +848,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}Нов {STRING} е на разположение! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} вече не приема {STRING} STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} вече не приема {STRING} или {STRING} STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} вече приема {STRING} @@ -914,6 +913,8 @@ STR_GAME_OPTIONS_CURRENCY_ZAR :Южноафр STR_GAME_OPTIONS_CURRENCY_CUSTOM :друга... STR_GAME_OPTIONS_CURRENCY_GEL :Грузинско лари (ГЕЛ) STR_GAME_OPTIONS_CURRENCY_IRR :Ирански Риал (ИРР) +STR_GAME_OPTIONS_CURRENCY_NTD :Нов тайвански долар +STR_GAME_OPTIONS_CURRENCY_HKD :Хонгконгски долар (HKD) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Движение по пътищата @@ -1107,6 +1108,7 @@ STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_MENU :Игрови н STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_INGAME :Игрови настройки (съхраняват се в записаната игра; важат само за текущата игра) STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_MENU :Настройки за компанията (съхраняват се в записаната игра; важат само за нови игри) STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_INGAME :Настройки за компанията (съхраняват се в записаната игра; важат само за текущата компания) +STR_CONFIG_SETTING_CATEGORY_AND_TYPE_HIDES :{BLACK}Покажете всички резултати от търсенето като зададете{}{SILVER}Категория {BLACK}на {WHITE}{STRING} {BLACK}и {SILVER}Тип {BLACK}на {WHITE}Всички видове настройки STR_CONFIG_SETTINGS_NONE :{WHITE}- Нищо - STR_CONFIG_SETTING_OFF :изключено @@ -1283,10 +1285,12 @@ STR_CONFIG_SETTING_POPULATION_IN_LABEL_HELPTEXT :Показва STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS :Дебелина на линиите в графиките: {STRING} STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Дебелина на линиите в графиките. Тънките линии са по-лесни за разчитане, но по-дебелите се забелязват и разграничават по-лесно. -STR_CONFIG_SETTING_LANDSCAPE :Пейзаж: {STRING} +STR_CONFIG_SETTING_LANDSCAPE :Терен: {STRING} STR_CONFIG_SETTING_LAND_GENERATOR :Генератор на земя: {STRING} STR_CONFIG_SETTING_LAND_GENERATOR_ORIGINAL :оригинален STR_CONFIG_SETTING_LAND_GENERATOR_TERRA_GENESIS :тера-генезис +STR_CONFIG_SETTING_TERRAIN_TYPE_HELPTEXT :(само за TerraGenesis) Хълмистост на терена +STR_CONFIG_SETTING_INDUSTRY_DENSITY_HELPTEXT :Задайте колко индустрии да се генерират и какво ниво да се поддържа по време на играта STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE :Максимално разстояние от ръба за нефтените рафинерии: {STRING} STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :Нефтените рафинерии се изграждат само близо до края на картата STR_CONFIG_SETTING_SNOWLINE_HEIGHT :Снежната ивица: {STRING} @@ -1296,6 +1300,7 @@ STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_SMOOTH :полегат STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_ROUGH :стръмен STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN_VERY_ROUGH :много стръмен STR_CONFIG_SETTING_RIVER_AMOUNT :Количество на реките: {STRING} +STR_CONFIG_SETTING_RIVER_AMOUNT_HELPTEXT :Изберете колко реки да се генерират STR_CONFIG_SETTING_TREE_PLACER :Алгоритъм за поставяне на дървета: {STRING} STR_CONFIG_SETTING_TREE_PLACER_NONE :без дървета STR_CONFIG_SETTING_TREE_PLACER_ORIGINAL :оригинален @@ -1583,6 +1588,11 @@ STR_CONFIG_SETTING_LARGER_TOWNS_DISABLED :Без STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :Множител за големината на града: {STRING} STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :Относителен размер на мегаполисите в сравнение с градовете в началото на играта +STR_CONFIG_SETTING_LINKGRAPH_TIME :Вземи {STRING}{NBSP}дни{P 0:2 "" s} за преизчисляване на графа за резпределение +STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :ръчно +STR_CONFIG_SETTING_DISTRIBUTION_SYMMETRIC :симетричен +STR_CONFIG_SETTING_DISTRIBUTION_PAX_HELPTEXT :"симетрично" означава, че приблизително един и същ брой пътници ще пътуват от спирка А до спирка Б и обратно. "асиметрично" означава, че произволен брой пътници могат да пътуват във всяка от посоките. "ръчно" означава, че няма да има автоматично разпределение за пътниците. +STR_CONFIG_SETTING_DISTRIBUTION_DEFAULT :Режим на разпределение на други класове товари: {STRING} STR_CONFIG_SETTING_DEMAND_SIZE :Количество на връщания товар при симетричнен режим: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY :Единици за скорост: {STRING} @@ -1628,13 +1638,13 @@ STR_CONFIG_SETTING_INTERFACE_GENERAL :{ORANGE}Осн STR_CONFIG_SETTING_INTERFACE_CONSTRUCTION :{ORANGE}Строене STR_CONFIG_SETTING_VEHICLES :{ORANGE}Автомобили STR_CONFIG_SETTING_VEHICLES_ROUTING :{ORANGE}Маршрутизация +STR_CONFIG_SETTING_LIMITATIONS :{ORANGE}Ограничения STR_CONFIG_SETTING_ENVIRONMENT_AUTHORITIES :{ORANGE}Права STR_CONFIG_SETTING_ENVIRONMENT_TOWNS :{ORANGE}Градове STR_CONFIG_SETTING_ENVIRONMENT_INDUSTRIES :{ORANGE}Индустрии STR_CONFIG_SETTING_AI :{ORANGE}Съперници STR_CONFIG_SETTING_AI_NPC :{ORANGE}Компютърни играчи -STR_CONFIG_SETTING_PATHFINDER_OPF :Оригинален STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(препоръчва се) @@ -1716,13 +1726,9 @@ STR_QUIT_NO :{BLACK}Не # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :ДОС STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -1908,6 +1914,7 @@ STR_NETWORK_START_SERVER_SET_PASSWORD :{BLACK}Пост STR_NETWORK_START_SERVER_PASSWORD_TOOLTIP :{BLACK}Защитаване на вашата игра с парола за да не е публично достъпна STR_NETWORK_START_SERVER_UNADVERTISED :Не +STR_NETWORK_START_SERVER_ADVERTISED :Да STR_NETWORK_START_SERVER_CLIENTS_SELECT :{BLACK}{NUM} клиент{P "" s} STR_NETWORK_START_SERVER_NUMBER_OF_CLIENTS :{BLACK}Макс. брой играчи: STR_NETWORK_START_SERVER_NUMBER_OF_CLIENTS_TOOLTIP :{BLACK}Избор на максималния брой клиенти. Не всички слотове трябва да се попълнят @@ -2347,6 +2354,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 :Път + # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Ориентация на гараж STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}Ориентация на гараж @@ -2630,9 +2639,21 @@ STR_ABOUT_VERSION :{BLACK}OpenTTD STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2019 The OpenTTD team # Framerate display window +STR_FRAMERATE_CAPTION :{WHITE}Скорост на кадрите +STR_FRAMERATE_RATE_GAMELOOP :{BLACK}Скороср на симулация: {STRING} +STR_FRAMERATE_SPEED_FACTOR :{BLACK}Текущ коефициент за скорост на играта: {DECIMAL}x +STR_FRAMERATE_CURRENT :{WHITE}Текущ +STR_FRAMERATE_AVERAGE :{WHITE}Средно +STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL} кадри/сек ############ Leave those lines in this order!! +STR_FRAMERATE_GL_ECONOMY :Обработка на товари: +STR_FRAMERATE_GL_LANDSCAPE :{BLACK} Тактове на света: ############ End of leave-in-this-order ############ Leave those lines in this order!! +STR_FRAMETIME_CAPTION_GAMELOOP :Цикъл на играта +STR_FRAMETIME_CAPTION_DRAWING :Графична обработка +STR_FRAMETIME_CAPTION_VIDEO :Видео изход +STR_FRAMETIME_CAPTION_ALLSCRIPTS :Общо GS/AI скриптове ############ End of leave-in-this-order @@ -2782,6 +2803,7 @@ STR_NEWGRF_SETTINGS_DISABLED :{RED}Изклю STR_NEWGRF_SETTINGS_INCOMPATIBLE :{G=n}{RED}Несъвместимо с тази версия на OpenTTD # NewGRF save preset window +STR_SAVE_PRESET_LIST_TOOLTIP :{BLACK}Списък на наличните предварително зададени настройки. Изберете една, за да я откопирате в името за запис по-долу STR_SAVE_PRESET_TITLE :{BLACK}Въведи име за шаблона STR_SAVE_PRESET_EDITBOX_TOOLTIP :{BLACK}Текущо избраното име за именуване на шаблона STR_SAVE_PRESET_CANCEL :{BLACK}Отказ @@ -2879,6 +2901,7 @@ STR_NEWGRF_BUGGY :{WHITE}NewGRF ' STR_NEWGRF_BUGGY_ARTICULATED_CARGO :{WHITE}Информация за товар/преобразувания на '{1:ENGINE}' се различава от листа с покупките. Това може да доведе до грешка при подновяване/преустройване STR_NEWGRF_BUGGY_ENDLESS_PRODUCTION_CALLBACK :{WHITE}'{1:STRING}' предизвика вечен цикъл в callback на производството STR_NEWGRF_BUGGY_UNKNOWN_CALLBACK_RESULT :{WHITE}Подизпълнение {1:HEX} върна неизвестен/невалиден резултат {2:HEX} +STR_NEWGRF_BUGGY_INVALID_CARGO_PRODUCTION_CALLBACK :{WHITE}'{1:STRING}' Върнат е невалиден тип товар в продуктивен callback на {2:HEX} # 'User removed essential NewGRFs'-placeholders for stuff without specs STR_NEWGRF_INVALID_CARGO :<невалиден товар> @@ -2912,6 +2935,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Въве STR_TOWN_DIRECTORY_CAPTION :{WHITE}Градове STR_TOWN_DIRECTORY_NONE :{ORANGE}- Отсъства - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Град){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Имена на градовете - натисни на името за да фокусираш този град. Ctrl отваря нов изглед към града. STR_TOWN_POPULATION :{BLACK}Обща популация на картата: {COMMA} @@ -3190,8 +3214,7 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Инфр STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Релсови части: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Сигнали STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Пътни части: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Път -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Трамвай +STR_COMPANY_INFRASTRUCTURE_VIEW_TRAM_SECT :{GOLD}Трамвайни вагони: STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Водни части: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Канали STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Станции: @@ -3202,8 +3225,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Индустрии STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Отсъства - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% превозено) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% превозено) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Имена на индустриите - натисни за да фокусираш върху индустрията. Ctrl+Click отваря нов прозорец на изглед върху индустрията. @@ -3266,6 +3287,7 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Безгруп STR_GROUP_DEFAULT_SHIPS :Безгрупни кораби STR_GROUP_DEFAULT_AIRCRAFTS :Безгрупни самолети + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Групи - Щракни на група за да видиш списък на всички превозни средства от тази група STR_GROUP_CREATE_TOOLTIP :{BLACK}Щракни да създадеш група STR_GROUP_DELETE_TOOLTIP :{BLACK}Изтрий избраната група @@ -3289,10 +3311,14 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Нови еле STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Нови Машини за Монорелсов път STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Нови Машини за Магниторелсов път -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Нови ЖП превозни средства STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Нова кола + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Нови ЖП превозни средства +STR_BUY_VEHICLE_ROAD_VEHICLE_ALL_CAPTION :Ново пътно превозно средство STR_BUY_VEHICLE_SHIP_CAPTION :Нови Кораби STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Нова летателна машина +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Цена: {GOLD}{CURRENCY_LONG}{BLACK} Тегло: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Скорост: {GOLD}{VELOCITY}{BLACK} Мощност: {GOLD}{POWER} @@ -3305,12 +3331,15 @@ STR_PURCHASE_INFO_REFITTABLE :(преустр STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Модел: {GOLD}{NUM}{BLACK} Живот: {GOLD}{COMMA} години STR_PURCHASE_INFO_RELIABILITY :{BLACK}Макс. надеждност: {GOLD}{COMMA}% STR_PURCHASE_INFO_COST :{BLACK}Цена: {GOLD}{CURRENCY_LONG} +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_ALL_BUT :Всичко освен {CARGO_LIST} STR_PURCHASE_INFO_MAX_TE :{BLACK}Макс. теглеща сила: {GOLD}{FORCE} STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Обхват: {GOLD}{COMMA} полета @@ -3325,11 +3354,15 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Купи STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Купи Кораб STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Купи самолет +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Купуване и преустройване на кораб +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Купуване и преустройване на самолет + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Купи маркираният влак. Shift строеж/цена за построяване STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Купи посоченото МПС. Shift строеж/цена за построяване STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Купи посоченият кораб. Shift строеж/цена за построяване STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Купи посоченият самолет. Shift строеж/цена за построяване + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Преименувай STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Преименувай STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Промяна на име @@ -3438,13 +3471,16 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Иск # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Съобщение от производител STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Създадохме нов {STRING}.{}Интересувате ли се от изключителното право да използвате това ПС за една година, за да видим как то работи преди да го пуснем на пазара за масова употреба? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :локомотив за двурелсов път -STR_ENGINE_PREVIEW_ROAD_VEHICLE :автомобил -STR_ENGINE_PREVIEW_AIRCRAFT :самолет -STR_ENGINE_PREVIEW_SHIP :кораб STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :локомотив за еднорелсов път STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :локомотив за магниторелсов път +STR_ENGINE_PREVIEW_ROAD_VEHICLE :автомобил + +STR_ENGINE_PREVIEW_AIRCRAFT :самолет +STR_ENGINE_PREVIEW_SHIP :кораб + STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Цена: {CURRENCY_LONG} Тегло: {WEIGHT_SHORT}{}Скорост: {VELOCITY} Мощност: {POWER}{}Разход: {CURRENCY_LONG}/г.{}Капацитет: {CARGO_LONG} STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Цена: {CURRENCY_LONG} Тегло: {WEIGHT_SHORT}{}Скорост: {VELOCITY} Мощност: {POWER} Макс. Т.С.: {6:FORCE}{}Експлоатационни разходи: {4:CURRENCY_LONG}/год.{}Вместимост: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Цена: {CURRENCY_LONG} Макс. Скорост: {VELOCITY}{}Вместимост: {CARGO_LONG}{}Експлоатационни разходи: {CURRENCY_LONG}/год. @@ -3479,14 +3515,17 @@ STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK}Прев STR_REPLACE_ENGINES :Двигатели STR_REPLACE_WAGONS :Вагони STR_REPLACE_ALL_RAILTYPE :Всички ЖП композиции +STR_REPLACE_ALL_ROADTYPE :Всички пътни превозни средства STR_REPLACE_HELP_RAILTYPE :{BLACK}Избор на ЖП линия с която да се заменят локомотивите +STR_REPLACE_HELP_ROADTYPE :Изберете типа път, за който искате да подмените двигателите. STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Показване с кой двигател се заменя ляво избрания, ако има STR_REPLACE_RAIL_VEHICLES :ЖП влакове STR_REPLACE_ELRAIL_VEHICLES :Електрически локомотиви STR_REPLACE_MONORAIL_VEHICLES :Монорелсови локомотиви STR_REPLACE_MAGLEV_VEHICLES :Маглев влакове + STR_REPLACE_REMOVE_WAGON :{BLACK}Премахване на вагон: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Автоматичната замяна ще запази дължината на влака като премахне вагони (започвайки от предните), ако замяната довежда до по-дълъг влак. @@ -3626,7 +3665,7 @@ STR_VEHICLE_DETAILS_TRAIN_ARTICULATED_RV_CAPACITY :{BLACK}Капа # Vehicle refit STR_REFIT_CAPTION :{WHITE}{VEHICLE} (Преустройване) STR_REFIT_TITLE :{GOLD}Изберете вид товар за превозване: -STR_REFIT_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Нов капацитет: {GOLD}{CARGO_LONG}{}{BLACK}Цена за преустройство: {RED}{CURRENCY_LONG} +STR_REFIT_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Нов капацитет: {GOLD}{CARGO_LONG}{}{BLACK}Цена за преустройсване: {RED}{CURRENCY_LONG} STR_REFIT_NEW_CAPACITY_INCOME_FROM_REFIT :{BLACK}Нов капцитет: {GOLD}{CARGO_LONG}{}{BLACK}Приход от преустройване: {GREEN}{CURRENCY_LONG} STR_REFIT_NEW_CAPACITY_COST_OF_AIRCRAFT_REFIT :{BLACK}Нова вместимост: {GOLD}{CARGO_LONG}, {GOLD}{CARGO_LONG}{}{BLACK}Цена за преоборудване: {RED}{CURRENCY_LONG} STR_REFIT_NEW_CAPACITY_INCOME_FROM_AIRCRAFT_REFIT :{BLACK}Нов капацитет: {GOLD}{CARGO_LONG}, {GOLD}{CARGO_LONG}{}{BLACK}Проход от преустройване: {GREEN}{CURRENCY_LONG} @@ -3812,9 +3851,12 @@ STR_TIMETABLE_TOOLTIP :{BLACK}Разп STR_TIMETABLE_NO_TRAVEL :Без преминаване STR_TIMETABLE_NOT_TIMETABLEABLE :Пътувай (автоматично; включено в разписанието, чрез следващата ваша заповед) STR_TIMETABLE_TRAVEL_NOT_TIMETABLED :Пътувай (без разписание) -STR_TIMETABLE_TRAVEL_NOT_TIMETABLED_SPEED :Пътувай с не повече от {2:VELOCITY} (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_STAY_FOR_ESTIMATED :(престой за {STRING}, без разписание) +STR_TIMETABLE_AND_TRAVEL_FOR_ESTIMATED :(Пътувай към {STRING}, без разписание) STR_TIMETABLE_STAY_FOR :и остани за {STRING} STR_TIMETABLE_AND_TRAVEL_FOR :и отпътувай към {STRING} STR_TIMETABLE_DAYS :{COMMA}{NBSP}ден{P "" а} @@ -3830,6 +3872,7 @@ 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 + Click задава началната дата и равномерно разпределя всички превозни средства, които споделят тази поръчка, на базата на тяхната относителна поръчка, ако поръчката е изцяло по разписание STR_TIMETABLE_CHANGE_TIME :{BLACK}Промени времето STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Промени времетраенето на маркираната заповед @@ -3929,6 +3972,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Избе STR_AI_LIST_CANCEL :{BLACK}Отмени STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Не променяй AI + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Параметри STR_AI_SETTINGS_CAPTION_AI :AI @@ -4200,7 +4244,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 :{WHITE}Пресичането на различни видове ЖП линии не е позволено. +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Пресичането на различни видове ЖП линии не е позволено. STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Тук не може да бъдат поставени сигнали... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Тук не могат да бъдат построени ЖП релси... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Не може да премахнеш тези ЖП релси... @@ -4220,6 +4264,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_NO_SUITABLE_ROAD :{WHITE}Няма подходящ път +STR_ERROR_INCOMPATIBLE_TRAMWAY :{WHITE}... несъвместима трамвайна линия # Waterway construction errors STR_ERROR_CAN_T_BUILD_CANALS :{WHITE}Тук не е възможно да се прокопае канал... @@ -4382,6 +4428,7 @@ STR_BASESOUNDS_DOS_DESCRIPTION :Оригина STR_BASESOUNDS_WIN_DESCRIPTION :Оригинални звуци на Transport Tycoon Deluxe за Windows. STR_BASESOUNDS_NONE_DESCRIPTION :Празен звуков пакет. STR_BASEMUSIC_WIN_DESCRIPTION :Оригинална музика на Transport Tycoon Deluxe за Windows. +STR_BASEMUSIC_TTO_DESCRIPTION :Оригинална Transport Tycoon (Original/World Editor) музика за DOS. STR_BASEMUSIC_NONE_DESCRIPTION :Празен музикален пакет. ##id 0x2000 diff --git a/src/lang/catalan.txt b/src/lang/catalan.txt index d915b8a058..b38c6a107b 100644 --- a/src/lang/catalan.txt +++ b/src/lang/catalan.txt @@ -11,8 +11,6 @@ ##gender Masculin Femenin -# $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. # 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. @@ -476,9 +474,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Commuta la consola STR_ABOUT_MENU_AI_DEBUG :Depuració de les IA i l'script de partida STR_ABOUT_MENU_SCREENSHOT :Captura de pantalla -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Captura de pantalla amb el zoom màxim -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Captura de pantalla amb el zoom predeterminat -STR_ABOUT_MENU_GIANT_SCREENSHOT :Captura de pantalla de tot el mapa STR_ABOUT_MENU_SHOW_FRAMERATE :Mostra els fotogrames per segon STR_ABOUT_MENU_ABOUT_OPENTTD :Quant a l'OpenTTD STR_ABOUT_MENU_SPRITE_ALIGNER :Alineador de sprites @@ -649,9 +644,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Personalitzat 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Volum de la música STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Volum dels efectes -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}MÍN -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}MÀX -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -868,6 +860,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}No{G u va} {STRING} disponible! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} ja no accepta més {STRING} STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} ja no accepta més {STRING} ni {STRING} STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} ara accepta {STRING} @@ -1201,8 +1194,8 @@ STR_CONFIG_SETTING_TRAIN_SLOPE_STEEPNESS_HELPTEXT :El pendent de l STR_CONFIG_SETTING_PERCENTAGE :{COMMA}% STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS :Pendent de les costes per als vehicles de carretera: {STRING} STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS_HELPTEXT :El pendent de les caselles amb costes per a vehicles de carretera. Els valors alts fan que sigui més difícil pujar els turons. -STR_CONFIG_SETTING_FORBID_90_DEG :Prohibeix fer girs de 90 graus als trens i vaixells: {STRING} -STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :Els girs de 90 graus succeeixen quan hi ha una via horitzontal seguida d'una de vertical a la cel·la annexa, provocant que el tren giri 90 graus quan travessi la vora de la cel·la en lloc dels 45 graus usuals en les altres combinacions. Això també s'aplica al gir dels vaixells. +STR_CONFIG_SETTING_FORBID_90_DEG :Prohibeix fer girs de 90 graus als trens: {STRING} +STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :Els girs de 90 graus succeeixen quan hi ha una via horitzontal seguida d'una de vertical a la cel·la annexa, provocant que el tren giri 90 graus quan travessi la vora de la cel·la en lloc dels 45 graus usuals en les altres combinacions. STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS :Permet ajuntar estacions no annexes: {STRING} STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS_HELPTEXT :Aquesta opció permet afegir parts noves a una estació existent sense estar les parts noves en contacte directe amb les existents. Cal clicar Ctrl+Clic mentre es col·loquen les parts noves. STR_CONFIG_SETTING_INFLATION :Inflació: {STRING} @@ -1258,8 +1251,8 @@ STR_CONFIG_SETTING_PLANE_SPEED :Factor de veloc STR_CONFIG_SETTING_PLANE_SPEED_HELPTEXT :Estableix la velocitat relativa dels avions en comparació amb els altres tipus de vehicles, per reduir la quantitat de guanys de transport dels avions STR_CONFIG_SETTING_PLANE_SPEED_VALUE :1 / {COMMA} STR_CONFIG_SETTING_PLANE_CRASHES :Nombre d'accidents d'avió: {STRING} -STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Estableix la probabilitat amb què succeeixen els accidents d'avió -STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Cap +STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Estableix la probabilitat amb què succeeixen els accidents d'avió.{}* Els avions grans sempre tenen un risc d'estavellar-se quan aterren en aeroports petits. +STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Cap* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Reduït STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normal STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Permet situar parades en carreteres que són propietat de la població: {STRING} @@ -1584,6 +1577,10 @@ STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :Activant aquest STR_CONFIG_SETTING_TOWN_FOUNDING_FORBIDDEN :Prohibit STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED :Permès STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED_CUSTOM_LAYOUT :Permès, disposició dels carrers personalitzada +STR_CONFIG_SETTING_TOWN_CARGOGENMODE :Generació de càrrega a les poblacions: {STRING} +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_HELPTEXT :Estableix quanta càrrega es produirà a les cases en funció dels habitants de la població.{}Creixement quadràtic: una població el doble de gran generarà el quàdruple de passatgers.{}Creixement lineal: una població el doble de gran generarà el doble de passatgers. +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_ORIGINAL :Quadràtica (original) +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_BITCOUNT :Lineal STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :Disposició de nous arbres durant la partida: {STRING} STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :Controla l'aparició aleatòria dels arbres durant una partida. Això podria afectar a les indústries que es basen en el creixement dels arbres, per exemple les serradores @@ -1711,7 +1708,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Distrib STR_CONFIG_SETTING_AI :{ORANGE}Competidors STR_CONFIG_SETTING_AI_NPC :{ORANGE}Jugadors IA -STR_CONFIG_SETTING_PATHFINDER_OPF :Original STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Recomanat) @@ -1795,13 +1791,9 @@ STR_QUIT_NO :{BLACK}No # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -2432,6 +2424,7 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Construe STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Intercanvia funció construeix/treu per la construcció de carreteres STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Canvia construeix/treu de la construcció de vies de tramvia + # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Orientació de la cotxera STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}Seleccioneu l'orientació desitjada de la cotxera per a vehicles de carretera. @@ -3355,8 +3348,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Infraest STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Trossos de vies: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Senyals STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Trossos de carretera: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Carretera -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Tramvia STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Cel·les d'aigua: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Canals STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Estacions: @@ -3367,8 +3358,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Indústries STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Cap - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% transportat) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% transportat) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Nom de les indústries - clica al nom per centrar la vista en la indústria. Ctrl+Clic obre una nova vista al lloc de la indústria @@ -3436,6 +3425,7 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Vehicles desagr STR_GROUP_DEFAULT_SHIPS :Vaixells desagrupats STR_GROUP_DEFAULT_AIRCRAFTS :Avions desagrupats + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Grups - Clica en un grup per llistar tots els vehicles d'aquest grup. Arrossega i solta per a canviar-ne la jerarquia. STR_GROUP_CREATE_TOOLTIP :{BLACK}Clica per crear un grup STR_GROUP_DELETE_TOOLTIP :{BLACK}Elimina el grup seleccionat @@ -3462,10 +3452,13 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Compra de nous STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Compra de nous vehicles monorail STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Compra de nous vehicles Maglev -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Compra de nous vehicles sobre vies STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Compra de nous vehicles de carretera + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Compra de nous vehicles sobre vies STR_BUY_VEHICLE_SHIP_CAPTION :Compra de nous vaixells STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Compra de noves aeronaus +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Cost: {GOLD}{CURRENCY_LONG}{BLACK} Pes: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Velocitat: {GOLD}{VELOCITY}{BLACK} Potència: {GOLD}{POWER} @@ -3500,11 +3493,13 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Compra e STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Compra el vaixell STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Compra l'aeronau + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Compra el tren/vagó seleccionat. Amb Maj+Clic, mostra el cost estimat sense comprar-lo. STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Compra el vehicle marcat. Amb Maj+Clic, mostra el cost estimat sense comprar-lo. STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Compra el vaixell seleccionat. Amb Maj+Clic, mostra el cost estimat sense comprar-lo. STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Compra l'aeronau marcada. Amb Maj+Clic, mostra el cost estimat sense comprar-la. + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Canvia el nom STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Canvia el nom STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Canvia el nom @@ -3613,13 +3608,16 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Estàs # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Missatge del fabricant de vehicles STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Acabem de dissenyar {G un una} {G nou nova} {STRING}. Esteu interessats en fer ús exclusiu d'aquest vehicle durant un any, per veure com va, abans del seu llançament mundial? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :{G=Femenin}locomotora de tren -STR_ENGINE_PREVIEW_ROAD_VEHICLE :{G=Masculin}automòbil -STR_ENGINE_PREVIEW_AIRCRAFT :{G=Masculin}avió -STR_ENGINE_PREVIEW_SHIP :{G=Masculin}vaixell STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :{G=Femenin}locomotora de monorail STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :{G=Femenin}locomotora de maglev +STR_ENGINE_PREVIEW_ROAD_VEHICLE :{G=Masculin}automòbil + +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_MAX_SPEED_CAP_RUNCOST :{BLACK}Cost: {CURRENCY_LONG} Vel. Màx: {VELOCITY}{}Capacitat: {CARGO_LONG}{}Cost d'utilització: {CURRENCY_LONG}/any @@ -3665,6 +3663,7 @@ STR_REPLACE_ELRAIL_VEHICLES :Trens Elèctric STR_REPLACE_MONORAIL_VEHICLES :Trens monorail STR_REPLACE_MAGLEV_VEHICLES :Trens maglev + STR_REPLACE_REMOVE_WAGON :{BLACK}Treure vagons: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Fer que la substitució automàtica mantingui la llargada del tren eliminant vagons (començant pel front), si substituint la màquina el tren es fa més llarg @@ -4115,6 +4114,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Seleccio STR_AI_LIST_CANCEL :{BLACK}Cancel·la STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}No canviïs l'script. + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}Paràmetres {STRING} STR_AI_SETTINGS_CAPTION_AI :de la IA @@ -4317,7 +4317,6 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... aque STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... sentit de la carretera en la direcció incorrecta STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... les estacions d'autobús de pas no poden tenir cantonades STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... les estacions d'autobús de pas no poden tenir interseccions -STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... la carretera és d'un sol sentit o està blocada. # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}No es pot treure part de la estació... @@ -4387,7 +4386,7 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}...abans STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Via de tren no apropiada STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}...abans s'ha de treure la via. STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}La carretera és un d'un sol sentit o està bloquejada -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Els passos a nivell no estan permesos en aquest tipus de via +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Els passos a nivell no estan permesos en aquest tipus de via STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Aquí no es poden construir senyals... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Aquí no es pot construir la via de tren... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Aquí no es pot treure la via de tren... diff --git a/src/lang/croatian.txt b/src/lang/croatian.txt index 5b434d912e..6c30b09997 100644 --- a/src/lang/croatian.txt +++ b/src/lang/croatian.txt @@ -12,8 +12,6 @@ ##case nom gen dat aku vok lok ins -# $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. # 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. @@ -333,6 +331,8 @@ STR_TOOLTIP_FILTER_CRITERIA :{BLACK}Odaberi STR_BUTTON_SORT_BY :{BLACK}Sortiraj prema STR_BUTTON_LOCATION :{BLACK}Lokacija STR_BUTTON_RENAME :{BLACK}Preimenuj +STR_BUTTON_CATCHMENT :{BLACK}Područje pokrivanja +STR_TOOLTIP_CATCHMENT :{BLACK}Uključi prikaz područja pokrivanja STR_TOOLTIP_CLOSE_WINDOW :{BLACK}Zatvori prozor STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Naslov prozora - povuci ovo za micanje prozora @@ -361,6 +361,7 @@ STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT_TOOLTIP :{BLACK}Uključi STR_BUTTON_DEFAULT :{BLACK}Zadano STR_BUTTON_CANCEL :{BLACK}Odustani STR_BUTTON_OK :{BLACK}OK +STR_WARNING_PASSWORD_SECURITY :{YELLOW}Upozorenje: Administratori servera mogu pročitati bilo koji tekst upisan ovdje. # On screen keyboard window STR_OSK_KEYBOARD_LAYOUT :`1234567890-=\qwertyuiop[]asdfghjkl;' zxcvbnm,./ . @@ -434,6 +435,7 @@ STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN :{BLACK}Približ STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT :{BLACK}Udalji pogled STR_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Izgradi željezničku prugu STR_TOOLBAR_TOOLTIP_BUILD_ROADS :{BLACK}Izgradi ceste +STR_TOOLBAR_TOOLTIP_BUILD_TRAMWAYS :{BLACK}Izgradi tramvajsku prugu STR_TOOLBAR_TOOLTIP_BUILD_SHIP_DOCKS :{BLACK}Izgradi pristaništa za brodove STR_TOOLBAR_TOOLTIP_BUILD_AIRPORTS :{BLACK}Izgradi zračne luke STR_TOOLBAR_TOOLTIP_LANDSCAPING :{BLACK}Otvori alatnu traku za krajolik kako bi spustio/izdignuo zemlju, posadio drveće, itd. @@ -454,6 +456,7 @@ STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION :{BLACK}Stvaranj STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Stvaranje gradova STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Stvaranje industrije STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Izgradnja ceste +STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Izgradnja tramvajske pruge STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Posadi drveće. Shift mijenja prikaz građenje/procjena troškova. STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Postavi znak STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Postavi objekt. Shift mijenja prikaz građenje/procjena troškova. @@ -571,9 +574,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Otvori konzolu STR_ABOUT_MENU_AI_DEBUG :Debugiranje UI-ja/Skripte igre STR_ABOUT_MENU_SCREENSHOT :Slika zaslona -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Zumirano do kraja na slici zaslona -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Standardno zumiranje slike zaslona -STR_ABOUT_MENU_GIANT_SCREENSHOT :Slika zaslona cijele karte STR_ABOUT_MENU_SHOW_FRAMERATE :Prikaži broj sličica u sekundi STR_ABOUT_MENU_ABOUT_OPENTTD :O 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Poravnanje spritea @@ -744,9 +744,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Proizvoljno 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Glasnoća glazbe STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Glasnoća zvukova -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}MIN -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}MAX -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -963,6 +960,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}Novi {STRING} je sada dostupan! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} više ne prihvaća {STRING.aku} STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} više ne prihvaća {STRING.aku} ili {STRING.aku} STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} od sada prihvaća {STRING.aku} @@ -1029,6 +1027,9 @@ STR_GAME_OPTIONS_CURRENCY_GEL :Gruzijski Lari STR_GAME_OPTIONS_CURRENCY_IRR :Iranski Rial (IRR) STR_GAME_OPTIONS_CURRENCY_RUB :Nove ruske rublje (RUB) STR_GAME_OPTIONS_CURRENCY_MXN :Meksički Pesos (MXN) +STR_GAME_OPTIONS_CURRENCY_NTD :Novi Tajvanski Dolar (NTD) +STR_GAME_OPTIONS_CURRENCY_CNY :Kineski Renminbi (CNY) +STR_GAME_OPTIONS_CURRENCY_HKD :Hongkonški Dolar (HKD) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Cestovna vozila @@ -1280,6 +1281,8 @@ STR_CONFIG_SETTING_AUTOSLOPE :Dopusti uređiv STR_CONFIG_SETTING_AUTOSLOPE_HELPTEXT :Dopusti uređivanje krajolika ispod građevina i pruga bez njihovog uklanjanja STR_CONFIG_SETTING_CATCHMENT :Dopusti realističnije veličine područja zahvaćanja: {STRING} STR_CONFIG_SETTING_CATCHMENT_HELPTEXT :Različiti dohvati za različite vrste stanica i zračnih luka +STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES :Stanice kompanije mogu opsluživati industrije sa priključenim neutralnim stanicama: {STRING} +STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES_HELPTEXT :Kada je uključeno, industrije sa priključenim stanicama (kao naftne platforme) mogu biti opsluživane od strane kompanija koje imaju stanice izgrađene u blizini. Kada je isključeno, ove industrije mogu biti opsluživane samo putem svojih priključenih stanica. Bilo koja stanica u blizini u vlasništvu neke kompanije neće moći opsluživati ove industrije niti će stanice priključene industriji moći opsluživati bilo što osim te industrije. STR_CONFIG_SETTING_EXTRADYNAMITE :Dopusti rušenje više cesta, mostova i tunela u vlasništvu grada: {STRING} STR_CONFIG_SETTING_EXTRADYNAMITE_HELPTEXT :Jednostavnije uklanjanje infrastrukture i građevina u vlasništvu grada STR_CONFIG_SETTING_TRAIN_LENGTH :Najveća dužina vlakova: {STRING} @@ -1296,8 +1299,8 @@ STR_CONFIG_SETTING_TRAIN_SLOPE_STEEPNESS_HELPTEXT :Kosina nagiba p STR_CONFIG_SETTING_PERCENTAGE :{COMMA}% STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS :Strmina nagiba za cestovna vozila: {STRING} STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS_HELPTEXT :Kosina nagiba polja za cestovna vozila. Veće vrijednosti čine nagib težim za penjanje -STR_CONFIG_SETTING_FORBID_90_DEG :Zabrani vlakovima i brodovima skretanja pod 90 stupnjeva: {STRING} -STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :Okreti za 90 stupnjeva se događaju kada vodoravni dio pruge odmah nastavlja okomiti dio pruge na sljedećem polju, dakle čineći zaokret vlaka od 90 stupnjeva prelaskom ruba polja umjesto uobičajenih 45 stupnjeva kod drugih kombinacija pruge. Ovo se primjenjuje i na radijus okretanja brodova +STR_CONFIG_SETTING_FORBID_90_DEG :Zabrani vlakovima skretanja pod 90 stupnjeva: {STRING} +STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :Okreti za 90 stupnjeva se događaju kada se na vodoravni dio pruge odmah nastavlja okomiti dio pruge na sljedećem polju, dakle čineći zaokret vlaka od 90 stupnjeva prelaskom ruba polja umjesto uobičajenih 45 stupnjeva kod drugih kombinacija pruge. STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS :Dopusti spajanje postaja koje nisu izravno jedna do druge {STRING} STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS_HELPTEXT :Dopusti dodavanje dijelova stanice bez izravnog dodira s postojećim dijelovima. Potrebno pritisnuti Ctrl+klik dok se dodaju novi dijelovi STR_CONFIG_SETTING_INFLATION :Inflacija: {STRING} @@ -1353,8 +1356,8 @@ STR_CONFIG_SETTING_PLANE_SPEED :Faktor brzine z STR_CONFIG_SETTING_PLANE_SPEED_HELPTEXT :Postavite relativnu brzinu zrakoplova u odnosu na ostale vrste vozila, kako bi se smanjio iznos prihoda od prijevoza zrakoplovom STR_CONFIG_SETTING_PLANE_SPEED_VALUE :1 / {COMMA} STR_CONFIG_SETTING_PLANE_CRASHES :Broj padova zrakoplova: {STRING} -STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Odredi šansu za događanje zrakoplovne nesreće -STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Ništa +STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Odredi šansu za događanje avionske nesreće.{}* Veliki avioni uvijek riskiraju nesreću kad slijeću na male aerodrome +STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Ništa* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Smanjeno STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normalno STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Dopusti prolazne postaje na cestama u vlasništvu gradova: {STRING} @@ -1577,6 +1580,9 @@ STR_CONFIG_SETTING_AI_IN_MULTIPLAYER :Dopusti UI u mr STR_CONFIG_SETTING_AI_IN_MULTIPLAYER_HELPTEXT :Dopusti UI računalnim-igračima da sudjeluju u igrama za više igrača STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES :#op-kodova prije prekida skripte: {STRING} STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES_HELPTEXT :Najveći broj računalnih koraka koje skripta može poduzeti u jednom krugu +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY :Maksimalno korištenje memorije po skripti: {STRING} +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_HELPTEXT :Koliko memorija svaka pojedina skripta može iskoristiti prije nego bude prisilno zatvorena. Ova postavka treba biti povećana za velike mape. +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_VALUE :{COMMA} MiB STR_CONFIG_SETTING_SERVINT_ISPERCENT :Servisni su intervali u postotcima: {STRING} STR_CONFIG_SETTING_SERVINT_ISPERCENT_HELPTEXT :Odaberi hoće li servis vozila potaknuti količina vremana koja je prošla od zadnjeg servisa ili postotni pad u odnosu na najveću pouzdanost @@ -1639,6 +1645,8 @@ STR_CONFIG_SETTING_SMOOTH_ECONOMY :Uključi stabil STR_CONFIG_SETTING_SMOOTH_ECONOMY_HELPTEXT :Kada je uključeno, promjene u industrijskoj proizvodnji su češće ali u manjim rasponima. Ova postavka obično nema efekta ukoliko su industrije postavljene iz nekog NewGRF-a STR_CONFIG_SETTING_ALLOW_SHARES :Dopusti kupovanje udjela u drugim tvrtkama: {STRING} STR_CONFIG_SETTING_ALLOW_SHARES_HELPTEXT :Kada je uključeno, dopušta se kupnja i prodaja dionica tvrtki. Dionice će postati dostupne samo za tvrtke određene starosti +STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES :Najmanja starost tvrtke za trgovanje udjelima: {STRING} +STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES_HELPTEXT :Odredite najmanju starost tvtke da bi drugi mogli kupovati i prodavati dionice. STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE :Postotak dobiti za dionicu koji se plaća kod sustava feedera: {STRING} STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE_HELPTEXT :Postotak prihoda koji će biti predan srednjim dionicama prijevoza feeder sustavima, daje više kontrole nad prihodima STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY :Kod povlačenja, postavi signale svakih: {STRING} @@ -1679,6 +1687,10 @@ STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :Uklučivanje ov STR_CONFIG_SETTING_TOWN_FOUNDING_FORBIDDEN :Zabranjeno STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED :Dopušteno STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED_CUSTOM_LAYOUT :Dopušteno, proizvoljan raspored grada +STR_CONFIG_SETTING_TOWN_CARGOGENMODE :Proizvodnja tereta u gradu: {STRING} +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_HELPTEXT :Koliko tereta proizvode kuće u gradu u odnosu na ukupno stanovništvo grada.{}Kvadratni rast: Grad dvostruke veličine proizvodi četverostruku količinu putnika.{}Linearni rast: Grad dvostruke veličine proizvodi dvostruku količinu putnika. +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_ORIGINAL :Kvadratno (originalno) +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_BITCOUNT :Linearno STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :Smještaj drveća u igri: {STRING} STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :Kontroliraj nasumično pojavljivanje stabala tijekom igre. Ovo može utjecati na industrije koje ovise o rastu stabala, npr. pilane @@ -1806,7 +1818,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Distrib STR_CONFIG_SETTING_AI :{ORANGE}Suparnici STR_CONFIG_SETTING_AI_NPC :{ORANGE}Računalni igrači -STR_CONFIG_SETTING_PATHFINDER_OPF :Original STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Preporučljivo) @@ -1890,13 +1901,9 @@ STR_QUIT_NO :{BLACK}Ne # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -2234,7 +2241,7 @@ STR_NETWORK_CHAT_ALL :[Svima] {STRING STR_NETWORK_CHAT_OSKTITLE :{BLACK}Upišite tekst mrežnog razgovora # Network messages -STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}Nisu pronađeni mrežni uređaji ili je kompajlirano bez opcije ENABLE_NETWORK +STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}Nisu pronađeni mrežni uređaji STR_NETWORK_ERROR_NOSERVER :{WHITE}Niti jedna mrežna igra nije pronađena STR_NETWORK_ERROR_NOCONNECTION :{WHITE}Poslužitelj nije odgovorio na zahtjev STR_NETWORK_ERROR_NEWGRF_MISMATCH :{WHITE}Spajanje nije moguće zbog razlike u NewGRF datotekama @@ -2526,6 +2533,11 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL :{BLACK}Izgradi STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Izgradi tramvajski tunel. Shift mijenja prikaz građenje/procjena troškova. STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Aktiviraj izgradnju/uklanjanje za izgradnju ceste STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Aktiviraj izgradnju/uklanjanje za izgradnju tramvaja +STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_ROAD :{BLACK}Pretvori/nadogradi vrstu ceste. Shift mijenja prikaz građenje/procjena troškova. +STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_TRAM :{BLACK}Pretvori/nadogradi vrstu tramvajske pruge. Shift mijenja prikaz građenje/procjena troškova. + +STR_ROAD_NAME_ROAD :Cesta +STR_ROAD_NAME_TRAM :Tramvajska pruga # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Smjer cestovnog spremišta @@ -2710,8 +2722,11 @@ STR_LAND_AREA_INFORMATION_NEWGRF_NAME :{BLACK}NewGRF: STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED :{BLACK}Prihvaćeni teret: {LTBLUE} STR_LAND_AREA_INFORMATION_CARGO_EIGHTS :({COMMA}/8 {STRING}) STR_LANG_AREA_INFORMATION_RAIL_TYPE :{BLACK}Vrsta željeznice: {LTBLUE}{STRING} +STR_LANG_AREA_INFORMATION_ROAD_TYPE :{BLACK}Vrsta ceste: {LTBLUE}{STRING} +STR_LANG_AREA_INFORMATION_TRAM_TYPE :{BLACK}Vrsta tramvaja: {LTBLUE}{STRING} STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT :{BLACK}Najveća brzina željeznice: {LTBLUE}{VELOCITY} STR_LANG_AREA_INFORMATION_ROAD_SPEED_LIMIT :{BLACK}Ograničenje brzine na cesti: {LTBLUE}{VELOCITY} +STR_LANG_AREA_INFORMATION_TRAM_SPEED_LIMIT :{BLACK}Limit brzine tramvaja: {LTBLUE}{VELOCITY} # Description of land area of different tiles STR_LAI_CLEAR_DESCRIPTION_ROCKS :Stijenje @@ -2821,6 +2836,7 @@ STR_FRAMERATE_SPEED_FACTOR :{BLACK}Trenutni STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}Koliko brzo se igra izvodi trenutno u usporedbi sa očekivanom brzinom u uobičajenoj simulaciji. STR_FRAMERATE_CURRENT :{WHITE}Trenutno STR_FRAMERATE_AVERAGE :{WHITE}Prosječno +STR_FRAMERATE_MEMORYUSE :{WHITE}Memorija STR_FRAMERATE_DATA_POINTS :{BLACK}Podaci bazirani na {COMMA} mjerama STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL} ms STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL} ms @@ -2828,6 +2844,9 @@ STR_FRAMERATE_MS_BAD :{RED}{DECIMAL} STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL} sličica/s STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL} sličica/s STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL} sličica/s +STR_FRAMERATE_BYTES_GOOD :{LTBLUE}{BYTES} +STR_FRAMERATE_BYTES_WARN :{YELLOW}{BYTES} +STR_FRAMERATE_BYTES_BAD :{RED}{BYTES} STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} ms STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} s ############ Leave those lines in this order!! @@ -3120,7 +3139,7 @@ STR_NEWGRF_LIST_MISSING :{RED}Nedostaju STR_NEWGRF_BROKEN :{WHITE}Ponašanje NewGRF '{0:STRING}' će vjerojatno uzrokovati deharmonizaciju i/ili rušenje igre STR_NEWGRF_BROKEN_POWERED_WAGON :{WHITE}Promijenjen status motoriziranog vagona za '{1:ENGINE}' kad vozilo nije u spremištu. STR_NEWGRF_BROKEN_VEHICLE_LENGTH :{WHITE}Ovo mijenja dužinu vozila za '{1:ENGINE}' kada vozilo nije unutar spremišta -STR_NEWGRF_BROKEN_CAPACITY :{WHITE}Promijenilo je kapacitet vozila za '{1:ENGINE}' kada nije u spremšta ili se remontira +STR_NEWGRF_BROKEN_CAPACITY :{WHITE}Promijenilo je kapacitet vozila za '{1:ENGINE}' kada nije u spremištu ili se prenamjenjuje STR_BROKEN_VEHICLE_LENGTH :{WHITE}Vlak'{VEHICLE}' koji pripada tvrtci '{COMPANY}' neispravne je dužine. Uzrok problema je vjerojatno u NewGRF datotekama. Igra će se možda deharmonizirati ili srušiti STR_NEWGRF_BUGGY :{WHITE}NewGRF '{0:STRING}' daje netočne informacije @@ -3194,6 +3213,8 @@ STR_TOWN_VIEW_RENAME_TOWN_BUTTON :Preimenuj grad # Town local authority window STR_LOCAL_AUTHORITY_CAPTION :{WHITE}Lokalna samouprava grada {TOWN}a +STR_LOCAL_AUTHORITY_ZONE :{BLACK}Zona +STR_LOCAL_AUTHORITY_ZONE_TOOLTIP :{BLACK}Pokaži područje sa granicama lokalne vlasti STR_LOCAL_AUTHORITY_COMPANY_RATINGS :{BLACK}Ocjene prijevoznih tvrtki: STR_LOCAL_AUTHORITY_COMPANY_RATING :{YELLOW}{COMPANY} {COMPANY_NUM}: {ORANGE}{STRING} STR_LOCAL_AUTHORITY_ACTIONS_TITLE :{BLACK}Dostupne radnje: @@ -3451,8 +3472,7 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Infrastr STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Dijelovi pruge: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Signali STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Dijelovi ceste: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Cesta -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Tramvajska pruga +STR_COMPANY_INFRASTRUCTURE_VIEW_TRAM_SECT :{GOLD}Dijelovi tramvaja: STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Polje s vodom: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Kanali STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Postaje: @@ -3463,9 +3483,12 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Industrije STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Ništa - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% prevezeno) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% prevezeno) +STR_INDUSTRY_DIRECTORY_ITEM_INFO :{BLACK}{CARGO_LONG}{STRING}{YELLOW} ({COMMA}% prevezeno){BLACK} STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} +STR_INDUSTRY_DIRECTORY_ITEM_PROD1 :{ORANGE}{INDUSTRY} {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PROD2 :{ORANGE}{INDUSTRY} {STRING}, {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PROD3 :{ORANGE}{INDUSTRY} {STRING}, {STRING}, {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PRODMORE :{ORANGE}{INDUSTRY} {STRING}, {STRING}, {STRING} i {NUM} više... STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Imena industrija - za centriranje pogleda klikni na ime. Ctrl+klik otvara novi prozor sa lokacijom industrije # Industry view @@ -3532,6 +3555,8 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Negrupirana ces STR_GROUP_DEFAULT_SHIPS :Negrupirani brodovi STR_GROUP_DEFAULT_AIRCRAFTS :Negrupirani zrakoplovi +STR_GROUP_COUNT_WITH_SUBGROUP :{TINY_FONT}{COMMA} (+{COMMA}) + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Grupe - kliknite na grupu kako bi izlistali sva vozila ove grupe. Povucite i prenesite grupe za postavljanje hijerarhije. STR_GROUP_CREATE_TOOLTIP :{BLACK}Klikni za kreiranje grupe STR_GROUP_DELETE_TOOLTIP :{BLACK}Obriši odabranu grupu @@ -3558,12 +3583,18 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Nova električn STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Nova jednotračna željeznička vozila STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Nova vozila Maglev -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Nova pružna vozila STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Nova cestovna vozila +STR_BUY_VEHICLE_TRAM_VEHICLE_CAPTION :Novi tramvaji + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Nova pružna vozila +STR_BUY_VEHICLE_ROAD_VEHICLE_ALL_CAPTION :Nova cestovna vozila STR_BUY_VEHICLE_SHIP_CAPTION :Novi brodovi STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Novi zrakoplov +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Cijena: {GOLD}{CURRENCY_LONG}{BLACK} Težina {GOLD}{WEIGHT_SHORT} +STR_PURCHASE_INFO_COST_REFIT_WEIGHT :{BLACK}Cijena : {GOLD}{CURRENCY_LONG}{BLACK} (Cijena prenamjene: {GOLD}{CURRENCY_LONG}{BLACK}) Težina: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Brzina: {GOLD}{VELOCITY}{BLACK} Snaga: {GOLD}{POWER} STR_PURCHASE_INFO_SPEED :{BLACK}Brzina: {GOLD}{VELOCITY} STR_PURCHASE_INFO_SPEED_OCEAN :{BLACK}Brzina na oceanu: {GOLD}{VELOCITY} @@ -3574,8 +3605,10 @@ STR_PURCHASE_INFO_REFITTABLE :(prenamjenjiv) STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Dizajnirano: {GOLD}{NUM}{BLACK} Životni vijek: {GOLD}{COMMA} godina STR_PURCHASE_INFO_RELIABILITY :{BLACK}Najveća pouzdanost: {GOLD}{COMMA}% STR_PURCHASE_INFO_COST :{BLACK}Cijena: {GOLD}{CURRENCY_LONG} +STR_PURCHASE_INFO_COST_REFIT :{BLACK}Cijena: {GOLD}{CURRENCY_LONG}{BLACK} (Cijena prenamjene: {GOLD}{CURRENCY_LONG}{BLACK}) STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Težina: {GOLD}{WEIGHT_SHORT} ({WEIGHT_SHORT}) STR_PURCHASE_INFO_COST_SPEED :{BLACK}Trošak: {GOLD}{CURRENCY_LONG}{BLACK} Brzina: {GOLD}{VELOCITY} +STR_PURCHASE_INFO_COST_REFIT_SPEED :{BLACK}Cijena: {GOLD}{CURRENCY_LONG}{BLACK} (Cijena prenamjene: {GOLD}{CURRENCY_LONG}{BLACK}) Brzina: {GOLD}{VELOCITY} STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Nosivost: {GOLD}{CARGO_LONG}, {CARGO_LONG} STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK} Pokretni vagoni:.{GOLD}+{POWER}{BLACK} Težina: {GOLD}+{WEIGHT_SHORT} STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Prenamjenjivo u: {GOLD}{STRING} @@ -3596,11 +3629,21 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Kupi voz STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Kupi brod STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Kupi zrakoplov +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Kupi i prenamijeni vozilo +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Kupi i prenamijeni vozilo +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Kupi i prenamijeni brod +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Kupi i prenamijeni zrakoplov + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Kupi označeni vlak. Shift+Klik prikazuje trošak bez kupnje. STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Kupi označeno cestovno vozilo. Shift+Klik prikazuje trošak bez kupnje. STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Kupi označeni brod. Shift+Klik prikazuje trošak bez kupnje. STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Kupi označeni zrakoplov. Shift+Klik prikazuje trošak bez kupnje. +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Kupi i prenamijeni označeni vlak. Shift+Klik prikazuje trošak bez kupnje. +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Kupi i prenamijeni označeno cestovno vozilo. Shift+Klik prikazuje trošak bez kupnje. +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Kupi i prenamijeni označeni brod. Shift+Klik prikazuje trošak bez kupnje. +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Kupi i prenamijeni označeni zrakoplov. Shift+Klik prikazuje trošak bez kupnje. + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Preimenuj STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Preimenuj STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Preimenuj @@ -3709,13 +3752,18 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Upravo # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Poruka od proizvođača vozila STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Upravo smo dizajnirali novi {STRING} - jeste li zainteresirani za jednogodišnje ekskluzivno pravo uporabe ovog vozila, kako bi vidjeli kako se vozilo ponaša prije nego što postane univerzalno dostupno? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :željeznička lokomotiva -STR_ENGINE_PREVIEW_ROAD_VEHICLE :cestovno vozilo -STR_ENGINE_PREVIEW_AIRCRAFT :zrakoplov -STR_ENGINE_PREVIEW_SHIP :brod +STR_ENGINE_PREVIEW_ELRAIL_LOCOMOTIVE :lokomotiva za elektrificiranu željeznicu STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :jednotračna željeznička lokomotiva STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :maglev lokomotiva +STR_ENGINE_PREVIEW_ROAD_VEHICLE :cestovno vozilo +STR_ENGINE_PREVIEW_TRAM_VEHICLE :tramvaj + +STR_ENGINE_PREVIEW_AIRCRAFT :zrakoplov +STR_ENGINE_PREVIEW_SHIP :brod + STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Cijena: {CURRENCY_LONG} Težina: {WEIGHT_SHORT}{}Brzina: {VELOCITY} Snaga: {POWER}{}Trošak uporabe: {CURRENCY_LONG}/god{}Kapacitet: {CARGO_LONG} STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Trošak: {CURRENCY_LONG} Težina: {WEIGHT_SHORT}{}Brzina: {VELOCITY} Snaga: {POWER} Maks. T.E.: {6:FORCE}{}Trošak uporabe: {4:CURRENCY_LONG}/god{}Nosivost: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Trošak: {CURRENCY_LONG} Maks. brzina: {VELOCITY}{}Nosivost: {CARGO_LONG}{}Trošak uporabe: {CURRENCY_LONG}/god @@ -3753,14 +3801,19 @@ STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK}Prebaci STR_REPLACE_ENGINES :Lokomotive STR_REPLACE_WAGONS :Vagoni STR_REPLACE_ALL_RAILTYPE :Sva pružna vozila +STR_REPLACE_ALL_ROADTYPE :Sva cestovna vozila STR_REPLACE_HELP_RAILTYPE :{BLACK}Odaberite vrstu željeznice za koju želite zamijeniti lokomotive +STR_REPLACE_HELP_ROADTYPE :{BLACK}Odaberite vrstu ceste za koju želite zamijeniti vozila STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Prikazuje sa kojom se lokomotivom zamjenjuje lijevo odabrana lokomotiva, ako postoji koji STR_REPLACE_RAIL_VEHICLES :Pružna vozila STR_REPLACE_ELRAIL_VEHICLES :Električna pružna vozila STR_REPLACE_MONORAIL_VEHICLES :Jednotračna vozila STR_REPLACE_MAGLEV_VEHICLES :Željeznička vozila Maglev +STR_REPLACE_ROAD_VEHICLES :Cestovna vozila +STR_REPLACE_TRAM_VEHICLES :Tramvaji + STR_REPLACE_REMOVE_WAGON :{BLACK}Uklanjanje vagona: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Automatska zamjena zadržava istu dužinu vlaka tako da ukloni suvišne vagone (počevši od naprijed), ako bi zamjena lokomotive učinila vlak dužim @@ -3903,9 +3956,9 @@ STR_VEHICLE_DETAILS_TRAIN_ARTICULATED_RV_CAPACITY :{BLACK}Nosivost STR_REFIT_CAPTION :{WHITE}{VEHICLE} (Prenamijeni) STR_REFIT_TITLE :{GOLD}Odaberi vrstu tereta za prijevoz: STR_REFIT_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Nova nosivost: {GOLD}{CARGO_LONG}{}{BLACK}Cijena prenamjene: {RED}{CURRENCY_LONG} -STR_REFIT_NEW_CAPACITY_INCOME_FROM_REFIT :{BLACK}Novi kapacitet: {GOLD}{CARGO_LONG}{}{BLACK}Prihod od remonta: {GREEN}{CURRENCY_LONG} -STR_REFIT_NEW_CAPACITY_COST_OF_AIRCRAFT_REFIT :{BLACK}Novi kapacitet: {GOLD}{CARGO_LONG}, {GOLD}{CARGO_LONG}{}{BLACK}Trošak remonta: {RED}{CURRENCY_LONG} -STR_REFIT_NEW_CAPACITY_INCOME_FROM_AIRCRAFT_REFIT :{BLACK}Novi kapacitet: {GOLD}{CARGO_LONG}, {GOLD}{CARGO_LONG}{}{BLACK}Prihod od remonta: {GREEN}{CURRENCY_LONG} +STR_REFIT_NEW_CAPACITY_INCOME_FROM_REFIT :{BLACK}Novi kapacitet: {GOLD}{CARGO_LONG}{}{BLACK}Prihod od prenamjene: {GREEN}{CURRENCY_LONG} +STR_REFIT_NEW_CAPACITY_COST_OF_AIRCRAFT_REFIT :{BLACK}Novi kapacitet: {GOLD}{CARGO_LONG}, {GOLD}{CARGO_LONG}{}{BLACK}Cijena prenamjene: {RED}{CURRENCY_LONG} +STR_REFIT_NEW_CAPACITY_INCOME_FROM_AIRCRAFT_REFIT :{BLACK}Novi kapacitet: {GOLD}{CARGO_LONG}, {GOLD}{CARGO_LONG}{}{BLACK}Prihod od prenamjene: {GREEN}{CURRENCY_LONG} STR_REFIT_SELECT_VEHICLES_TOOLTIP :{BLACK}Odaberi vozila za remont. Povlačenje mišem dopušta odabir više vozila. Klik na prazninu će označiti cijelo vozilo. Ctrl+Klik će označiti vozilo i niz koji slijedi. STR_REFIT_TRAIN_LIST_TOOLTIP :{BLACK}Odaberi vrstu tereta koju će vlak prevoziti @@ -4211,6 +4264,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Odaberi STR_AI_LIST_CANCEL :{BLACK}Odustani STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Nemoj mijenjati skriptu + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parametri STR_AI_SETTINGS_CAPTION_AI :UI @@ -4413,7 +4467,6 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... ovo STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... cesta je orijentirana u krivom smjeru STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... prolazne postaje ne mogu imati zavoje STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... prolazne postaje ne mogu imati raskrižja -STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... cesta je jednosmjerna ili je blokirana # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Nije moguće ukloniti dio postaje... @@ -4483,7 +4536,8 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Najprije STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Nije prikladno za želježnicku prugu STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Najprije je potrebno ukloniti željezničku prugu STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Cesta je jednosmjerna ili je blokirana -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Pružni prijelazi nisu dopušteni za ovu vrstu pruge +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Pružni prijelazi nisu dopušteni za ovu vrstu pruge +STR_ERROR_CROSSING_DISALLOWED_ROAD :{WHITE}Pružni prijelazi nisu dopušteni za ovu vrstu ceste STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Ovdje nije moguće postaviti signale... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Ovdje nije moguće izgraditi željezničke tračnice... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Nije moguće ukloniti željezničku prugu odavde... @@ -4503,6 +4557,12 @@ STR_ERROR_CAN_T_REMOVE_ROAD_FROM :{WHITE}Nije mog STR_ERROR_CAN_T_REMOVE_TRAMWAY_FROM :{WHITE}Nije moguće ukloniti tramvaj odavde... STR_ERROR_THERE_IS_NO_ROAD :{WHITE}... nema ceste STR_ERROR_THERE_IS_NO_TRAMWAY :{WHITE}... nema tramvajske pruge +STR_ERROR_CAN_T_CONVERT_ROAD :{WHITE}Ovdje nije moguće pretvoriti cestu... +STR_ERROR_CAN_T_CONVERT_TRAMWAY :{WHITE}Ovdje nije moguće pretvoriti tramvajsku prugu... +STR_ERROR_NO_SUITABLE_ROAD :{WHITE}Nema prikladne ceste +STR_ERROR_NO_SUITABLE_TRAMWAY :{WHITE}Nema prikladne tramvajske pruge +STR_ERROR_INCOMPATIBLE_ROAD :{WHITE}... nekompatibilna cesta +STR_ERROR_INCOMPATIBLE_TRAMWAY :{WHITE}... nekompatibilna tramvajska pruga # Waterway construction errors STR_ERROR_CAN_T_BUILD_CANALS :{WHITE}Ovdje nije moguće izgraditi kanale... @@ -4555,6 +4615,7 @@ STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Nije mog STR_ERROR_GROUP_CAN_T_DELETE :{WHITE}Nije moguće obrisati ovu grupu... STR_ERROR_GROUP_CAN_T_RENAME :{WHITE}Nije moguće preimenovati ovu grupu... 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 grupnoj hijerarhiji nisu dozvoljene STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}Nije moguće ukloniti sva vozila iz ove grupe... STR_ERROR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}Nije moguće dodati vozila u ovu grupu STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}Nije moguće dodati dijeljena vozila u grupu... diff --git a/src/lang/czech.txt b/src/lang/czech.txt index ebb716e0f8..e99fa39588 100644 --- a/src/lang/czech.txt +++ b/src/lang/czech.txt @@ -12,8 +12,6 @@ ##case nom gen dat acc voc loc ins big small -# $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. # 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. @@ -264,6 +262,8 @@ STR_COLOUR_ORANGE :Oranžová STR_COLOUR_BROWN :Hnědá STR_COLOUR_GREY :Šedá STR_COLOUR_WHITE :Bílá +STR_COLOUR_RANDOM :Náhodná +STR_COLOUR_DEFAULT :Výchozí # Units used in OpenTTD STR_UNITS_VELOCITY_IMPERIAL :{COMMA}{NBSP}m{P íle íle il}/h @@ -310,6 +310,8 @@ STR_TOOLTIP_FILTER_CRITERIA :{BLACK}Vyber t STR_BUTTON_SORT_BY :{BLACK}Řadit podle STR_BUTTON_LOCATION :{BLACK}Umístění STR_BUTTON_RENAME :{BLACK}Přejmenovat +STR_BUTTON_CATCHMENT :{BLACK}Pokrytí +STR_TOOLTIP_CATCHMENT :{BLACK}Zapnout/vypnout zvýrazňování oblasti pokrytí STR_TOOLTIP_CLOSE_WINDOW :{BLACK}Zavřít okno STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Titulek okna - tahej pro posun okna @@ -338,6 +340,7 @@ STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT_TOOLTIP :{BLACK}Zapnutí STR_BUTTON_DEFAULT :{BLACK}Původní STR_BUTTON_CANCEL :{BLACK}Zrušit STR_BUTTON_OK :{BLACK}OK +STR_WARNING_PASSWORD_SECURITY :{YELLOW}Upozornění: Administrátor serveru může zjistit a přečíst jakýkoliv text sem vložený. # On screen keyboard window STR_OSK_KEYBOARD_LAYOUT :"+ěščřžýáíé=-\qwertyuiopú)asdfghjklů' zxcvbnm,./ . @@ -411,6 +414,7 @@ STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN :{BLACK}Přiblí STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT :{BLACK}Oddálit pohled STR_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Budovat železnici STR_TOOLBAR_TOOLTIP_BUILD_ROADS :{BLACK}Budovat silniční síť +STR_TOOLBAR_TOOLTIP_BUILD_TRAMWAYS :{BLACK}Výstavba tramvajových tratí STR_TOOLBAR_TOOLTIP_BUILD_SHIP_DOCKS :{BLACK}Budovat vodní cesty STR_TOOLBAR_TOOLTIP_BUILD_AIRPORTS :{BLACK}Stavět letiště STR_TOOLBAR_TOOLTIP_LANDSCAPING :{BLACK}Otevřít nástrojovou lištu na úpravu terénu, výsadbu stromů, atd. @@ -431,6 +435,7 @@ STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION :{BLACK}Generov STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Generování měst 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_PLACE_SIGN :{BLACK}Umístit popisek STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Umisťte objekt. Shift zobrazí odhad ceny @@ -539,6 +544,7 @@ STR_TOOLBAR_SOUND_MUSIC :Zvuk/Hudba ############ range for message menu starts STR_NEWS_MENU_LAST_MESSAGE_NEWS_REPORT :Poslední zpráva nebo článek STR_NEWS_MENU_MESSAGE_HISTORY_MENU :Historie zpráv +STR_NEWS_MENU_DELETE_ALL_MESSAGES :Smazat všechny zprávy ############ range ends here ############ range for about menu starts @@ -547,9 +553,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Zobrazit nebo skrýt konzoli STR_ABOUT_MENU_AI_DEBUG :Ladění AI / herních skriptů STR_ABOUT_MENU_SCREENSHOT :Screenshot -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Screenshot v plném přiblížení -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Screenshot ve výchozím přiblížení -STR_ABOUT_MENU_GIANT_SCREENSHOT :Screenshot celé mapy STR_ABOUT_MENU_SHOW_FRAMERATE :Zobrazit počet snímků za sekundu STR_ABOUT_MENU_ABOUT_OPENTTD :O 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Zarovnávání spritů @@ -732,9 +735,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Volba 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Hlasitost hudby STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Hlasitost efektů -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}MIN -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}MAX -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -759,10 +759,12 @@ STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Zapnout/ STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Ukaž skladbu ve výběrovém okně # Playlist window +STR_PLAYLIST_MUSIC_SELECTION_SETNAME :{WHITE}Hudební program - '{STRING}' STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Index skladeb STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Program - '{STRING}' STR_PLAYLIST_CLEAR :{TINY_FONT}{BLACK}Vymazat +STR_PLAYLIST_CHANGE_SET :{BLACK}Změnit program STR_PLAYLIST_TOOLTIP_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Vyprázdnit současný program (jen u Voleb 1 a 2) STR_PLAYLIST_TOOLTIP_CHANGE_SET :{BLACK}Změnit výběr hudby na jinou nainstalovanou sadu. STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK :{BLACK}Skladba se přidá do zvoleného programu (Volba 1 nebo 2) klepnutím na její název @@ -949,6 +951,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}Nov{G ý á é í é é á} {STRING} k dispozici! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} už dále nepřijímá {STRING.acc} STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} už dále nepřijímá {STRING.acc} ani {STRING.acc} STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} nyní přijímá {STRING.acc} @@ -1014,6 +1017,10 @@ STR_GAME_OPTIONS_CURRENCY_CUSTOM :Vlastní... STR_GAME_OPTIONS_CURRENCY_GEL :Georgijské Lari (GEL) STR_GAME_OPTIONS_CURRENCY_IRR :Íránský Riál (IRR) STR_GAME_OPTIONS_CURRENCY_RUB :Ruský rubl (RUB) +STR_GAME_OPTIONS_CURRENCY_MXN :Mexické peso (MXN) +STR_GAME_OPTIONS_CURRENCY_NTD :Nový taiwanský dolar (NTD) +STR_GAME_OPTIONS_CURRENCY_CNY :Čínský renminbi (CNY) +STR_GAME_OPTIONS_CURRENCY_HKD :Hongkongský dolar (HKD) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Silniční vozidla jezdí @@ -1070,13 +1077,18 @@ STR_GAME_OPTIONS_RESOLUTION_TOOLTIP :{BLACK}Zvolit r STR_GAME_OPTIONS_RESOLUTION_OTHER :jiné STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Velikost rozhraní -STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Zvolil velikost prvků uživatelského rozhraní +STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Zvolit velikost prvků uživatelského rozhraní 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_FONT_ZOOM :{BLACK}Velikost písma +STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Zvolit velikost písma +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_BASE_GRF :{BLACK}Základní sada grafiky STR_GAME_OPTIONS_BASE_GRF_TOOLTIP :{BLACK}Zvol základní sadu grafiky @@ -1260,6 +1272,8 @@ STR_CONFIG_SETTING_AUTOSLOPE :Povolit srovná STR_CONFIG_SETTING_AUTOSLOPE_HELPTEXT :Povoluje změnu terénu pod budovami a tratěmi bez jejich odstranění STR_CONFIG_SETTING_CATCHMENT :Povolit u oblasti pokrytí realističtější velikost: {STRING} STR_CONFIG_SETTING_CATCHMENT_HELPTEXT :Rozdílná velikost oblasti pokrytí u různých stanic a letišť +STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES :Obsluhovat průmysl s vlastní stanicí i prostřednictvím jiných stanic: {STRING} +STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES_HELPTEXT :Pokud je zapnuto, průmysl s vlastní stanicí (např. ropné plošiny) může být obsluhován i prostřednictvím společnostmi vlastněných stanic v okolí. Pokud je vypnuto, tento průmysl může být obsluhován pouze prostřednictvím vlastní stanice. Společnostmi vlastněné stanice v okolí nebudou moci tento průmysl obsluhovat a vlastní stanice tohoto průmyslu nebude moci obsluhovat žádný jiný průmysl ani domy v okolí. STR_CONFIG_SETTING_EXTRADYNAMITE :Povolit bourání více městských silnic, mostů a tunelů: {STRING} STR_CONFIG_SETTING_EXTRADYNAMITE_HELPTEXT :Usnadňuje odstranění městských staveb a silnic STR_CONFIG_SETTING_TRAIN_LENGTH :Maximální délka vlaků: {STRING} @@ -1276,8 +1290,8 @@ STR_CONFIG_SETTING_TRAIN_SLOPE_STEEPNESS_HELPTEXT :Strnost svahů STR_CONFIG_SETTING_PERCENTAGE :{COMMA}% STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS :Strmost svahu pro silniční vozidla: {STRING} STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS_HELPTEXT :Vyšší hodnoty ztěžují vozidlům výjezd do kopce -STR_CONFIG_SETTING_FORBID_90_DEG :Zakázat vlakům a lodím otáčení o 90 stupňů: {STRING} -STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :90° zatočení nastane ve chvíli, kdy vodorovná kolej přímo navazuje na svislou kolej na vedlejším políčku. Vlak tak zatáčí o 90° místo klasických 45° u jiných kombinací kolejí. Ovlivní i zatáčení lodí. +STR_CONFIG_SETTING_FORBID_90_DEG :Zakázat vlakům otáčení o 90 stupňů: {STRING} +STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :90° zatočení nastane ve chvíli, kdy vodorovná kolej přímo navazuje na svislou kolej na vedlejším políčku. Vlak tak zatáčí o 90° místo klasických 45° u jiných kombinací kolejí. STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS :Umožnit spojení nesousedících stanic: {STRING} STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS_HELPTEXT :Povolit přidávání částí stanice, které se nedotýkají již existujících částí. Je potřeba stisknout Ctrl při přidávání nových částí. STR_CONFIG_SETTING_INFLATION :Inflace: {STRING} @@ -1333,8 +1347,8 @@ STR_CONFIG_SETTING_PLANE_SPEED :Poměr rychlost STR_CONFIG_SETTING_PLANE_SPEED_HELPTEXT :Nastavit poměr rychlostí letadel ku ostatním dopravním prostředům, pro snížení zisku z nákladu převáženého letadly. STR_CONFIG_SETTING_PLANE_SPEED_VALUE :1 / {COMMA} STR_CONFIG_SETTING_PLANE_CRASHES :Počet leteckých havárií: {STRING} -STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Určuje šanci na havárii letadel -STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Žádný +STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Určuje pravděpodobnost leteckých neštěstí.{}* Při přistávání velkých letadel na malých letištích hrozí zvýšené nebezpeší havárie vždy. +STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Žádná* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Redukovaný STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Obvyklý STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Stavba průjezdných zastávek na obecních silnicích: {STRING} @@ -1345,6 +1359,8 @@ STR_CONFIG_SETTING_DYNAMIC_ENGINES_EXISTING_VEHICLES :{WHITE}Toto nas STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE :Udržování infrastruktury: {STRING} STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE_HELPTEXT :Pokud je zapnuto, je třeba platit za údržbu infrastruktury. Náklady vzrůstají společně s velikostí dopravní sítě, takže velké společnosti platí více než malé. +STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR :Počáteční barva společnosti: {STRING} +STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR_HELPTEXT :Vyberte počáteční barvu společnosti STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS :Žádný druh letiště nezastará: {STRING} STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS_HELPTEXT :Povolení této možnosti způsobí, že všechny druhy letišť zůstanou po uvedení dostupné napořád. (nezastarají). @@ -1379,6 +1395,8 @@ STR_CONFIG_SETTING_POPULATION_IN_LABEL :Zobrazovat popu STR_CONFIG_SETTING_POPULATION_IN_LABEL_HELPTEXT :Zobrazovat městskou populaci u názvu města na mapě STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS :Tloušťky čar v grafech: {STRING} STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Tloušťka čáry v grafech. Tenká čára se čte přesněji, silnější je lépe viditelná a barva je snadněji rozpoznatelná. +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_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 @@ -1390,8 +1408,8 @@ STR_CONFIG_SETTING_TERRAIN_TYPE :Druh terénu: { STR_CONFIG_SETTING_TERRAIN_TYPE_HELPTEXT :(pouze TerraGenesis) Hornatost terénu STR_CONFIG_SETTING_INDUSTRY_DENSITY :Množství průmyslu: {STRING} STR_CONFIG_SETTING_INDUSTRY_DENSITY_HELPTEXT :Nastavuje množství průmyslu, které bude nyní vytvořeno a udržováno v průběhu hry -STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE :Maximální vzdálenost rafinerie od okraje mapy: {STRING} -STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :Ropné rafinerie jsou stavěny pouze blízko okrajům mapy. Pokud je mapa ostrov, pak je to pobřeží. +STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE :Maximální vzdálenost ropného průmyslu od okraje mapy: {STRING} +STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :Omezení, jak daleko od okrajů mapy mohou být postaveny rafinerie a ropné vrty. Je-li při okraji mapy voda, toto omezení zajišťuje, že se rafinerie a ropné vrty vyskytují poblíž pobřeží. Na mapách větších než 256 polí je toto omezení úměrně přizpůsobeno. STR_CONFIG_SETTING_SNOWLINE_HEIGHT :Výška sněhové čáry: {STRING} STR_CONFIG_SETTING_SNOWLINE_HEIGHT_HELPTEXT :Určuje o jaké výšky se vyskytuje sníh u subarktického klimatu. Sníh rovněž ovlivňuje vytváření průmyslu a požadavky na růst měst STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN :Členitost krajiny: {STRING} @@ -1429,6 +1447,12 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Barva terénu n STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :zelená STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :tmavě zelená STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :fialová +STR_CONFIG_SETTING_SCROLLMODE :Reakce pohledů na scrollování: {STRING} +STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :Reakce na scrollování v mapě +STR_CONFIG_SETTING_SCROLLMODE_DEFAULT :Pohyb v pohledu pomocí pravého tlačítka myši, poloha myši uzamčena +STR_CONFIG_SETTING_SCROLLMODE_RMB_LOCKED :Pohyb v mapě pomocí pravého tlačítka myši, poloha myši uzamčena +STR_CONFIG_SETTING_SCROLLMODE_RMB :Pohyb v mapě pomocí pravého tlačítka myši +STR_CONFIG_SETTING_SCROLLMODE_LMB :Pohyb v mapě pomocí levého tlačítka myši STR_CONFIG_SETTING_SMOOTH_SCROLLING :Plynulé posouvání po mapě: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Ovládá jak se hlavní pohled posouvá na specifické místo na mapě, kliknutím na minimapu nebo spuštěním příkazu na posun na specifický objekt na mapě. Pokud zapnuto, pohled se posouvá plynule, pokud vypnuto, skáče pohled přímo na cílové místo STR_CONFIG_SETTING_MEASURE_TOOLTIP :Ukázat rozměry při použití stavebních nástrojů: {STRING} @@ -1549,6 +1573,9 @@ STR_CONFIG_SETTING_AI_IN_MULTIPLAYER :Povolit AI v s STR_CONFIG_SETTING_AI_IN_MULTIPLAYER_HELPTEXT :Umožňuje AI počítačem řízeným hráčům připojit se do hry s více hráči STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES :#opcodes před skripty než budou pozastaveny: {STRING} STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES_HELPTEXT :Maximální počet výpočetních kroků, které může skript vykonat za jeden tah +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY :Max. využití paměti skriptem: {STRING} +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_HELPTEXT :Určuje, kolik paměti může každý skript využít. Při překročení bude okamžitě ukončen. Pro větší mapy bude možná třeba tuto hodnotu zvýšit. +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_VALUE :{COMMA} MiB STR_CONFIG_SETTING_SERVINT_ISPERCENT :Intervaly servisů v procentech: {STRING} STR_CONFIG_SETTING_SERVINT_ISPERCENT_HELPTEXT :Vyber, jestli potřebu návštěvy servisu určuje čas od poslední návštěvy nebo určitý pokles % spolehlivosti od jejího maxima. @@ -1607,10 +1634,16 @@ STR_CONFIG_SETTING_NEWS_MESSAGES_FULL :Plná STR_CONFIG_SETTING_COLOURED_NEWS_YEAR :Barevné noviny se objeví v roce: {STRING} STR_CONFIG_SETTING_COLOURED_NEWS_YEAR_HELPTEXT :Rok od kterého budou novinová oznámeni zobrazena v barvách. Před tímto rokem jsou černobílá. STR_CONFIG_SETTING_STARTING_YEAR :Počáteční datum: {STRING} +STR_CONFIG_SETTING_ENDING_YEAR :Rok vyhodnocení: {STRING} +STR_CONFIG_SETTING_ENDING_YEAR_HELPTEXT :Rok, kdy je ve hře uzavřeno hodnocení společností. Na konci tohoto roku je zaznamenáno skóre společností a je zobrazena tabulka nejlepších společností, ale ve hře je možné pokračovat i dál.{}Pokud je nastaven rok před rokem počátku hry, tabulka s hodnocením nebude zobrazena nikdy. +STR_CONFIG_SETTING_ENDING_YEAR_VALUE :{NUM} +STR_CONFIG_SETTING_ENDING_YEAR_ZERO :Nikdy STR_CONFIG_SETTING_SMOOTH_ECONOMY :Plynulé změny ekonomiky (více menších změn): {STRING} STR_CONFIG_SETTING_SMOOTH_ECONOMY_HELPTEXT :Pokud je zapnuto, produkce průmyslu se mění častěji ale změny jsou menší. Toto nastavení většinou nemá vliv na průmysl, který je přidaný novou grafikou STR_CONFIG_SETTING_ALLOW_SHARES :Povolit kupování podílu z ostatních společností: {STRING} -STR_CONFIG_SETTING_ALLOW_SHARES_HELPTEXT :Pokud je zapnuto, umožní kupovaní podílů ve společnostech. Podíly jsou k dispozici pouze u společností určitého stáří +STR_CONFIG_SETTING_ALLOW_SHARES_HELPTEXT :Pokud je zapnuto, umožní kupovaní akcií ve společnostech. Akcie jsou k dispozici pouze u společností od určitého stáří +STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES :Minimální stáří společnosti pro obchod s akciemi: {STRING} +STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES_HELPTEXT :Určuje stáří společnosti, od kterého mohou ostatní společnosti kupovat a prodávat její akcie. STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE :Podíl ze zisku při překládce: {STRING} STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE_HELPTEXT :Procentuální podíl příjmu, který je předán mezistanicím v překládacích systémech, předá větší kontrolu nad příjmem STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY :Při tažení umisťovat návěstidla každých: {STRING} @@ -1651,6 +1684,10 @@ STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :Povoluje hráč STR_CONFIG_SETTING_TOWN_FOUNDING_FORBIDDEN :Zakázáno STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED :Povoleno STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED_CUSTOM_LAYOUT :Povoleno s výběrem rozložení a velikosti města +STR_CONFIG_SETTING_TOWN_CARGOGENMODE :Produkce nákladu městy: {STRING} +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_HELPTEXT :Určuje, kolik nákladu je produkováno domy ve městě relativně k celkovému počtu obyvatel města.{}Kvadratická závislost: Dvakrát větší město produkuje čtyřikrát více cestujících.{}Lineární závislost: Dvakrát větší město produkuje dvakrát více cestujících. +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_ORIGINAL :Kvadratický (původní) +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_BITCOUNT :Lineární STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :Umístění stromů ve hře: {STRING} STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :Náhodné umisťování stromů během hry. Může ovlivnit průmysl závisející na růstu stromů, například pily. @@ -1778,7 +1815,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Distrib STR_CONFIG_SETTING_AI :{ORANGE}Konkurenti STR_CONFIG_SETTING_AI_NPC :{ORANGE}Umělá inteligence -STR_CONFIG_SETTING_PATHFINDER_OPF :Původní STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(doporučený) @@ -1862,13 +1898,9 @@ STR_QUIT_NO :{BLACK}Ne # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unixu STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -1897,6 +1929,7 @@ STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Změnit STR_CHEAT_SETUP_PROD :{LTBLUE}Povolit změnu produkce průmyslu: {ORANGE}{STRING} # Livery window +STR_LIVERY_CAPTION :{WHITE}{COMPANY} - barevné schéma STR_LIVERY_GENERAL_TOOLTIP :{BLACK}Zobrazit všeobecná barevná schémata STR_LIVERY_TRAIN_TOOLTIP :{BLACK}Zobrazit barevná schémata pro vlaky @@ -2156,6 +2189,7 @@ STR_NETWORK_CONNECTION_DISCONNECT :{BLACK}Odpojit STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Server je chráněný. Napiš heslo STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Společnost je chráněná. Napiš heslo +STR_NETWORK_COMPANY_LIST_CLIENT_LIST_CAPTION :Seznam klientů # Network company list added strings STR_NETWORK_COMPANY_LIST_CLIENT_LIST :Seznam hráčů @@ -2204,7 +2238,7 @@ STR_NETWORK_CHAT_ALL :[Všichni] {STR STR_NETWORK_CHAT_OSKTITLE :{BLACK}Zadej zprávu # Network messages -STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}Žádná síťová zařízení nebyla nalezena (nebo je hra zkompilována bez ENABLE_NETWORK) +STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}Žádná síťová zařízení nebyla nalezena STR_NETWORK_ERROR_NOSERVER :{WHITE}Nenalezena žádná síťová hra STR_NETWORK_ERROR_NOCONNECTION :{WHITE}Server neodpověděl na požadavek STR_NETWORK_ERROR_NEWGRF_MISMATCH :{WHITE}Nelze se připojit kvůli rozdílným grafikám @@ -2496,6 +2530,11 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL :{BLACK}Postavit STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Postavit tramvajový tunel. Stisknutý Shift pro zobrazení odhadu ceny STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Stavět nebo bourat silnici nebo zastávku STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Přepínání mezi výstavbou a bouráním tramvajové tratě +STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_ROAD :{BLACK}Změnit nebo vylepšit typ silnice (na tento). Stisknutý Shift pro zobrazení odhadu ceny +STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_TRAM :{BLACK}Změnit nebo vylepšit druh tramvajové tratě (na tento). Stisknutý Shift pro zobrazení odhadu ceny + +STR_ROAD_NAME_ROAD :Silnice +STR_ROAD_NAME_TRAM :Tramvajová trať # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Orientace garáže @@ -2686,8 +2725,11 @@ STR_LAND_AREA_INFORMATION_NEWGRF_NAME :{BLACK}NewGRF: STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED :{BLACK}Přijímané zboží: {LTBLUE} STR_LAND_AREA_INFORMATION_CARGO_EIGHTS :({COMMA}/8 {STRING}) STR_LANG_AREA_INFORMATION_RAIL_TYPE :{BLACK}Druh kolejí: {LTBLUE}{STRING} +STR_LANG_AREA_INFORMATION_ROAD_TYPE :{BLACK}Typ silnice: {LTBLUE}{STRING} +STR_LANG_AREA_INFORMATION_TRAM_TYPE :{BLACK}Typ tramvaje: {LTBLUE}{STRING} STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT :{BLACK}Rychlostní omezení tratě: {LTBLUE}{VELOCITY} STR_LANG_AREA_INFORMATION_ROAD_SPEED_LIMIT :{BLACK}Rychlostní omezení silnice: {LTBLUE}{VELOCITY} +STR_LANG_AREA_INFORMATION_TRAM_SPEED_LIMIT :{BLACK}Omezení rychlosti pro tramvaje: {LTBLUE}{VELOCITY} # Description of land area of different tiles STR_LAI_CLEAR_DESCRIPTION_ROCKS :Kamení @@ -2788,23 +2830,61 @@ STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD # Framerate display window STR_FRAMERATE_CAPTION :{WHITE}Počet snímků za sekundu +STR_FRAMERATE_CAPTION_SMALL :{STRING}{WHITE} ({DECIMAL}x) +STR_FRAMERATE_RATE_GAMELOOP :{BLACK}Rychlost simulace: {STRING} +STR_FRAMERATE_RATE_GAMELOOP_TOOLTIP :{BLACK}Počet kroků hry simulovaných za 1 sekundu. +STR_FRAMERATE_RATE_BLITTER :{BLACK}Počet snímků za sekundu: {STRING} STR_FRAMERATE_RATE_BLITTER_TOOLTIP :{BLACK}Počet snímků videa vykreslovaných za sekundu. -STR_FRAMERATE_SPEED_FACTOR :{WHITE}Aktuální činitel rychlosti hry: {DECIMAL}x +STR_FRAMERATE_SPEED_FACTOR :{BLACK}Aktuální činitel rychlosti hry: {DECIMAL}x STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}Rychlost, kterou hra právě běží, v porovnání s očekávanou rychlostí při běžné rychlosti simulace. +STR_FRAMERATE_CURRENT :{WHITE}Aktuální STR_FRAMERATE_AVERAGE :{WHITE}Průměr -STR_FRAMERATE_MS_BAD :{RED}{DECIMAL}{WHITE} ms -STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL}{WHITE} sním{P "ek" "ky" "ků"}/s -STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL}{WHITE} sním{P "ek" "ky" "ků"}/s +STR_FRAMERATE_MEMORYUSE :{WHITE}Paměť +STR_FRAMERATE_DATA_POINTS :{BLACK}Podle {COMMA} měření +STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL} ms +STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL} ms +STR_FRAMERATE_MS_BAD :{RED}{DECIMAL} ms +STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL} sním{P "ek" "ky" "ků"}/s +STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL} sním{P "ek" "ky" "ků"}/s +STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL} sním{P "ek" "ky" "ků"}/s +STR_FRAMERATE_BYTES_GOOD :{LTBLUE}{BYTES} +STR_FRAMERATE_BYTES_WARN :{YELLOW}{BYTES} +STR_FRAMERATE_BYTES_BAD :{RED}{BYTES} STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} ms STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} s ############ Leave those lines in this order!! -STR_FRAMERATE_GL_ECONOMY :{WHITE} Manipulace s nákladem: -STR_FRAMERATE_DRAWING :{WHITE}Vykreslování grafiky: +STR_FRAMERATE_GAMELOOP :{BLACK}Herní smyčka celkem: +STR_FRAMERATE_GL_ECONOMY :{BLACK} Manipulace s nákladem: +STR_FRAMERATE_GL_TRAINS :{BLACK} Kroky vlaků: +STR_FRAMERATE_GL_ROADVEHS :{BLACK} Kroky silničních vozidel: +STR_FRAMERATE_GL_SHIPS :{BLACK} Kroky lodí: +STR_FRAMERATE_GL_AIRCRAFT :{BLACK} Kroky letadel: +STR_FRAMERATE_GL_LANDSCAPE :{BLACK} Kroky terénu: +STR_FRAMERATE_GL_LINKGRAPH :{BLACK} Zpoždění grafu spojení: +STR_FRAMERATE_DRAWING :{BLACK}Vykreslování grafiky: +STR_FRAMERATE_DRAWING_VIEWPORTS :{BLACK} Pohledy: +STR_FRAMERATE_VIDEO :{BLACK}Video: +STR_FRAMERATE_SOUND :{BLACK}Míchání zvuků: +STR_FRAMERATE_ALLSCRIPTS :{BLACK} Skripty/AI celkem: +STR_FRAMERATE_GAMESCRIPT :{BLACK} Herní skript: +STR_FRAMERATE_AI :{BLACK} AI {NUM} {STRING} ############ End of leave-in-this-order ############ Leave those lines in this order!! +STR_FRAMETIME_CAPTION_GAMELOOP :Herní smyčka STR_FRAMETIME_CAPTION_GL_ECONOMY :Manipulace s nákladem +STR_FRAMETIME_CAPTION_GL_TRAINS :Kroky vlaků +STR_FRAMETIME_CAPTION_GL_ROADVEHS :Kroky silničních vozidel +STR_FRAMETIME_CAPTION_GL_SHIPS :Kroky lodí +STR_FRAMETIME_CAPTION_GL_AIRCRAFT :Kroky letadel +STR_FRAMETIME_CAPTION_GL_LANDSCAPE :Kroky terénu +STR_FRAMETIME_CAPTION_GL_LINKGRAPH :Zpoždění grafu spojení STR_FRAMETIME_CAPTION_DRAWING :Vykreslování grafiky +STR_FRAMETIME_CAPTION_DRAWING_VIEWPORTS :Vykreslování pohledů +STR_FRAMETIME_CAPTION_VIDEO :Video STR_FRAMETIME_CAPTION_SOUND :Míchání zvuků +STR_FRAMETIME_CAPTION_ALLSCRIPTS :Herní skripty/AI celkem +STR_FRAMETIME_CAPTION_GAMESCRIPT :Herní skript +STR_FRAMETIME_CAPTION_AI :AI {NUM} {STRING} ############ End of leave-in-this-order @@ -2830,6 +2910,9 @@ STR_SAVELOAD_DETAIL_CAPTION :{BLACK}Vlastnos STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}Není dostupná žádná informace STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING} STR_SAVELOAD_DETAIL_GRFSTATUS :{SILVER}Grafiky: {WHITE}{STRING} +STR_SAVELOAD_FILTER_TITLE :{BLACK}Filtr: +STR_SAVELOAD_OVERWRITE_TITLE :{WHITE}Přepsat soubor +STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}Opravdu chcete přepsat existující soubor? STR_SAVELOAD_OSKTITLE :{BLACK}Zadej jméno pro uloženou hru @@ -2947,7 +3030,12 @@ STR_NEWGRF_SETTINGS_VERSION :{BLACK}Verze: { STR_NEWGRF_SETTINGS_MIN_VERSION :{BLACK}Minimální kompatibilní verze: {SILVER}{NUM} STR_NEWGRF_SETTINGS_MD5SUM :{BLACK}MD5sum: {SILVER}{STRING} STR_NEWGRF_SETTINGS_PALETTE :{BLACK}Paleta: {SILVER}{STRING} +STR_NEWGRF_SETTINGS_PALETTE_DEFAULT :Výchozí (D) +STR_NEWGRF_SETTINGS_PALETTE_DEFAULT_32BPP :32 bpp +STR_NEWGRF_SETTINGS_PALETTE_LEGACY :Originální (W) +STR_NEWGRF_SETTINGS_PALETTE_LEGACY_32BPP :Originální (W) / 32 bpp STR_NEWGRF_SETTINGS_PARAMETER :{BLACK}Parametry: {SILVER}{STRING} +STR_NEWGRF_SETTINGS_PARAMETER_NONE :Žádný STR_NEWGRF_SETTINGS_NO_INFO :{BLACK}Informace nejsou k dispozici STR_NEWGRF_SETTINGS_NOT_FOUND :{RED}Nenalezen odpovídající soubor @@ -3028,6 +3116,7 @@ STR_NEWGRF_ERROR_READ_BOUNDS :Čtení konce p STR_NEWGRF_ERROR_GRM_FAILED :Požadované zdroje GRF nejsou dostupné (sprite {3:NUM}) STR_NEWGRF_ERROR_FORCEFULLY_DISABLED :{1:STRING} byla vypnuta {STRING} STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT :Neplatný/neznámý sprite layout formát (sprite {3:NUM}) +STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG :Příliš mnoho prvků v seznamu hodnot vlastností (sprite {3:NUM}, vlastnost {4:HEX}) # NewGRF related 'general' warnings STR_NEWGRF_POPUP_CAUTION_CAPTION :{WHITE}Varování! @@ -3125,6 +3214,8 @@ STR_TOWN_VIEW_RENAME_TOWN_BUTTON :Přejmenovat m # Town local authority window STR_LOCAL_AUTHORITY_CAPTION :{WHITE}Místní správa města {TOWN} +STR_LOCAL_AUTHORITY_ZONE :{BLACK}Oblast +STR_LOCAL_AUTHORITY_ZONE_TOOLTIP :{BLACK}Zobrazit oblast působnosti místní správy STR_LOCAL_AUTHORITY_COMPANY_RATINGS :{BLACK}Hodnocení společností: STR_LOCAL_AUTHORITY_COMPANY_RATING :{YELLOW}{COMPANY} {COMPANY_NUM}: {ORANGE}{STRING} STR_LOCAL_AUTHORITY_ACTIONS_TITLE :{BLACK}Možné činnosti: @@ -3153,6 +3244,7 @@ STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}Podplat # Goal window STR_GOALS_CAPTION :{WHITE}{COMPANY} Cíle STR_GOALS_SPECTATOR_CAPTION :{WHITE}Globální cíle +STR_GOALS_SPECTATOR :Globální cíle STR_GOALS_GLOBAL_TITLE :{BLACK}Globální cíle: STR_GOALS_TEXT :{ORANGE}{STRING} STR_GOALS_NONE :{ORANGE}- Žádné - @@ -3201,6 +3293,7 @@ STR_SUBSIDIES_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Kliknut # Story book window STR_STORY_BOOK_CAPTION :{WHITE}{COMPANY} Kniha příběhů STR_STORY_BOOK_SPECTATOR_CAPTION :{WHITE}Globální kniha příběhů +STR_STORY_BOOK_SPECTATOR :Globální kniha příběhů STR_STORY_BOOK_TITLE :{YELLOW}{STRING} STR_STORY_BOOK_GENERIC_PAGE_ITEM :Strana {NUM} STR_STORY_BOOK_SEL_PAGE_TOOLTIP :{BLACK}Skoč na určitou stranu vybranou v tomto seznamu @@ -3380,8 +3473,7 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Infrastr STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Železniční oblasti: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Semafory STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Silniční oblasti: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Silnice -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Tramvajové koleje +STR_COMPANY_INFRASTRUCTURE_VIEW_TRAM_SECT :{GOLD}Tramvajové tratě: STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Vodní oblasti: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Průplavy STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Stanice: @@ -3392,10 +3484,17 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Průmysl STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Nic - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% přepraveno) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% přepraveno) +STR_INDUSTRY_DIRECTORY_ITEM_INFO :{BLACK}{CARGO_LONG}{STRING}{YELLOW} ({COMMA}% přepraveno){BLACK} STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} +STR_INDUSTRY_DIRECTORY_ITEM_PROD1 :{ORANGE}{INDUSTRY} {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PROD2 :{ORANGE}{INDUSTRY} {STRING}, {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PROD3 :{ORANGE}{INDUSTRY} {STRING}, {STRING}, {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PRODMORE :{ORANGE}{INDUSTRY} {STRING}, {STRING}, {STRING} a {NUM} další... STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Název průmyslu - pohled na něj zaměříš kliknutím na jeho jméno. Při stisknutém Ctrl otevřeš nový pohled +STR_INDUSTRY_DIRECTORY_ACCEPTED_CARGO_FILTER :{BLACK}Přijímá náklad: {SILVER}{STRING} +STR_INDUSTRY_DIRECTORY_PRODUCED_CARGO_FILTER :{BLACK}Produkuje náklad: {SILVER}{STRING} +STR_INDUSTRY_DIRECTORY_FILTER_ALL_TYPES :Všechny druhy nákladu +STR_INDUSTRY_DIRECTORY_FILTER_NONE :Žádný # Industry view STR_INDUSTRY_VIEW_CAPTION :{WHITE}{INDUSTRY} @@ -3405,6 +3504,9 @@ STR_INDUSTRY_VIEW_LOCATION_TOOLTIP :{BLACK}Vystřed STR_INDUSTRY_VIEW_PRODUCTION_LEVEL :{BLACK}Produkce: {YELLOW}{COMMA}% STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE :{YELLOW}Průmysl oznámila blížící se uzavření! +STR_INDUSTRY_VIEW_REQUIRES_N_CARGO :{BLACK}Vyžaduje: {YELLOW}{STRING}{STRING} +STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Produkuje: {YELLOW}{STRING}{STRING} +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} @@ -3458,10 +3560,13 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Nezařazená si STR_GROUP_DEFAULT_SHIPS :Nezařazené lodě STR_GROUP_DEFAULT_AIRCRAFTS :Nezařazená letadla +STR_GROUP_COUNT_WITH_SUBGROUP :{TINY_FONT}{COMMA} (+{COMMA}) + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Skupiny - Kliknutím na skupinu se zobrazí seznam vozidel ve skupině. Přetáhnutím skupin je uspořádáš. STR_GROUP_CREATE_TOOLTIP :{BLACK}Kliknutím vytvoříš skupinu STR_GROUP_DELETE_TOOLTIP :{BLACK}Vymazat vybranou skupinu STR_GROUP_RENAME_TOOLTIP :{BLACK}Přejmenovat vybranou skupinu +STR_GROUP_LIVERY_TOOLTIP :{BLACK}Změnit nátěr vozidel vybrané skupiny STR_GROUP_REPLACE_PROTECTION_TOOLTIP :{BLACK}Kliknutím nebude na tuto skupinu mít vliv automatická výměna vozidel STR_QUERY_GROUP_DELETE_CAPTION :{WHITE}Smazat Skupinu @@ -3483,12 +3588,18 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Nové elektrick STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Nové lokomotivy a vagony pro monorail STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Nové lokomotivy a vagony Maglev -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Nová železniční vozidla STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Nová silniční vozidla +STR_BUY_VEHICLE_TRAM_VEHICLE_CAPTION :Nové tramvaje + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Nová železniční vozidla +STR_BUY_VEHICLE_ROAD_VEHICLE_ALL_CAPTION :Nová silniční vozidla STR_BUY_VEHICLE_SHIP_CAPTION :Nové lodě STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Nové letadlo +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Cena: {GOLD}{CURRENCY_LONG}{BLACK} Hmotnost: {GOLD}{WEIGHT_SHORT} +STR_PURCHASE_INFO_COST_REFIT_WEIGHT :{BLACK}Cena: {GOLD}{CURRENCY_LONG}{BLACK} (Cena přestavby: {GOLD}{CURRENCY_LONG}{BLACK}) Hmotnost: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Rychlost: {GOLD}{VELOCITY}{BLACK} Výkon: {GOLD}{POWER} STR_PURCHASE_INFO_SPEED :{BLACK}Rychlost: {GOLD}{VELOCITY} STR_PURCHASE_INFO_SPEED_OCEAN :{BLACK}Rychlost na moři: {GOLD}{VELOCITY} @@ -3499,12 +3610,15 @@ STR_PURCHASE_INFO_REFITTABLE :(lze přestavě STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Vyvinuto: {GOLD}{NUM}{BLACK} Životnost: {GOLD}{COMMA} {P rok roky let} STR_PURCHASE_INFO_RELIABILITY :{BLACK}Max. spolehlivost: {GOLD}{COMMA}% STR_PURCHASE_INFO_COST :{BLACK}Cena: {GOLD}{CURRENCY_LONG} +STR_PURCHASE_INFO_COST_REFIT :{BLACK}Náklady: {GOLD}{CURRENCY_LONG}{BLACK} (Náklady na přestavbu: {GOLD}{CURRENCY_LONG}{BLACK}) STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Hmotnost: {GOLD}{WEIGHT_SHORT} ({WEIGHT_SHORT}) STR_PURCHASE_INFO_COST_SPEED :{BLACK}Cena: {GOLD}{CURRENCY_LONG}{BLACK} Rychlost: {GOLD}{VELOCITY} +STR_PURCHASE_INFO_COST_REFIT_SPEED :{BLACK}Cena: {GOLD}{CURRENCY_LONG}{BLACK} (Cena přestavby: {GOLD}{CURRENCY_LONG}{BLACK}) Rychlost: {GOLD}{VELOCITY} STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Kapacita: {GOLD}{CARGO_LONG}, {CARGO_LONG} STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Poháněné vagony: {GOLD}+{POWER}{BLACK} Hmotnost: {GOLD}+{WEIGHT_SHORT} STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Refitovatelné na: {GOLD}{STRING} STR_PURCHASE_INFO_ALL_TYPES :Všechny druhy nákladu +STR_PURCHASE_INFO_NONE :Žádné STR_PURCHASE_INFO_ALL_BUT :Všechny kromě {CARGO_LIST} STR_PURCHASE_INFO_MAX_TE :{BLACK}Max. tažná síla: {GOLD}{FORCE} STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Dosah: {GOLD}{COMMA} polí @@ -3520,11 +3634,21 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Koupit v STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Koupit loď STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Koupit letadlo +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Koupit a přestavět vozy +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Koupit a přestavět vozidlo +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Koupit a přestavět loď +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_BUTTON :Koupit a přestavět letadlo + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Kup označený vagon/lokomotivu. Stisknutý Shift pro zobrazení odhadu ceny STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Koupit označené vozidlo. Stisknutý Shift pro zobrazení odhadu ceny STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Koupit označenou loď. Stisknutý Shift pro zobrazení odhadu ceny STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Koupit označené letadlo. Stisknutý Shift pro zobrazení odhadu ceny +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_TOOLTIP :Koupit a přestavět označený vagon/lokomotivu. Stiskněte Shift pro zobrazení odhadu ceny. +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Koupit a přestavět označené vozidlo. Stiskněte Shift pro zobrazení odhadu ceny. +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Koupit a přestavět označenou loď. Stiskněte Shift pro zobrazení odhadu ceny. +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Koupit a přestavět označené letadlo. Stiskněte Shift pro zobrazení odhadu ceny. + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Přejmenovat STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Přejmenovat STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Přejmenovat @@ -3633,16 +3757,21 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Chceš # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Zpráva od výrobce dopravních prostředků STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Právě jsme vyvinuli nov{G ý ou é é é é á} {STRING.acc}. Měl byste zájem o roční výhradní právo na používání tohoto prostředku, aby byl otestován před uvedením na trh? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :{G=f}lokomotiva STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE.acc :lokomotivu -STR_ENGINE_PREVIEW_ROAD_VEHICLE :{G=n}silniční vozidlo -STR_ENGINE_PREVIEW_AIRCRAFT :{G=n}letadlo -STR_ENGINE_PREVIEW_SHIP :{G=f}loď +STR_ENGINE_PREVIEW_ELRAIL_LOCOMOTIVE :elektrická lokomotiva STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :{G=f}lokomotiva pro monorail STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE.acc :lokomotivu pro monorail STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :{G=f}lokomotiva Maglev STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE.acc :lokomotivu Maglev +STR_ENGINE_PREVIEW_ROAD_VEHICLE :{G=n}silniční vozidlo +STR_ENGINE_PREVIEW_TRAM_VEHICLE :tramvaj + +STR_ENGINE_PREVIEW_AIRCRAFT :{G=n}letadlo +STR_ENGINE_PREVIEW_SHIP :{G=f}loď + STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Cena: {CURRENCY_LONG} Hmotnost: {WEIGHT_SHORT}{}Rychlost: {VELOCITY} Výkon: {POWER}{}Cena provozu: {CURRENCY_LONG} ročně{}Kapacita: {CARGO_LONG} STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Cena: {CURRENCY_LONG} Váha: {WEIGHT_SHORT}{}Rychlost: {VELOCITY} Síla: {POWER} Maximální tažná síla: {6:FORCE}{}Provozní náklady: {4:CURRENCY_LONG}/rok{}Kapacita: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Cena: {CURRENCY_LONG} Max. rychlost: {VELOCITY}{}Kapacita: {CARGO_LONG}{}Cena provozu: {CURRENCY_LONG} ročně @@ -3680,14 +3809,19 @@ STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK}Přepne STR_REPLACE_ENGINES :lokomotivy STR_REPLACE_WAGONS :vagony STR_REPLACE_ALL_RAILTYPE :Všechna drážní vozidla +STR_REPLACE_ALL_ROADTYPE :Všechna silniční vozidla STR_REPLACE_HELP_RAILTYPE :{BLACK}Vyber typ kolejí, pro které chceš měnit lokomotivy +STR_REPLACE_HELP_ROADTYPE :{BLACK}Vyber typ silnice, pro které chceš nahrazovat vozidla STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Tady je zobrazeno, za jakou lokomotivu se ta v levém seznamu vyměňuje STR_REPLACE_RAIL_VEHICLES :Železniční lokomotivy STR_REPLACE_ELRAIL_VEHICLES :Elektrické lokomotivy STR_REPLACE_MONORAIL_VEHICLES :Lokomotivy pro monorail STR_REPLACE_MAGLEV_VEHICLES :Lokomotivy Maglev +STR_REPLACE_ROAD_VEHICLES :Silniční vozidla +STR_REPLACE_TRAM_VEHICLES :Tramvaje + STR_REPLACE_REMOVE_WAGON :{BLACK}Odebírání vagonů: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Funkce automatického vylepšování vlaků může udržovat stejnou délku vlaku odstraňovaním vagonů (od začátku vlaku), pokud by změna mašiny vlak prodloužila @@ -3831,7 +3965,7 @@ STR_REFIT_CAPTION :{WHITE}{VEHICLE STR_REFIT_TITLE :{GOLD}Zvolit druh nákladu: STR_REFIT_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Nová kapacita: {GOLD}{CARGO_LONG}{}{BLACK}Cena přestavby: {RED}{CURRENCY_LONG} STR_REFIT_NEW_CAPACITY_INCOME_FROM_REFIT :{BLACK}Nová kapacita: {GOLD}{CARGO_LONG}{}{BLACK}Příjem za přestavbu: {GREEN}{CURRENCY_LONG} -STR_REFIT_NEW_CAPACITY_COST_OF_AIRCRAFT_REFIT :{BLACK}Nová kapacita: {GOLD}{CARGO_LONG}, {GOLD}{CARGO_LONG}{}{BLACK}Cena za předělání: {RED}{CURRENCY_LONG} +STR_REFIT_NEW_CAPACITY_COST_OF_AIRCRAFT_REFIT :{BLACK}Nová kapacita: {GOLD}{CARGO_LONG}, {GOLD}{CARGO_LONG}{}{BLACK}Cena přestavby: {RED}{CURRENCY_LONG} STR_REFIT_NEW_CAPACITY_INCOME_FROM_AIRCRAFT_REFIT :{BLACK}Nová kapacita: {GOLD}{CARGO_LONG}, {GOLD}{CARGO_LONG}{}{BLACK}Výnos z přestavby: {GREEN}{CURRENCY_LONG} STR_REFIT_SELECT_VEHICLES_TOOLTIP :{BLACK}Vybere vozidla k obnově. Tažení myší vybere více vozidel. Kliknutí na prázdné místo vybere celé vozidlo. Ctrl+Click vybere vozidlo a následující řetěz @@ -3907,6 +4041,7 @@ STR_ORDER_CONDITIONAL_AGE :Stáří vozidl STR_ORDER_CONDITIONAL_REQUIRES_SERVICE :Vyžaduje údržbu STR_ORDER_CONDITIONAL_UNCONDITIONALLY :Vždy STR_ORDER_CONDITIONAL_REMAINING_LIFETIME :Zbývající životnost (v letech) +STR_ORDER_CONDITIONAL_MAX_RELIABILITY :Nejvyšší dosažitelná spolehlivost STR_ORDER_CONDITIONAL_COMPARATOR_TOOLTIP :{BLACK}Jak porovnat vlastnost vozidla se zadanou hodnotou STR_ORDER_CONDITIONAL_COMPARATOR_EQUALS :se rovná @@ -4137,6 +4272,14 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Vybrat o STR_AI_LIST_CANCEL :{BLACK}Zrušit STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Neměňte skript +STR_SCREENSHOT_CAPTION :{WHITE}Pořídit snímek obrazovky +STR_SCREENSHOT_SCREENSHOT :{BLACK}Běžný snímek obrazovky +STR_SCREENSHOT_ZOOMIN_SCREENSHOT :{BLACK}Snímek obrazovky v úplném přiblížení +STR_SCREENSHOT_DEFAULTZOOM_SCREENSHOT :{BLACK}Snímek obrazovky ve výchozím přiblížení +STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Snímek celé mapy +STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Snímek výškové mapy +STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Snímek (náhledové) mapy světa + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parametry STR_AI_SETTINGS_CAPTION_AI :AI @@ -4339,7 +4482,6 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... tato STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... silnice je otočena jiným směrem STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... průjezdné zastávky nemohou být v zatáčce STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... průjezdné zastávky nemohou být na křižovatce -STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... silnice je jednosměrná nebo uzavřená. # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Nelze odstranit část stanice... @@ -4409,7 +4551,8 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Je nutn STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Žádné použitelné koleje STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Je nutné nejprve odstranit koleje STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Silnice je jednosměrná nebo zablokovaná -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Železniční přejezd není povolen pro tento typ kolejí +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Tento typ kolejí nedovoluje výstavbu železničních přejezdů +STR_ERROR_CROSSING_DISALLOWED_ROAD :{WHITE}Tento typ silnice nedovoluje výstavbu železničních přejezdů. STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Zde nelze postavit semafory... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Zde nelze postavit koleje... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Odsud nelze odstranit koleje... @@ -4429,6 +4572,12 @@ STR_ERROR_CAN_T_REMOVE_ROAD_FROM :{WHITE}Odsud ne STR_ERROR_CAN_T_REMOVE_TRAMWAY_FROM :{WHITE}Odsud nelze odstranit tramvajovou trať... STR_ERROR_THERE_IS_NO_ROAD :{WHITE}... není zde žádná silnice STR_ERROR_THERE_IS_NO_TRAMWAY :{WHITE}... není zde žádná tramvajová trať +STR_ERROR_CAN_T_CONVERT_ROAD :{WHITE}Zde nelze změnit typ silnice... +STR_ERROR_CAN_T_CONVERT_TRAMWAY :{WHITE}Zde nelze změnit druh tramvajové tratě... +STR_ERROR_NO_SUITABLE_ROAD :{WHITE}Neexistuje vhodná silnice +STR_ERROR_NO_SUITABLE_TRAMWAY :{WHITE}Neexistuje vhodná tramvajová trať +STR_ERROR_INCOMPATIBLE_ROAD :{WHITE}... nevhodný druh silnice +STR_ERROR_INCOMPATIBLE_TRAMWAY :{WHITE}... nevhodný typ tramvajové tratě # Waterway construction errors STR_ERROR_CAN_T_BUILD_CANALS :{WHITE}Zde nelze postavit průplav... @@ -4488,6 +4637,7 @@ STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Nelze vy STR_ERROR_GROUP_CAN_T_DELETE :{WHITE}Nelze vymazat skupinu... STR_ERROR_GROUP_CAN_T_RENAME :{WHITE}Nelze přejmenovat skupinu... STR_ERROR_GROUP_CAN_T_SET_PARENT :{WHITE}Nelze nastavit nadřazenou skupinu +STR_ERROR_GROUP_CAN_T_SET_PARENT_RECURSION :{WHITE}... skupina nemůže patřit do skupiny, která patří pod ní STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}Nelze odstranit všechna vozidla ze skupiny... STR_ERROR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}Nelze přidat vozidlo do skupiny... STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}Nelze přidat sdílená vozidla do skupiny... diff --git a/src/lang/danish.txt b/src/lang/danish.txt index 99fe68921d..de2a67da59 100644 --- a/src/lang/danish.txt +++ b/src/lang/danish.txt @@ -10,8 +10,6 @@ ##grflangid 0x2d -# $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. # 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. @@ -237,6 +235,8 @@ STR_TOOLTIP_FILTER_CRITERIA :{BLACK}Vælg fi STR_BUTTON_SORT_BY :{BLACK}Sortér på STR_BUTTON_LOCATION :{BLACK}Lokalitet STR_BUTTON_RENAME :{BLACK}Omdøb +STR_BUTTON_CATCHMENT :{BLACK}Dækning +STR_TOOLTIP_CATCHMENT :{BLACK}Aktiver visning af dækningsområde STR_TOOLTIP_CLOSE_WINDOW :{BLACK}Luk vindue STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Vinduestitel - træk her for at flytte vinduet @@ -265,6 +265,7 @@ STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT_TOOLTIP :{BLACK}Ved at a STR_BUTTON_DEFAULT :{BLACK}Standard STR_BUTTON_CANCEL :{BLACK}Annuller STR_BUTTON_OK :{BLACK}OK +STR_WARNING_PASSWORD_SECURITY :{YELLOW}Advarsel: Server administratoren kan være i stand til at læse al tekst skrevet her. # On screen keyboard window STR_OSK_KEYBOARD_LAYOUT :`1234567890-=\qwertyuiop[]asdfghjkl;' zxcvbnm,./ . @@ -338,6 +339,7 @@ STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN :{BLACK}Zoom ind STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT :{BLACK}Zoom ud STR_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Byg jernbanespor STR_TOOLBAR_TOOLTIP_BUILD_ROADS :{BLACK}Byg veje +STR_TOOLBAR_TOOLTIP_BUILD_TRAMWAYS :{BLACK}Byg sporveje STR_TOOLBAR_TOOLTIP_BUILD_SHIP_DOCKS :{BLACK}Byg havne STR_TOOLBAR_TOOLTIP_BUILD_AIRPORTS :{BLACK}Byg lufthavne STR_TOOLBAR_TOOLTIP_LANDSCAPING :{BLACK}Åbn landskabsværktøjslinjen for at hæve/sænke terræn, plante træer, osv. @@ -358,6 +360,7 @@ STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION :{BLACK}Landskab STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Bygenerering 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_PLACE_SIGN :{BLACK}Placér skilt STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Placér objekt. Shift viser tidsestimat @@ -475,9 +478,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Tænd/Sluk konsol STR_ABOUT_MENU_AI_DEBUG :Computerspiller/spilscript debug STR_ABOUT_MENU_SCREENSHOT :Skærmbillede (Ctrl-S) -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Fuldt zoomet skærmbillede -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Standard zoom skærmbillede -STR_ABOUT_MENU_GIANT_SCREENSHOT :Kæmpe skærmbillede (Ctrl-G) STR_ABOUT_MENU_SHOW_FRAMERATE :Vis spilhastighed STR_ABOUT_MENU_ABOUT_OPENTTD :Om 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Spritejustering @@ -648,9 +648,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Custom 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Musik lydstyrke STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Effekt lydstyrke -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}MIN -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}MAKS -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -860,13 +857,15 @@ STR_NEWS_VEHICLE_IS_LOST :{WHITE}{VEHICLE STR_NEWS_VEHICLE_IS_UNPROFITABLE :{WHITE}{VEHICLE}s indtjening sidste år var {CURRENCY_LONG} STR_NEWS_AIRCRAFT_DEST_TOO_FAR :{WHITE}{VEHICLE} kan ikke nå til næste destination, da den er uden for rækkevidde -STR_NEWS_ORDER_REFIT_FAILED :{WHITE}{VEHICLE} stoppet fordi en ombygnings ordre fejlede +STR_NEWS_ORDER_REFIT_FAILED :{WHITE}{VEHICLE} stoppet fordi en tilpasningsordre fejlede STR_NEWS_VEHICLE_AUTORENEW_FAILED :{WHITE}Automatisk fornyelse mislykkedes for {VEHICLE}{}{STRING} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLACK}Ny {STRING} er nu tilgængelig! STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}Ny {STRING} er nu tilgængelig! - {ENGINE} +STR_NEWS_SHOW_VEHICLE_GROUP_TOOLTIP :{BLACK}Åbn gruppevinduet med fokus på dette fartøjs gruppe + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} accepterer ikke længere {STRING} STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} accepterer ikke længere {STRING} eller {STRING} STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} accepterer nu {STRING} @@ -933,6 +932,9 @@ STR_GAME_OPTIONS_CURRENCY_GEL :Georgiske Lari STR_GAME_OPTIONS_CURRENCY_IRR :Iranske Rialer (IRR) STR_GAME_OPTIONS_CURRENCY_RUB :Ny Russisk Rubel (RUB) STR_GAME_OPTIONS_CURRENCY_MXN :Meksikansk Peso (MXN) +STR_GAME_OPTIONS_CURRENCY_NTD :Ny Taiwan dollar (NTD) +STR_GAME_OPTIONS_CURRENCY_CNY :Kinesisk Renminbi (CNY) +STR_GAME_OPTIONS_CURRENCY_HKD :Hong Kong Dollar (HKD) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Vejkøretøjer @@ -1184,6 +1186,8 @@ STR_CONFIG_SETTING_AUTOSLOPE :Tillad landskab STR_CONFIG_SETTING_AUTOSLOPE_HELPTEXT :Tillad landskabsformning under bygninger og spor uden at fjerne dem STR_CONFIG_SETTING_CATCHMENT :Tillad mere realistisk størrelse på stationernes opland: {STRING} STR_CONFIG_SETTING_CATCHMENT_HELPTEXT :Har forskellige størrelser oplande til forskellige typer af stationer og lufthavne +STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES :Selskabers stationer kan betjene industrier med tilknyttede neutrale stationer: {STRING} +STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES_HELPTEXT :Når aktiveret kan industries med tilknyttede stationer (så som Boreplatforme) også betjenes af andre selskabers stationer i nærheden. Når deaktiveret, kan disse industrier kun betjenes af deres egen tilknyttede station. Andre stationer i nærheden kan ikke betjene dem, og industriens tilknyttede station vil heller ikke betjene andet end industrien. STR_CONFIG_SETTING_EXTRADYNAMITE :Tillad nedriving af flere by-ejede veje, broer og tunneler: {STRING} STR_CONFIG_SETTING_EXTRADYNAMITE_HELPTEXT :Gør det nemmere at fjerne by-ejede infrastruktur og bygninger STR_CONFIG_SETTING_TRAIN_LENGTH :Den maksimale længde af tog: {STRING} @@ -1200,8 +1204,8 @@ STR_CONFIG_SETTING_TRAIN_SLOPE_STEEPNESS_HELPTEXT :Stejlhed af skr STR_CONFIG_SETTING_PERCENTAGE :{COMMA}% STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS :Skrånings stejlhed for vejkøretøjer: {STRING} STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS_HELPTEXT :Stejlhed af skrå felter for vej køretøjer. Højere værdier gør det vanskeligere at bestige en bakke -STR_CONFIG_SETTING_FORBID_90_DEG :Forbyd skibe og tog at dreje 90 grader: {STRING} -STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :90 graders drejninger forekommer når et horisontalt spor er direkte efterfulgt af et lodret spor stykke på det tilstødende felt, hvorved toget drejer 90 grader ved kørsel på feltets kant stedet for de sædvanlige 45 grader for andre spor kombinationer. Dette gælder også for drejeradius af skibe +STR_CONFIG_SETTING_FORBID_90_DEG :Forbyd tog at dreje 90 grader: {STRING} +STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :90 graders drejninger forekommer når et vandret sporstykke er direkte efterfulgt af et lodret sporstykke på det tilstødende felt. Således drejer toget 90 grader når det passerer feltets kant, i stedet for de sædvanlige 45 grader for andre sporkombinationer. STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS :Tillad sammenkædning af stationer der ikke ligger direkte op ad hinanden: {STRING} STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS_HELPTEXT :Tillad at tilføje dele til en station uden direkte at berøre eksisterende dele. Ctrl+Klik for at sætte nye dele STR_CONFIG_SETTING_INFLATION :Inflation: {STRING} @@ -1257,8 +1261,8 @@ STR_CONFIG_SETTING_PLANE_SPEED :Fly hastigheds- STR_CONFIG_SETTING_PLANE_SPEED_HELPTEXT :Indstil den relative hastighed af fly i forhold til andre køretøjstyper, for at reducere mængden af indkomst for transport med fly STR_CONFIG_SETTING_PLANE_SPEED_VALUE :1 / {COMMA} STR_CONFIG_SETTING_PLANE_CRASHES :Antal flystyrt: {STRING} -STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Angiv chancen for et flystyrt sker -STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Ingen +STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Angiv sandsynligheden for at fly styrter ned.{}* Store fly har altid en risiko for at styrte når de lander på små lufthavne. +STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Ingen* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :reduceret STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normal STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Tillad gennemkørsels-stop på veje ejet af en by: {STRING} @@ -1305,6 +1309,8 @@ STR_CONFIG_SETTING_POPULATION_IN_LABEL :Vis byens indby STR_CONFIG_SETTING_POPULATION_IN_LABEL_HELPTEXT :Vis befolkningen i byerne i deres etiket på kortet STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS :Linjetykkelse i grafer: {STRING} STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Bredde af linjerne i graferne. En tynd linie er mere læsbar, en tykkere linje er nemmere at se og det er lettere at skelne mellem farverne +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_LANDSCAPE :Landskab: {STRING} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Landskaber definerer grundlæggende gameplay-scenarier med forskellige laster og krav by vækst. NewGRF og spil Scripts tillader finere kontrol selv @@ -1316,8 +1322,8 @@ STR_CONFIG_SETTING_TERRAIN_TYPE :Terræn type: { STR_CONFIG_SETTING_TERRAIN_TYPE_HELPTEXT :(TerraGenesis only) Hilliness af landskabet STR_CONFIG_SETTING_INDUSTRY_DENSITY :Industri tæthed: {STRING} STR_CONFIG_SETTING_INDUSTRY_DENSITY_HELPTEXT :Angiv hvor mange industrier skal genereres og hvilket niveau der bevares i løbet af spillet -STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE :Max afstand fra kant til olieraffinaderier: {STRING} -STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :Olieraffinaderier er kun opføres nær kortets grænse, det er ved kysten for kort med øer +STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE :Maksimal afstand fra kant til olieindustrier: {STRING} +STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :Grænse for hvor langt fra kortets kant olieraffinaderier kan blive bygget. På ø-kort sikrer dette at de er nær kysten. På kort større end 256 felter bliver denne værdi automatisk skaleret op. STR_CONFIG_SETTING_SNOWLINE_HEIGHT :Snelinjehøjden: {STRING} STR_CONFIG_SETTING_SNOWLINE_HEIGHT_HELPTEXT :Kontrol med på hvilket højde sneen begynder i sub-arktiske landskab. Sne påvirker også industrien generation og betingelser by vækst STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN :Tærrenets hårdhed (kun TerraGenesis) : {STRING} @@ -1481,6 +1487,9 @@ STR_CONFIG_SETTING_AI_IN_MULTIPLAYER :Tillad computer STR_CONFIG_SETTING_AI_IN_MULTIPLAYER_HELPTEXT :Tillad computerstyrede spillere at deltage i multiplayer spil STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES :#opcodes før scriptet bliver stoppet: {STRING} STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES_HELPTEXT :Maximale nummer af udregninger et script kan eksekvere i en tur +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY :Maks hukommelsesforbrug per script: {STRING} +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_HELPTEXT :Hvor meget hukommelse et enkelt script må anvende før det bliver tvungent afbrudt. Det kan være nødvendigt at forøge dette for spil på store kort. +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_VALUE :{COMMA} MiB STR_CONFIG_SETTING_SERVINT_ISPERCENT :Service intervaller er i procent: {STRING} STR_CONFIG_SETTING_SERVINT_ISPERCENT_HELPTEXT :Vælg om vedligeholdelse bliver udløst af forløbet tid, eller pålideligheden som falder en givet procenttal i forhold til maximum pålideligheden @@ -1539,10 +1548,16 @@ STR_CONFIG_SETTING_NEWS_MESSAGES_FULL :Fuld STR_CONFIG_SETTING_COLOURED_NEWS_YEAR :Farvede nyheder dukker op i: {STRING} STR_CONFIG_SETTING_COLOURED_NEWS_YEAR_HELPTEXT :Året hvor nyheds-annonceringer bliver udskrevet i farver. Før dette år, bruger det sort / hvid STR_CONFIG_SETTING_STARTING_YEAR :Start dato: {STRING} +STR_CONFIG_SETTING_ENDING_YEAR :Slutår for pointoptælling: {STRING} +STR_CONFIG_SETTING_ENDING_YEAR_HELPTEXT :Årstal hvor spillet slutter pointoptælling. Ved slutningen af dette år bliver selskabets point optaget, og topresultater-skærmen bliver vist. Spillerne kan fortsætte med at spille efter dette.{}Hvis dette er før spillets start år, bliver topresultater-skærmen aldrig vist. +STR_CONFIG_SETTING_ENDING_YEAR_VALUE :{NUM} +STR_CONFIG_SETTING_ENDING_YEAR_ZERO :Aldrig STR_CONFIG_SETTING_SMOOTH_ECONOMY :Aktiver rolig økonomi (flere små ændringer): {STRING} STR_CONFIG_SETTING_SMOOTH_ECONOMY_HELPTEXT :Når slået til, ændre industriproduktion oftere, og i små trin. Denne indstilling har normalt ingen effekt, hvis industrityper er fastsat af NewGRF STR_CONFIG_SETTING_ALLOW_SHARES :Tillad at købe aktier i andre selskaber: {STRING} STR_CONFIG_SETTING_ALLOW_SHARES_HELPTEXT :Hvis aktiveret, tillades køb og salg af selskabsaktier. Aktier vil kun være tilgængelige for selskaber der er nået en hvis alder +STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES :Mindste selskabsalder for aktiehandel: {STRING} +STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES_HELPTEXT :Indstil mindste alder på selskaber, før andre kan købe og sælge aktier i dem. STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE :Procentdel af deloverskud som skal betales i hovedsystemer: {STRING} STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE_HELPTEXT :Procentdel af indkomst givet til de mellemliggende dele i hovedsystemer, giver mere kontrol over indkomst STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY :Når der trækkes, placer signaler hvert: {STRING} @@ -1583,6 +1598,10 @@ STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :Hvis denne inds STR_CONFIG_SETTING_TOWN_FOUNDING_FORBIDDEN :Forbudt STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED :Tilladt STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED_CUSTOM_LAYOUT :Tilladt, tilpasset by-layout +STR_CONFIG_SETTING_TOWN_CARGOGENMODE :Godsgenerering i byer: {STRING} +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_HELPTEXT :Hvor meget gods der bliver produceret af byers bygninger, i forhold til byens samlede indbyggertal.{}Kvadratisk vækst: En by med dobbelt indbyggertal genererer fire gange så mange passagerer.{}Lineær vækst: En by med dobbelt indbyggertal genererer dobbelt så mange passagerer. +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_ORIGINAL :Kvadratisk (original) +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_BITCOUNT :Lineær STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :Placering af træer i spillet: {STRING} STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :Kontroller den tilfældige fremkomst af træer i løbet af spillet. Dette vil påvirke industrier der afhænger træers vækst, f.eks. savværker @@ -1710,7 +1729,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Fragtdi STR_CONFIG_SETTING_AI :{ORANGE}Modstandere STR_CONFIG_SETTING_AI_NPC :{ORANGE}Computerstyrede spillere -STR_CONFIG_SETTING_PATHFINDER_OPF :Original STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Anbefalet) @@ -1794,13 +1812,9 @@ STR_QUIT_NO :{BLACK}Nej # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -2138,7 +2152,7 @@ STR_NETWORK_CHAT_ALL :[Alle] {STRING} STR_NETWORK_CHAT_OSKTITLE :{BLACK}Skriv tekst i netværks-chat # Network messages -STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}Ingen netværksheder fundet eller kompilet uden ENABLE_NETWORK +STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}Ingen netværksheder fundet STR_NETWORK_ERROR_NOSERVER :{WHITE}Kunne ikke finde nogen netværksspil STR_NETWORK_ERROR_NOCONNECTION :{WHITE}Serveren besvarede ikke denne forspørgsel STR_NETWORK_ERROR_NEWGRF_MISMATCH :{WHITE}Kunne ikke tilslutte grundet NewGRF ulighed @@ -2430,6 +2444,11 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL :{BLACK}Byg en t STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Byg en sporvejstunnel. Shift skifter mellem at bygge og vise prisoverslag. STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Skift mellem bygning/fjernelse af veje STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Skift mellem bygning/fjernelse af sporveje +STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_ROAD :{BLACK}Konverter/opgrader typen af vej. Shift skifter mellem at bygge og vise prisoverslag +STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_TRAM :{BLACK}Konverter/opgrader typen af sporvej. Shift skifter mellem at bygge og vise prisoverslag + +STR_ROAD_NAME_ROAD :Vej +STR_ROAD_NAME_TRAM :Sporvej # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Retning af værksted @@ -2614,8 +2633,11 @@ STR_LAND_AREA_INFORMATION_NEWGRF_NAME :{BLACK}NewGRF: STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED :{BLACK}Accepteret last: {LTBLUE} STR_LAND_AREA_INFORMATION_CARGO_EIGHTS :({COMMA}/8 {STRING}) STR_LANG_AREA_INFORMATION_RAIL_TYPE :{BLACK}Tog type: {LTBLUE}{STRING} +STR_LANG_AREA_INFORMATION_ROAD_TYPE :{BLACK}Vejtype: {LTBLUE}{STRING} +STR_LANG_AREA_INFORMATION_TRAM_TYPE :{BLACK}Sporvejstype: {LTBLUE}{STRING} STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT :{BLACK}Togspors hastighedsgrænse: {LTBLUE}{VELOCITY} STR_LANG_AREA_INFORMATION_ROAD_SPEED_LIMIT :{BLACK}Vej hastighedsbegrænsning: {LTBLUE}{VELOCITY} +STR_LANG_AREA_INFORMATION_TRAM_SPEED_LIMIT :{BLACK}Sporvogn hastighedsgrænse: {LTBLUE}{VELOCITY} # Description of land area of different tiles STR_LAI_CLEAR_DESCRIPTION_ROCKS :Klipper @@ -2725,6 +2747,7 @@ STR_FRAMERATE_SPEED_FACTOR :{BLACK}Aktuel s STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}Hvor hurtigt spillet aktuelt kører, i forhold til det forventede ved normal simulationshastighed. STR_FRAMERATE_CURRENT :{WHITE}Aktuel STR_FRAMERATE_AVERAGE :{WHITE}Gennemsnit +STR_FRAMERATE_MEMORYUSE :{WHITE}Hukommelse STR_FRAMERATE_DATA_POINTS :{BLACK}Data baseret på {COMMA} målinger STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL} ms STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL} ms @@ -2732,6 +2755,9 @@ STR_FRAMERATE_MS_BAD :{RED}{DECIMAL} STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL} billeder/s STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL} billeder/s STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL} billeder/s +STR_FRAMERATE_BYTES_GOOD :{LTBLUE}{BYTES} +STR_FRAMERATE_BYTES_WARN :{YELLOW}{BYTES} +STR_FRAMERATE_BYTES_BAD :{RED}{BYTES} STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} ms STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} s ############ Leave those lines in this order!! @@ -3028,7 +3054,7 @@ STR_NEWGRF_BROKEN_CAPACITY :{WHITE}Det ænd STR_BROKEN_VEHICLE_LENGTH :{WHITE}Toget '{VEHICLE}' fra selskabet '{COMPANY}' har ugyldig længde. Det skyldes sandsynligvis at problem med en NewGRF. Risiko for at spillet mister synkronisering eller går ned. STR_NEWGRF_BUGGY :{WHITE}NewGRF '{0:STRING}' indeholder forkert information -STR_NEWGRF_BUGGY_ARTICULATED_CARGO :{WHITE}Fragt-/ombygningsinformation for '{1:ENGINE}' afviger fra indkøbslisten efter konstruktion. Dette kan medføre, at autofornyelse ikke fungerer korrekt. +STR_NEWGRF_BUGGY_ARTICULATED_CARGO :{WHITE}Fragt-/tilpasningsinformation for '{1:ENGINE}' afviger fra indkøbslisten efter konstruktion. Dette kan medføre, at autofornyelse ikke fungerer korrekt. STR_NEWGRF_BUGGY_ENDLESS_PRODUCTION_CALLBACK :{WHITE}'{1:STRING}' forårsagede en uendelig løkke i produktions-callback'en. STR_NEWGRF_BUGGY_UNKNOWN_CALLBACK_RESULT :{WHITE}Callback {1:HEX} returnerede ukendt/ugyldigt resultat {2:HEX} STR_NEWGRF_BUGGY_INVALID_CARGO_PRODUCTION_CALLBACK :{WHITE}'{1:STRING}' returnerede ugyldig godstype i produktion-callback ved {2:HEX} @@ -3098,6 +3124,8 @@ STR_TOWN_VIEW_RENAME_TOWN_BUTTON :Omdøb byen # Town local authority window STR_LOCAL_AUTHORITY_CAPTION :{WHITE}{TOWN} lokal myndighed +STR_LOCAL_AUTHORITY_ZONE :{BLACK}Zone +STR_LOCAL_AUTHORITY_ZONE_TOOLTIP :{BLACK}Vis zone og grænse for den lokale myndighed STR_LOCAL_AUTHORITY_COMPANY_RATINGS :{BLACK}Transportselskabsbedømmelse: STR_LOCAL_AUTHORITY_COMPANY_RATING :{YELLOW}{COMPANY} {COMPANY_NUM}: {ORANGE}{STRING} STR_LOCAL_AUTHORITY_ACTIONS_TITLE :{BLACK}Handlinger til rådighed: @@ -3355,8 +3383,7 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Infrastr STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Spor-stykker: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Signaler STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Vej-stykker: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Vej -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Sporvogne +STR_COMPANY_INFRASTRUCTURE_VIEW_TRAM_SECT :{GOLD}Sporvejsdele: STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Vand-felter: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Kanaler STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Stationer: @@ -3367,10 +3394,17 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Industrier STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Ingen - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% transporteret) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% transporteret) +STR_INDUSTRY_DIRECTORY_ITEM_INFO :{BLACK}{CARGO_LONG}{STRING}{YELLOW} ({COMMA}% transporteret){BLACK} STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} +STR_INDUSTRY_DIRECTORY_ITEM_PROD1 :{ORANGE}{INDUSTRY} {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PROD2 :{ORANGE}{INDUSTRY} {STRING}, {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PROD3 :{ORANGE}{INDUSTRY} {STRING}, {STRING}, {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PRODMORE :{ORANGE}{INDUSTRY} {STRING}, {STRING}, {STRING} og {NUM} flere... STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Industrinavne - klik på navn for at centrere visningen over en industri. Ctrl+Klik åbner et nyt vindue ved industriens lokalitet. +STR_INDUSTRY_DIRECTORY_ACCEPTED_CARGO_FILTER :{BLACK}Accepteret last: {SILVER}{STRING} +STR_INDUSTRY_DIRECTORY_PRODUCED_CARGO_FILTER :{BLACK}Produceret last: {SILVER}{STRING} +STR_INDUSTRY_DIRECTORY_FILTER_ALL_TYPES :Alle lasttyper +STR_INDUSTRY_DIRECTORY_FILTER_NONE :Ingen # Industry view STR_INDUSTRY_VIEW_CAPTION :{WHITE}{INDUSTRY} @@ -3436,6 +3470,8 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Ikke-grupperede STR_GROUP_DEFAULT_SHIPS :Ikke-grupperede skibe STR_GROUP_DEFAULT_AIRCRAFTS :Ikke-grupperede fly +STR_GROUP_COUNT_WITH_SUBGROUP :{TINY_FONT}{COMMA} (+{COMMA}) + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Grupper - klik på en gruppe for at vise alle køretøjer i gruppen STR_GROUP_CREATE_TOOLTIP :{BLACK}Klik for at oprette en gruppe STR_GROUP_DELETE_TOOLTIP :{BLACK}Slet den valgte gruppe @@ -3462,27 +3498,35 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Nye elektriske STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Nye monorailkøretøjer STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Nye magnetskinnekøretøjer -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Jernbanekøretøjer STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Nye køretøjer +STR_BUY_VEHICLE_TRAM_VEHICLE_CAPTION :Nye sporvogne + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Jernbanekøretøjer +STR_BUY_VEHICLE_ROAD_VEHICLE_ALL_CAPTION :Nye vejkøretøjer STR_BUY_VEHICLE_SHIP_CAPTION :Nye skibe STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Nyt fly +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Pris: {GOLD}{CURRENCY_LONG}{BLACK} Vægt: {GOLD}{WEIGHT_SHORT} +STR_PURCHASE_INFO_COST_REFIT_WEIGHT :{BLACK}Pris: {GOLD}{CURRENCY_LONG}{BLACK} (Pris for tilpasning: {GOLD}{CURRENCY_LONG}{BLACK}) Vægt: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Hastighed: {GOLD}{VELOCITY}{BLACK} Styrke: {GOLD}{POWER} STR_PURCHASE_INFO_SPEED :{BLACK}Hastighed: {GOLD}{VELOCITY} STR_PURCHASE_INFO_SPEED_OCEAN :{BLACK}Hastighed på havet: {GOLD}{VELOCITY} STR_PURCHASE_INFO_SPEED_CANAL :{BLACK}Hastighed på kanal/flod: {GOLD}{VELOCITY} STR_PURCHASE_INFO_RUNNINGCOST :{BLACK}Driftsomkostninger: {GOLD}{CURRENCY_LONG}/år STR_PURCHASE_INFO_CAPACITY :{BLACK}Lasteevne: {GOLD}{CARGO_LONG} {STRING} -STR_PURCHASE_INFO_REFITTABLE :(kan ombygges) +STR_PURCHASE_INFO_REFITTABLE :(kan tilpasses) STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Designet: {GOLD}{NUM}{BLACK} Levetid: {GOLD}{COMMA} år STR_PURCHASE_INFO_RELIABILITY :{BLACK}Maks. pålidelighed: {GOLD}{COMMA}% STR_PURCHASE_INFO_COST :{BLACK}Pris: {GOLD}{CURRENCY_LONG} +STR_PURCHASE_INFO_COST_REFIT :{BLACK}Pris: {GOLD}{CURRENCY_LONG}{BLACK} (Pris for tilpasning: {GOLD}{CURRENCY_LONG}{BLACK}) STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Vægt: {GOLD}{WEIGHT_SHORT} ({WEIGHT_SHORT}) STR_PURCHASE_INFO_COST_SPEED :{BLACK}Pris: {GOLD}{CURRENCY_LONG}{BLACK} Hastighed: {GOLD}{VELOCITY} +STR_PURCHASE_INFO_COST_REFIT_SPEED :{BLACK}Pris: {GOLD}{CURRENCY_LONG}{BLACK} (Pris for tilpasning: {GOLD}{CURRENCY_LONG}{BLACK}) Hastighed: {GOLD}{VELOCITY} STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Kapacitet: {GOLD}{CARGO_LONG}, {CARGO_LONG} STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Motoriserede Vogne: {GOLD}+{POWER}{BLACK} Vægt: {GOLD}+{WEIGHT_SHORT} -STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Kan ombygges til: {GOLD}{STRING} +STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Kan tilpasses til: {GOLD}{STRING} STR_PURCHASE_INFO_ALL_TYPES :Alle lasttyper STR_PURCHASE_INFO_NONE :Ingen STR_PURCHASE_INFO_ALL_BUT :Alle undtagen {CARGO_LIST} @@ -3500,11 +3544,21 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Køb kø STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Køb skib STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Køb et fly +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Køb og tilpas køretøj +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Køb og tilpas køretøj +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Køb og tilpas skib +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Køb og tilpas fly + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Køb det markerede lokomotiv/togvogn. Shift skifter mellem at købe og vise prisoverslag. STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Køb det markerede køretøj. Shift skifter mellem at købe og vise prisoverslag. STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Køb det markerede skib. Shift skifter mellem at købe og vise prisoverslag. STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Køb det markerede fly. Shift skifter mellem at købe og vise prisoverslag. +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Køb og tilpas det markerede lokomotiv/togvogn. Shift+klik viser prisoverslag uden at købe +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Køb og tilpas det markerede vejkøretøj. Shift+klik viser prisoverslag uden at købe +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Køb og tilpas det markerede skib. Shift+klik viser prisoverslag uden at købe. +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Køb og tilpas det markerede fly. Shift+klik viser prisoverslag uden at købe. + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Omdøb STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Omdøb STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Omdøb @@ -3613,13 +3667,18 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Du er v # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Besked fra køretøjsfabrikken STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Vi har lige designet et nyt {STRING} - er du interesseret i et års ekslusiv testkørsel, så vi kan se hvordan det klarer sig inden vi gør det frit tilgængeligt? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :jernbanelokomotiv -STR_ENGINE_PREVIEW_ROAD_VEHICLE :vejkøretøj -STR_ENGINE_PREVIEW_AIRCRAFT :fly -STR_ENGINE_PREVIEW_SHIP :skib +STR_ENGINE_PREVIEW_ELRAIL_LOCOMOTIVE :elektrisk jernbanelokomotiv STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :monoraillokomotiv STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :magnettog +STR_ENGINE_PREVIEW_ROAD_VEHICLE :vejkøretøj +STR_ENGINE_PREVIEW_TRAM_VEHICLE :sporvogn + +STR_ENGINE_PREVIEW_AIRCRAFT :fly +STR_ENGINE_PREVIEW_SHIP :skib + STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Pris: {CURRENCY_LONG} Vægt: {WEIGHT_SHORT}{}Hastighed: {VELOCITY} Styrke: {POWER}{}Driftsomkostninger: {CURRENCY_LONG}/år{}Kapacitet: {CARGO_LONG} STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Pris: {CURRENCY_LONG} Vægt: {WEIGHT_SHORT}{}Hastighed: {VELOCITY} Hestekræfter: {POWER} Maks. Trækkraft: {6:FORCE}{}Driftsomkostning: {4:CURRENCY_LONG}/år{}Kapacitet: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Pris: {CURRENCY_LONG} Maks. hast.: {VELOCITY}{}Kapacitet: {CARGO_LONG}{}Driftsomkostninger: {CURRENCY_LONG}/år @@ -3657,14 +3716,19 @@ STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK}Skift im STR_REPLACE_ENGINES :Lokomotiver STR_REPLACE_WAGONS :Vogne STR_REPLACE_ALL_RAILTYPE :Alle jernbanevogne +STR_REPLACE_ALL_ROADTYPE :Alle vejkøretøjer STR_REPLACE_HELP_RAILTYPE :{BLACK}Vælg den skinne type, du ønsker at udskifte lokomotiver til +STR_REPLACE_HELP_ROADTYPE :{BLACK}Vælg vejtypen du ønsker at udskifte køretøjer for STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Viser hvilket køretøj det valgte køretøj til venstre bliver udskiftet med, hvis det udskiftes STR_REPLACE_RAIL_VEHICLES :Jernbane STR_REPLACE_ELRAIL_VEHICLES :Eltog STR_REPLACE_MONORAIL_VEHICLES :Monorail STR_REPLACE_MAGLEV_VEHICLES :Magnetskinnetog +STR_REPLACE_ROAD_VEHICLES :Vejkøretøjer +STR_REPLACE_TRAM_VEHICLES :Sporvogne + STR_REPLACE_REMOVE_WAGON :{BLACK}Fjern vogn: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Få autoudskift til at bevare længden af tog ved at fjerne vogne (startende fra fronten), hvis autoudskiftningen gør toget længere. @@ -3688,10 +3752,10 @@ STR_VEHICLE_VIEW_CLONE_AIRCRAFT_INFO :{BLACK}Dette vi STR_VEHICLE_VIEW_TRAIN_IGNORE_SIGNAL_TOOLTIP :{BLACK}Tving toget til at fortsætte uden at vente på at signalet skifter til grønt -STR_VEHICLE_VIEW_TRAIN_REFIT_TOOLTIP :{BLACK}Ombyg toget til at køre med en anden lasttype -STR_VEHICLE_VIEW_ROAD_VEHICLE_REFIT_TOOLTIP :{BLACK}Ombyg vejkøretøj til at laste en anden type last -STR_VEHICLE_VIEW_SHIP_REFIT_TOOLTIP :{BLACK}Ombyg skibet til at sejle med en anden slags last -STR_VEHICLE_VIEW_AIRCRAFT_REFIT_TOOLTIP :{BLACK}Ombyg flyet til at flyve med en anden slags last +STR_VEHICLE_VIEW_TRAIN_REFIT_TOOLTIP :{BLACK}Tilpas toget til at køre med en anden lasttype +STR_VEHICLE_VIEW_ROAD_VEHICLE_REFIT_TOOLTIP :{BLACK}Tilpas vejkøretøj til at køre med en anden lasttype +STR_VEHICLE_VIEW_SHIP_REFIT_TOOLTIP :{BLACK}Tilpas skibet til at sejle med en anden lasttype +STR_VEHICLE_VIEW_AIRCRAFT_REFIT_TOOLTIP :{BLACK}Tilpas flyet til at flyve med en anden lasttype STR_VEHICLE_VIEW_TRAIN_REVERSE_TOOLTIP :{BLACK}Vend retningen af toget STR_VEHICLE_VIEW_ROAD_VEHICLE_REVERSE_TOOLTIP :{BLACK}Tving køretøjet til at vende @@ -3804,28 +3868,28 @@ STR_VEHICLE_DETAILS_TRAIN_TOTAL_CARGO_TOOLTIP :{BLACK}Vis tota STR_VEHICLE_DETAILS_TRAIN_ARTICULATED_RV_CAPACITY :{BLACK}Kapacitet: {LTBLUE} # Vehicle refit -STR_REFIT_CAPTION :{WHITE}{VEHICLE} (Ombyg) +STR_REFIT_CAPTION :{WHITE}{VEHICLE} (tilpas) STR_REFIT_TITLE :{GOLD}Vælg den lasttype der skal transporteres: -STR_REFIT_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Ny kapacitet: {GOLD}{CARGO_LONG}{}{BLACK}Pris for ombyggelse: {RED}{CURRENCY_LONG} -STR_REFIT_NEW_CAPACITY_INCOME_FROM_REFIT :{BLACK}Ny kapacitet: {GOLD}{CARGO_LONG}{}{BLACK}Indtægt fra ombygning: {GREEN}{CURRENCY_LONG} -STR_REFIT_NEW_CAPACITY_COST_OF_AIRCRAFT_REFIT :{BLACK}Nye kapacitet: {GOLD}{CARGO_LONG},{GOLD}{CARGO_LONG}{}{BLACK}Pris for at ombygge: {RED}{CURRENCY_LONG} -STR_REFIT_NEW_CAPACITY_INCOME_FROM_AIRCRAFT_REFIT :{BLACK}Ny kapacitet: {GOLD}{CARGO_LONG}, {GOLD}{CARGO_LONG}{}{BLACK}Indtægt fra ombygning: {GREEN}{CURRENCY_LONG} -STR_REFIT_SELECT_VEHICLES_TOOLTIP :{BLACK}Vælg køretøjer der skal ombygges. klik og træk med musen for at vælge flere køretøjer. Klik på et tomt felt for at vælge hele køretøjet. Ctrl + klik vælger et køretøj og den efterfølgende kæde +STR_REFIT_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Ny kapacitet: {GOLD}{CARGO_LONG}{}{BLACK}Pris for tilpasning: {RED}{CURRENCY_LONG} +STR_REFIT_NEW_CAPACITY_INCOME_FROM_REFIT :{BLACK}Ny kapacitet: {GOLD}{CARGO_LONG}{}{BLACK}Indtægt fra tilpasning: {GREEN}{CURRENCY_LONG} +STR_REFIT_NEW_CAPACITY_COST_OF_AIRCRAFT_REFIT :{BLACK}Ny kapacitet: {GOLD}{CARGO_LONG},{GOLD}{CARGO_LONG}{}{BLACK}Pris for tilpasning: {RED}{CURRENCY_LONG} +STR_REFIT_NEW_CAPACITY_INCOME_FROM_AIRCRAFT_REFIT :{BLACK}Ny kapacitet: {GOLD}{CARGO_LONG}, {GOLD}{CARGO_LONG}{}{BLACK}Indtægt fra tilpasning: {GREEN}{CURRENCY_LONG} +STR_REFIT_SELECT_VEHICLES_TOOLTIP :{BLACK}Vælg køretøjer der skal tilpasses. Klik og træk med musen for at vælge flere køretøjer. Klik på et tomt felt for at vælge hele køretøjet. Ctrl+klik vælger et køretøj og den efterfølgende kæde STR_REFIT_TRAIN_LIST_TOOLTIP :{BLACK}Vælg den lasttype toget skal kører med STR_REFIT_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Vælg lasttype som lastbilen skal transportere STR_REFIT_SHIP_LIST_TOOLTIP :{BLACK}Vælg den slags last skibet skal sejle med STR_REFIT_AIRCRAFT_LIST_TOOLTIP :{BLACK}Vælg den type last flyet skal flyve med -STR_REFIT_TRAIN_REFIT_BUTTON :{BLACK}Ombyg toget -STR_REFIT_ROAD_VEHICLE_REFIT_BUTTON :{BLACK}Ombyg lastbil -STR_REFIT_SHIP_REFIT_BUTTON :{BLACK}Ombyg skibet -STR_REFIT_AIRCRAFT_REFIT_BUTTON :{BLACK}Ombyg fly +STR_REFIT_TRAIN_REFIT_BUTTON :{BLACK}Tilpas tog +STR_REFIT_ROAD_VEHICLE_REFIT_BUTTON :{BLACK}Tilpas vejkøretøj +STR_REFIT_SHIP_REFIT_BUTTON :{BLACK}Tilpas skibet +STR_REFIT_AIRCRAFT_REFIT_BUTTON :{BLACK}Tilpas fly -STR_REFIT_TRAIN_REFIT_TOOLTIP :{BLACK}Ombyg toget til at køre med den markerede lasttype -STR_REFIT_ROAD_VEHICLE_REFIT_TOOLTIP :{BLACK}Ombyg vejkøretøjet til at laste den markerede type last -STR_REFIT_SHIP_REFIT_TOOLTIP :{BLACK}Ombyg skibet til den markerede slags last -STR_REFIT_AIRCRAFT_REFIT_TOOLTIP :{BLACK}Ombyg flyet til at flyve med den markerede slags last +STR_REFIT_TRAIN_REFIT_TOOLTIP :{BLACK}Tilpas tog til at køre med den markerede lasttype +STR_REFIT_ROAD_VEHICLE_REFIT_TOOLTIP :{BLACK}Tilpas vejkøretøjet til at køre med den markerede lasttype +STR_REFIT_SHIP_REFIT_TOOLTIP :{BLACK}Tilpas skibet til den markerede lasttype +STR_REFIT_AIRCRAFT_REFIT_TOOLTIP :{BLACK}Tilpas flyet til at flyve med den markerede lasttype # Order view STR_ORDERS_CAPTION :{WHITE}{VEHICLE} (Ordrer) @@ -3861,8 +3925,8 @@ STR_ORDER_DROP_TRANSFER :Overfør STR_ORDER_DROP_NO_UNLOADING :Ingen losning STR_ORDER_TOOLTIP_UNLOAD :{BLACK}Ændr losseregel for den valgte ordre -STR_ORDER_REFIT :{BLACK}Ombyg -STR_ORDER_REFIT_TOOLTIP :{BLACK}Vælg hvilken lasttype, der skal ombygges til i denne ordre. CTRL-klik for at fjerne ombygningsinstruktion +STR_ORDER_REFIT :{BLACK}Tilpas +STR_ORDER_REFIT_TOOLTIP :{BLACK}Vælg hvilken lasttype, der skal tilpasses til i denne ordre. Ctrl+klik for at fjerne tilpasningsinstruktion STR_ORDER_REFIT_AUTO :{BLACK}Auto-tilpas STR_ORDER_REFIT_AUTO_TOOLTIP :{BLACK}Vælg typen af last der skal auto-tilpasses denne ordre. Ctrl+Click for at fjerne auto-tilpas-funktionen. Auto-tilpasning vil kun kunne gøres, hvis køretøjet tillader det STR_ORDER_DROP_REFIT_AUTO :Bestemt last @@ -3932,8 +3996,8 @@ STR_ORDER_SHIP_DEPOT :Skibsdok STR_ORDER_GO_TO_NEAREST_DEPOT_FORMAT :{STRING} {STRING} {STRING} STR_ORDER_GO_TO_DEPOT_FORMAT :{STRING} {DEPOT} -STR_ORDER_REFIT_ORDER :(Ombyg til {STRING}) -STR_ORDER_REFIT_STOP_ORDER :(Ombyg til {STRING} og stop) +STR_ORDER_REFIT_ORDER :(Tilpas til {STRING}) +STR_ORDER_REFIT_STOP_ORDER :(Tilpas til {STRING} og stop) STR_ORDER_STOP_ORDER :(Stop) STR_ORDER_GO_TO_STATION :{STRING} {STATION} {STRING} @@ -4115,6 +4179,14 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Vælg ma STR_AI_LIST_CANCEL :{BLACK}Afbryd STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Skift ikke script'et +STR_SCREENSHOT_CAPTION :{WHITE}Tag skærmbillede +STR_SCREENSHOT_SCREENSHOT :{BLACK}Normalt skærmbillede +STR_SCREENSHOT_ZOOMIN_SCREENSHOT :{BLACK}Fuldt zoomet-ind skærmbillede +STR_SCREENSHOT_DEFAULTZOOM_SCREENSHOT :{BLACK}Standard zoom skærmbillede +STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Fuldt kort skærmbillede +STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Højdekort skærmbillede +STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Minikort skærmbillede + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parametre STR_AI_SETTINGS_CAPTION_AI :AI @@ -4317,7 +4389,6 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... denn STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... vejen peger i den forkerte retning STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... drive-through stops kan ikke have hjørner STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... drive-through stops kan ikke have kryds -STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}vejen er ensrettet eller blokeret # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Kan ikke fjerne en del af en station... @@ -4384,10 +4455,11 @@ STR_ERROR_AUTOREPLACE_MONEY_LIMIT :(ikke penge nok # Rail construction errors STR_ERROR_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}Umulig sporkombination STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Det er nødvendigt at fjerne signalet først -STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Ingen brugbar jernbane +STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Ingen egnet jernbane STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Det er nødvendigt at fjerne jernbaneskinnerne først STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Vejen er ensrettet eller blokeret -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Niveaukrydsning ikke tilladt for denne type skinner +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Niveaukrydsning ikke tilladt for denne type skinner +STR_ERROR_CROSSING_DISALLOWED_ROAD :{WHITE}Niveaukrydsning ikke tilladt for denne type vej STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Kan ikke bygge signaler her... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Kan ikke bygge jernbane her... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Kan ikke fjerne jernbane herfra... @@ -4407,6 +4479,12 @@ STR_ERROR_CAN_T_REMOVE_ROAD_FROM :{WHITE}Kan ikke STR_ERROR_CAN_T_REMOVE_TRAMWAY_FROM :{WHITE}Kan ikke fjerne sporvej her... STR_ERROR_THERE_IS_NO_ROAD :{WHITE}... der er ingen vej STR_ERROR_THERE_IS_NO_TRAMWAY :{WHITE}... der er ikke noget spor +STR_ERROR_CAN_T_CONVERT_ROAD :{WHITE}Kan ikke konvertere vejtype her... +STR_ERROR_CAN_T_CONVERT_TRAMWAY :{WHITE}Kan ikke konvertere sporvejstype her... +STR_ERROR_NO_SUITABLE_ROAD :{WHITE}Ingen passende vej +STR_ERROR_NO_SUITABLE_TRAMWAY :{WHITE}Ingen egnet sporvej +STR_ERROR_INCOMPATIBLE_ROAD :{WHITE}... inkompatibel vej +STR_ERROR_INCOMPATIBLE_TRAMWAY :{WHITE}... inkompatibel sporvej # Waterway construction errors STR_ERROR_CAN_T_BUILD_CANALS :{WHITE}Kan ikke bygge en kanal her... @@ -4459,6 +4537,7 @@ STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Kan ikke STR_ERROR_GROUP_CAN_T_DELETE :{WHITE}Kan ikke slette denne gruppe... STR_ERROR_GROUP_CAN_T_RENAME :{WHITE}Kan ikke omdøbe gruppe... STR_ERROR_GROUP_CAN_T_SET_PARENT :{WHITE}Kan ikke sætte overordnede gruppe ... +STR_ERROR_GROUP_CAN_T_SET_PARENT_RECURSION :{WHITE}... løkker i gruppe-hierarkiet er ikke tilladt STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}Kan ikke fjerne alle køretøjer fra denne gruppe... STR_ERROR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}Kan ikke tilføje køretøjet til denne gruppe... STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}Kan ikke tilføje delte køretøjer til gruppe... @@ -4469,10 +4548,10 @@ STR_ERROR_ROAD_VEHICLE_IN_THE_WAY :{WHITE}Køretø STR_ERROR_SHIP_IN_THE_WAY :{WHITE}Der er et skib i vejen STR_ERROR_AIRCRAFT_IN_THE_WAY :{WHITE}Fly i vejen -STR_ERROR_CAN_T_REFIT_TRAIN :{WHITE}Kan ikke ombygge toget... -STR_ERROR_CAN_T_REFIT_ROAD_VEHICLE :{WHITE}Kan ikke ombygge vejkøretøj -STR_ERROR_CAN_T_REFIT_SHIP :{WHITE}Kan ikke ombygge skib... -STR_ERROR_CAN_T_REFIT_AIRCRAFT :{WHITE}Kan ikke ombygge fly... +STR_ERROR_CAN_T_REFIT_TRAIN :{WHITE}Kan ikke tilpasse tog... +STR_ERROR_CAN_T_REFIT_ROAD_VEHICLE :{WHITE}Kan ikke tilpasse vejkøretøj +STR_ERROR_CAN_T_REFIT_SHIP :{WHITE}Kan ikke tilpasse skib... +STR_ERROR_CAN_T_REFIT_AIRCRAFT :{WHITE}Kan ikke tilpasse fly... STR_ERROR_CAN_T_RENAME_TRAIN :{WHITE}Kan ikke give toget navn... STR_ERROR_CAN_T_RENAME_ROAD_VEHICLE :{WHITE}Kan ikke give køretøjet et navn... diff --git a/src/lang/dutch.txt b/src/lang/dutch.txt index 69109d5622..67273ad3ce 100644 --- a/src/lang/dutch.txt +++ b/src/lang/dutch.txt @@ -10,8 +10,6 @@ ##grflangid 0x1f -# $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. # 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. @@ -98,7 +96,7 @@ STR_QUANTITY_NOTHING : STR_QUANTITY_PASSENGERS :{COMMA}{NBSP}passagier{P "" s} STR_QUANTITY_COAL :{WEIGHT_LONG} kolen STR_QUANTITY_MAIL :{COMMA}{NBSP}zak{P "" ken} post -STR_QUANTITY_OIL :{VOLUME_LONG} Vaten olie +STR_QUANTITY_OIL :{VOLUME_LONG} vaten olie STR_QUANTITY_LIVESTOCK :{COMMA}{NBSP}stuk{P "" s} vee STR_QUANTITY_GOODS :{COMMA}{NBSP}krat{P "" ten} goederen STR_QUANTITY_GRAIN :{WEIGHT_LONG} graan @@ -237,6 +235,8 @@ STR_TOOLTIP_FILTER_CRITERIA :{BLACK}Selectee STR_BUTTON_SORT_BY :{BLACK}Sorteren op STR_BUTTON_LOCATION :{BLACK}Locatie STR_BUTTON_RENAME :{BLACK}Hernoemen +STR_BUTTON_CATCHMENT :{BLACK}Dekking +STR_TOOLTIP_CATCHMENT :{BLACK}Schakelt weergave van dekkingsgebied om STR_TOOLTIP_CLOSE_WINDOW :{BLACK}Venster sluiten STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Vensternaam - sleep om venster te verplaatsen @@ -265,6 +265,7 @@ STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT_TOOLTIP :{BLACK}Wanneer STR_BUTTON_DEFAULT :{BLACK}Standaard STR_BUTTON_CANCEL :{BLACK}Annuleren STR_BUTTON_OK :{BLACK}OK +STR_WARNING_PASSWORD_SECURITY :{YELLOW}Waarschuwing: het kan zijn dat serverbeheerders tekst niet kunnen lezen die hier wordt ingevoerd. # On screen keyboard window STR_OSK_KEYBOARD_LAYOUT :`1234567890-=\qwertyuiop[]asdfghjkl;' zxcvbnm,./ . @@ -338,6 +339,7 @@ STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN :{BLACK}Inzoomen STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT :{BLACK}Uitzoomen STR_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Spoorwegen bouwen STR_TOOLBAR_TOOLTIP_BUILD_ROADS :{BLACK}Wegen bouwen +STR_TOOLBAR_TOOLTIP_BUILD_TRAMWAYS :{BLACK}Tramsporen bouwen STR_TOOLBAR_TOOLTIP_BUILD_SHIP_DOCKS :{BLACK}Dokken en havens bouwen STR_TOOLBAR_TOOLTIP_BUILD_AIRPORTS :{BLACK}Vliegvelden bouwen STR_TOOLBAR_TOOLTIP_LANDSCAPING :{BLACK}Hiermee open je de landschapsbalk om land te verhogen/verlagen, bomen te planten, enz. @@ -358,6 +360,7 @@ STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION :{BLACK}Landscha STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Stadsontwikkeling 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_PLACE_SIGN :{BLACK}Bord plaatsen STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Object plaatsen. Shift schakelt tussen bouwen/inschatting van de kosten @@ -475,9 +478,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Console in-uitschakelen STR_ABOUT_MENU_AI_DEBUG :Probleemoplossing AI/spelscript STR_ABOUT_MENU_SCREENSHOT :Schermfoto -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Ingezoomde schermfoto -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Schermfoto met standaardzoom -STR_ABOUT_MENU_GIANT_SCREENSHOT :Schermfoto van de hele kaart STR_ABOUT_MENU_SHOW_FRAMERATE :Framesnelheid weergeven STR_ABOUT_MENU_ABOUT_OPENTTD :Over 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Sprite-uitlijner @@ -648,9 +648,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Aangepast 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Muziekvolume STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Effectenvolume -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}MIN -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}MAX -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -867,6 +864,8 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}Nieuw {STRING} nu beschikbaar! - {ENGINE} +STR_NEWS_SHOW_VEHICLE_GROUP_TOOLTIP :{BLACK}Groepsvenster openen met focus op groep van voertuig + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} accepteert geen {STRING} meer STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} accepteert geen {STRING} of {STRING} meer STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} accepteert voortaan {STRING} @@ -933,6 +932,9 @@ STR_GAME_OPTIONS_CURRENCY_GEL :Georgische Lari STR_GAME_OPTIONS_CURRENCY_IRR :Iraanse Rial (IRR) STR_GAME_OPTIONS_CURRENCY_RUB :Nieuwe Russische Roebel (RUB) STR_GAME_OPTIONS_CURRENCY_MXN :Mexicaanse peso (MXN) +STR_GAME_OPTIONS_CURRENCY_NTD :Nieuwe Taiwanse dollar (NTD) +STR_GAME_OPTIONS_CURRENCY_CNY :Chinese Renminbi (CNY) +STR_GAME_OPTIONS_CURRENCY_HKD :Hong Kong Dollar (HKD) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Wegvoertuigen @@ -1184,6 +1186,8 @@ STR_CONFIG_SETTING_AUTOSLOPE :Omgeving aanpas STR_CONFIG_SETTING_AUTOSLOPE_HELPTEXT :Staat het aanpassen van funderingen onder gebouwen en sporen toe zonder deze te verwijderen STR_CONFIG_SETTING_CATCHMENT :Meer realistische verzorgingsgebieden toestaan: {STRING} 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_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. STR_CONFIG_SETTING_TRAIN_LENGTH :Maximale lengte van treinen: {STRING} @@ -1201,7 +1205,7 @@ STR_CONFIG_SETTING_PERCENTAGE :{COMMA}% STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS :Hellingsteilheid voor wegvoertuigen: {STRING} STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS_HELPTEXT :Steilheid van een schuine tegel voor een wegvoertuig. Hogere waarden maken het moeilijker om een heuvel te beklimmen STR_CONFIG_SETTING_FORBID_90_DEG :Treinen en schepen mogen niet 90° draaien: {STRING} -STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :Draaiingen met 90° treden op wanneer een horizontale baan direct gevolgd wordt door een verticaal baanstuk op de aangrenzende tegel, waardoor de trein daarna 90 graden draait wanneer de tegelrand wordt overgestoken in plaats van de gebruikelijke 45 graden voor andere spoorcombinaties. Dit geldt ook voor de draaicirkel van schepen +STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :Draaiingen met 90° treden op wanneer een horizontale baan direct gevolgd wordt door een verticaal baanstuk op de aangrenzende tegel, waardoor de trein daarna 90 graden draait wanneer de tegelrand wordt overgestoken in plaats van de gebruikelijke 45 graden voor andere spoorcombinaties. STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS :Samenvoegen van indirect aansluitende stations toestaan: {STRING} STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS_HELPTEXT :Staat toe dat er aanvullende onderdelen aan een station worden geplaatst zonder dat reeds bestaande onderdelen beïnvloed worden. Ctrl+klik is vereist tijdens het plaatsen van nieuwe onderdelen. STR_CONFIG_SETTING_INFLATION :Inflatie: {STRING} @@ -1258,7 +1262,7 @@ STR_CONFIG_SETTING_PLANE_SPEED_HELPTEXT :Stel de relatie STR_CONFIG_SETTING_PLANE_SPEED_VALUE :1 / {COMMA} STR_CONFIG_SETTING_PLANE_CRASHES :Aantal neerstortende vliegtuigen: {STRING} STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Bepaalt de kans op neerstorten van een vliegtuig -STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Geen +STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Geen* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Verminderd STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normaal STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Haltes plaatsen op door stad beheerde wegen toestaan: {STRING} @@ -1305,6 +1309,8 @@ STR_CONFIG_SETTING_POPULATION_IN_LABEL :Inwoneraantal b STR_CONFIG_SETTING_POPULATION_IN_LABEL_HELPTEXT :Aantal inwoners van een stad weergeven bij naam op de kaart STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS :Dikte van de lijnen in grafieken: {STRING} STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Breedte van de lijnen in de grafiek. Een dunne lijn is preciezer leesbaar, een dikke lijn is makkelijker te zien en kleuren zijn makkelijker om te onderscheiden +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_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. @@ -1481,6 +1487,9 @@ STR_CONFIG_SETTING_AI_IN_MULTIPLAYER :Computerspelers STR_CONFIG_SETTING_AI_IN_MULTIPLAYER_HELPTEXT :Computerspelers toestaan in netwerkspellen STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES :Aantal opcodes voordat scripts worden gestopt: {STRING} STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES_HELPTEXT :Maximumaantal berekeningsstappen die een script kan maken in een beurt +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY :Max. geheugengebruik per script: {STRING} +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_HELPTEXT :De hoeveelheid geheugen die een script mag gebruiken voordat het geforceerd wordt beëindigd. Voor grote kaarten moet deze waarde misschien verhoogd worden. +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 @@ -1539,10 +1548,16 @@ STR_CONFIG_SETTING_NEWS_MESSAGES_FULL :Volledig STR_CONFIG_SETTING_COLOURED_NEWS_YEAR :Kleurenfoto's verschijnen in: {STRING} STR_CONFIG_SETTING_COLOURED_NEWS_YEAR_HELPTEXT :Jaar dat de krant aankondigt in kleur te gaan afdrukken. Voor dit jaar wordt zwart-wit gebruikt STR_CONFIG_SETTING_STARTING_YEAR :Startjaar: {STRING} +STR_CONFIG_SETTING_ENDING_YEAR :Eindjaar voor score: {STRING} +STR_CONFIG_SETTING_ENDING_YEAR_HELPTEXT :Jaar dat het spel eindigt ten behoeve van de score. Aan het einde van dit jaar wordt de score van het bedrijf vastgelegd en verschijnt het venster met topscores. De spelers kunnen echter doorgaan met spelen.{}Als dit voor het startjaar ligt, verschijnt het venster met topscores niet. +STR_CONFIG_SETTING_ENDING_YEAR_VALUE :{NUM} +STR_CONFIG_SETTING_ENDING_YEAR_ZERO :Nooit STR_CONFIG_SETTING_SMOOTH_ECONOMY :Vloeiende economie inschakelen (meer, kleinere veranderingen): {STRING} STR_CONFIG_SETTING_SMOOTH_ECONOMY_HELPTEXT :Wanneer dit is ingeschakeld, verandert de productie van industrieën vaker en in kleinere stappen. Deze instelling heeft meestal geen effect als de industriesoorten worden geleverd door een NewGRF. STR_CONFIG_SETTING_ALLOW_SHARES :Kopen van aandelen in andere bedrijven toestaan: {STRING} STR_CONFIG_SETTING_ALLOW_SHARES_HELPTEXT :Wanneer ingeschakeld is het toegestaan om bedrijfsaandelen te kopen en te verkopen. Aandelen zullen alleen beschikbaar zijn voor bedrijven die een bepaalde leeftijd hebben bereikt +STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES :Minimale leeftijd van bedrijf om aandelen te kunnen verhandelen: {STRING} +STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES_HELPTEXT :Hiermee wordt de minimale leeftijd van een bedrijf ingesteld waarna anderen aandelen in dat bedrijf kunnen gaan kopen en verkopen. STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE :Percentage van routeopbrengst in overdrachtssysteem: {STRING} STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE_HELPTEXT :Percentage van het inkomen besteed aan de intermediaire delen in feedersystemen waardoor er meer controle over de inkomsten is STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY :Bij slepen, seinen plaatsen om de: {STRING} @@ -1583,6 +1598,10 @@ STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :Wanneer deze in STR_CONFIG_SETTING_TOWN_FOUNDING_FORBIDDEN :Verboden STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED :Toestaan STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED_CUSTOM_LAYOUT :Toestaan, eigen wegpatroon +STR_CONFIG_SETTING_TOWN_CARGOGENMODE :Genereren van vracht in steden: {STRING} +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_HELPTEXT :Hoeveel vracht wordt geproduceerd door huizen in steden, in relatie tot de totale bevolking van de stad.{}Kwadratische groei: een stad die twee keer zo groot is, genereert vier keer zo veel passagiers.{}Lineaire groei: een stad die twee keer zo groot is, genereert twee keer zo veel passagiers. +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_ORIGINAL :Kwadratisch (origineel) +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_BITCOUNT :Lineair STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :Plaatsing van bomen in het spel: {STRING} STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :Beheert het willekeurig verschijnen van bomen tijdens het spel. Dit kan gevolgen hebben voor industrietakken die afhankelijk zijn van groei van bomen, bijvoorbeeld houtzagerijen. @@ -1710,7 +1729,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Vrachtd STR_CONFIG_SETTING_AI :{ORANGE}Tegenstanders STR_CONFIG_SETTING_AI_NPC :{ORANGE}Computerspelers -STR_CONFIG_SETTING_PATHFINDER_OPF :Origineel STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Aanbevolen) @@ -1794,13 +1812,9 @@ STR_QUIT_NO :{BLACK}Nee # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -1860,7 +1874,7 @@ STR_LIVERY_PASSENGER_SHIP :Passagiersschip STR_LIVERY_FREIGHT_SHIP :Vrachtschip STR_LIVERY_HELICOPTER :Helikopter STR_LIVERY_SMALL_PLANE :Klein vliegtuig -STR_LIVERY_LARGE_PLANE :Groot Vliegtuig +STR_LIVERY_LARGE_PLANE :Groot vliegtuig STR_LIVERY_PASSENGER_TRAM :Passagierstram STR_LIVERY_FREIGHT_TRAM :Vrachttram @@ -2138,7 +2152,7 @@ STR_NETWORK_CHAT_ALL :[Iedereen] {STR STR_NETWORK_CHAT_OSKTITLE :{BLACK}Geef tekst voor netwerkchat # Network messages -STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}Geen netwerkapparaten gevonden of gecompileerd zonder ENABLE_NETWORK +STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}Geen netwerkapparaten gevonden STR_NETWORK_ERROR_NOSERVER :{WHITE}Kon geen enkel netwerkspel vinden STR_NETWORK_ERROR_NOCONNECTION :{WHITE}De server beantwoordde het verzoek niet STR_NETWORK_ERROR_NEWGRF_MISMATCH :{WHITE}Kan geen verbinding maken, je hebt niet dezelfde NewGRF-bestanden als de server @@ -2412,7 +2426,7 @@ STR_BRIDGE_TUBULAR_SILICON :Buis, silicium # Road construction toolbar STR_ROAD_TOOLBAR_ROAD_CONSTRUCTION_CAPTION :{WHITE}Wegen bouwen -STR_ROAD_TOOLBAR_TRAM_CONSTRUCTION_CAPTION :{WHITE}Bouw tramsporen +STR_ROAD_TOOLBAR_TRAM_CONSTRUCTION_CAPTION :{WHITE}Tramsporen bouwen STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_SECTION :{BLACK}Weg bouwen. Ctrl schakelt tussen bouwen/verwijderen van de weg. Shift schakelt tussen bouwen/inschatting van de kosten. STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION :{BLACK}Bouw tramsporen. Ctrl schakelt tussen bouwen/verwijderen van tramsporen. Shift schakelt tussen bouwen/inschatting van de kosten STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOROAD :{BLACK}Wegen bouwen met de automatische methode. Ctrl schakelt tussen bouwen/verwijderen van de weg. Shift schakelt tussen bouwen/inschatting van de kosten. @@ -2430,6 +2444,11 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL :{BLACK}Wegtunne 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_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. + +STR_ROAD_NAME_ROAD :Weg +STR_ROAD_NAME_TRAM :Tramspoor # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Richting van garage @@ -2614,8 +2633,11 @@ STR_LAND_AREA_INFORMATION_NEWGRF_NAME :{BLACK}NewGRF: STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED :{BLACK}Geaccepteerde vracht: {LTBLUE} STR_LAND_AREA_INFORMATION_CARGO_EIGHTS :({COMMA}/8 {STRING}) STR_LANG_AREA_INFORMATION_RAIL_TYPE :{BLACK}Spoortype: {LTBLUE}{STRING} +STR_LANG_AREA_INFORMATION_ROAD_TYPE :{BLACK}Wegtype: {LTBLUE}{STRING} +STR_LANG_AREA_INFORMATION_TRAM_TYPE :{BLACK}Tramtype: {LTBLUE}{STRING} STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT :{BLACK}Spoorsnelheidslimiet: {LTBLUE}{VELOCITY} STR_LANG_AREA_INFORMATION_ROAD_SPEED_LIMIT :{BLACK}Snelheidslimiet weg: {LTBLUE}{VELOCITY} +STR_LANG_AREA_INFORMATION_TRAM_SPEED_LIMIT :{BLACK}Tramsnelheidslimiet: {LTBLUE}{VELOCITY} # Description of land area of different tiles STR_LAI_CLEAR_DESCRIPTION_ROCKS :Rotsen @@ -2725,6 +2747,7 @@ STR_FRAMERATE_SPEED_FACTOR :{BLACK}Huidige STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}Hoe snel het spel momenteel draait, vergeleken met de verwachte snelheid bij een normale simulatiesnelheid. STR_FRAMERATE_CURRENT :{WHITE}Huidig STR_FRAMERATE_AVERAGE :{WHITE}Gemiddeld +STR_FRAMERATE_MEMORYUSE :{WHITE}Geheugen STR_FRAMERATE_DATA_POINTS :{BLACK}Gegevens gebaseerd op {COMMA} metingen STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL} ms STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL} ms @@ -2732,6 +2755,9 @@ STR_FRAMERATE_MS_BAD :{RED}{DECIMAL} STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL} frames/s STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL} frames/s STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL} frames/s +STR_FRAMERATE_BYTES_GOOD :{LTBLUE}{BYTES} +STR_FRAMERATE_BYTES_WARN :{YELLOW}{BYTES} +STR_FRAMERATE_BYTES_BAD :{RED}{BYTES} STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} ms STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} s ############ Leave those lines in this order!! @@ -2856,7 +2882,7 @@ STR_SE_MAPGEN_FLAT_WORLD_HEIGHT_QUERY_CAPT :{WHITE}Verander # Map generation progress STR_GENERATION_WORLD :{WHITE}Bezig met wereldontwikkeling... STR_GENERATION_ABORT :{BLACK}Stop -STR_GENERATION_ABORT_CAPTION :{WHITE}Stop Wereldontwikkeling +STR_GENERATION_ABORT_CAPTION :{WHITE}Wereldontwikkeling stoppen STR_GENERATION_ABORT_MESSAGE :{YELLOW}Weet je zeker dat je de actie wilt stoppen? STR_GENERATION_PROGRESS :{WHITE}{NUM}% compleet STR_GENERATION_PROGRESS_NUM :{BLACK}{NUM} / {NUM} @@ -3098,6 +3124,8 @@ STR_TOWN_VIEW_RENAME_TOWN_BUTTON :Plaats hernoeme # Town local authority window STR_LOCAL_AUTHORITY_CAPTION :{WHITE} Gemeenteraad van {TOWN} +STR_LOCAL_AUTHORITY_ZONE :{BLACK}Zone +STR_LOCAL_AUTHORITY_ZONE_TOOLTIP :{BLACK}Zone weergeven binnen de gemeentegrenzen STR_LOCAL_AUTHORITY_COMPANY_RATINGS :{BLACK}Reputatie van transportbedrijven: STR_LOCAL_AUTHORITY_COMPANY_RATING :{YELLOW}{COMPANY} {COMPANY_NUM}: {ORANGE}{STRING} STR_LOCAL_AUTHORITY_ACTIONS_TITLE :{BLACK}Beschikbare acties: @@ -3117,7 +3145,7 @@ STR_LOCAL_AUTHORITY_ACTION_BRIBE :Gemeentebestuur STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}Begin een kleine reclamecampagne om meer passagiers en vracht naar jouw transportdiensten te trekken.{}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.{}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.{}Kosten: {CURRENCY_LONG} -STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{YELLOW}Financier een herstelling van het wegennetwerk. Veroorzaakt tot 6 maanden lang een aanzienlijke verstoring van het wegverkeer.{}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.{}Kosten: {CURRENCY_LONG} STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{YELLOW}De bouw van nieuwe commerciële gebouwen in de stad financieren.{}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} @@ -3355,8 +3383,7 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Infrastr STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Spoordelen: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Seinen STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Wegdelen: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Weg -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Tramsporen +STR_COMPANY_INFRASTRUCTURE_VIEW_TRAM_SECT :{GOLD}Tramdelen: STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Watertegels: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Kanalen STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Stations: @@ -3367,15 +3394,22 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Industrielijst STR_INDUSTRY_DIRECTORY_NONE :{ORANGE} Geen -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% vervoerd) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% vervoerd) +STR_INDUSTRY_DIRECTORY_ITEM_INFO :{BLACK}{CARGO_LONG}{STRING}{YELLOW} ({COMMA}% vervoerd){BLACK} STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} +STR_INDUSTRY_DIRECTORY_ITEM_PROD1 :{ORANGE}{INDUSTRY} {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PROD2 :{ORANGE}{INDUSTRY} {STRING}, {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PROD3 :{ORANGE}{INDUSTRY} {STRING}, {STRING}, {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PRODMORE :{ORANGE}{INDUSTRY} {STRING}, {STRING}, {STRING} en {NUM} meer... STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Industrienamen - klik op een naam om het scherm te centreren op de industrie. Ctrl+klik opent een nieuw venster op de locatie van de industrie. +STR_INDUSTRY_DIRECTORY_ACCEPTED_CARGO_FILTER :{BLACK}Geaccepteerde vracht: {SILVER}{STRING} +STR_INDUSTRY_DIRECTORY_PRODUCED_CARGO_FILTER :{BLACK}Geproduceerde vracht: {SILVER}{STRING} +STR_INDUSTRY_DIRECTORY_FILTER_ALL_TYPES :Alle soorten vracht +STR_INDUSTRY_DIRECTORY_FILTER_NONE :Geen # Industry view STR_INDUSTRY_VIEW_CAPTION :{WHITE}{INDUSTRY} STR_INDUSTRY_VIEW_PRODUCTION_LAST_MONTH_TITLE :{BLACK}Productie vorige maand: -STR_INDUSTRY_VIEW_TRANSPORTED :{YELLOW}{CARGO_LONG}{STRING}{BLACK} ({COMMA}% getransporteerd) +STR_INDUSTRY_VIEW_TRANSPORTED :{YELLOW}{CARGO_LONG}{STRING}{BLACK} ({COMMA}% vervoerd) STR_INDUSTRY_VIEW_LOCATION_TOOLTIP :{BLACK}Centreer het scherm op de locatie van de industrie. Ctrl+klik opent een nieuws venster op de locatie van de industrie STR_INDUSTRY_VIEW_PRODUCTION_LEVEL :{BLACK}Productieniveau: {YELLOW}{COMMA}% STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE :{YELLOW}De industrie heeft een dreigende sluiting aangekondigd! @@ -3436,6 +3470,8 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Niet-gegroepeer STR_GROUP_DEFAULT_SHIPS :Niet-gegroepeerde schepen STR_GROUP_DEFAULT_AIRCRAFTS :Niet-gegroepeerde vliegtuigen +STR_GROUP_COUNT_WITH_SUBGROUP :{TINY_FONT}{COMMA} (+{COMMA}) + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Groepen - Klik op een groep voor een lijst van alle voertuigen in deze groep. Klik en sleep om hiërarchie te beheren STR_GROUP_CREATE_TOOLTIP :{BLACK}Klik om een groep te creëren STR_GROUP_DELETE_TOOLTIP :{BLACK}Verwijder de geselecteerde groep @@ -3462,12 +3498,18 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Nieuwe elektris STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Nieuwe monorailvoertuigen STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Nieuwe zweefspoorvoertuigen -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Nieuwe spoorvoertuigen STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Nieuwe wegvoertuigen +STR_BUY_VEHICLE_TRAM_VEHICLE_CAPTION :Nieuwe trams + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Nieuwe spoorvoertuigen +STR_BUY_VEHICLE_ROAD_VEHICLE_ALL_CAPTION :Nieuwe wegvoertuigen STR_BUY_VEHICLE_SHIP_CAPTION :Nieuwe schepen STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Nieuwe vliegtuigen +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Kosten: {GOLD}{CURRENCY_LONG}{BLACK} Gewicht: {GOLD}{WEIGHT_SHORT} +STR_PURCHASE_INFO_COST_REFIT_WEIGHT :{BLACK}Kosten: {GOLD}{CURRENCY_LONG}{BLACK} (ombouwkosten: {GOLD}{CURRENCY_LONG}{BLACK}) Gewicht: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Snelheid: {GOLD}{VELOCITY}{BLACK} Vermogen: {GOLD}{POWER} STR_PURCHASE_INFO_SPEED :{BLACK}Snelheid: {GOLD}{VELOCITY} STR_PURCHASE_INFO_SPEED_OCEAN :{BLACK}Snelheid op oceaan: {GOLD}{VELOCITY} @@ -3478,8 +3520,10 @@ STR_PURCHASE_INFO_REFITTABLE :(ombouwbaar) STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Ontworpen: {GOLD}{NUM}{BLACK} Levensduur: {GOLD}{COMMA} jaar STR_PURCHASE_INFO_RELIABILITY :{BLACK}Max. betrouwbaarheid: {GOLD}{COMMA}% STR_PURCHASE_INFO_COST :{BLACK}Kosten: {GOLD}{CURRENCY_LONG} +STR_PURCHASE_INFO_COST_REFIT :{BLACK}Kosten: {GOLD}{CURRENCY_LONG}{BLACK} (ombouwkosten: {GOLD}{CURRENCY_LONG}{BLACK}) STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Gewicht: {GOLD}{WEIGHT_SHORT} ({WEIGHT_SHORT}) STR_PURCHASE_INFO_COST_SPEED :{BLACK}Kosten: {GOLD}{CURRENCY_LONG}{BLACK} Snelheid: {GOLD}{VELOCITY} +STR_PURCHASE_INFO_COST_REFIT_SPEED :{BLACK}Kosten: {GOLD}{CURRENCY_LONG}{BLACK} (ombouwkosten: {GOLD}{CURRENCY_LONG}{BLACK}) Snelheid: {GOLD}{VELOCITY} STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Capaciteit: {GOLD}{CARGO_LONG}, {CARGO_LONG} STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Aangedreven wagons: {GOLD}+{POWER}{BLACK} Gewicht: {GOLD}+{WEIGHT_SHORT} STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Om te bouwen naar: {GOLD}{STRING} @@ -3500,11 +3544,21 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Wegvoert STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Schip kopen STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Vliegtuig kopen +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Voertuig kopen en ombouwen +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Voertuig kopen en ombouwen +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Schip kopen en ombouwen +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Vliegtuig kopen en ombouwen + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Geselecteerd spoorvoertuig bouwen. Shift+klik geeft de verwachte kosten zonder te kopen. STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Koop het geselecteerde wegvoertuig. Shift+klik geeft de verwachte kosten zonder te kopen. STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Koop het geselecteerde schip. Shift+klik geeft de verwachte kosten zonder te kopen STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Koop het geselecteerde vliegtuig. Shift+klik geeft de verwachte kosten zonder te kopen. +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Koop de geselecteerde trein en bouw hem om. Shift+klik geeft de verwachte kosten zonder te kopen. +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Koop het geselecteerde wegvoertuig en bouw het om. Shift+klik geeft de geschatte kosten zonder te kopen. +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Koop het geselecteerde schip en bouw het om. Shift+klik geeft de verwachte kosten zonder te kopen. +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Koop het geselecteerde vliegtuig en bouw het om. Shift+klik geeft de verwachte kosten zonder te kopen. + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Hernoemen STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Hernoemen STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Hernoemen @@ -3613,13 +3667,18 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Je staa # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Bericht van voertuigenfabrikant STR_ENGINE_PREVIEW_MESSAGE :{GOLD}We hebben zojuist een nieuwe {STRING} ontworpen - ben je geïnteresseerd in een jaar lang exclusief gebruik van dit voertuig, zodat we kunnen zien of het goed werkt voordat we het wereldwijd beschikbaar maken? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :spoorlocomotief -STR_ENGINE_PREVIEW_ROAD_VEHICLE :wegvoertuig -STR_ENGINE_PREVIEW_AIRCRAFT :vliegtuig -STR_ENGINE_PREVIEW_SHIP :schip +STR_ENGINE_PREVIEW_ELRAIL_LOCOMOTIVE :elektrische locomotief STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :monoraillocomotief STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :zweeflocomotief +STR_ENGINE_PREVIEW_ROAD_VEHICLE :wegvoertuig +STR_ENGINE_PREVIEW_TRAM_VEHICLE :tram + +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_MAX_SPEED_CAP_RUNCOST :{BLACK}Kosten: {CURRENCY_LONG} Max.snelheid: {VELOCITY}{}Capaciteit: {CARGO_LONG}{}Gebruikskosten: {CURRENCY_LONG}/jaar @@ -3657,14 +3716,19 @@ STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK}Wissel t STR_REPLACE_ENGINES :Motoren STR_REPLACE_WAGONS :Wagons STR_REPLACE_ALL_RAILTYPE :Alle treinen +STR_REPLACE_ALL_ROADTYPE :Alle wegvoertuigen 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_REPLACE_INFO_TAB :{BLACK}Dit geeft weer waarmee de links geselecteerde locomotief vervangen wordt STR_REPLACE_RAIL_VEHICLES :Spoorvoertuigen STR_REPLACE_ELRAIL_VEHICLES :Elektrische spoorvoertuigen STR_REPLACE_MONORAIL_VEHICLES :Monorailvoertuigen STR_REPLACE_MAGLEV_VEHICLES :Magneetzweefspoorvoertuigen +STR_REPLACE_ROAD_VEHICLES :Wegvoertuigen +STR_REPLACE_TRAM_VEHICLES :Trams + STR_REPLACE_REMOVE_WAGON :{BLACK}Wagons verwijderen: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}De te vervangen trein behoudt zijn lengte door wagons weg te halen (startend aan de voorkant), als het vervangen de trein langer zou maken @@ -4023,7 +4087,7 @@ STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Verander STR_TIMETABLE_CLEAR_TIME :{BLACK}Tijd wissen STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Verwijder de tijdsduur die de geselecteerde order mag duren -STR_TIMETABLE_CHANGE_SPEED :{BLACK}Wijzig Maximumsnelheid +STR_TIMETABLE_CHANGE_SPEED :{BLACK}Maximumsnelheid wijzigen STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Wijzig de maximumsnelheid voor de gekozen order STR_TIMETABLE_CLEAR_SPEED :{BLACK}Snelheidslimiet wissen @@ -4115,6 +4179,14 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Gemarkee STR_AI_LIST_CANCEL :{BLACK}Annuleren STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Script niet wijzigen +STR_SCREENSHOT_CAPTION :{WHITE}Een schermafbeelding maken +STR_SCREENSHOT_SCREENSHOT :{BLACK}Normale schermafbeelding +STR_SCREENSHOT_ZOOMIN_SCREENSHOT :{BLACK}Volledig ingezoomde schermafbeelding +STR_SCREENSHOT_DEFAULTZOOM_SCREENSHOT :{BLACK}Standaard gezoomde schermafbeelding +STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Schermafbeelding van de hele kaart +STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Schermafbeelding van de hoogtekaart +STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Schermafbeelding van de minikaart + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parameters STR_AI_SETTINGS_CAPTION_AI :AI @@ -4317,7 +4389,6 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... deze STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... weg is in de verkeerde richting STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... doorrij haltes kunnen geen bochten hebben STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... doorrij haltes kunnen geen kruisingen hebben -STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... weg is eenrichtingsverkeer of geblokkeerd # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Kan deel van station niet verwijderen... @@ -4387,7 +4458,8 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Verwijde STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Geen bruikbaar spoor STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Moet spoor eerst verwijderen STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Weg is eenrichtingsverkeer of geblokkeerd -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Gelijkvloerse kruisingen zijn niet toegestaan voor dit type spoor +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Gelijkvloerse kruisingen zijn niet toegestaan voor dit type spoor +STR_ERROR_CROSSING_DISALLOWED_ROAD :{WHITE}Gelijkvloerse kruisingen zijn niet toegestaan voor dit type weg STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Kan hier geen seinen plaatsen... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Kan hier geen spoor leggen... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Kan hier geen spoor verwijderen... @@ -4407,6 +4479,12 @@ STR_ERROR_CAN_T_REMOVE_ROAD_FROM :{WHITE}Kan hier STR_ERROR_CAN_T_REMOVE_TRAMWAY_FROM :{WHITE}Kan de tramrails hier niet verwijderen... STR_ERROR_THERE_IS_NO_ROAD :{WHITE}...er is geen weg STR_ERROR_THERE_IS_NO_TRAMWAY :{WHITE}...er is geen tramlijn +STR_ERROR_CAN_T_CONVERT_ROAD :{WHITE}Kan wegtype hier niet converteren... +STR_ERROR_CAN_T_CONVERT_TRAMWAY :{WHITE}Kan tramtype hier niet converteren... +STR_ERROR_NO_SUITABLE_ROAD :{WHITE}Geen geschikte weg +STR_ERROR_NO_SUITABLE_TRAMWAY :{WHITE}Geen geschikt tramspoor +STR_ERROR_INCOMPATIBLE_ROAD :{WHITE}... weg niet geschikt +STR_ERROR_INCOMPATIBLE_TRAMWAY :{WHITE}... treinspoor niet geschikt # Waterway construction errors STR_ERROR_CAN_T_BUILD_CANALS :{WHITE}Kan hier geen kanaal bouwen... @@ -4459,6 +4537,7 @@ STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Kan groe STR_ERROR_GROUP_CAN_T_DELETE :{WHITE}Kan deze groep niet verwijderen... STR_ERROR_GROUP_CAN_T_RENAME :{WHITE}Kan deze groep niet hernoemen... STR_ERROR_GROUP_CAN_T_SET_PARENT :{WHITE}Kan huidige groep niet instellen... +STR_ERROR_GROUP_CAN_T_SET_PARENT_RECURSION :{WHITE}... lussen in de groepshiërarchie zijn niet toegestaan STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}Kan niet alle voertuigen van deze groep verwijderen... STR_ERROR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}Kan niet alle voertuigen aan deze groep toevoegen... STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}Kan niet alle gedeelde voertuigen aan deze groep toevoegen... @@ -5068,41 +5147,3 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) - -# Android strings -STR_ABOUT_MENU_TUTORIAL :{BLACK}Studieles -STR_SMALLMAP_TOOLTIP_SHOW_LEGEND :{BLACK}Kaartlegenda weergeven / beschrijving van kaartpictogrammen -STR_CONFIG_SETTING_VERTICAL_TOOLBAR :Verticale werkbalk: {STRING} -STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :De hoofdwerkbalk is onderverdeeld in twee verticale werkbalken aan de zijkanten van het scherm -STR_CONFIG_SETTING_COMPACT_VERTICAL_TOOLBAR :Compacte verticale werkblak: {STRING} -STR_CONFIG_SETTING_COMPACT_VERTICAL_TOOLBAR_HELPTEXT :Geen knop 'Werkbalk wisselen' in de verticale werkbalk, maar meer submenu's -STR_CONFIG_SETTING_BUTTON_SIZE :{BLACK}Knopgrootte -STR_CONFIG_SETTING_BUTTON_SIZE_TOOLTIP :{BLACK}Grootte van alle bedieningselementen -STR_CONFIG_SETTING_FONT_SIZE :{BLACK}Lettertypegrootte -STR_CONFIG_SETTING_FONT_SIZE_TOOLTIP :{BLACK}Grootte van alle spellettertypen -STR_CONFIG_SETTING_BUILD_CONFIRMATION :Handelingen bevestigen: {STRING} -STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :Bevestigingsdialoogvenster weergeven bij het bouwen van wegen en stations -STR_CONFIG_SETTING_WINDOWS_TITLEBARS :{BLACK}Titelbalken -STR_CONFIG_SETTING_WINDOWS_TITLEBARS_HELPTEXT :{BLACK}Titelbalken op alle vensters weergeven of verbergen om ruimte te besparen -STR_CONFIG_SETTING_WINDOWS_DECORATIONS :Vensterdecoraties: {STRING} -STR_CONFIG_SETTING_WINDOWS_DECORATIONS_HELPTEXT :Versieringen op de vensterranden -STR_CONFIG_SETTING_VIDEO_8BPP :{BLACK}8 bits -STR_CONFIG_SETTING_VIDEO_8BPP_HELPTEXT :{BLACK}Stel de video-kleurdiepte in op 8 bits per pixel, deze videomodus ondersteunt bewegend water -STR_CONFIG_SETTING_VIDEO_16BPP :{BLACK}16 bits -STR_CONFIG_SETTING_VIDEO_16BPP_HELPTEXT :{BLACK}Stel de video-kleurdiepte in op 16 bits per pixel, herstart noodzakelijk, deze videomodus ondersteunt geen bewegend water -STR_CONFIG_SETTING_VIDEO_24BPP :{BLACK}24 bits -STR_CONFIG_SETTING_VIDEO_24BPP_HELPTEXT :{BLACK}Stel de video-kleurdiepte in op 24 bits per pixel, deze videomodus ondersteunt bewegend water -STR_TABLET_CLOSE_TOOLTIP :{BLACK}Alle open vensters sluiten (behalve vastgezette) -STR_TABLET_SHIFT_TOOLTIP :{BLACK}Druk hierop voor een schatting van de kosten van een handeling -STR_TABLET_CTRL_TOOLTIP :{BLACK}Gebruik dit voor handelingen waarvoor de toets 'CTRL' wordt gebruikt -STR_TUTORIAL_WINDOW_TITLE :{BLACK}Studievideo's -STR_TUTORIAL_WINDOW_TOOLTIP :{BLACK}Een videospeler openen om studievideo's te bekijken -STR_TUTORIAL_ROADS_AND_STATIONS :{BLACK}Wegen en stations bouwen, voertuigen kopen -STR_TUTORIAL_RAILWAYS :{BLACK}Spoorwegen en treinen -STR_TUTORIAL_ROAD_VEHICLES :{BLACK}Wegvoertuigen -STR_TUTORIAL_SHIPS :{BLACK}Schepen en dokken -STR_TUTORIAL_CARGO :{BLACK}Typen vracht -STR_SAVELOAD_LOAD_NETWORK_BUTTON :{BLACK}Laden vanaf netwerk -STR_SAVELOAD_LOAD_NETWORK_TOOLTIP :{BLACK}Een spel laden uit de netwerkopslag -STR_SAVELOAD_SAVE_NETWORK_BUTTON :{BLACK}Opslaan naar netwerk -STR_SAVELOAD_SAVE_NETWORK_TOOLTIP :{BLACK}Reservekopie van het spel maken op de netwerkopslag diff --git a/src/lang/english.txt b/src/lang/english.txt index 5cf249d458..577d1527b0 100644 --- a/src/lang/english.txt +++ b/src/lang/english.txt @@ -10,8 +10,6 @@ ##grflangid 0x01 -# $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. # 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. @@ -237,6 +235,8 @@ STR_TOOLTIP_FILTER_CRITERIA :{BLACK}Select f STR_BUTTON_SORT_BY :{BLACK}Sort by STR_BUTTON_LOCATION :{BLACK}Location STR_BUTTON_RENAME :{BLACK}Rename +STR_BUTTON_CATCHMENT :{BLACK}Coverage +STR_TOOLTIP_CATCHMENT :{BLACK}Toggle coverage area display STR_TOOLTIP_CLOSE_WINDOW :{BLACK}Close window STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Window title - drag this to move window @@ -265,6 +265,7 @@ STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT_TOOLTIP :{BLACK}By enabl STR_BUTTON_DEFAULT :{BLACK}Default STR_BUTTON_CANCEL :{BLACK}Cancel STR_BUTTON_OK :{BLACK}OK +STR_WARNING_PASSWORD_SECURITY :{YELLOW}Warning: Server administrators may be able to read any text entered here. # On screen keyboard window STR_OSK_KEYBOARD_LAYOUT :`1234567890-=\qwertyuiop[]asdfghjkl;' zxcvbnm,./ . @@ -338,6 +339,7 @@ STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN :{BLACK}Zoom the STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT :{BLACK}Zoom the view out STR_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Build railway track STR_TOOLBAR_TOOLTIP_BUILD_ROADS :{BLACK}Build roads +STR_TOOLBAR_TOOLTIP_BUILD_TRAMWAYS :{BLACK}Build tramways STR_TOOLBAR_TOOLTIP_BUILD_SHIP_DOCKS :{BLACK}Build ship docks STR_TOOLBAR_TOOLTIP_BUILD_AIRPORTS :{BLACK}Build airports STR_TOOLBAR_TOOLTIP_LANDSCAPING :{BLACK}Open the landscaping toolbar to raise/lower land, plant trees, etc. @@ -358,6 +360,7 @@ STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION :{BLACK}Landscap STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Town generation 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_PLACE_SIGN :{BLACK}Place sign STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Place object. Shift toggles building/showing cost estimate @@ -470,9 +473,6 @@ STR_ABOUT_MENU_TUTORIAL :{BLACK}Tutorial STR_ABOUT_MENU_TOGGLE_CONSOLE :Toggle console STR_ABOUT_MENU_AI_DEBUG :AI/Game script debug STR_ABOUT_MENU_SCREENSHOT :Screenshot -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Fully zoomed in screenshot -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Default zoom screenshot -STR_ABOUT_MENU_GIANT_SCREENSHOT :Whole map screenshot STR_ABOUT_MENU_SHOW_FRAMERATE :Show frame rate STR_ABOUT_MENU_ABOUT_OPENTTD :About 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Sprite aligner @@ -643,9 +643,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Custom 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Music Volume STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Effects Volume -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}MIN -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}MAX -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -863,6 +860,8 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}New {STRING} now available! - {ENGINE} +STR_NEWS_SHOW_VEHICLE_GROUP_TOOLTIP :{BLACK}Open the group window focused on the vehicle's group + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} no longer accepts {STRING} STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} no longer accepts {STRING} or {STRING} STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} now accepts {STRING} @@ -929,6 +928,9 @@ STR_GAME_OPTIONS_CURRENCY_GEL :Georgian Lari ( STR_GAME_OPTIONS_CURRENCY_IRR :Iranian Rial (IRR) STR_GAME_OPTIONS_CURRENCY_RUB :New Russian Ruble (RUB) STR_GAME_OPTIONS_CURRENCY_MXN :Mexican Peso (MXN) +STR_GAME_OPTIONS_CURRENCY_NTD :New Taiwan Dollar (NTD) +STR_GAME_OPTIONS_CURRENCY_CNY :Chinese Renminbi (CNY) +STR_GAME_OPTIONS_CURRENCY_HKD :Hong Kong Dollar (HKD) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Road vehicles @@ -1155,7 +1157,7 @@ STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Maximum amount STR_CONFIG_SETTING_INTEREST_RATE :Interest rate: {STRING2} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Loan interest rate; also controls inflation, if enabled STR_CONFIG_SETTING_RUNNING_COSTS :Running costs: {STRING2} -STR_CONFIG_SETTING_RUNNING_COSTS_HELPTEXT :Set level of maintainance and running costs of vehicles and infrastructure +STR_CONFIG_SETTING_RUNNING_COSTS_HELPTEXT :Set level of maintenance and running costs of vehicles and infrastructure STR_CONFIG_SETTING_CONSTRUCTION_SPEED :Construction speed: {STRING2} STR_CONFIG_SETTING_CONSTRUCTION_SPEED_HELPTEXT :Limit the amount of construction actions for AIs STR_CONFIG_SETTING_VEHICLE_BREAKDOWNS :Vehicle breakdowns: {STRING2} @@ -1180,6 +1182,8 @@ STR_CONFIG_SETTING_AUTOSLOPE :Allow landscapi STR_CONFIG_SETTING_AUTOSLOPE_HELPTEXT :Allow landscaping under buildings and tracks without removing them STR_CONFIG_SETTING_CATCHMENT :Allow more realistically sized catchment areas: {STRING2} STR_CONFIG_SETTING_CATCHMENT_HELPTEXT :Have differently sized catchment areas for different types of stations and airports +STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES :Company stations can serve industries with attached neutral stations: {STRING2} +STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES_HELPTEXT :When enabled, industries with attached stations (such as Oil Rigs) may also be served by company owned stations built nearby. When disabled, these industries may only be served by their attached stations. Any nearby company stations won't be able to serve them, nor will the attached station serve anything else other than the industry STR_CONFIG_SETTING_EXTRADYNAMITE :Allow removal of more town-owned roads, bridges and tunnels: {STRING2} STR_CONFIG_SETTING_EXTRADYNAMITE_HELPTEXT :Make it easier to remove town-owned infrastructure and buildings STR_CONFIG_SETTING_TRAIN_LENGTH :Maximum length of trains: {STRING2} @@ -1196,8 +1200,8 @@ STR_CONFIG_SETTING_TRAIN_SLOPE_STEEPNESS_HELPTEXT :Steepness of a STR_CONFIG_SETTING_PERCENTAGE :{COMMA}% STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS :Slope steepness for road vehicles: {STRING2} STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS_HELPTEXT :Steepness of a sloped tile for a road vehicle. Higher values make it more difficult to climb a hill -STR_CONFIG_SETTING_FORBID_90_DEG :Forbid trains and ships from making 90° turns: {STRING2} -STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :90 degree turns occur when a horizontal track is directly followed by a vertical track piece on the adjacent tile, thus making the train turn by 90 degree when traversing the tile edge instead of the usual 45 degrees for other track combinations. This also applies to the turning radius of ships +STR_CONFIG_SETTING_FORBID_90_DEG :Forbid trains from making 90° turns: {STRING2} +STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :90 degree turns occur when a horizontal track is directly followed by a vertical track piece on the adjacent tile, thus making the train turn by 90 degree when traversing the tile edge instead of the usual 45 degrees for other track combinations. STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS :Allow to join stations not directly adjacent: {STRING2} STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS_HELPTEXT :Allow adding parts to a station without directly touching the existing parts. Needs Ctrl+Click while placing the new parts STR_CONFIG_SETTING_INFLATION :Inflation: {STRING2} @@ -1273,8 +1277,8 @@ STR_CONFIG_SETTING_PLANE_SPEED :Plane speed fac 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 STR_CONFIG_SETTING_PLANE_SPEED_VALUE :1 / {COMMA} STR_CONFIG_SETTING_PLANE_CRASHES :Number of plane crashes: {STRING2} -STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Set the chance of an aircraft crash happening -STR_CONFIG_SETTING_PLANE_CRASHES_NONE :None +STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Set the chance of a random aircraft crash happening.{}* Large airplanes always have a risk of crashing when landing on small airports +STR_CONFIG_SETTING_PLANE_CRASHES_NONE :None* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Reduced STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normal STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Allow drive-through road stops on town owned roads: {STRING2} @@ -1321,6 +1325,8 @@ STR_CONFIG_SETTING_POPULATION_IN_LABEL :Show town popul STR_CONFIG_SETTING_POPULATION_IN_LABEL_HELPTEXT :Display the population of towns in their label on the map STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS :Thickness of lines in graphs: {STRING2} STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Width of the line in the graphs. A thin line is more precisely readable, a thicker line is easier to see and colours are easier to distinguish +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_LANDSCAPE :Landscape: {STRING2} 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 @@ -1332,8 +1338,8 @@ STR_CONFIG_SETTING_TERRAIN_TYPE :Terrain type: { STR_CONFIG_SETTING_TERRAIN_TYPE_HELPTEXT :(TerraGenesis only) Hilliness of the landscape STR_CONFIG_SETTING_INDUSTRY_DENSITY :Industry density: {STRING2} STR_CONFIG_SETTING_INDUSTRY_DENSITY_HELPTEXT :Set how many industries should be generated and what level should be maintained during the game -STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE :Maximum distance from edge for Oil refineries: {STRING2} -STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :Oil refineries are only constructed near the map border, that is at the coast for island maps +STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE :Maximum distance from edge for Oil industries: {STRING2} +STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :Limit for how far from the map border oil refineries and oil rigs can be constructed. On island maps this ensures they are near the coast. On maps larger than 256 tiles, this value is scaled up. STR_CONFIG_SETTING_SNOWLINE_HEIGHT :Snow line height: {STRING2} STR_CONFIG_SETTING_SNOWLINE_HEIGHT_HELPTEXT :Control at what height snow starts in sub-arctic landscape. Snow also affects industry generation and town growth requirements STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN :Roughness of terrain: {STRING2} @@ -1497,6 +1503,9 @@ STR_CONFIG_SETTING_AI_IN_MULTIPLAYER :Allow AIs in mu STR_CONFIG_SETTING_AI_IN_MULTIPLAYER_HELPTEXT :Allow AI computer players to participate in multiplayer games STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES :#opcodes before scripts are suspended: {STRING2} STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES_HELPTEXT :Maximum number of computation steps that a script can take in one turn +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY :Max memory usage per script: {STRING2} +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_HELPTEXT :How much memory a single script may consume before it's forcibly terminated. This may need to be increased for large maps. +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_VALUE :{COMMA} MiB STR_CONFIG_SETTING_SERVINT_ISPERCENT :Service intervals are in percents: {STRING2} STR_CONFIG_SETTING_SERVINT_ISPERCENT_HELPTEXT :Choose whether servicing of vehicles is triggered by the time passed since last service or by reliability dropping by a certain percentage of the maximum reliability @@ -1555,10 +1564,16 @@ STR_CONFIG_SETTING_NEWS_MESSAGES_FULL :Full STR_CONFIG_SETTING_COLOURED_NEWS_YEAR :Coloured news appears in: {STRING2} STR_CONFIG_SETTING_COLOURED_NEWS_YEAR_HELPTEXT :Year that the newspaper announcements get printed in colour. Before this year, it uses monochrome black/white STR_CONFIG_SETTING_STARTING_YEAR :Starting year: {STRING2} +STR_CONFIG_SETTING_ENDING_YEAR :Scoring end year: {STRING2} +STR_CONFIG_SETTING_ENDING_YEAR_HELPTEXT :Year the game ends for scoring purposes. At the end of this year, the company's score is recorded and the high-score screen is displayed, but the players can continue playing after that.{}If this is before the starting year, the high-score screen is never displayed. +STR_CONFIG_SETTING_ENDING_YEAR_VALUE :{NUM} +STR_CONFIG_SETTING_ENDING_YEAR_ZERO :Never STR_CONFIG_SETTING_SMOOTH_ECONOMY :Enable smooth economy (more, smaller changes): {STRING2} STR_CONFIG_SETTING_SMOOTH_ECONOMY_HELPTEXT :When enabled, industry production changes more often, and in smaller steps. This setting has usually no effect, if industry types are provided by a NewGRF STR_CONFIG_SETTING_ALLOW_SHARES :Allow buying shares from other companies: {STRING2} STR_CONFIG_SETTING_ALLOW_SHARES_HELPTEXT :When enabled, allow buying and selling of company shares. Shares will only be available for companies reaching a certain age +STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES :Minimum company age to trade shares: {STRING2} +STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES_HELPTEXT :Set the minimum age of a company for others to be able to buy and sell shares from them. STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE :Percentage of leg profit to pay in feeder systems: {STRING2} STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE_HELPTEXT :Percentage of income given to the intermediate legs in feeder systems, giving more control over the income STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY :When dragging, place signals every: {STRING2} @@ -1599,6 +1614,10 @@ STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :Enabling this s STR_CONFIG_SETTING_TOWN_FOUNDING_FORBIDDEN :Forbidden STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED :Allowed STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED_CUSTOM_LAYOUT :Allowed, custom town layout +STR_CONFIG_SETTING_TOWN_CARGOGENMODE :Town cargo generation: {STRING2} +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_HELPTEXT :How much cargo is produced by houses in towns, relative to the overall population of the town.{}Quadratic growth: A town twice the size generates four times as many passengers.{}Linear growth: A town twice the size generates twice the amount of passengers. +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_ORIGINAL :Quadratic (original) +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_BITCOUNT :Linear STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :In game placement of trees: {STRING2} STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :Control random appearance of trees during the game. This might affect industries which rely on tree growth, for example lumber mills @@ -1726,7 +1745,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Cargo d STR_CONFIG_SETTING_AI :{ORANGE}Competitors STR_CONFIG_SETTING_AI_NPC :{ORANGE}Computer players -STR_CONFIG_SETTING_PATHFINDER_OPF :Original STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Recommended) @@ -1810,13 +1828,9 @@ STR_QUIT_NO :{BLACK}No # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -2154,7 +2168,7 @@ STR_NETWORK_CHAT_ALL :[All] {RAW_STRI STR_NETWORK_CHAT_OSKTITLE :{BLACK}Enter text for network chat # Network messages -STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}No network devices found or compiled without ENABLE_NETWORK +STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}No network devices found STR_NETWORK_ERROR_NOSERVER :{WHITE}Could not find any network games STR_NETWORK_ERROR_NOCONNECTION :{WHITE}The server didn't answer the request STR_NETWORK_ERROR_NEWGRF_MISMATCH :{WHITE}Could not connect due to NewGRF mismatch @@ -2170,6 +2184,7 @@ STR_NETWORK_ERROR_WRONG_PASSWORD :{WHITE}Wrong pa STR_NETWORK_ERROR_SERVER_FULL :{WHITE}The server is full STR_NETWORK_ERROR_SERVER_BANNED :{WHITE}You are banned from this server STR_NETWORK_ERROR_KICKED :{WHITE}You were kicked out of the game +STR_NETWORK_ERROR_KICK_MESSAGE :{WHITE}Reason: {RAW_STRING} STR_NETWORK_ERROR_CHEATER :{WHITE}Cheating is not allowed on this server STR_NETWORK_ERROR_TOO_MANY_COMMANDS :{WHITE}You were sending too many commands to the server STR_NETWORK_ERROR_TIMEOUT_PASSWORD :{WHITE}You took too long to enter the password @@ -2229,6 +2244,7 @@ STR_NETWORK_MESSAGE_GIVE_MONEY :*** {RAW_STRING STR_NETWORK_MESSAGE_GAVE_MONEY_AWAY :*** You gave {1:RAW_STRING} {2:CURRENCY_LONG} 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}) # Content downloading window STR_CONTENT_TITLE :{WHITE}Content downloading @@ -2446,6 +2462,11 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL :{BLACK}Build ro STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Build tramway tunnel. Shift toggles building/showing cost estimate STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Toggle build/remove for road construction STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Toggle build/remove for tramway construction +STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_ROAD :{BLACK}Convert/Upgrade the type of road. Shift toggles building/showing cost estimate +STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_TRAM :{BLACK}Convert/Upgrade the type of tram. Shift toggles building/showing cost estimate + +STR_ROAD_NAME_ROAD :Road +STR_ROAD_NAME_TRAM :Tramway # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Road Depot Orientation @@ -2637,8 +2658,11 @@ STR_LAND_AREA_INFORMATION_NEWGRF_NAME :{BLACK}NewGRF: STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED :{BLACK}Cargo accepted: {LTBLUE} STR_LAND_AREA_INFORMATION_CARGO_EIGHTS :({COMMA}/8 {STRING}) STR_LANG_AREA_INFORMATION_RAIL_TYPE :{BLACK}Rail type: {LTBLUE}{STRING} +STR_LANG_AREA_INFORMATION_ROAD_TYPE :{BLACK}Road type: {LTBLUE}{STRING} +STR_LANG_AREA_INFORMATION_TRAM_TYPE :{BLACK}Tram type: {LTBLUE}{STRING} STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT :{BLACK}Rail speed limit: {LTBLUE}{VELOCITY} STR_LANG_AREA_INFORMATION_ROAD_SPEED_LIMIT :{BLACK}Road speed limit: {LTBLUE}{VELOCITY} +STR_LANG_AREA_INFORMATION_TRAM_SPEED_LIMIT :{BLACK}Tram speed limit: {LTBLUE}{VELOCITY} # Description of land area of different tiles STR_LAI_CLEAR_DESCRIPTION_ROCKS :Rocks @@ -2748,6 +2772,7 @@ STR_FRAMERATE_SPEED_FACTOR :{BLACK}Current STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}How fast the game is currently running, compared to the expected speed at normal simulation rate. STR_FRAMERATE_CURRENT :{WHITE}Current STR_FRAMERATE_AVERAGE :{WHITE}Average +STR_FRAMERATE_MEMORYUSE :{WHITE}Memory STR_FRAMERATE_DATA_POINTS :{BLACK}Data based on {COMMA} measurements STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL} ms STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL} ms @@ -2755,6 +2780,9 @@ STR_FRAMERATE_MS_BAD :{RED}{DECIMAL} STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL} frames/s STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL} frames/s STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL} frames/s +STR_FRAMERATE_BYTES_GOOD :{LTBLUE}{BYTES} +STR_FRAMERATE_BYTES_WARN :{YELLOW}{BYTES} +STR_FRAMERATE_BYTES_BAD :{RED}{BYTES} STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} ms STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} s ############ Leave those lines in this order!! @@ -3133,6 +3161,8 @@ STR_TOWN_VIEW_RENAME_TOWN_BUTTON :Rename Town # Town local authority window STR_LOCAL_AUTHORITY_CAPTION :{WHITE}{TOWN} local authority +STR_LOCAL_AUTHORITY_ZONE :{BLACK}Zone +STR_LOCAL_AUTHORITY_ZONE_TOOLTIP :{BLACK}Show zone within local authority boundaries STR_LOCAL_AUTHORITY_COMPANY_RATINGS :{BLACK}Transport company ratings: STR_LOCAL_AUTHORITY_COMPANY_RATING :{YELLOW}{COMPANY} {COMPANY_NUM}: {ORANGE}{STRING} STR_LOCAL_AUTHORITY_ACTIONS_TITLE :{BLACK}Actions available: @@ -3390,8 +3420,7 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Infrastr STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Rail pieces: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Signals STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Road pieces: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Road -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Tramway +STR_COMPANY_INFRASTRUCTURE_VIEW_TRAM_SECT :{GOLD}Tram pieces: STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Water tiles: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Canals STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Stations: @@ -3402,10 +3431,17 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Industries STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- None - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{RAW_STRING}){YELLOW} ({COMMA}% transported) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{RAW_STRING}/{CARGO_LONG}{RAW_STRING}){YELLOW} ({COMMA}%/{COMMA}% transported) +STR_INDUSTRY_DIRECTORY_ITEM_INFO :{BLACK}{CARGO_LONG}{RAW_STRING}{YELLOW} ({COMMA}% transported){BLACK} STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} +STR_INDUSTRY_DIRECTORY_ITEM_PROD1 :{ORANGE}{INDUSTRY} {STRING4} +STR_INDUSTRY_DIRECTORY_ITEM_PROD2 :{ORANGE}{INDUSTRY} {STRING4}, {STRING4} +STR_INDUSTRY_DIRECTORY_ITEM_PROD3 :{ORANGE}{INDUSTRY} {STRING4}, {STRING4}, {STRING4} +STR_INDUSTRY_DIRECTORY_ITEM_PRODMORE :{ORANGE}{INDUSTRY} {STRING4}, {STRING4}, {STRING4} and {NUM} more... STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Industry names - click on name to centre main view on industry. Ctrl+Click opens a new viewport on industry location +STR_INDUSTRY_DIRECTORY_ACCEPTED_CARGO_FILTER :{BLACK}Accepted cargo: {SILVER}{STRING} +STR_INDUSTRY_DIRECTORY_PRODUCED_CARGO_FILTER :{BLACK}Produced cargo: {SILVER}{STRING} +STR_INDUSTRY_DIRECTORY_FILTER_ALL_TYPES :All cargo types +STR_INDUSTRY_DIRECTORY_FILTER_NONE :None # Industry view STR_INDUSTRY_VIEW_CAPTION :{WHITE}{INDUSTRY} @@ -3471,6 +3507,8 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Ungrouped road STR_GROUP_DEFAULT_SHIPS :Ungrouped ships STR_GROUP_DEFAULT_AIRCRAFTS :Ungrouped aircraft +STR_GROUP_COUNT_WITH_SUBGROUP :{TINY_FONT}{COMMA} (+{COMMA}) + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Groups - click on a group to list all vehicles of this group. Drag and drop groups to arrange hierarchy. STR_GROUP_CREATE_TOOLTIP :{BLACK}Click to create a group STR_GROUP_DELETE_TOOLTIP :{BLACK}Delete the selected group @@ -3497,12 +3535,18 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :New Electric Ra STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :New Monorail Vehicles STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :New Maglev Vehicles -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :New Rail Vehicles STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :New Road Vehicles +STR_BUY_VEHICLE_TRAM_VEHICLE_CAPTION :New Tram Vehicles + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :New Rail Vehicles +STR_BUY_VEHICLE_ROAD_VEHICLE_ALL_CAPTION :New Road Vehicles STR_BUY_VEHICLE_SHIP_CAPTION :New Ships STR_BUY_VEHICLE_AIRCRAFT_CAPTION :New Aircraft +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Cost: {GOLD}{CURRENCY_LONG}{BLACK} Weight: {GOLD}{WEIGHT_SHORT} +STR_PURCHASE_INFO_COST_REFIT_WEIGHT :{BLACK}Cost: {GOLD}{CURRENCY_LONG}{BLACK} (Refit Cost: {GOLD}{CURRENCY_LONG}{BLACK}) Weight: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Speed: {GOLD}{VELOCITY}{BLACK} Power: {GOLD}{POWER} STR_PURCHASE_INFO_SPEED :{BLACK}Speed: {GOLD}{VELOCITY} STR_PURCHASE_INFO_SPEED_OCEAN :{BLACK}Speed on ocean: {GOLD}{VELOCITY} @@ -3513,8 +3557,10 @@ STR_PURCHASE_INFO_REFITTABLE :(refittable) STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Designed: {GOLD}{NUM}{BLACK} Life: {GOLD}{COMMA} year{P "" s} STR_PURCHASE_INFO_RELIABILITY :{BLACK}Max. Reliability: {GOLD}{COMMA}% STR_PURCHASE_INFO_COST :{BLACK}Cost: {GOLD}{CURRENCY_LONG} +STR_PURCHASE_INFO_COST_REFIT :{BLACK}Cost: {GOLD}{CURRENCY_LONG}{BLACK} (Refit Cost: {GOLD}{CURRENCY_LONG}{BLACK}) STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Weight: {GOLD}{WEIGHT_SHORT} ({WEIGHT_SHORT}) STR_PURCHASE_INFO_COST_SPEED :{BLACK}Cost: {GOLD}{CURRENCY_LONG}{BLACK} Speed: {GOLD}{VELOCITY} +STR_PURCHASE_INFO_COST_REFIT_SPEED :{BLACK}Cost: {GOLD}{CURRENCY_LONG}{BLACK} (Refit Cost: {GOLD}{CURRENCY_LONG}{BLACK}) Speed: {GOLD}{VELOCITY} STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Capacity: {GOLD}{CARGO_LONG}, {CARGO_LONG} STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Powered Wagons: {GOLD}+{POWER}{BLACK} Weight: {GOLD}+{WEIGHT_SHORT} STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Refittable to: {GOLD}{STRING2} @@ -3535,11 +3581,21 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Buy Vehi STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Buy Ship STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Buy Aircraft +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Buy and Refit Vehicle +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Buy and Refit Vehicle +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Buy and Refit Ship +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Buy and Refit Aircraft + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Buy the highlighted train vehicle. Shift+Click shows estimated cost without purchase STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Buy the highlighted road vehicle. Shift+Click shows estimated cost without purchase STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Buy the highlighted ship. Shift+Click shows estimated cost without purchase STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Buy the highlighted aircraft. Shift+Click shows estimated cost without purchase +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Buy and refit the highlighted train vehicle. Shift+Click shows estimated cost without purchase +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Buy and refit the highlighted road vehicle. Shift+Click shows estimated cost without purchase +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Buy and refit the highlighted ship. Shift+Click shows estimated cost without purchase +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Buy and refit the highlighted aircraft. Shift+Click shows estimated cost without purchase + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Rename STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Rename STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Rename @@ -3648,13 +3704,18 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}You are # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Message from vehicle manufacturer STR_ENGINE_PREVIEW_MESSAGE :{GOLD}We have just designed a new {STRING} - would you be interested in a year's exclusive use of this vehicle, so we can see how it performs before making it universally available? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :railway locomotive -STR_ENGINE_PREVIEW_ROAD_VEHICLE :road vehicle -STR_ENGINE_PREVIEW_AIRCRAFT :aircraft -STR_ENGINE_PREVIEW_SHIP :ship +STR_ENGINE_PREVIEW_ELRAIL_LOCOMOTIVE :electrified railway locomotive STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :monorail locomotive STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :maglev locomotive +STR_ENGINE_PREVIEW_ROAD_VEHICLE :road vehicle +STR_ENGINE_PREVIEW_TRAM_VEHICLE :tramway vehicle + +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_MAX_SPEED_CAP_RUNCOST :{BLACK}Cost: {CURRENCY_LONG} Max. Speed: {VELOCITY}{}Capacity: {CARGO_LONG}{}Running Cost: {CURRENCY_LONG}/yr @@ -3692,14 +3753,19 @@ STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK}Switch b STR_REPLACE_ENGINES :Engines STR_REPLACE_WAGONS :Wagons STR_REPLACE_ALL_RAILTYPE :All rail vehicles +STR_REPLACE_ALL_ROADTYPE :All road vehicles STR_REPLACE_HELP_RAILTYPE :{BLACK}Choose the rail type you want to replace engines for +STR_REPLACE_HELP_ROADTYPE :{BLACK}Choose the road type you want to replace engines for STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Displays which engine the left selected engine is being replaced with, if any STR_REPLACE_RAIL_VEHICLES :Rail Vehicles STR_REPLACE_ELRAIL_VEHICLES :Electrified Rail Vehicles STR_REPLACE_MONORAIL_VEHICLES :Monorail Vehicles STR_REPLACE_MAGLEV_VEHICLES :Maglev Vehicles +STR_REPLACE_ROAD_VEHICLES :Road Vehicles +STR_REPLACE_TRAM_VEHICLES :Tramway Vehicles + STR_REPLACE_REMOVE_WAGON :{BLACK}Wagon removal: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Make autoreplace keep the length of a train the same by removing wagons (starting at the front), if replacing the engine would make the train longer @@ -4150,6 +4216,14 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Select h STR_AI_LIST_CANCEL :{BLACK}Cancel STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Don't change the script +STR_SCREENSHOT_CAPTION :{WHITE}Take a screenshot +STR_SCREENSHOT_SCREENSHOT :{BLACK}Normal screenshot +STR_SCREENSHOT_ZOOMIN_SCREENSHOT :{BLACK}Fully zoomed in screenshot +STR_SCREENSHOT_DEFAULTZOOM_SCREENSHOT :{BLACK}Default zoom screenshot +STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Whole map screenshot +STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Heightmap screenshot +STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Minimap screenshot + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parameters STR_AI_SETTINGS_CAPTION_AI :AI @@ -4352,7 +4426,6 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... this STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... road facing in the wrong direction STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... drive through stops can't have corners STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... drive through stops can't have junctions -STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... road is one way or blocked # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Can't remove part of station... @@ -4422,7 +4495,8 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Must rem STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}No suitable railway track STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Must remove railway track first STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Road is one way or blocked -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Level crossings not allowed for this rail type +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Level crossings not allowed for this rail type +STR_ERROR_CROSSING_DISALLOWED_ROAD :{WHITE}Level crossings not allowed for this road type STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Can't build signals here... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Can't build railway track here... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Can't remove railway track from here... @@ -4442,6 +4516,12 @@ STR_ERROR_CAN_T_REMOVE_ROAD_FROM :{WHITE}Can't re STR_ERROR_CAN_T_REMOVE_TRAMWAY_FROM :{WHITE}Can't remove tramway from here... STR_ERROR_THERE_IS_NO_ROAD :{WHITE}... there is no road STR_ERROR_THERE_IS_NO_TRAMWAY :{WHITE}... there is no tramway +STR_ERROR_CAN_T_CONVERT_ROAD :{WHITE}Can't convert road type here... +STR_ERROR_CAN_T_CONVERT_TRAMWAY :{WHITE}Can't convert tram type here... +STR_ERROR_NO_SUITABLE_ROAD :{WHITE}No suitable road +STR_ERROR_NO_SUITABLE_TRAMWAY :{WHITE}No suitable tramway +STR_ERROR_INCOMPATIBLE_ROAD :{WHITE}... incompatible road +STR_ERROR_INCOMPATIBLE_TRAMWAY :{WHITE}... incompatible tramway # Waterway construction errors STR_ERROR_CAN_T_BUILD_CANALS :{WHITE}Can't build canals here... @@ -4494,6 +4574,7 @@ STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Can't cr STR_ERROR_GROUP_CAN_T_DELETE :{WHITE}Can't delete this group... STR_ERROR_GROUP_CAN_T_RENAME :{WHITE}Can't rename group... STR_ERROR_GROUP_CAN_T_SET_PARENT :{WHITE}Can't set parent group... +STR_ERROR_GROUP_CAN_T_SET_PARENT_RECURSION :{WHITE}... loops in the group hierarchy are not allowed STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}Can't remove all vehicles from this group... STR_ERROR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}Can't add the vehicle to this group... STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}Can't add shared vehicles to group... diff --git a/src/lang/english_AU.txt b/src/lang/english_AU.txt index d63f021e1d..5f6678e01a 100644 --- a/src/lang/english_AU.txt +++ b/src/lang/english_AU.txt @@ -10,8 +10,6 @@ ##grflangid 0x3d -# $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. # 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. @@ -463,9 +461,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Toggle console STR_ABOUT_MENU_AI_DEBUG :AI/Game script debug STR_ABOUT_MENU_SCREENSHOT :Screenshot -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Zoomed in screenshot -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Default zoom screenshot -STR_ABOUT_MENU_GIANT_SCREENSHOT :Whole map screenshot STR_ABOUT_MENU_ABOUT_OPENTTD :About 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Sprite aligner STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Toggle bounding boxes @@ -635,9 +630,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Custom 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Music Volume STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Effects Volume -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}MIN -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}MAX -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -849,6 +841,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}New {STRING} now available! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} no longer accepts {STRING} STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} no longer accepts {STRING} or {STRING} STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} now accepts {STRING} @@ -1663,7 +1656,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Cargo d STR_CONFIG_SETTING_AI :{ORANGE}Competitors STR_CONFIG_SETTING_AI_NPC :{ORANGE}Computer players -STR_CONFIG_SETTING_PATHFINDER_OPF :Original STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Recommended) @@ -1744,13 +1736,9 @@ STR_QUIT_NO :{BLACK}No # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -2376,6 +2364,7 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Build tr STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Toggle build/remove for road construction STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Toggle build/remove for tramway construction + # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Road Depot Orientation STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}Select road vehicle depot orientation @@ -3227,8 +3216,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Infrastr STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Rail pieces: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Signals STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Road pieces: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Road -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Tramway STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Water tiles: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Canals STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Stations: @@ -3239,8 +3226,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Industries STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- None - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% transported) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% transported) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Industry names - click on name to centre main view on industry. Ctrl+Click opens a new viewport on industry location @@ -3302,6 +3287,7 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Ungrouped road STR_GROUP_DEFAULT_SHIPS :Ungrouped ships STR_GROUP_DEFAULT_AIRCRAFTS :Ungrouped aircraft + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Groups - click on a group to list all vehicles of this group. Drag and drop groups to arrange hierarchy. STR_GROUP_CREATE_TOOLTIP :{BLACK}Click to create a group STR_GROUP_DELETE_TOOLTIP :{BLACK}Delete the selected group @@ -3323,10 +3309,13 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :New Electric Ra STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :New Monorail Vehicles STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :New Maglev Vehicles -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :New Rail Vehicles STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :New Road Vehicles + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :New Rail Vehicles STR_BUY_VEHICLE_SHIP_CAPTION :New Ships STR_BUY_VEHICLE_AIRCRAFT_CAPTION :New Aircraft +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Cost: {GOLD}{CURRENCY_LONG}{BLACK} Weight: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Speed: {GOLD}{VELOCITY}{BLACK} Power: {GOLD}{POWER} @@ -3359,11 +3348,13 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Buy Vehi STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Buy Ship STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Buy Aircraft + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Buy the highlighted train vehicle. Shift+Click shows estimated cost without purchase STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Buy the highlighted road vehicle. Shift+Click shows estimated cost without purchase STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Buy the highlighted ship. Shift+Click shows estimated cost without purchase STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Buy the highlighted aircraft. Shift+Click shows estimated cost without purchase + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Rename STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Rename STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Rename @@ -3460,13 +3451,16 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}You are # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Message from vehicle manufacturer STR_ENGINE_PREVIEW_MESSAGE :{GOLD}We have just designed a new {STRING} - would you be interested in a year's exclusive use of this vehicle, so we can see how it performs before making it universally available? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :railway locomotive -STR_ENGINE_PREVIEW_ROAD_VEHICLE :road vehicle -STR_ENGINE_PREVIEW_AIRCRAFT :aircraft -STR_ENGINE_PREVIEW_SHIP :ship STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :monorail locomotive STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :maglev locomotive +STR_ENGINE_PREVIEW_ROAD_VEHICLE :road vehicle + +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_MAX_SPEED_CAP_RUNCOST :{BLACK}Cost: {CURRENCY_LONG} Max. Speed: {VELOCITY}{}Capacity: {CARGO_LONG}{}Running Cost: {CURRENCY_LONG}/yr @@ -3503,6 +3497,7 @@ STR_REPLACE_ELRAIL_VEHICLES :Electrified Rai STR_REPLACE_MONORAIL_VEHICLES :Monorail Vehicles STR_REPLACE_MAGLEV_VEHICLES :Maglev Vehicles + STR_REPLACE_REMOVE_WAGON :{BLACK}Wagon removal: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Make autoreplace keep the length of a train the same by removing wagons (starting at the front), if replacing the engine would make the train longer @@ -3950,6 +3945,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Select h STR_AI_LIST_CANCEL :{BLACK}Cancel STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Don't change the script + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parameters STR_AI_SETTINGS_CAPTION_AI :AI @@ -4220,7 +4216,7 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Must rem STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}No suitable railway track STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Must remove railway track first STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Road is one way or blocked -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Level crossings not allowed for this rail type +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Level crossings not allowed for this rail type STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Can't build signals here... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Can't build railway track here... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Can't remove railway track from here... diff --git a/src/lang/english_US.txt b/src/lang/english_US.txt index 9161686d9a..5a0a1817b5 100644 --- a/src/lang/english_US.txt +++ b/src/lang/english_US.txt @@ -10,8 +10,6 @@ ##grflangid 0x00 -# $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. # 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. @@ -237,6 +235,8 @@ STR_TOOLTIP_FILTER_CRITERIA :{BLACK}Select f STR_BUTTON_SORT_BY :{BLACK}Sort by STR_BUTTON_LOCATION :{BLACK}Location STR_BUTTON_RENAME :{BLACK}Rename +STR_BUTTON_CATCHMENT :{BLACK}Coverage +STR_TOOLTIP_CATCHMENT :{BLACK}Toggle coverage area display STR_TOOLTIP_CLOSE_WINDOW :{BLACK}Close window STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Window title - drag this to move window @@ -265,6 +265,7 @@ STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT_TOOLTIP :{BLACK}By enabl STR_BUTTON_DEFAULT :{BLACK}Default STR_BUTTON_CANCEL :{BLACK}Cancel STR_BUTTON_OK :{BLACK}OK +STR_WARNING_PASSWORD_SECURITY :{YELLOW}Warning: Server administrators may be able to read any text entered here. # On screen keyboard window STR_OSK_KEYBOARD_LAYOUT :`1234567890-=\qwertyuiop[]asdfghjkl;' zxcvbnm,./ . @@ -338,6 +339,7 @@ STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN :{BLACK}Zoom the STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT :{BLACK}Zoom the view out STR_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Build railroad track STR_TOOLBAR_TOOLTIP_BUILD_ROADS :{BLACK}Build roads +STR_TOOLBAR_TOOLTIP_BUILD_TRAMWAYS :{BLACK}Build streetcar lines STR_TOOLBAR_TOOLTIP_BUILD_SHIP_DOCKS :{BLACK}Build ship docks STR_TOOLBAR_TOOLTIP_BUILD_AIRPORTS :{BLACK}Build airports STR_TOOLBAR_TOOLTIP_LANDSCAPING :{BLACK}Open the landscaping toolbar to raise/lower land, plant trees, etc. @@ -358,6 +360,7 @@ STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION :{BLACK}Landscap STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Town generation 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_PLACE_SIGN :{BLACK}Place sign STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Place object. Shift toggles building/showing cost estimate @@ -475,9 +478,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Toggle console STR_ABOUT_MENU_AI_DEBUG :AI/Game script debug STR_ABOUT_MENU_SCREENSHOT :Screenshot -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Fully zoomed in screenshot -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Default zoom screenshot -STR_ABOUT_MENU_GIANT_SCREENSHOT :Whole map screenshot STR_ABOUT_MENU_SHOW_FRAMERATE :Show frame rate STR_ABOUT_MENU_ABOUT_OPENTTD :About 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Sprite aligner @@ -648,9 +648,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Custom 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Music Volume STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Effects Volume -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}MIN -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}MAX -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -867,6 +864,8 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}New {STRING} now available! - {ENGINE} +STR_NEWS_SHOW_VEHICLE_GROUP_TOOLTIP :{BLACK}Open the group window focused on the vehicle's group + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} no longer accepts {STRING} STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} no longer accepts {STRING} or {STRING} STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} now accepts {STRING} @@ -933,6 +932,9 @@ STR_GAME_OPTIONS_CURRENCY_GEL :Georgian Lari ( STR_GAME_OPTIONS_CURRENCY_IRR :Iranian Rial (IRR) STR_GAME_OPTIONS_CURRENCY_RUB :New Russian Ruble (RUB) STR_GAME_OPTIONS_CURRENCY_MXN :Mexican Peso (MXN) +STR_GAME_OPTIONS_CURRENCY_NTD :New Taiwan Dollar (NTD) +STR_GAME_OPTIONS_CURRENCY_CNY :Chinese Renminbi (CNY) +STR_GAME_OPTIONS_CURRENCY_HKD :Hong Kong Dollar (HKD) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Road vehicles @@ -1159,7 +1161,7 @@ STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Maximum amount STR_CONFIG_SETTING_INTEREST_RATE :Interest rate: {STRING} STR_CONFIG_SETTING_INTEREST_RATE_HELPTEXT :Loan interest rate; also controls inflation, if enabled STR_CONFIG_SETTING_RUNNING_COSTS :Running costs: {STRING} -STR_CONFIG_SETTING_RUNNING_COSTS_HELPTEXT :Set level of maintainance and running costs of vehicles and infrastructure +STR_CONFIG_SETTING_RUNNING_COSTS_HELPTEXT :Set level of maintenance and running costs of vehicles and infrastructure STR_CONFIG_SETTING_CONSTRUCTION_SPEED :Construction speed: {STRING} STR_CONFIG_SETTING_CONSTRUCTION_SPEED_HELPTEXT :Limit the amount of construction actions for AIs STR_CONFIG_SETTING_VEHICLE_BREAKDOWNS :Vehicle breakdowns: {STRING} @@ -1184,6 +1186,8 @@ STR_CONFIG_SETTING_AUTOSLOPE :Allow terraform STR_CONFIG_SETTING_AUTOSLOPE_HELPTEXT :Allow terraforming under buildings and tracks without removing them STR_CONFIG_SETTING_CATCHMENT :Allow more realistically sized catchment areas: {STRING} STR_CONFIG_SETTING_CATCHMENT_HELPTEXT :Have differently sized catchment areas for different types of stations and airports +STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES :Company stations can serve industries that have built-in neutral stations: {STRING} +STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES_HELPTEXT :When enabled, industries with attached stations (such as Oil Rigs) may also be served by company owned stations built nearby. When disabled, these industries may only be served by their attached stations. Any nearby company stations won't be able to serve them, nor will the attached station serve anything else other than the industry STR_CONFIG_SETTING_EXTRADYNAMITE :Allow removal of more town-owned roads, bridges and tunnels: {STRING} STR_CONFIG_SETTING_EXTRADYNAMITE_HELPTEXT :Make it easier to remove town-owned infrastructure and buildings STR_CONFIG_SETTING_TRAIN_LENGTH :Maximum length of trains: {STRING} @@ -1200,8 +1204,8 @@ STR_CONFIG_SETTING_TRAIN_SLOPE_STEEPNESS_HELPTEXT :Steepness of a STR_CONFIG_SETTING_PERCENTAGE :{COMMA}% STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS :Slope steepness for road vehicles: {STRING} STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS_HELPTEXT :Steepness of a sloped tile for a road vehicle. Higher values make it more difficult to climb a hill -STR_CONFIG_SETTING_FORBID_90_DEG :Forbid trains and ships from making 90° turns: {STRING} -STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :90 degree turns occur when a horizontal track is directly followed by a vertical track piece on the adjacent tile, thus making the train turn by 90 degree when traversing the tile edge instead of the usual 45 degrees for other track combinations. This also applies to the turning radius of ships +STR_CONFIG_SETTING_FORBID_90_DEG :Forbid trains from making 90° turns: {STRING} +STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :90 degree turns occur when a horizontal track is directly followed by a vertical track piece on the adjacent tile, thus making the train turn by 90 degrees when traversing the tile edge instead of the usual 45 degrees for other track combinations. STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS :Allow joining stations not directly adjacent: {STRING} STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS_HELPTEXT :Allow adding parts to a station without directly touching the existing parts. Needs Ctrl+Click while placing the new parts STR_CONFIG_SETTING_INFLATION :Inflation: {STRING} @@ -1257,8 +1261,8 @@ STR_CONFIG_SETTING_PLANE_SPEED :Plane speed fac 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 STR_CONFIG_SETTING_PLANE_SPEED_VALUE :1 / {COMMA} STR_CONFIG_SETTING_PLANE_CRASHES :Number of plane crashes: {STRING} -STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Set the chance of an aircraft crash happening -STR_CONFIG_SETTING_PLANE_CRASHES_NONE :None +STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Set the chance of a random aircraft crash happening.{}* Large airplanes always have a risk of crashing when landing on small airports +STR_CONFIG_SETTING_PLANE_CRASHES_NONE :None* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Reduced STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normal STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Allow drive-through road stops on town owned roads: {STRING} @@ -1305,6 +1309,7 @@ STR_CONFIG_SETTING_POPULATION_IN_LABEL :Show town popul STR_CONFIG_SETTING_POPULATION_IN_LABEL_HELPTEXT :Display the population of towns in their label on the map STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS :Thickness of lines in graphs: {STRING} STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Width of the line in the graphs. A thin line is more precisely readable, a thicker line is easier to see and colors are easier to distinguish +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_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 @@ -1316,8 +1321,8 @@ STR_CONFIG_SETTING_TERRAIN_TYPE :Terrain type: { STR_CONFIG_SETTING_TERRAIN_TYPE_HELPTEXT :(TerraGenesis only) Hilliness of the landscape STR_CONFIG_SETTING_INDUSTRY_DENSITY :Industry density: {STRING} STR_CONFIG_SETTING_INDUSTRY_DENSITY_HELPTEXT :Set how many industries should be generated and what level should be maintained during the game -STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE :Maximum distance from edge for Oil refineries: {STRING} -STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :Oil refineries are only constructed near the map border, that is at the coast for island maps +STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE :Maximum distance from edge for Oil industries: {STRING} +STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :Limit for how far from the map border oil refineries and oil rigs can be constructed. On island maps this ensures they are near the coast. On maps larger than 256 tiles, this value is scaled up. STR_CONFIG_SETTING_SNOWLINE_HEIGHT :Snow line height: {STRING} STR_CONFIG_SETTING_SNOWLINE_HEIGHT_HELPTEXT :Control at what height snow starts in sub-arctic landscape. Snow also affects industry generation and town growth requirements STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN :Roughness of terrain: {STRING} @@ -1481,6 +1486,9 @@ STR_CONFIG_SETTING_AI_IN_MULTIPLAYER :Allow AIs in mu STR_CONFIG_SETTING_AI_IN_MULTIPLAYER_HELPTEXT :Allow AI computer players to participate in multiplayer games STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES :#opcodes before scripts are suspended: {STRING} STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES_HELPTEXT :Maximum number of computation steps that a script can take in one turn +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY :Max memory usage per script: {STRING} +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_HELPTEXT :How much memory a single script may consume before it's forcibly terminated. This may need to be increased for large maps. +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_VALUE :{COMMA} MiB STR_CONFIG_SETTING_SERVINT_ISPERCENT :Maintenance intervals are in percents: {STRING} STR_CONFIG_SETTING_SERVINT_ISPERCENT_HELPTEXT :Choose whether maintenance of vehicles is triggered by the time passed since last maintenance or by reliability dropping by a certain percentage of the maximum reliability @@ -1539,10 +1547,16 @@ STR_CONFIG_SETTING_NEWS_MESSAGES_FULL :Full STR_CONFIG_SETTING_COLOURED_NEWS_YEAR :Colored news appears in: {STRING} STR_CONFIG_SETTING_COLOURED_NEWS_YEAR_HELPTEXT :Year that the newspaper announcements get printed in color. Before this year, it uses monochrome black/white STR_CONFIG_SETTING_STARTING_YEAR :Starting year: {STRING} +STR_CONFIG_SETTING_ENDING_YEAR :Scoring end year: {STRING} +STR_CONFIG_SETTING_ENDING_YEAR_HELPTEXT :Year the game ends for scoring purposes. At the end of this year, the company's score is recorded and the high-score screen is displayed, but the players can continue playing after that.{}If this is before the starting year, the high-score screen is never displayed. +STR_CONFIG_SETTING_ENDING_YEAR_VALUE :{NUM} +STR_CONFIG_SETTING_ENDING_YEAR_ZERO :Never STR_CONFIG_SETTING_SMOOTH_ECONOMY :Enable smooth economy (more, smaller changes): {STRING} STR_CONFIG_SETTING_SMOOTH_ECONOMY_HELPTEXT :When enabled, industry production changes more often, and in smaller steps. This setting has usually no effect, if industry types are provided by a NewGRF STR_CONFIG_SETTING_ALLOW_SHARES :Allow buying shares from other companies: {STRING} STR_CONFIG_SETTING_ALLOW_SHARES_HELPTEXT :When enabled, allow buying and selling of company shares. Shares will only be available for companies reaching a certain age +STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES :Minimum company age to trade shares: {STRING} +STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES_HELPTEXT :Set the minimum age of a company for others to be able to buy and sell shares from them. STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE :Percentage of leg profit to pay in feeder systems: {STRING} STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE_HELPTEXT :Percentage of income given to the intermediate legs in feeder systems, giving more control over the income STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY :When dragging, place signals every: {STRING} @@ -1583,6 +1597,10 @@ STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :Enabling this s STR_CONFIG_SETTING_TOWN_FOUNDING_FORBIDDEN :Forbidden STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED :Allowed STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED_CUSTOM_LAYOUT :Allowed, custom town layout +STR_CONFIG_SETTING_TOWN_CARGOGENMODE :Town cargo generation: {STRING} +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_HELPTEXT :How much cargo is produced by houses in towns, relative to the overall population of the town.{}Quadratic growth: A town twice the size generates four times as many passengers.{}Linear growth: A town twice the size generates twice the amount of passengers. +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_ORIGINAL :Quadratic (original) +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_BITCOUNT :Linear STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :In-game placement of trees: {STRING} STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :Control random appearance of trees during the game. This might affect industries which rely on tree growth, for example lumber mills @@ -1648,7 +1666,7 @@ STR_CONFIG_SETTING_DEMAND_DISTANCE_HELPTEXT :If you set this STR_CONFIG_SETTING_DEMAND_SIZE :Amount of returning cargo for symmetric mode: {STRING} STR_CONFIG_SETTING_DEMAND_SIZE_HELPTEXT :Setting this to less than 100% makes the symmetric distribution behave more like the asymmetric one. Less cargo will be forcibly sent back if a certain amount is sent to a station. If you set it to 0% the symmetric distribution behaves just like the asymmetric one. STR_CONFIG_SETTING_SHORT_PATH_SATURATION :Saturation of short paths before using high-capacity paths: {STRING} -STR_CONFIG_SETTING_SHORT_PATH_SATURATION_HELPTEXT :Frequently there are multiple paths between two given stations. Cargodist will saturate the shortest path first, then use the second shortest path until that is saturated and so on. Saturation is determined by an estimation of capacity and planned usage. Once it has saturated all paths, if there is still demand left, it will overload all paths, prefering the ones with high capacity. Most of the time the algorithm will not estimate the capacity accurately, though. This setting allows you to specify up to which percentage a shorter path must be saturated in the first pass before choosing the next longer one. Set it to less than 100% to avoid overcrowded stations in case of overestimated capacity. +STR_CONFIG_SETTING_SHORT_PATH_SATURATION_HELPTEXT :Frequently there are multiple paths between two given stations. Cargodist will saturate the shortest path first, then use the second shortest path until that is saturated and so on. Saturation is determined by an estimation of capacity and planned usage. Once it has saturated all paths, if there is still demand left, it will overload all paths, preferring the ones with high capacity. Most of the time the algorithm will not estimate the capacity accurately, though. This setting allows you to specify up to which percentage a shorter path must be saturated in the first pass before choosing the next longer one. Set it to less than 100% to avoid overcrowded stations in case of overestimated capacity. STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY :Speed units: {STRING} STR_CONFIG_SETTING_LOCALISATION_UNITS_VELOCITY_HELPTEXT :Whenever a speed is shown in the user interface, show it in the selected units @@ -1710,7 +1728,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Cargo d STR_CONFIG_SETTING_AI :{ORANGE}Competitors STR_CONFIG_SETTING_AI_NPC :{ORANGE}Computer players -STR_CONFIG_SETTING_PATHFINDER_OPF :Original STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Recommended) @@ -1794,13 +1811,9 @@ STR_QUIT_NO :{BLACK}No # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -2138,7 +2151,7 @@ STR_NETWORK_CHAT_ALL :[All] {STRING}: STR_NETWORK_CHAT_OSKTITLE :{BLACK}Enter text for network chat # Network messages -STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}No network devices found or compiled without ENABLE_NETWORK +STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}No network devices found STR_NETWORK_ERROR_NOSERVER :{WHITE}Could not find any network games STR_NETWORK_ERROR_NOCONNECTION :{WHITE}The server didn't answer the request STR_NETWORK_ERROR_NEWGRF_MISMATCH :{WHITE}Could not connect due to NewGRF mismatch @@ -2430,6 +2443,11 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL :{BLACK}Build ro STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Build streetcar tunnel. Shift toggles building/showing cost estimate STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Toggle build/remove for road construction STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Toggle build/remove for streetcar track construction +STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_ROAD :{BLACK}Convert/Upgrade the type of road. Shift toggles building/showing cost estimate +STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_TRAM :{BLACK}Convert/Upgrade the type of streetcar. Shift toggles building/showing cost estimate + +STR_ROAD_NAME_ROAD :Road +STR_ROAD_NAME_TRAM :Streetcar line # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Road Depot Orientation @@ -2614,8 +2632,11 @@ STR_LAND_AREA_INFORMATION_NEWGRF_NAME :{BLACK}NewGRF: STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED :{BLACK}Cargo accepted: {LTBLUE} STR_LAND_AREA_INFORMATION_CARGO_EIGHTS :({COMMA}/8 {STRING}) STR_LANG_AREA_INFORMATION_RAIL_TYPE :{BLACK}Rail type: {LTBLUE}{STRING} +STR_LANG_AREA_INFORMATION_ROAD_TYPE :{BLACK}Road type: {LTBLUE}{STRING} +STR_LANG_AREA_INFORMATION_TRAM_TYPE :{BLACK}Streetcar type: {LTBLUE}{STRING} STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT :{BLACK}Rail speed limit: {LTBLUE}{VELOCITY} STR_LANG_AREA_INFORMATION_ROAD_SPEED_LIMIT :{BLACK}Road speed limit: {LTBLUE}{VELOCITY} +STR_LANG_AREA_INFORMATION_TRAM_SPEED_LIMIT :{BLACK}Tram speed limit: {LTBLUE}{VELOCITY} # Description of land area of different tiles STR_LAI_CLEAR_DESCRIPTION_ROCKS :Rocks @@ -2725,6 +2746,7 @@ STR_FRAMERATE_SPEED_FACTOR :{BLACK}Current STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}How fast the game is currently running, compared to the expected speed at normal simulation rate. STR_FRAMERATE_CURRENT :{WHITE}Current STR_FRAMERATE_AVERAGE :{WHITE}Average +STR_FRAMERATE_MEMORYUSE :{WHITE}Memory STR_FRAMERATE_DATA_POINTS :{BLACK}Data based on {COMMA} measurements STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL} ms STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL} ms @@ -2732,6 +2754,9 @@ STR_FRAMERATE_MS_BAD :{RED}{DECIMAL} STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL} frames/s STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL} frames/s STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL} frames/s +STR_FRAMERATE_BYTES_GOOD :{LTBLUE}{BYTES} +STR_FRAMERATE_BYTES_WARN :{YELLOW}{BYTES} +STR_FRAMERATE_BYTES_BAD :{RED}{BYTES} STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} ms STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} s ############ Leave those lines in this order!! @@ -3098,6 +3123,8 @@ STR_TOWN_VIEW_RENAME_TOWN_BUTTON :Rename Town # Town local authority window STR_LOCAL_AUTHORITY_CAPTION :{WHITE}{TOWN} local authority +STR_LOCAL_AUTHORITY_ZONE :{BLACK}Zone +STR_LOCAL_AUTHORITY_ZONE_TOOLTIP :{BLACK}Show zone within local authority boundaries STR_LOCAL_AUTHORITY_COMPANY_RATINGS :{BLACK}Transport company ratings: STR_LOCAL_AUTHORITY_COMPANY_RATING :{YELLOW}{COMPANY} {COMPANY_NUM}: {ORANGE}{STRING} STR_LOCAL_AUTHORITY_ACTIONS_TITLE :{BLACK}Actions available: @@ -3355,8 +3382,7 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Infrastr STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Rail pieces: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Signals STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Road pieces: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Road -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Streetcar +STR_COMPANY_INFRASTRUCTURE_VIEW_TRAM_SECT :{GOLD}Streetcar pieces: STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Water tiles: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Canals STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Stations: @@ -3367,8 +3393,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Industries STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- None - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% transported) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% transported) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Industry names - click on name to center main view on industry. Ctrl+Click opens a new viewport on industry location @@ -3436,6 +3460,8 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Ungrouped road STR_GROUP_DEFAULT_SHIPS :Ungrouped ships STR_GROUP_DEFAULT_AIRCRAFTS :Ungrouped aircraft +STR_GROUP_COUNT_WITH_SUBGROUP :{TINY_FONT}{COMMA} (+{COMMA}) + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Groups - click on a group to list all vehicles of this group. Drag and drop groups to arrange hierarchy. STR_GROUP_CREATE_TOOLTIP :{BLACK}Click to create a group STR_GROUP_DELETE_TOOLTIP :{BLACK}Delete the selected group @@ -3462,12 +3488,18 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :New Electric Ra STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :New Monorail Vehicles STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :New Maglev Vehicles -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :New Rail Vehicles STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :New Road Vehicles +STR_BUY_VEHICLE_TRAM_VEHICLE_CAPTION :New Streetcars + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :New Rail Vehicles +STR_BUY_VEHICLE_ROAD_VEHICLE_ALL_CAPTION :New Road Vehicles STR_BUY_VEHICLE_SHIP_CAPTION :New Ships STR_BUY_VEHICLE_AIRCRAFT_CAPTION :New Aircraft +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Cost: {GOLD}{CURRENCY_LONG}{BLACK} Weight: {GOLD}{WEIGHT_SHORT} +STR_PURCHASE_INFO_COST_REFIT_WEIGHT :{BLACK}Cost: {GOLD}{CURRENCY_LONG}{BLACK} (Refit Cost: {GOLD}{CURRENCY_LONG}{BLACK}) Weight: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Speed: {GOLD}{VELOCITY}{BLACK} Power: {GOLD}{POWER} STR_PURCHASE_INFO_SPEED :{BLACK}Speed: {GOLD}{VELOCITY} STR_PURCHASE_INFO_SPEED_OCEAN :{BLACK}Speed on ocean: {GOLD}{VELOCITY} @@ -3478,8 +3510,10 @@ STR_PURCHASE_INFO_REFITTABLE :(refittable) STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Designed: {GOLD}{NUM}{BLACK} Life: {GOLD}{COMMA} year{P "" s} STR_PURCHASE_INFO_RELIABILITY :{BLACK}Max. Reliability: {GOLD}{COMMA}% STR_PURCHASE_INFO_COST :{BLACK}Cost: {GOLD}{CURRENCY_LONG} +STR_PURCHASE_INFO_COST_REFIT :{BLACK}Cost: {GOLD}{CURRENCY_LONG}{BLACK} (Refit Cost: {GOLD}{CURRENCY_LONG}{BLACK}) STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Weight: {GOLD}{WEIGHT_SHORT} ({WEIGHT_SHORT}) STR_PURCHASE_INFO_COST_SPEED :{BLACK}Cost: {GOLD}{CURRENCY_LONG}{BLACK} Speed: {GOLD}{VELOCITY} +STR_PURCHASE_INFO_COST_REFIT_SPEED :{BLACK}Cost: {GOLD}{CURRENCY_LONG}{BLACK} (Refit Cost: {GOLD}{CURRENCY_LONG}{BLACK}) Speed: {GOLD}{VELOCITY} STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Capacity: {GOLD}{CARGO_LONG}, {CARGO_LONG} STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Powered Wagons: {GOLD}+{POWER}{BLACK} Weight: {GOLD}+{WEIGHT_SHORT} STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Refittable to: {GOLD}{STRING} @@ -3500,11 +3534,21 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Buy Vehi STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Buy Ship STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Buy Aircraft +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Buy and Refit Vehicle +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Buy and Refit Vehicle +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Buy and Refit Ship +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Buy and Refit Aircraft + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Buy the highlighted train vehicle. Shift+Click shows estimated cost without purchase STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Buy the highlighted road vehicle. Shift+Click shows estimated cost without purchase STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Buy the highlighted ship. Shift+Click shows estimated cost without purchase STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Buy the highlighted aircraft. Shift+Click shows estimated cost without purchase +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Buy and refit the highlighted train vehicle. Shift+Click shows estimated cost without purchase +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Buy and refit the highlighted road vehicle. Shift+Click shows estimated cost without purchase +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Buy and refit the highlighted ship. Shift+Click shows estimated cost without purchase +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Buy and refit the highlighted aircraft. Shift+Click shows estimated cost without purchase + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Rename STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Rename STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Rename @@ -3613,13 +3657,18 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}You are # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Message from vehicle manufacturer STR_ENGINE_PREVIEW_MESSAGE :{GOLD}We have just designed a new {STRING} - would you be interested in a year's exclusive use of this vehicle, so we can see how it performs before making it universally available ? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :railroad locomotive -STR_ENGINE_PREVIEW_ROAD_VEHICLE :road vehicle -STR_ENGINE_PREVIEW_AIRCRAFT :aircraft -STR_ENGINE_PREVIEW_SHIP :ship +STR_ENGINE_PREVIEW_ELRAIL_LOCOMOTIVE :electrified railway locomotive STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :monorail locomotive STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :maglev locomotive +STR_ENGINE_PREVIEW_ROAD_VEHICLE :road vehicle +STR_ENGINE_PREVIEW_TRAM_VEHICLE :streetcar + +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_MAX_SPEED_CAP_RUNCOST :{BLACK}Cost: {CURRENCY_LONG} Max. Speed: {VELOCITY}{}Capacity: {CARGO_LONG}{}Running Cost: {CURRENCY_LONG}/yr @@ -3657,14 +3706,19 @@ STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK}Switch b STR_REPLACE_ENGINES :Engines STR_REPLACE_WAGONS :Cars STR_REPLACE_ALL_RAILTYPE :All rail vehicles +STR_REPLACE_ALL_ROADTYPE :All road vehicles STR_REPLACE_HELP_RAILTYPE :{BLACK}Choose the rail type you want to replace engines for +STR_REPLACE_HELP_ROADTYPE :{BLACK}Choose the road type you want to replace engines for STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Displays which engine the left selected engine is being replaced with, if any STR_REPLACE_RAIL_VEHICLES :Rail Vehicles STR_REPLACE_ELRAIL_VEHICLES :Electrified Rail Vehicles STR_REPLACE_MONORAIL_VEHICLES :Monorail Vehicles STR_REPLACE_MAGLEV_VEHICLES :Maglev Vehicles +STR_REPLACE_ROAD_VEHICLES :Road Vehicles +STR_REPLACE_TRAM_VEHICLES :Streetcars + STR_REPLACE_REMOVE_WAGON :{BLACK}Car removal: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Make autoreplace keep the length of a train the same by removing cars (starting at the front), if replacing the engine would make the train longer @@ -4115,6 +4169,14 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Select h STR_AI_LIST_CANCEL :{BLACK}Cancel STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Don't change the script +STR_SCREENSHOT_CAPTION :{WHITE}Take a screenshot +STR_SCREENSHOT_SCREENSHOT :{BLACK}Normal screenshot +STR_SCREENSHOT_ZOOMIN_SCREENSHOT :{BLACK}Fully zoomed in screenshot +STR_SCREENSHOT_DEFAULTZOOM_SCREENSHOT :{BLACK}Default zoom screenshot +STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Whole map screenshot +STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Heightmap screenshot +STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Minimap screenshot + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parameters STR_AI_SETTINGS_CAPTION_AI :AI @@ -4317,7 +4379,6 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... this STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... road facing in the wrong direction STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... drive through stops can't have corners STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... drive through stops can't have junctions -STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... road is one way or blocked # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Can't remove part of station... @@ -4387,7 +4448,8 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Must rem STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}No suitable railroad track STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Must remove railroad track first STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Road is one way or blocked -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Grade crossings not allowed for this rail type +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Grade crossings not allowed for this rail type +STR_ERROR_CROSSING_DISALLOWED_ROAD :{WHITE}Level crossings not allowed for this road type STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Can't build signals here... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Can't build railroad track here... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Can't remove railroad track from here... @@ -4407,6 +4469,12 @@ STR_ERROR_CAN_T_REMOVE_ROAD_FROM :{WHITE}Can't re STR_ERROR_CAN_T_REMOVE_TRAMWAY_FROM :{WHITE}Can't remove streetcar track from here... STR_ERROR_THERE_IS_NO_ROAD :{WHITE}... there is no road STR_ERROR_THERE_IS_NO_TRAMWAY :{WHITE}... there is no streetcar track +STR_ERROR_CAN_T_CONVERT_ROAD :{WHITE}Can't convert road type here... +STR_ERROR_CAN_T_CONVERT_TRAMWAY :{WHITE}Can't convert streetcar type here... +STR_ERROR_NO_SUITABLE_ROAD :{WHITE}No suitable road +STR_ERROR_NO_SUITABLE_TRAMWAY :{WHITE}No suitable streetcar line +STR_ERROR_INCOMPATIBLE_ROAD :{WHITE}... incompatible road +STR_ERROR_INCOMPATIBLE_TRAMWAY :{WHITE}... incompatible streetcar line # Waterway construction errors STR_ERROR_CAN_T_BUILD_CANALS :{WHITE}Can't build canals here... @@ -4459,6 +4527,7 @@ STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Can't cr STR_ERROR_GROUP_CAN_T_DELETE :{WHITE}Can't delete this group... STR_ERROR_GROUP_CAN_T_RENAME :{WHITE}Can't rename group... STR_ERROR_GROUP_CAN_T_SET_PARENT :{WHITE}Can't set parent group... +STR_ERROR_GROUP_CAN_T_SET_PARENT_RECURSION :{WHITE}... loops in the group hierarchy are not allowed STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}Can't remove all vehicles from this group... STR_ERROR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}Can't add the vehicle to this group... STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}Can't add shared vehicles to group... diff --git a/src/lang/esperanto.txt b/src/lang/esperanto.txt index e367b6682c..e6efa88273 100644 --- a/src/lang/esperanto.txt +++ b/src/lang/esperanto.txt @@ -11,8 +11,6 @@ ##case n -# $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. # 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. @@ -466,9 +464,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Baskuligi Konzolon STR_ABOUT_MENU_AI_DEBUG :AI/Ludo skripto sencimigo STR_ABOUT_MENU_SCREENSHOT :Ekranfoto -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Pligrandiga ekranfoto -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Ekranfoto defaŭlte zoma -STR_ABOUT_MENU_GIANT_SCREENSHOT :Tuta karto ekranfoto STR_ABOUT_MENU_ABOUT_OPENTTD :Pri 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Bildeto-liniigilo STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Montri/ne montri limigujo @@ -638,9 +633,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Propra 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Muzika Volumeno STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Efekta Volumeno -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}MIN -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}MAKS -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -846,6 +838,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}Nova {STRING} nun haveblas! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} ne plu akceptas {STRING.n} STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} ne plu akceptas {STRING.n} aŭ {STRING.n} STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} nun akceptas {STRING.n} @@ -1368,7 +1361,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_INDUSTRIES :{ORANGE}Industr STR_CONFIG_SETTING_AI :{ORANGE}Konkurantoj STR_CONFIG_SETTING_AI_NPC :{ORANGE}Komputil-ludantoj -STR_CONFIG_SETTING_PATHFINDER_OPF :Originale STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Rekomendite) @@ -1427,13 +1419,9 @@ STR_QUIT_NO :{BLACK}Ne # Supported OSes STR_OSNAME_WINDOWS :Vindozo -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unikso STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -2006,6 +1994,7 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL :{BLACK}Konstruu STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Konstrui tramtunelon. Baskulu inter konstrui/(kosto)taksi per maljuskliga klavo STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Ĉu konstrui ĉu forigi por vojkonstruado + # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Direkto de la stratveturila garaĝo STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}Elekti direkton de la stratveturila garaĝo @@ -2715,8 +2704,6 @@ STR_BUY_COMPANY_MESSAGE :{WHITE}Ni serĉ # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Industrioj STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Neniu - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% transportite) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% transportite) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Industrionomoj - klaku nomon por centri vidon ĉe la industrio. Ctrl+Klak por malfermi novan vidujon ĉe la loko @@ -2777,6 +2764,7 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Sengrupaj strat STR_GROUP_DEFAULT_SHIPS :Sengrupaj ŝipoj STR_GROUP_DEFAULT_AIRCRAFTS :Sengrupaj aviadiloj + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Grupoj - klaku grupon por listigi ĉiujn veturilojn de tiu ĉi grupo. Trenu/faligu grupojn por ordigi ĝin STR_GROUP_CREATE_TOOLTIP :{BLACK}Klaku por krei grupon STR_GROUP_DELETE_TOOLTIP :{BLACK}Viŝu la selektitan grupon @@ -2795,10 +2783,13 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Novaj Elektraj STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Novaj Unurelaj Veturiloj STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Novaj Maglevaj Veturiloj -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Novaj stratveturiloj STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Novaj stratveturiloj + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Novaj stratveturiloj STR_BUY_VEHICLE_SHIP_CAPTION :Novaj Ŝipoj STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Novaj Aviadiloj +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Kosto: {GOLD}{CURRENCY_LONG}{BLACK} Pezo: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Rapido: {GOLD}{VELOCITY}{BLACK} Forto: {GOLD}{POWER} @@ -2830,11 +2821,13 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Aĉeti V STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Aĉeti Ŝipon STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Aĉeti Aviadilon + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Aĉeti la emfazitan trajnveturilon. Montri taksitaj kostoj sen aĉeti per maljuskliga klavo + Klaki STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Aĉeti la emfazitan stratveturilon. Montri taksitaj kostoj sen aĉeti per maljuskliga klavo + Klaki STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Aĉeti la emfazitan ŝipon. Montri taksitaj kostoj sen aĉeti per maljuskliga klavo + Klaki STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Aĉeti la emfazitan aviadilon. Montri taksitaj kostoj sen aĉeti per maljuskliga klavo + Klaki + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Alinomi STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Alinomi STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Alinomi @@ -2938,13 +2931,16 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Vi vend # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Mesaĝo de veturil-produktanto STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Nova {STRING} estas inventita - ĉu vi ŝatus jaron ekskluzive uzi la veturilon, por ke ni povu vidi ĝian funkciadon antaŭ ol ĝi estos plene havebla? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :fervoja lokomotivo -STR_ENGINE_PREVIEW_ROAD_VEHICLE :stratveturilo -STR_ENGINE_PREVIEW_AIRCRAFT :aviadilo -STR_ENGINE_PREVIEW_SHIP :ŝipo STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :unurellokomotivo STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :magleva lokomotivo +STR_ENGINE_PREVIEW_ROAD_VEHICLE :stratveturilo + +STR_ENGINE_PREVIEW_AIRCRAFT :aviadilo +STR_ENGINE_PREVIEW_SHIP :ŝipo + STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Kosto: {CURRENCY_LONG} Pezo: {WEIGHT_SHORT}{}Rapido: {VELOCITY} Forto: {POWER}{}Irkosto: po {CURRENCY_LONG} jare{}Kapablo: {CARGO_LONG} STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Kosto: {CURRENCY_LONG} Pezo: {WEIGHT_SHORT}{}Rapido: {VELOCITY} Povo: {POWER} Maks. T.E.: {6:FORCE}{}Irkosto: {4:CURRENCY_LONG}/jaro{}Kapacito: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Kosto: {CURRENCY_LONG} Maks. Rapido: {VELOCITY}{}Kapacito: {CARGO_LONG}{}Irkosto: {CURRENCY_LONG}/jaro @@ -2978,6 +2974,7 @@ STR_REPLACE_ELRAIL_VEHICLES :Elektraj Relaj STR_REPLACE_MONORAIL_VEHICLES :Unurelaj Veturiloj STR_REPLACE_MAGLEV_VEHICLES :Maglevaj Veturiloj + STR_REPLACE_REMOVE_WAGON :{BLACK}Vagonforigo: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Ĉe aŭtomata anstataŭigo tenu saman longecon de la trajno per forigo de vagonoj (defronte), se per nova maŝino la trajno plilongiĝas @@ -3384,6 +3381,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Elekti e 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 STR_AI_SETTINGS_CAPTION_AI :AI @@ -3647,7 +3645,7 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Unue vi STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Nekonvena fervojtrako STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Antaŭe devas la trako esti detruita STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Strato estas unudirekta aŭ blokita -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Traknivelaj pasejoj ne permesa por ĉi tio fervojtipo +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Traknivelaj pasejoj ne permesa por ĉi tio fervojtipo STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Ne povas konstrui signalojn ĉi tie... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Ne povas konstrui trakon ĉi tie... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Ne povas forigi trakon de ĉi tie... diff --git a/src/lang/estonian.txt b/src/lang/estonian.txt index 38c8b62600..e6e2023a54 100644 --- a/src/lang/estonian.txt +++ b/src/lang/estonian.txt @@ -11,8 +11,6 @@ ##case g in sü -# $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. # 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. @@ -529,9 +527,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Lülita konsool sisse/välja STR_ABOUT_MENU_AI_DEBUG :Arvutivea otsing STR_ABOUT_MENU_SCREENSHOT :Ekraanitõmmis -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Suurendatud ekraanitõmmis -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Tavasuurendusega ekraanitõmmis -STR_ABOUT_MENU_GIANT_SCREENSHOT :Terve kaardi ekraanitõmmis STR_ABOUT_MENU_SHOW_FRAMERATE :Näita kaadrisagedust STR_ABOUT_MENU_ABOUT_OPENTTD :'OpenTTD' kohta STR_ABOUT_MENU_SPRITE_ALIGNER :Sprite aligner @@ -702,9 +697,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Omatehtud 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Muusika helitugevus STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Efektide helitugevus -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}VÄHIM -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}SUURIM -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -916,6 +908,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}Uus {STRING} saadaval! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}Jaam {STATION} ei võta enam vastu veost {STRING} STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}Jaam {STATION} ei võta enam vastu veoseid {STRING}, ega {STRING} STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}Jaam {STATION} võtab nüüd vastu veost {STRING} @@ -980,7 +973,9 @@ STR_GAME_OPTIONS_CURRENCY_ZAR :Lõuna-Aafrika STR_GAME_OPTIONS_CURRENCY_CUSTOM :Omatehtud... STR_GAME_OPTIONS_CURRENCY_GEL :Gruusia lari (GEL) STR_GAME_OPTIONS_CURRENCY_IRR :Iraani rial (IRR) +STR_GAME_OPTIONS_CURRENCY_RUB :Uus Vene rubla (RUB) STR_GAME_OPTIONS_CURRENCY_MXN :Mehhiko Peeso (MXN) +STR_GAME_OPTIONS_CURRENCY_HKD :Hong Kongi dollar (HKD) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Sõidukid @@ -1043,7 +1038,9 @@ 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 :Ruudu suurus +STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Vali kasutatav liideseelementide suurus +STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Ruudu suurus STR_GAME_OPTIONS_BASE_GRF :{BLACK}Alusgraafika kogu STR_GAME_OPTIONS_BASE_GRF_TOOLTIP :{BLACK}Valib kasutatava alusgraafika kogu @@ -1745,7 +1742,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Kaubaja STR_CONFIG_SETTING_AI :{ORANGE}Konkurendid STR_CONFIG_SETTING_AI_NPC :{ORANGE}Arvuti -STR_CONFIG_SETTING_PATHFINDER_OPF :Algne STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(soovitatud) @@ -1828,13 +1824,9 @@ STR_QUIT_NO :{BLACK}Ei # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -2464,6 +2456,7 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Ehita tr STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Lülitu maanteede ehitamise ja lammutamise vahel STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Lülitu trammitee ehitamise ja lammutamise vahel + # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Depoo suund STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}Vali depoole suund @@ -2646,6 +2639,7 @@ STR_LAND_AREA_INFORMATION_AIRPORTTILE_NAME :{BLACK}Lennujaa STR_LAND_AREA_INFORMATION_NEWGRF_NAME :{BLACK}NewGRF: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED :{BLACK}Vastuvõetavad veosed: {LTBLUE} STR_LAND_AREA_INFORMATION_CARGO_EIGHTS :({COMMA}/8 {STRING}) +STR_LANG_AREA_INFORMATION_TRAM_TYPE :{BLACK}Trammi tüüp: {LTBLUE}{STRING} STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT :{BLACK}Raudtee kiiruspiirang: {LTBLUE}{VELOCITY} STR_LANG_AREA_INFORMATION_ROAD_SPEED_LIMIT :{BLACK}Lubatud piirkiirus: {LTBLUE}{VELOCITY} @@ -2748,6 +2742,7 @@ STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD # Framerate display window STR_FRAMERATE_CAPTION :{WHITE}Kaadrisagedus +STR_FRAMERATE_RATE_GAMELOOP_TOOLTIP :{BLACK}Simuleeritud mänguhetkede arv sekundis. STR_FRAMERATE_RATE_BLITTER_TOOLTIP :{BLACK}Renderdatud videokaadrite arv sekundis. STR_FRAMERATE_AVERAGE :{WHITE}Keskmine STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL} ms @@ -2757,6 +2752,7 @@ STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMA STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL} kaadrit/s STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL} kaadrit/s ############ Leave those lines in this order!! +STR_FRAMERATE_GAMELOOP :{BLACK}Mängutsükli lõppkokkuvõte: STR_FRAMERATE_GL_AIRCRAFT :{BLACK} Õhusõiduki sammud: STR_FRAMERATE_GL_LINKGRAPH :{BLACK} Ahelgraafiku viide: STR_FRAMERATE_DRAWING :{BLACK}Graafika renderdamine: @@ -3338,8 +3334,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE} {COMPAN STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Raudtee tükid: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Signaalid STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Tee tükid: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Tee -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Trammitee STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Veekogu ruudud: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Kanalid STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Jaamad: @@ -3350,8 +3344,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Tööstused STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Puudub - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% veetud) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% veetud) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Tööstuste nimed - klõpsates keskendatakse vaade tööstusele. Ctrl+klõps avab uue vaate ettevõtte asukohast @@ -3413,6 +3405,7 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Rühmitamata s STR_GROUP_DEFAULT_SHIPS :Rühmitamata laevad STR_GROUP_DEFAULT_AIRCRAFTS :Rühmitamata õhusõidukid + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Rühm - Klõpsa rühmal, et kõiki seal olevaid sõidukeid järjestada STR_GROUP_CREATE_TOOLTIP :{BLACK}Klõpsa rühma loomiseks STR_GROUP_DELETE_TOOLTIP :{BLACK}Eemalda valitud rühm @@ -3428,6 +3421,7 @@ STR_GROUP_REMOVE_ALL_VEHICLES :Eemalda kõik s STR_GROUP_RENAME_CAPTION :{BLACK}Rühma nime vahetamine STR_GROUP_PROFIT_THIS_YEAR :Kasum sellel aastal: +STR_GROUP_OCCUPANCY_VALUE :{NUM}% # Build vehicle window STR_BUY_VEHICLE_TRAIN_RAIL_CAPTION :Uued rööbassõidukid @@ -3435,10 +3429,13 @@ 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_TRAIN_ALL_CAPTION :Rööbassõidukid STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Uued mootorsõidukid + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Rööbassõidukid STR_BUY_VEHICLE_SHIP_CAPTION :Uued laevad STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Uus lennuk +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Hind: {GOLD}{CURRENCY_LONG}{BLACK} Tühimass: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Tippkiirus: {GOLD}{VELOCITY}{BLACK} Võimsus: {GOLD}{POWER} @@ -3453,6 +3450,7 @@ STR_PURCHASE_INFO_RELIABILITY :{BLACK}Parim te STR_PURCHASE_INFO_COST :{BLACK}Hind: {GOLD}{CURRENCY_LONG} STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Mass: {GOLD}{WEIGHT_SHORT} {WEIGHT_SHORT}) STR_PURCHASE_INFO_COST_SPEED :{BLACK}Hind: {GOLD}{CURRENCY_LONG}{BLACK} Tippkiirus: {GOLD}{VELOCITY} +STR_PURCHASE_INFO_COST_REFIT_SPEED :{BLACK}Hind: {GOLD}{CURRENCY_LONG}{BLACK} (Ümberseadistamise maksumus: {GOLD}{CURRENCY_LONG}{BLACK}) Kiirus: {GOLD}{VELOCITY} STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Kandevõime: {GOLD}{CARGO_LONG}, {CARGO_LONG} STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Kiirendavad vagunid: {GOLD}+{POWER}{BLACK} Mass: {GOLD}+{WEIGHT_SHORT} STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Ümberseadistatav: {GOLD}{STRING} @@ -3471,11 +3469,13 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Ehita ve STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Ehita laev STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Ehita lennuk + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Osta valitud raudteesõiduk. Shift+klõpsuga kuvatakse eeldatav ostuhind STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Osta valitud mootorsõiduk. Shift+klõpsuga kuvatakse eeldatav ostuhind STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Osta valitud laev. Shift+klõpsuga kuvatakse eeldatav ostuhind STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Osta valitud õhusõiduk. Shift+klõpsuga kuvatakse eeldatav ostuhind + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Nimevahetus STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Nimevahetus STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Nimevahetus @@ -3584,13 +3584,16 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Sa oled # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Teade veovahendite tootjalt STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Me töötasime välja uue {STRING}. Kas te oleksite huvitatud selle ainuõiguslikust katsetamisest järgneva aasta jooksul, et me saaksime jälgida kuidas see toimib? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :raudteevedur -STR_ENGINE_PREVIEW_ROAD_VEHICLE :mootorsõiduk -STR_ENGINE_PREVIEW_AIRCRAFT :lennuk -STR_ENGINE_PREVIEW_SHIP :laev STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :monorelssvedur STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :magnethõljukvedur +STR_ENGINE_PREVIEW_ROAD_VEHICLE :mootorsõiduk + +STR_ENGINE_PREVIEW_AIRCRAFT :lennuk +STR_ENGINE_PREVIEW_SHIP :laev + 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_MAX_SPEED_CAP_RUNCOST :{BLACK}Hind: {CURRENCY_LONG} Tippkiirus: {VELOCITY}{}Kandevõime: {CARGO_LONG}{}Käituskulud: {CURRENCY_LONG}/a @@ -3634,6 +3637,8 @@ STR_REPLACE_ELRAIL_VEHICLES :Elektrirongid STR_REPLACE_MONORAIL_VEHICLES :Monorelssveerem STR_REPLACE_MAGLEV_VEHICLES :Magnethõljukveerem +STR_REPLACE_ROAD_VEHICLES :Maanteesõidukid + STR_REPLACE_REMOVE_WAGON :{BLACK}Vagunite eemaldus: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Sunni automaatset asendust hoidma rongi pikkust selleks (eest alustades) veeremit eemaldades, juhul kui uus vagun muudaks rongi pikemaks. @@ -4082,6 +4087,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Vali esi STR_AI_LIST_CANCEL :{BLACK}Loobu STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Ära skripti muuda + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parameetrid STR_AI_SETTINGS_CAPTION_AI :Tehismõistus @@ -4284,7 +4290,6 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... see STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... tee on vales suunas STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... nurgad ei saa läbisõidupeatustes olla STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... ristmikud ei saa olla läbisõidupeatustes -STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... tee on ühesuunaline või blokeeritud # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Siinset jaamablokki ei saa lammutada... @@ -4354,7 +4359,7 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Signaali STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Sobiv rongitee puudub STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Rööbastee tuleb eelnevalt lammutada STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Läbipääsmatu või ühesuunaline maantee -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Ülesõidukohad on selle raudteetüübi puhul keelatud +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Ülesõidukohad on selle raudteetüübi puhul keelatud STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Siia ei saa signaale rajada... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Siia ei saa raudteed ehitada... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Siit ei saa raudteed lammutada... @@ -4374,6 +4379,7 @@ STR_ERROR_CAN_T_REMOVE_ROAD_FROM :{WHITE}Siinset STR_ERROR_CAN_T_REMOVE_TRAMWAY_FROM :{WHITE}Siinset trammiteed ei saa lammutada... STR_ERROR_THERE_IS_NO_ROAD :{WHITE}... siin pole autoteed STR_ERROR_THERE_IS_NO_TRAMWAY :{WHITE}... siin pole trammiteed +STR_ERROR_INCOMPATIBLE_ROAD :{WHITE}... sobimatu tee # Waterway construction errors STR_ERROR_CAN_T_BUILD_CANALS :{WHITE}Siia ei saa kanaleid ehitada... @@ -4536,6 +4542,7 @@ STR_BASESOUNDS_DOS_DESCRIPTION :Algse Transport STR_BASESOUNDS_WIN_DESCRIPTION :Algse Transport Tycoon Deluxe Windowsi versiooni helid. STR_BASESOUNDS_NONE_DESCRIPTION :Helikogu ilma helideta. STR_BASEMUSIC_WIN_DESCRIPTION :Algse Transport Tycoon Deluxe Windowsi versiooni muusika. +STR_BASEMUSIC_DOS_DESCRIPTION :Algse Transport Tycoon Deluxe DOSi versiooni muusika. STR_BASEMUSIC_NONE_DESCRIPTION :Muusikakogu ilma muusikata. ##id 0x2000 diff --git a/src/lang/faroese.txt b/src/lang/faroese.txt index 1b7b1a062c..889cb350e2 100644 --- a/src/lang/faroese.txt +++ b/src/lang/faroese.txt @@ -11,8 +11,6 @@ ##gender m f n -# $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. # 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. @@ -450,9 +448,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Console opið ella lukka STR_ABOUT_MENU_AI_DEBUG :AI/Spæl script debug STR_ABOUT_MENU_SCREENSHOT :Skermmynd -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Suma in skermmynd -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Vanliga suma skermmynd -STR_ABOUT_MENU_GIANT_SCREENSHOT :Skermmynd av øllum kortinum STR_ABOUT_MENU_SHOW_FRAMERATE :Vís mynda títtleika STR_ABOUT_MENU_ABOUT_OPENTTD :Um 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Sprite aligner @@ -623,9 +618,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Sjálvgjørdur 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Tónleika ljóðstyrki STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Effekt ljóðstyrki -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}MIN -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}MAX -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}: STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -830,6 +822,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}Nýtt {STRING} til sølu! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} tekur ikki longur ímóti {STRING} STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} tekur ikki longur ímóti hvørki {STRING} ella {STRING} STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} tekur nú ímóti {STRING} @@ -1523,7 +1516,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_INDUSTRIES :{ORANGE}Ídnað STR_CONFIG_SETTING_AI :{ORANGE}Kappingarneytar STR_CONFIG_SETTING_AI_NPC :{ORANGE}Teldu spælarir -STR_CONFIG_SETTING_PATHFINDER_OPF :Upprunaligur STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Viðmældur) @@ -1591,13 +1583,9 @@ STR_QUIT_NO :{BLACK}Nei # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -2168,6 +2156,7 @@ STR_BRIDGE_TUBULAR_SILICON :Rør, silikon STR_ROAD_TOOLBAR_ROAD_CONSTRUCTION_CAPTION :{WHITE}Vegagerð STR_ROAD_TOOLBAR_TRAM_CONSTRUCTION_CAPTION :{WHITE}Sporvogna bygging + # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Akfars goymslu ætt STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}Vel hvønn veg akfars goymslan skal venda @@ -2894,8 +2883,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Innanker STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Jarnbreyta pettir: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Tekin STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Vega pettir: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Vegur -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Sporvognur STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Vatn puntar: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Siglingarennir STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Støðir: @@ -2906,8 +2893,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Ídnaðir STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Einki - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% flutt) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% flutt) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Ídnaðar nøvn - trýst á eitt navn fyri at savna høvuðs sýni á ídnað. Ctrl+trýst letur ein nýggjan sýnisglugga upp á ídnaðin @@ -2968,6 +2953,7 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Óbólkaði akf STR_GROUP_DEFAULT_SHIPS :Óbólkaði skip STR_GROUP_DEFAULT_AIRCRAFTS :Óbólkaði flogfør + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Bólkar - trýst á ein bólk fyri at síggja øll flutningstól í hesum bólki STR_GROUP_CREATE_TOOLTIP :{BLACK}Trýst fyri at gera ein bólk STR_GROUP_DELETE_TOOLTIP :{BLACK}Strika valda bólkin @@ -2987,10 +2973,13 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Nýggj ravmagns STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Nýggj einsporaði jarnbreyta flutningstól STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Nýggj maglev flutningstól -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Nýggj jarnbreyta flutningstól STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Nýggj akfør + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Nýggj jarnbreyta flutningstól STR_BUY_VEHICLE_SHIP_CAPTION :Nýggj skip STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Nýggj flogfør +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Kostnaður: {GOLD}{CURRENCY_LONG}{BLACK} Vekt: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Ferð: {GOLD}{VELOCITY}{BLACK} Megi: {GOLD}{POWER} @@ -3023,11 +3012,13 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Keyp akf STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Keyp skip STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Keyp flogfar + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Keyp undirstrikaða tok flutningstóli. Shift+trýst vísur kostnaðar meting uttan at keypa STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Keyp undirstrikaða akfari. Shift+trýst vísur kostnaðar meting uttan at keypa STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Keyp undirstrikaða skipi. Shift+trýst vísur kostnaðar meting uttan at keypa STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Keyp undirstrikaða flogfari. Shift+trýst vísur kostnaðar meting uttan at keypa + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Navngev STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Navngev STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Navngev @@ -3124,13 +3115,16 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Tú er # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Boð frá framleiðarinum av flutningstólinum STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Vit hava júst sniðgivi eitt nýtt {STRING} - hevði tú havt áhuga í einkarrættindum at nýtt hetta flutningstóli í eitt ár, so vit kunnu síggja hvussu ta virkar áðrenn vit gera ta tøkt á marknaðinum? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :jarnbreyta lokomotiv -STR_ENGINE_PREVIEW_ROAD_VEHICLE :{G=n}akfar -STR_ENGINE_PREVIEW_AIRCRAFT :{G=n}flogfar -STR_ENGINE_PREVIEW_SHIP :skip STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :einsporað lokomotiv STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :maglev lokomotiv +STR_ENGINE_PREVIEW_ROAD_VEHICLE :{G=n}akfar + +STR_ENGINE_PREVIEW_AIRCRAFT :{G=n}flogfar +STR_ENGINE_PREVIEW_SHIP :skip + STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Kostnaður: {CURRENCY_LONG} Vekt: {WEIGHT_SHORT}{}Ferð: {VELOCITY} Megi: {POWER}{}Rakstrar kostnaður: {CURRENCY_LONG}/ár{}Pláss: {CARGO_LONG} STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Kostnaður: {CURRENCY_LONG} Vekt: {WEIGHT_SHORT}{}Ferð: {VELOCITY} Megi: {POWER} Maks. D.Ó.: {6:FORCE}{}Rakstrar kostnaður: {4:CURRENCY_LONG}/ár{}Pláss: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Kostnaður: {CURRENCY_LONG} Maks. Ferð: {VELOCITY}{}Pláss: {CARGO_LONG}{}Rakstrar kostnaður: {CURRENCY_LONG}/ár @@ -3167,6 +3161,7 @@ STR_REPLACE_ELRAIL_VEHICLES :Ravmagns jarnbr STR_REPLACE_MONORAIL_VEHICLES :Einsporaði jarnbreyta flutningstól STR_REPLACE_MAGLEV_VEHICLES :Maglev flutningstól + STR_REPLACE_REMOVE_WAGON :{BLACK}Vogn burturrudding: {ORANGE}{STRING} # Vehicle view @@ -3526,6 +3521,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Vel undi STR_AI_LIST_CANCEL :{BLACK}Angra STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Ikki broyta scripti + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parametur STR_AI_SETTINGS_CAPTION_AI :AI @@ -3792,7 +3788,7 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Neyðugt STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Ikki hóskandi jarnbreyt STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Neyðugt at beina burtur jarnbreyt fyrst STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Vegur er einvegis ella blokeraður -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Javnir krossvegir ikki loyvdir fyri hetta slagi av tok bana +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Javnir krossvegir ikki loyvdir fyri hetta slagi av tok bana STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Kann ikki byggja jarnbreytatekin her... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Kann ikki byggja jarnbreyt her... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Kann ikki beina burtur jarnbreyt hagani... diff --git a/src/lang/finnish.txt b/src/lang/finnish.txt index f6dc2c7054..f4ae3ba4a9 100644 --- a/src/lang/finnish.txt +++ b/src/lang/finnish.txt @@ -10,8 +10,6 @@ ##grflangid 0x35 -# $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. # 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. @@ -237,6 +235,8 @@ STR_TOOLTIP_FILTER_CRITERIA :{BLACK}Valitse STR_BUTTON_SORT_BY :{BLACK}Lajittele STR_BUTTON_LOCATION :{BLACK}Sijainti STR_BUTTON_RENAME :{BLACK}Nimeä uudelleen +STR_BUTTON_CATCHMENT :{BLACK}Vaikutusalue +STR_TOOLTIP_CATCHMENT :{BLACK}Valitse, näytetäänkö vaikutusalue STR_TOOLTIP_CLOSE_WINDOW :{BLACK}Sulje ikkuna STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Ikkunan otsake – siirrä ikkunaa vetämällä tästä @@ -259,12 +259,13 @@ STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT :{BLACK}Näytä STR_SHOW_HIDDEN_ENGINES_VEHICLE_TRAIN_TOOLTIP :{BLACK}Kun otat tämän käyttöön, myös piilotetut junat näytetään STR_SHOW_HIDDEN_ENGINES_VEHICLE_ROAD_VEHICLE_TOOLTIP :{BLACK}Kun otat tämän käyttöön, myös piilotetut ajoneuvot näytetään STR_SHOW_HIDDEN_ENGINES_VEHICLE_SHIP_TOOLTIP :{BLACK}Kun otat tämän käyttöön, myös piilotetut laivat näytetään -STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT_TOOLTIP :{BLACK}Kun otat tämän käyttöön, myös piilotetut lentokoneet näytetään +STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT_TOOLTIP :{BLACK}Kun otat tämän käyttöön, myös piilotetut ilma-alukset näytetään # Query window STR_BUTTON_DEFAULT :{BLACK}Oletus STR_BUTTON_CANCEL :{BLACK}Peruuta STR_BUTTON_OK :{BLACK}OK +STR_WARNING_PASSWORD_SECURITY :{YELLOW}Varoitus: Palvelimen ylläpitäjät saattavat nähdä kaiken tähän kirjoittamasi. # On screen keyboard window STR_OSK_KEYBOARD_LAYOUT :§1234567890+´ qwertyuiopå¨asdfghjklöä' zxcvbnm,.- . @@ -333,11 +334,12 @@ STR_TOOLBAR_TOOLTIP_FUND_CONSTRUCTION_OF_NEW :{BLACK}Rahoita STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_TRAINS :{BLACK}Näytä luettelo yhtiön junista. Ctrl+Klik avaa ryhmä/kulkuneuvolistan STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_ROAD_VEHICLES :{BLACK}Näytä luettelo yhtiön ajoneuvoista. Ctrl+Klik avaa ryhmä/kulkuneuvoikkunan STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_SHIPS :{BLACK}Näytä luettelo yhtiön laivoista. Ctrl+Klik avaa ryhmä/kulkuneuvoikkunan -STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_AIRCRAFT :{BLACK}Näytä luettelo yhtiön lentokoneista. Ctrl+Klik avaa ryhmä/kulkuneuvoikkunan +STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_AIRCRAFT :{BLACK}Näytä luettelo yhtiön ilma-aluksista. Ctrl+Klik avaa ryhmä/kulkuneuvoikkunan STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN :{BLACK}Lähennä näkymää STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT :{BLACK}Loitonna näkymää STR_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Rakenna rautateitä STR_TOOLBAR_TOOLTIP_BUILD_ROADS :{BLACK}Rakenna teitä +STR_TOOLBAR_TOOLTIP_BUILD_TRAMWAYS :{BLACK}Rakenna raitioteitä STR_TOOLBAR_TOOLTIP_BUILD_SHIP_DOCKS :{BLACK}Rakenna satamia STR_TOOLBAR_TOOLTIP_BUILD_AIRPORTS :{BLACK}Rakenna lentokenttiä STR_TOOLBAR_TOOLTIP_LANDSCAPING :{BLACK}Avaa maastonmuokkaustyökalupalkki maan kohottamiseen/madaltamiseen, puiden istuttamiseen, jne. @@ -358,6 +360,7 @@ STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION :{BLACK}Maaston STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Kuntien luonti 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_PLACE_SIGN :{BLACK}Sijoita kyltti STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Sijoita objekti. Shift vaihtaa rakennustilan ja kustannusarvion välillä @@ -475,9 +478,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Konsoli STR_ABOUT_MENU_AI_DEBUG :Tekoälyn/peliskriptin virheenjäljitys STR_ABOUT_MENU_SCREENSHOT :Kuvakaappaus -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Täysin lähennetty kuvakaappaus -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Kuvakaappaus oletuslähennystasolla -STR_ABOUT_MENU_GIANT_SCREENSHOT :Koko kartan kuvakaappaus STR_ABOUT_MENU_SHOW_FRAMERATE :Näytä kuvataajuus STR_ABOUT_MENU_ABOUT_OPENTTD :Tietoja OpenTTD:stä STR_ABOUT_MENU_SPRITE_ALIGNER :Sprite-kohdistaja @@ -616,7 +616,7 @@ STR_PERFORMANCE_DETAIL_AMOUNT_INT :{BLACK}({COMMA} STR_PERFORMANCE_DETAIL_PERCENT :{WHITE}{NUM}% STR_PERFORMANCE_DETAIL_SELECT_COMPANY_TOOLTIP :{BLACK}Näytä tietoja tästä yhtiöstä ############ Those following lines need to be in this order!! -STR_PERFORMANCE_DETAIL_VEHICLES :{BLACK}Liikennevälineitä: +STR_PERFORMANCE_DETAIL_VEHICLES :{BLACK}Kulkuneuvot: STR_PERFORMANCE_DETAIL_STATIONS :{BLACK}Asemia: STR_PERFORMANCE_DETAIL_MIN_PROFIT :{BLACK}Vähimmäistuotto: STR_PERFORMANCE_DETAIL_MIN_INCOME :{BLACK}Vähimmäistulo: @@ -627,7 +627,7 @@ STR_PERFORMANCE_DETAIL_MONEY :{BLACK}Raha: STR_PERFORMANCE_DETAIL_LOAN :{BLACK}Laina: STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Yhteensä: ############ End of order list -STR_PERFORMANCE_DETAIL_VEHICLES_TOOLTIP :{BLACK}Liikennevälineiden määrä. Tähän kuuluvat ajoneuvot, junat, laivat ja lentokoneet +STR_PERFORMANCE_DETAIL_VEHICLES_TOOLTIP :{BLACK}Kulkuveuvojen määrä. Tähän kuuluvat ajoneuvot, junat, laivat ja ilma-alukset STR_PERFORMANCE_DETAIL_STATIONS_TOOLTIP :{BLACK}Asemien osien määrä. Kaikki osat asemista (esim. rautatieasema, bussipysäkki, lentokenttä) lasketaan, vaikka ne olisivat yhdistettynä yhdeksi asemaksi STR_PERFORMANCE_DETAIL_MIN_PROFIT_TOOLTIP :{BLACK}Vähätuottoisimman kulkuneuvon tulo (kaikkien yli 2 vuotta vanhojen kulkuneuvojen) STR_PERFORMANCE_DETAIL_MIN_INCOME_TOOLTIP :{BLACK}Viimeisen 12 neljänneksen vähätuottoisimman kuun käteistuoton määrä @@ -648,9 +648,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Oma 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Musiikin voimakkuus STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Äänitehosteiden voimakkuus -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}MIN -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}MAX -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -706,7 +703,7 @@ STR_HIGHSCORE_PRESIDENT_OF_COMPANY_ACHIEVES_STATUS :{BIG_FONT}{WHIT STR_SMALLMAP_CAPTION :{WHITE}Kartta – {STRING} STR_SMALLMAP_TYPE_CONTOURS :Korkeuserot -STR_SMALLMAP_TYPE_VEHICLES :Liikennevälineet +STR_SMALLMAP_TYPE_VEHICLES :Kulkuneuvot STR_SMALLMAP_TYPE_INDUSTRIES :Teollisuus STR_SMALLMAP_TYPE_ROUTEMAP :Rahtivirta STR_SMALLMAP_TYPE_ROUTES :Reitit @@ -727,11 +724,11 @@ STR_SMALLMAP_LEGENDA_ROADS :{TINY_FONT}{BLA STR_SMALLMAP_LEGENDA_RAILROADS :{TINY_FONT}{BLACK}Rautatiet STR_SMALLMAP_LEGENDA_STATIONS_AIRPORTS_DOCKS :{TINY_FONT}{BLACK}Asemat/lentokentät/satamat STR_SMALLMAP_LEGENDA_BUILDINGS_INDUSTRIES :{TINY_FONT}{BLACK}Rakennukset/Teollisuus -STR_SMALLMAP_LEGENDA_VEHICLES :{TINY_FONT}{BLACK}Liikennevälineet +STR_SMALLMAP_LEGENDA_VEHICLES :{TINY_FONT}{BLACK}Kulkuneuvot STR_SMALLMAP_LEGENDA_TRAINS :{TINY_FONT}{BLACK}Junat STR_SMALLMAP_LEGENDA_ROAD_VEHICLES :{TINY_FONT}{BLACK}Ajoneuvot STR_SMALLMAP_LEGENDA_SHIPS :{TINY_FONT}{BLACK}Laivat -STR_SMALLMAP_LEGENDA_AIRCRAFT :{TINY_FONT}{BLACK}Lentokoneet +STR_SMALLMAP_LEGENDA_AIRCRAFT :{TINY_FONT}{BLACK}Ilma-alukset STR_SMALLMAP_LEGENDA_TRANSPORT_ROUTES :{TINY_FONT}{BLACK}Kuljetusreitit STR_SMALLMAP_LEGENDA_FOREST :{TINY_FONT}{BLACK}Metsä STR_SMALLMAP_LEGENDA_RAILROAD_STATION :{TINY_FONT}{BLACK}Rautatieasema @@ -792,11 +789,11 @@ STR_NEWS_FIRST_CARGO_TRAM_ARRIVAL :{BIG_FONT}{BLAC STR_NEWS_FIRST_SHIP_ARRIVAL :{BIG_FONT}{BLACK}Asukkaat juhlivat . . .{}{STATION} vastaanottaa ensimmäisen laivan! STR_NEWS_FIRST_AIRCRAFT_ARRIVAL :{BIG_FONT}{BLACK}Asukkaat juhlivat . . .{}{STATION} vastaanottaa ensimmäisen lentokoneen! -STR_NEWS_TRAIN_CRASH :{BIG_FONT}{BLACK}Junaonnettomuus!{}{COMMA} kuolee törmäyksen jälkeisessä tulipallossa. -STR_NEWS_ROAD_VEHICLE_CRASH_DRIVER :{BIG_FONT}{BLACK}Tasoristeysturma!{}Kuljettaja kuolee junan ja auton törmäyksen jälkeisessä tulipallossa -STR_NEWS_ROAD_VEHICLE_CRASH :{BIG_FONT}{BLACK}Tasoristeysturma!{}{COMMA} kuolee junan ja auton törmäyksen jälkeisessä tulipallossa -STR_NEWS_AIRCRAFT_CRASH :{BIG_FONT}{BLACK}Lento-onnettomuus!{}{COMMA} kuolee tulipallossa asemalla {STATION}. -STR_NEWS_PLANE_CRASH_OUT_OF_FUEL :{BIG_FONT}{BLACK}Lento-onnettomuus!{}Lentokoneelta loppui polttoaine, {COMMA} kuolee tulipallossa +STR_NEWS_TRAIN_CRASH :{BIG_FONT}{BLACK}Junaonnettomuus!{}{COMMA} kuollut törmäyksen jälkeisessä tulipallossa +STR_NEWS_ROAD_VEHICLE_CRASH_DRIVER :{BIG_FONT}{BLACK}Tasoristeysturma!{}Kuljettaja kuollut junan ja auton törmäyksen jälkeisessä tulipallossa +STR_NEWS_ROAD_VEHICLE_CRASH :{BIG_FONT}{BLACK}Tasoristeysturma!{}{COMMA} kuoli junan ja auton törmäyksen jälkeisessä tulipallossa +STR_NEWS_AIRCRAFT_CRASH :{BIG_FONT}{BLACK}Lento-onnettomuus!{}{1:STATION}: {0:COMMA} kuollut tulipallossa +STR_NEWS_PLANE_CRASH_OUT_OF_FUEL :{BIG_FONT}{BLACK}Lento-onnettomuus!{}Polttoaineen loppuminen johti {COMMA} ihmisen kuolemaan tulipallossa STR_NEWS_DISASTER_ZEPPELIN :{BIG_FONT}{BLACK}{STATION}: Ilmalaivaonnettomuus! STR_NEWS_DISASTER_SMALL_UFO :{BIG_FONT}{BLACK}Ajoneuvo tuhoutui törmäyksessä UFO:n kanssa! @@ -867,6 +864,8 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}Uusi {STRING} on nyt saatavilla! – {ENGINE} +STR_NEWS_SHOW_VEHICLE_GROUP_TOOLTIP :{BLACK}Avaa ryhmäikkuna kulkuneuvon ryhmään kohdistettuna + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} ei ota enää vastaan {STRING}. STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} ei ota enää vastaan {STRING} tai {STRING}. STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} ottaa nyt vastaan {STRING}. @@ -933,6 +932,9 @@ STR_GAME_OPTIONS_CURRENCY_GEL :Georgian lari ( STR_GAME_OPTIONS_CURRENCY_IRR :Iranin rial (IRR) STR_GAME_OPTIONS_CURRENCY_RUB :Uusi Venäjän rupla (RUB) STR_GAME_OPTIONS_CURRENCY_MXN :Meksikon peso (MXN) +STR_GAME_OPTIONS_CURRENCY_NTD :Uusi Taiwanin dollari (TWD) +STR_GAME_OPTIONS_CURRENCY_CNY :Kiinan renminbi (CNY) +STR_GAME_OPTIONS_CURRENCY_HKD :Hongkongin dollari (HKD) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Kulkuneuvot @@ -1184,6 +1186,8 @@ STR_CONFIG_SETTING_AUTOSLOPE :Salli maaston m STR_CONFIG_SETTING_AUTOSLOPE_HELPTEXT :Sallii maaston muokkaamisen rakennusten ja ratojen alta tuhoamatta niitä STR_CONFIG_SETTING_CATCHMENT :Realistisemman kokoiset vaikutusalueet: {STRING} STR_CONFIG_SETTING_CATCHMENT_HELPTEXT :Erityyppisillä asemilla ja lentokentillä on eri kokoiset vaikutusalueet +STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES :Yhtiöiden asemat voivat palvella laitoksia, joilla on omat asemat: {STRING} +STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES_HELPTEXT :Mikäli käytössä, asemilla valmiiksi varustettuja teollisuuslaitoksia (kuten öljylauttoja) voivat palvella myös yhtiöiden lähistölle rakentamat asemat. Mikäli pois käytöstä, tällaisia laitoksia voivat palvella vain niiden omat asemat. Lähistöllä olevat yhtiöiden asemat eivät tällöin voi palvella näitä laitoksia, eivätkä laitosten asemat palvele muita kuin näitä laitoksia STR_CONFIG_SETTING_EXTRADYNAMITE :Kunnan omistamien teiden, siltojen ja tunneleiden raivaaminen sallittu: {STRING} STR_CONFIG_SETTING_EXTRADYNAMITE_HELPTEXT :Tekee kuntien omistaman infrastruktuurin ja rakennusten tuhoamisesta helpompaa STR_CONFIG_SETTING_TRAIN_LENGTH :Junien maksimipituus: {STRING} @@ -1200,8 +1204,8 @@ STR_CONFIG_SETTING_TRAIN_SLOPE_STEEPNESS_HELPTEXT :Mäkien jyrkkyy STR_CONFIG_SETTING_PERCENTAGE :{COMMA}{NBSP}% STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS :Mäkien jyrkkyys ajoneuvoille: {STRING} STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS_HELPTEXT :Mäkien jyrkkyys ajoneuvoille. Korkeammat arvot tekevät mäkien nousemisesta vaikeampaa -STR_CONFIG_SETTING_FORBID_90_DEG :90 asteen käännökset kielletty junilta ja laivoilta: {STRING} -STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :90 asteen käännöksiä esiintyy kun vaakasuuntaista rataa seuraa pystysuuntainen rata viereisellä ruudulla, tämä vaatii junan kääntymään 90 astetta ruutujen reunalla normaalin 45 asteen sijasta. Tämä asetus vaikuttaa myös laivojen kääntymissäteeseen +STR_CONFIG_SETTING_FORBID_90_DEG :90 asteen käännökset kielletty junilta: {STRING} +STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :90 asteen käännöksiä esiintyy kun vaakasuuntaista rataa seuraa pystysuuntainen rata viereisellä ruudulla, tämä vaatii junan kääntymään 90 astetta ruutujen reunalla normaalin 45 asteen sijasta. STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS :Salli ei-vierekkäisten asemien yhdistäminen: {STRING} STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS_HELPTEXT :Mahdollistaa aseman osien rakentamisen vaikka ne eivät olisi kosketuksissa olemassaoleviin aseman osiin. Vaatii Ctrl-näppäimen painamisen rakennettaessa STR_CONFIG_SETTING_INFLATION :Inflaatio: {STRING} @@ -1254,11 +1258,11 @@ STR_CONFIG_SETTING_ALLOW_GIVE_MONEY_HELPTEXT :Sallii rahan si STR_CONFIG_SETTING_FREIGHT_TRAINS :Rahdin painokerroin raskaiden junien simulointia varten: {STRING} STR_CONFIG_SETTING_FREIGHT_TRAINS_HELPTEXT :Määritä rahdin kuljettamisen vaikutus junissa. Korkeammat arvot tekevät rahdin kuljettamisesta raskaampaa junille, erityisesti mäissä STR_CONFIG_SETTING_PLANE_SPEED :Lentokoneiden nopeuskerroin: {STRING} -STR_CONFIG_SETTING_PLANE_SPEED_HELPTEXT :Määritä lentokoneiden suhteellinen nopeus verrattuna toisiin kulkuneuvotyyppeihin +STR_CONFIG_SETTING_PLANE_SPEED_HELPTEXT :Määritä lentokoneiden suhteellinen nopeus verrattuna toisiin kulkuneuvotyyppeihin, jotta vähennetään ilma-alusksilla tehtyjen kuljetusten tuottoa STR_CONFIG_SETTING_PLANE_SPEED_VALUE :1 / {COMMA} STR_CONFIG_SETTING_PLANE_CRASHES :Lento-onnettomuuksien määrä: {STRING} -STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Määrittää lento-onnettomuuksien todennäköisyyden -STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Ei yhtään +STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Määrittää lento-onnettomuuksien todennäköisyyden.{}¹ Isot lentokoneet voivat kuitenkin aina tuhoutua pienille lentokentille laskeutuessaan. +STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Ei yhtään¹ STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Vähennetty STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Tavallinen STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Läpiajettavat pysäkit kuntien omistamille teille: {STRING} @@ -1305,6 +1309,8 @@ STR_CONFIG_SETTING_POPULATION_IN_LABEL :Näytä kunnan STR_CONFIG_SETTING_POPULATION_IN_LABEL_HELPTEXT :Näytä kuntien asukasluvut kartalla STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS :Viivojen paksuus kuvaajissa: {STRING} STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Viivan leveys kuvaajissa. Ohut viiva on tarkasti luettavissa kun taas paksumpi viiva on helpompi nähdä ja sen värit ovat helpommin havaittavissa +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_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 @@ -1316,8 +1322,8 @@ STR_CONFIG_SETTING_TERRAIN_TYPE :Maaston tyyppi: STR_CONFIG_SETTING_TERRAIN_TYPE_HELPTEXT :(Vain TerraGenesis) Maaston mäkisyys STR_CONFIG_SETTING_INDUSTRY_DENSITY :Teollisuuden määrä: {STRING} STR_CONFIG_SETTING_INDUSTRY_DENSITY_HELPTEXT :Määritä, kuinka paljon teollisuutta tulisi luoda ja millä tasolla teollisuuden tulisi pysytellä pelin aikana -STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE :Suurin sallittu etäisyys kartan reunoilta öljynjalostamoille: {STRING} -STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :Öljynjalostamoja rakennetaan ainoastaan kartan reunoille eli rannikoille saarikartoilla +STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE :Suurin sallittu etäisyys kartan reunoilta öljyteollisuudelle: {STRING} +STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :Öljynjalostamojen ja öljylauttojen suurin etäisyys kartan reunasta. Saarikartoilla tämä takaa sen, että ne ovat lähellä rannikkoa. Yli 256 ruudun kartoilla tätä arvoa suurennetaan suhteessa kartan kokoon. STR_CONFIG_SETTING_SNOWLINE_HEIGHT :Lumirajan korkeus: {STRING} STR_CONFIG_SETTING_SNOWLINE_HEIGHT_HELPTEXT :Määritä, millä korkeudella lumiraja on pohjoisessa maastotyypissä. Lumi vaikuttaa teollisuuslaitosten luontiin sekä kuntien kasvuedellytyksiin STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN :Maaston epätasaisuus: {STRING} @@ -1457,8 +1463,8 @@ STR_CONFIG_SETTING_MAX_TRAINS :Suurin sallittu STR_CONFIG_SETTING_MAX_TRAINS_HELPTEXT :Yhtiön suurin sallittu junien määrä STR_CONFIG_SETTING_MAX_ROAD_VEHICLES :Suurin sallittu ajoneuvojen määrä yhtiötä kohden: {STRING} STR_CONFIG_SETTING_MAX_ROAD_VEHICLES_HELPTEXT :Yhtiön suurin sallittu ajoneuvojen määrä -STR_CONFIG_SETTING_MAX_AIRCRAFT :Suurin sallittu lentokoneiden määrä yhtiötä kohden: {STRING} -STR_CONFIG_SETTING_MAX_AIRCRAFT_HELPTEXT :Yhtiön suurin sallittu lentokoneiden määrä +STR_CONFIG_SETTING_MAX_AIRCRAFT :Suurin sallittu ilma-alusten määrä yhtiötä kohden: {STRING} +STR_CONFIG_SETTING_MAX_AIRCRAFT_HELPTEXT :Yhtiön suurin sallittu ilma-alusten määrä STR_CONFIG_SETTING_MAX_SHIPS :Suurin sallittu laivojen määrä yhtiötä kohden: {STRING} STR_CONFIG_SETTING_MAX_SHIPS_HELPTEXT :Yhtiön suurin sallittu laivojen määrä @@ -1466,8 +1472,8 @@ STR_CONFIG_SETTING_AI_BUILDS_TRAINS :Tietokoneella e STR_CONFIG_SETTING_AI_BUILDS_TRAINS_HELPTEXT :Mikäli käytössä, junien rakentaminen ei ole mahdollista tietokonepelaajille STR_CONFIG_SETTING_AI_BUILDS_ROAD_VEHICLES :Tietokoneella ei ole ajoneuvoja: {STRING} STR_CONFIG_SETTING_AI_BUILDS_ROAD_VEHICLES_HELPTEXT :Mikäli käytössä, ajoneuvojen rakentaminen ei ole mahdollista tietokonepelaajille -STR_CONFIG_SETTING_AI_BUILDS_AIRCRAFT :Tietokoneella ei ole lentokoneita: {STRING} -STR_CONFIG_SETTING_AI_BUILDS_AIRCRAFT_HELPTEXT :Mikäli käytössä, lentokoneiden rakentaminen ei ole mahdollista tietokonepelaajille +STR_CONFIG_SETTING_AI_BUILDS_AIRCRAFT :Tietokoneella ei ole ilma-aluksia: {STRING} +STR_CONFIG_SETTING_AI_BUILDS_AIRCRAFT_HELPTEXT :Mikäli käytössä, ilma-alusten rakentaminen ei ole mahdollista tietokonepelaajille STR_CONFIG_SETTING_AI_BUILDS_SHIPS :Tietokoneella ei ole laivoja: {STRING} STR_CONFIG_SETTING_AI_BUILDS_SHIPS_HELPTEXT :Mikäli käytössä, laivojen rakentaminen ei ole mahdollista tietokonepelaajille @@ -1481,6 +1487,9 @@ STR_CONFIG_SETTING_AI_IN_MULTIPLAYER :Salli tekoälyt STR_CONFIG_SETTING_AI_IN_MULTIPLAYER_HELPTEXT :Sallii tietokonepelaajien osallistumisen moninpeleihin STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES :#opcodet ennen skriptin pysäyttämistä: {STRING} STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES_HELPTEXT :Suurin sallittu määrä laskutoimituksia, jonka skripti voi suorittaa yhden vuoron aikana +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY :Skriptikohtainen muistinkäyttö enintään: {STRING} +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_HELPTEXT :Kuinka paljon muistia yksittäinen skripti saa käyttää, ennen kuin se pakotetaan lopettamaan. Jos kartta on iso, tätä arvoa voi joutua suurentamaan. +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_VALUE :{COMMA} MiB STR_CONFIG_SETTING_SERVINT_ISPERCENT :Huoltovälit ovat prosentteina: {STRING} STR_CONFIG_SETTING_SERVINT_ISPERCENT_HELPTEXT :Määritä, aiheuttaako edellisestä huollosta kulunut aika vai luotettavuuden laskeminen kulkuneuvon huoltamisen @@ -1539,10 +1548,16 @@ STR_CONFIG_SETTING_NEWS_MESSAGES_FULL :Täysi STR_CONFIG_SETTING_COLOURED_NEWS_YEAR :Värilliset uutiset ilmestyvät: {STRING} STR_CONFIG_SETTING_COLOURED_NEWS_YEAR_HELPTEXT :Vuosi, jonka jälkeen sanomalehdet ovat värillisiä. Ennen tätä vuotta sanomalehdet käyttävät mustavalkoisia kuvia STR_CONFIG_SETTING_STARTING_YEAR :Aloitusvuosi: {STRING} +STR_CONFIG_SETTING_ENDING_YEAR :Pistelaskun päättymisvuosi: {STRING} +STR_CONFIG_SETTING_ENDING_YEAR_HELPTEXT :Pelin päättymisvuosi pisteiden laskemista varten. Tämän vuoden lopussa talletetaan yhtiön pistemäärä ja näytetään ennätysluettelo; pelaajat voivat jatkaa pelaamista tämän jälkeenkin.{}Jos päättymisvuosi on ennen alkamisvuotta, ennätyksiä ei näytetä koskaan. +STR_CONFIG_SETTING_ENDING_YEAR_VALUE :{NUM} +STR_CONFIG_SETTING_ENDING_YEAR_ZERO :Ei koskaan STR_CONFIG_SETTING_SMOOTH_ECONOMY :Tasainen talous (enemmän pieniä muutoksia): {STRING} STR_CONFIG_SETTING_SMOOTH_ECONOMY_HELPTEXT :Mikäli käytössä, teollisuuden tuotanto muuttuu useammin ja vähemmän kerrallaan. Tällä asetuksella ei ole yleensä vaikutusta mikäli teollisuustyypit ovat NewGRF:n tarjoamia STR_CONFIG_SETTING_ALLOW_SHARES :Salli toisten yhtiöiden osakkeiden ostaminen: {STRING} STR_CONFIG_SETTING_ALLOW_SHARES_HELPTEXT :Mikäli käytössä, toisten yhtiöiden osakkeiden ostaminen ja myyminen on mahdollista. Osakkeet ovat saatavilla vain yhtiöille, jotka ovat saavuttaneet tietyn iän +STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES :Yhtiön vähimmäisikä osakekaupoille: {STRING} +STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES_HELPTEXT :Aseta yhtiölle vähimmäisikä, jonka jälkeen muut voivat ostaa ja myydä yhtiön osakkeita. STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE :Syöttöjärjestelmään maksettavan tuoton osuus: {STRING} STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE_HELPTEXT :Osuus tuotosta, joka annetaan välittäjille syöttöjärjestelmissä STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY :Opastimien väli vedettäessä: {STRING} @@ -1583,6 +1598,10 @@ STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :Mikäli käytö STR_CONFIG_SETTING_TOWN_FOUNDING_FORBIDDEN :Kielletty STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED :Sallittu STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED_CUSTOM_LAYOUT :Sallittu, oma tiekaava +STR_CONFIG_SETTING_TOWN_CARGOGENMODE :Taajamarahdin luonti: {STRING} +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_HELPTEXT :Talojen tuottaman rahdin määrä suhteessa kunnan asukaslukuun.{}Neliöllinen kasvu: Kaksinkertainen asukasmäärä tuottaa matkustajia nelinkertaisesti.{}Lineaarinen kasvu: Kaksinkertainen asukasmäärä tuottaa matkustajia kaksinkertaisesti. +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_ORIGINAL :Neliöllinen (alkuperäinen) +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_BITCOUNT :Lineaarinen STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :Puiden istutus pelissä: {STRING} STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :Määrittää puiden sattumanvaraisen luomisen. Tämä voi vaikuttaa teollisuuslaitoksiin jotka ovat riippuvaisia puiden kasvamisesta, esimerkiksi sahat @@ -1710,7 +1729,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Rahdin STR_CONFIG_SETTING_AI :{ORANGE}Kilpailijat STR_CONFIG_SETTING_AI_NPC :{ORANGE}Tietokonepelaajat -STR_CONFIG_SETTING_PATHFINDER_OPF :Alkuperäinen STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Suositeltu) @@ -1794,13 +1812,9 @@ STR_QUIT_NO :{BLACK}Ei # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -1835,7 +1849,7 @@ STR_LIVERY_GENERAL_TOOLTIP :{BLACK}Näytä STR_LIVERY_TRAIN_TOOLTIP :{BLACK}Näytä junien väriteemat STR_LIVERY_ROAD_VEHICLE_TOOLTIP :{BLACK}Näytä tieajoneuvojen väriteemat STR_LIVERY_SHIP_TOOLTIP :{BLACK}Näytä laivojen väriteemat -STR_LIVERY_AIRCRAFT_TOOLTIP :{BLACK}Näytä lentokoneiden väriteemat +STR_LIVERY_AIRCRAFT_TOOLTIP :{BLACK}Näytä ilma-alusten väriteemat STR_LIVERY_PRIMARY_TOOLTIP :{BLACK}Valitse valitulle teemalle ensisijainen väri. Ctrl+Klik asettaa tämän värin jokaiselle teemalle STR_LIVERY_SECONDARY_TOOLTIP :{BLACK}Valitse valitulle teemalle toissijainen väri. Ctrl+Klik asettaa tämän värin jokaiselle teemalle STR_LIVERY_PANEL_TOOLTIP :{BLACK}Valitse muutettava väriteema, tai valitse useita Ctrl pohjassa. Paina valintalaatikkoa valitaksesi teeman @@ -2138,7 +2152,7 @@ STR_NETWORK_CHAT_ALL :[Kaikki] {STRIN STR_NETWORK_CHAT_OSKTITLE :{BLACK}Syötä teksti verkkokeskustelua varten # Network messages -STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}Verkkolaitteita ei löytynyt tai käännetty ilman ENABLE_NETWORK-valintaa +STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}Verkkolaitteita ei löytynyt STR_NETWORK_ERROR_NOSERVER :{WHITE}Verkkopelejä ei löytynyt STR_NETWORK_ERROR_NOCONNECTION :{WHITE}Palvelin ei vastannut pyyntöön STR_NETWORK_ERROR_NEWGRF_MISMATCH :{WHITE}Yhteyden muodostaminen epäonnistui NewGRF-virheen vuoksi @@ -2430,6 +2444,11 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL :{BLACK}Rakenna STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Rakenna raitiotietunneli. Shift vaihtaa rakennustilan ja kustannusarvion välillä STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Tien rakentaminen/siirtäminen päälle/pois STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Vaihda raitiotien rakentamisen ja purkamisen välillä +STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_ROAD :{BLACK}Muunna tai päivitä tien tyyppi. Shift vaihtaa muuntotilan ja kustannusarvion välillä +STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_TRAM :{BLACK}Muunna tai päivitä raitiotien tyyppi. Shift vaihtaa muuntotilan ja kustannusarvion välillä + +STR_ROAD_NAME_ROAD :Tie +STR_ROAD_NAME_TRAM :Raitiotie # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Autovarikon suunta @@ -2614,8 +2633,11 @@ STR_LAND_AREA_INFORMATION_NEWGRF_NAME :{BLACK}NewGRF: STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED :{BLACK}Vastaanottaa rahtia: {LTBLUE} STR_LAND_AREA_INFORMATION_CARGO_EIGHTS :({COMMA}/8 {STRING}) STR_LANG_AREA_INFORMATION_RAIL_TYPE :{BLACK}Raidetyyppi: {LTBLUE}{STRING} +STR_LANG_AREA_INFORMATION_ROAD_TYPE :{BLACK}Tien tyyppi: {LTBLUE}{STRING} +STR_LANG_AREA_INFORMATION_TRAM_TYPE :{BLACK}Raitiotien tyyppi: {LTBLUE}{STRING} STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT :{BLACK}Radan nopeusrajoitus: {LTBLUE}{VELOCITY} STR_LANG_AREA_INFORMATION_ROAD_SPEED_LIMIT :{BLACK}Tien nopeusrajoitus: {LTBLUE}{VELOCITY} +STR_LANG_AREA_INFORMATION_TRAM_SPEED_LIMIT :{BLACK}Raitiotien nopeusrajoitus: {LTBLUE}{VELOCITY} # Description of land area of different tiles STR_LAI_CLEAR_DESCRIPTION_ROCKS :Kalliota @@ -2725,6 +2747,7 @@ STR_FRAMERATE_SPEED_FACTOR :{BLACK}Pelin ny STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}Pelin tämänhetkinen nopeus verrattuna normaalilla simulaationopeudella odotettavissa olevaan STR_FRAMERATE_CURRENT :{WHITE}Nykyinen STR_FRAMERATE_AVERAGE :{WHITE}Keskiarvo +STR_FRAMERATE_MEMORYUSE :{WHITE}Muisti STR_FRAMERATE_DATA_POINTS :{BLACK}Data perustuu {COMMA} mittaukseen STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL} ms STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL} ms @@ -2732,6 +2755,9 @@ STR_FRAMERATE_MS_BAD :{RED}{DECIMAL} STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL} kuvaa/s STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL} kuvaa/s STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL} kuvaa/s +STR_FRAMERATE_BYTES_GOOD :{LTBLUE}{BYTES} +STR_FRAMERATE_BYTES_WARN :{YELLOW}{BYTES} +STR_FRAMERATE_BYTES_BAD :{RED}{BYTES} STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} ms STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} s ############ Leave those lines in this order!! @@ -3098,6 +3124,8 @@ STR_TOWN_VIEW_RENAME_TOWN_BUTTON :Nimeä kunta # Town local authority window STR_LOCAL_AUTHORITY_CAPTION :{WHITE}{TOWN}: viranomaiset +STR_LOCAL_AUTHORITY_ZONE :{BLACK}Alue +STR_LOCAL_AUTHORITY_ZONE_TOOLTIP :{BLACK}Näytä paikallisviranomaisten hallinnoiman alueen raja STR_LOCAL_AUTHORITY_COMPANY_RATINGS :{BLACK}Kuljetusyhtiön arvioinnit: STR_LOCAL_AUTHORITY_COMPANY_RATING :{YELLOW}{COMPANY} {COMPANY_NUM}: {ORANGE}{STRING} STR_LOCAL_AUTHORITY_ACTIONS_TITLE :{BLACK}Toiminnot: @@ -3259,7 +3287,7 @@ STR_STATION_VIEW_SCHEDULED_SHIPS_TOOLTIP :{BLACK}Näytä STR_STATION_VIEW_RENAME_STATION_CAPTION :Nimeä asema/lastausalue STR_STATION_VIEW_CLOSE_AIRPORT :{BLACK}Sulje lentokenttä -STR_STATION_VIEW_CLOSE_AIRPORT_TOOLTIP :{BLACK}Estä lentokoneiden laskeutuminen tälle lentokentälle +STR_STATION_VIEW_CLOSE_AIRPORT_TOOLTIP :{BLACK}Estä ilma-aluksia laskeutumasta tälle lentokentälle # Waypoint/buoy view window STR_WAYPOINT_VIEW_CAPTION :{WHITE}{WAYPOINT} @@ -3278,12 +3306,12 @@ STR_FINANCES_SECTION_CONSTRUCTION :{GOLD}Rakentami STR_FINANCES_SECTION_NEW_VEHICLES :{GOLD}Uudet kulkuneuvot STR_FINANCES_SECTION_TRAIN_RUNNING_COSTS :{GOLD}Junien käyttökustannukset STR_FINANCES_SECTION_ROAD_VEHICLE_RUNNING_COSTS :{GOLD}Ajoneuvojen käyttökustannukset -STR_FINANCES_SECTION_AIRCRAFT_RUNNING_COSTS :{GOLD}Lentokoneiden käyttökustannukset +STR_FINANCES_SECTION_AIRCRAFT_RUNNING_COSTS :{GOLD}Ilma-alusten käyttökustannukset STR_FINANCES_SECTION_SHIP_RUNNING_COSTS :{GOLD}Laivojen käyttökustannukset STR_FINANCES_SECTION_PROPERTY_MAINTENANCE :{GOLD}Omaisuudenhallinta STR_FINANCES_SECTION_TRAIN_INCOME :{GOLD}Junien tulot STR_FINANCES_SECTION_ROAD_VEHICLE_INCOME :{GOLD}Ajoneuvojen tulot -STR_FINANCES_SECTION_AIRCRAFT_INCOME :{GOLD}Lentokoneiden tulot +STR_FINANCES_SECTION_AIRCRAFT_INCOME :{GOLD}Ilma-alusten tulot STR_FINANCES_SECTION_SHIP_INCOME :{GOLD}Laivojen tulot STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}Lainan korko STR_FINANCES_SECTION_OTHER :{GOLD}Muuta @@ -3309,7 +3337,7 @@ STR_COMPANY_VIEW_COLOUR_SCHEME_TITLE :{GOLD}Väriteem STR_COMPANY_VIEW_VEHICLES_TITLE :{GOLD}Kulkuneuvot: STR_COMPANY_VIEW_TRAINS :{WHITE}{COMMA} juna{P "" a} STR_COMPANY_VIEW_ROAD_VEHICLES :{WHITE}{COMMA} ajoneuvo{P "" a} -STR_COMPANY_VIEW_AIRCRAFT :{WHITE}{COMMA} lentokone{P "" tta} +STR_COMPANY_VIEW_AIRCRAFT :{WHITE}{COMMA} ilma-alus{P "" ta} STR_COMPANY_VIEW_SHIPS :{WHITE}{COMMA} laiva{P "" a} STR_COMPANY_VIEW_VEHICLES_NONE :{WHITE}Ei mitään STR_COMPANY_VIEW_COMPANY_VALUE :{GOLD}Yhtiön arvo: {WHITE}{CURRENCY_LONG} @@ -3355,8 +3383,7 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}{COMPANY STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Rautatiepalat: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Opastimet STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Teiden palat: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Tie -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Raitiotie +STR_COMPANY_INFRASTRUCTURE_VIEW_TRAM_SECT :{GOLD}Raitiotiepalat: STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Vesiruudut: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Kanavat STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Asemat: @@ -3367,10 +3394,17 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Teollisuusala STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Ei mitään - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}{NBSP}% kuljetettu) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}{NBSP}% / {COMMA}{NBSP}% kuljetettu) +STR_INDUSTRY_DIRECTORY_ITEM_INFO :{BLACK}{CARGO_LONG}{STRING}{YELLOW} ({COMMA}% kuljetettu){BLACK} STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} +STR_INDUSTRY_DIRECTORY_ITEM_PROD1 :{ORANGE}{INDUSTRY} {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PROD2 :{ORANGE}{INDUSTRY} {STRING}, {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PROD3 :{ORANGE}{INDUSTRY} {STRING}, {STRING}, {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PRODMORE :{ORANGE}{INDUSTRY} {STRING}, {STRING}, {STRING} ja {NUM} muuta STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Teollisuusmuotojen nimet - kohdista päänäkymä teollisuuslaitokseen napsauttamalla nimeä. Ctrl+Klik avaa uuden näkymäikkunan teollisuuslaitoksen sijaintiin +STR_INDUSTRY_DIRECTORY_ACCEPTED_CARGO_FILTER :{BLACK}Vastaanotettava rahti: {SILVER}{STRING} +STR_INDUSTRY_DIRECTORY_PRODUCED_CARGO_FILTER :{BLACK}Tuotettu rahti: {SILVER}{STRING} +STR_INDUSTRY_DIRECTORY_FILTER_ALL_TYPES :Kaikki rahtityypit +STR_INDUSTRY_DIRECTORY_FILTER_NONE :Ei mitään # Industry view STR_INDUSTRY_VIEW_CAPTION :{WHITE}{INDUSTRY} @@ -3395,7 +3429,7 @@ STR_CONFIG_GAME_PRODUCTION_LEVEL :{WHITE}Muuta tu STR_VEHICLE_LIST_TRAIN_CAPTION :{WHITE}{STRING} - {COMMA} juna{P "" a} STR_VEHICLE_LIST_ROAD_VEHICLE_CAPTION :{WHITE}{STRING} - {COMMA} ajoneuvo{P "" a} STR_VEHICLE_LIST_SHIP_CAPTION :{WHITE}{STRING} - {COMMA} laiva{P "" a} -STR_VEHICLE_LIST_AIRCRAFT_CAPTION :{WHITE}{STRING} - {COMMA} lentokone{P "" tta} +STR_VEHICLE_LIST_AIRCRAFT_CAPTION :{WHITE}{STRING} - {COMMA} ilma-alus{P "" ta} STR_VEHICLE_LIST_TRAIN_LIST_TOOLTIP :{BLACK}Junat – napsauta junaa saadaksesi tietoja STR_VEHICLE_LIST_ROAD_VEHICLE_TOOLTIP :{BLACK}Ajoneuvot – napsauta ajoneuvoa saadaksesi tietoja @@ -3412,7 +3446,7 @@ STR_VEHICLE_LIST_AVAILABLE_ENGINES_TOOLTIP :{BLACK}Näytä STR_VEHICLE_LIST_MANAGE_LIST :{BLACK}Muokkaa listaa STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}Ohjaa kaikkia listan kulkuneuvoja -STR_VEHICLE_LIST_REPLACE_VEHICLES :Korvaa liikennevälineitä +STR_VEHICLE_LIST_REPLACE_VEHICLES :Korvaa kulkuneuvoja STR_VEHICLE_LIST_SEND_FOR_SERVICING :Lähetä huoltoon STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :Lähetä varikolle @@ -3429,12 +3463,14 @@ STR_VEHICLE_LIST_SHARED_ORDERS_LIST_CAPTION :{WHITE}{COMMA} STR_GROUP_ALL_TRAINS :Kaikki junat STR_GROUP_ALL_ROAD_VEHICLES :Kaikki ajoneuvot STR_GROUP_ALL_SHIPS :Kaikki laivat -STR_GROUP_ALL_AIRCRAFTS :Kaikki lentoalukset +STR_GROUP_ALL_AIRCRAFTS :Kaikki ilma-alukset STR_GROUP_DEFAULT_TRAINS :Muut junat STR_GROUP_DEFAULT_ROAD_VEHICLES :Muut ajoneuvot STR_GROUP_DEFAULT_SHIPS :Muut laivat -STR_GROUP_DEFAULT_AIRCRAFTS :Muut lentokoneet +STR_GROUP_DEFAULT_AIRCRAFTS :Muut ilma-alukset + +STR_GROUP_COUNT_WITH_SUBGROUP :{TINY_FONT}{COMMA} (+{COMMA}) STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Ryhmät – napsauta ryhmää nähdäksesi kaikki kulkuneuvot tässä ryhmässä. Järjestä ryhmiä vetämällä ja pudottamalla. STR_GROUP_CREATE_TOOLTIP :{BLACK}Luo ryhmä @@ -3457,17 +3493,23 @@ STR_GROUP_OCCUPANCY :Nykyinen käytt STR_GROUP_OCCUPANCY_VALUE :{NUM} % # Build vehicle window -STR_BUY_VEHICLE_TRAIN_RAIL_CAPTION :Uusi juna +STR_BUY_VEHICLE_TRAIN_RAIL_CAPTION :Uudet junat STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Uusi sähköjuna STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Uusi yksiraidejuna STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Uusi Maglev-juna +STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Uudet ajoneuvot +STR_BUY_VEHICLE_TRAM_VEHICLE_CAPTION :Uudet raitiovaunut + +############ range for vehicle availability starts STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Uudet junat -STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Uusia ajoneuvoja -STR_BUY_VEHICLE_SHIP_CAPTION :Uusia laivoja -STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Uusi lentokone +STR_BUY_VEHICLE_ROAD_VEHICLE_ALL_CAPTION :Uudet ajoneuvot +STR_BUY_VEHICLE_SHIP_CAPTION :Uudet laivat +STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Uusi ilma-alus +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Hinta: {GOLD}{CURRENCY_LONG}{BLACK} Paino: {GOLD}{WEIGHT_SHORT} +STR_PURCHASE_INFO_COST_REFIT_WEIGHT :{BLACK}Hinta: {GOLD}{CURRENCY_LONG}{BLACK} (Sovituskustannus: {GOLD}{CURRENCY_LONG}{BLACK}) Paino: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Nopeus: {GOLD}{VELOCITY}{BLACK} Teho: {GOLD}{POWER} STR_PURCHASE_INFO_SPEED :{BLACK}Nopeus: {GOLD}{VELOCITY} STR_PURCHASE_INFO_SPEED_OCEAN :{BLACK}Nopeus merellä: {GOLD}{VELOCITY} @@ -3478,8 +3520,10 @@ STR_PURCHASE_INFO_REFITTABLE :(sovitettava) STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Suunniteltu: {GOLD}{NUM}{BLACK} Elinikä: {GOLD}{COMMA} vuo{P si tta} STR_PURCHASE_INFO_RELIABILITY :{BLACK}Enimmäisluotettavuus: {GOLD}{COMMA}{NBSP}% STR_PURCHASE_INFO_COST :{BLACK}Hinta: {GOLD}{CURRENCY_LONG} +STR_PURCHASE_INFO_COST_REFIT :{BLACK}Hinta: {GOLD}{CURRENCY_LONG}{BLACK} (Sovituskustannus: {GOLD}{CURRENCY_LONG}{BLACK}) STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Paino: {GOLD}{WEIGHT_SHORT} ({WEIGHT_SHORT}) STR_PURCHASE_INFO_COST_SPEED :{BLACK}Hinta: {GOLD}{CURRENCY_LONG}{BLACK} Nopeus: {GOLD}{VELOCITY} +STR_PURCHASE_INFO_COST_REFIT_SPEED :{BLACK}Hinta: {GOLD}{CURRENCY_LONG}{BLACK} (Sovituskustannus: {GOLD}{CURRENCY_LONG}{BLACK}) Nopeus: {GOLD}{VELOCITY} STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Kapasiteetti: {GOLD}{CARGO_LONG}, {CARGO_LONG} STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Moottoroidut vaunut: {GOLD}+{POWER}{BLACK} Paino: {GOLD}+{WEIGHT_SHORT} STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Sovitettavissa: {GOLD}{STRING} @@ -3488,22 +3532,32 @@ STR_PURCHASE_INFO_NONE :Ei mitään STR_PURCHASE_INFO_ALL_BUT :Kaikki paitsi {CARGO_LIST} STR_PURCHASE_INFO_MAX_TE :{BLACK}Suurin vetovoima: {GOLD}{FORCE} STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Toimintasäde: {GOLD}{COMMA} ruutua -STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Lentokonetyyppi: {GOLD}{STRING} +STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Ilma-alustyyppi: {GOLD}{STRING} STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Junien valintaluettelo. Lisää tietoja junaa napsauttamalla. Ctrl+Klik näyttää tai piilottaa kulkuneuvon tyypin STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Ajoneuvojen valintaluettelo. Napsauta ajoneuvoa saadaksesi lisää tietoja. Ctrl+Klik näyttää tai piilottaa ajoneuvon tyypin STR_BUY_VEHICLE_SHIP_LIST_TOOLTIP :{BLACK}Laivojen valintaluettelo. Napsauta laivaa saadaksesi lisää tietoja. Ctrl+Klik näyttää tai piilottaa laivan tyypin -STR_BUY_VEHICLE_AIRCRAFT_LIST_TOOLTIP :{BLACK}Lentokoneiden valintaluettelo. Napsauta lentokonetta saadaksesi lisää tietoja. Ctrl+Klik näyttää tai piilottaa lentokoneen tyypin +STR_BUY_VEHICLE_AIRCRAFT_LIST_TOOLTIP :{BLACK}Ilma-alusten valintaluettelo. Napsauta ilma-alusta saadaksesi lisää tietoja. Ctrl+Klik näyttää tai piilottaa ilma-aluksen tyypin STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_BUTTON :{BLACK}Osta yksikkö STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Osta ajoneuvo STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Osta laiva -STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Osta lentokone +STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Osta ilma-alus + +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Osta ja sovita yksikkö +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Osta ja sovita ajoneuvo +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Osta ja sovita laiva +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Osta ja sovita ilma-alus STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Osta valittu yksikkö. Shift+Klik näyttää kustannusarvion ostamatta STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Osta valittu ajoneuvo. Shift+Klik näyttää kustannusarvion ostamatta STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Osta valittu laiva. Shift+Klik näyttää kustannusarvion ostamatta -STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Osta korostettu lentokone. Shift+Klik näyttää kustannusarvion ostamatta +STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Osta korostettu ilma-alus. Shift+Klik näyttää kustannusarvion ostamatta + +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Osta ja sovita valittu yksikkö. Shift+Klik näyttää kustannusarvion ostamatta +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Osta ja sovita valittu ajoneuvo. Shift+Klik näyttää kustannusarvion ostamatta +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Osta ja sovita valittu laiva. Shift+Klik näyttää kustannusarvion ostamatta +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Osta ja sovita valittu ilma-alus. Shift+Klik näyttää kustannusarvion ostamatta STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Nimeä STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Nimeä @@ -3528,12 +3582,12 @@ STR_BUY_VEHICLE_AIRCRAFT_SHOW_TOGGLE_BUTTON :{BLACK}Näytä STR_BUY_VEHICLE_TRAIN_HIDE_SHOW_TOGGLE_TOOLTIP :{BLACK}Näytä tai piilota junan tyyppi STR_BUY_VEHICLE_ROAD_VEHICLE_HIDE_SHOW_TOGGLE_TOOLTIP :{BLACK}Näytä tai piilota ajoneuvon tyyppi STR_BUY_VEHICLE_SHIP_HIDE_SHOW_TOGGLE_TOOLTIP :{BLACK}Näytä tai piilota laivan tyyppi -STR_BUY_VEHICLE_AIRCRAFT_HIDE_SHOW_TOGGLE_TOOLTIP :{BLACK}Näytä tai piilota lentokoneen tyyppi +STR_BUY_VEHICLE_AIRCRAFT_HIDE_SHOW_TOGGLE_TOOLTIP :{BLACK}Näytä tai piilota ilma-aluksen tyyppi -STR_QUERY_RENAME_TRAIN_TYPE_CAPTION :{WHITE}Nimeä juna(vaunu)n tyyppi uudelleen. +STR_QUERY_RENAME_TRAIN_TYPE_CAPTION :{WHITE}Nimeä juna(vaunu)n tyyppi uudelleen STR_QUERY_RENAME_ROAD_VEHICLE_TYPE_CAPTION :{WHITE}Nimeä ajoneuvon tyyppi uudelleen -STR_QUERY_RENAME_SHIP_TYPE_CAPTION :{WHITE}Nimeä laivatyyppi uudelleen. -STR_QUERY_RENAME_AIRCRAFT_TYPE_CAPTION :{WHITE}Nimeä lentokonetyyppi uudelleen. +STR_QUERY_RENAME_SHIP_TYPE_CAPTION :{WHITE}Nimeä laivatyyppi uudelleen +STR_QUERY_RENAME_AIRCRAFT_TYPE_CAPTION :{WHITE}Nimeä ilma-alustyyppi uudelleen # Depot window STR_DEPOT_CAPTION :{WHITE}{DEPOT} @@ -3566,22 +3620,22 @@ STR_DEPOT_SELL_ALL_BUTTON_AIRCRAFT_TOOLTIP :{BLACK}Myy kaik STR_DEPOT_AUTOREPLACE_TRAIN_TOOLTIP :{BLACK}Korvaa kaikki veturitallilla olevat junat automaattisesti STR_DEPOT_AUTOREPLACE_ROAD_VEHICLE_TOOLTIP :{BLACK}Korvaa kaikki varikolla olevat ajoneuvot automaattisesti STR_DEPOT_AUTOREPLACE_SHIP_TOOLTIP :{BLACK}Korvaa kaikki telakalla olevat laivat automaattisesti -STR_DEPOT_AUTOREPLACE_AIRCRAFT_TOOLTIP :{BLACK}Korvaa kaikki hallissa olevat lento-alukset automaattisesti +STR_DEPOT_AUTOREPLACE_AIRCRAFT_TOOLTIP :{BLACK}Korvaa kaikki hallissa olevat lentokoneet automaattisesti -STR_DEPOT_TRAIN_NEW_VEHICLES_BUTTON :{BLACK}Uusia liikennevälineitä -STR_DEPOT_ROAD_VEHICLE_NEW_VEHICLES_BUTTON :{BLACK}Uusia ajoneuvoja -STR_DEPOT_SHIP_NEW_VEHICLES_BUTTON :{BLACK}Uusia laivoja -STR_DEPOT_AIRCRAFT_NEW_VEHICLES_BUTTON :{BLACK}Uusia lentokoneita +STR_DEPOT_TRAIN_NEW_VEHICLES_BUTTON :{BLACK}Uudet kulkuneuvot +STR_DEPOT_ROAD_VEHICLE_NEW_VEHICLES_BUTTON :{BLACK}Uudet ajoneuvot +STR_DEPOT_SHIP_NEW_VEHICLES_BUTTON :{BLACK}Uudet laivat +STR_DEPOT_AIRCRAFT_NEW_VEHICLES_BUTTON :{BLACK}Uudet lentokoneet STR_DEPOT_TRAIN_NEW_VEHICLES_TOOLTIP :{BLACK}Osta uusi yksikkö STR_DEPOT_ROAD_VEHICLE_NEW_VEHICLES_TOOLTIP :{BLACK}Osta uusi ajoneuvo STR_DEPOT_SHIP_NEW_VEHICLES_TOOLTIP :{BLACK}Osta uusi laiva -STR_DEPOT_AIRCRAFT_NEW_VEHICLES_TOOLTIP :{BLACK}Osta uusi lentokone +STR_DEPOT_AIRCRAFT_NEW_VEHICLES_TOOLTIP :{BLACK}Osta uusi ilma-alus STR_DEPOT_CLONE_TRAIN :{BLACK}Kloonaa juna STR_DEPOT_CLONE_ROAD_VEHICLE :{BLACK}Kloonaa ajoneuvo STR_DEPOT_CLONE_SHIP :{BLACK}Kloonaa laiva -STR_DEPOT_CLONE_AIRCRAFT :{BLACK}Kloonaa lentokone +STR_DEPOT_CLONE_AIRCRAFT :{BLACK}Kloonaa ilma-alus STR_DEPOT_CLONE_TRAIN_DEPOT_INFO :{BLACK}Tämä ostaa kopion junasta ja kaikista sen vaunuista. Napsauta tätä painiketta ja sen jälkeen junaa varikon sisä- tai ulkopuolella. Ctrl+Klik jakaa komennot. Shift+Klik näyttää kustannusarvion ostamatta kopiota STR_DEPOT_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Tämä ostaa kopion ajoneuvosta. Napsauta tätä painiketta ja sen jälkeen ajoneuvoa varikon sisä- tai ulkopuolella. Ctrl+Klik jakaa komennot. Shift+Klik näyttää kustannusarvion ostamatta kopiota @@ -3613,20 +3667,25 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Olet my # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Viesti kulkuneuvovalmistajalta STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Olemme juuri suunnitelleet uuden {STRING} – oletteko kiinnostunut vuoden yksinoikeutetusta kokeilusta, jotta näemme miten tuote suoriutuu ennen kuin julkistamme sen yleiseen käyttöön? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :veturin -STR_ENGINE_PREVIEW_ROAD_VEHICLE :ajoneuvon -STR_ENGINE_PREVIEW_AIRCRAFT :lentokoneen -STR_ENGINE_PREVIEW_SHIP :laivan +STR_ENGINE_PREVIEW_ELRAIL_LOCOMOTIVE :sähköradan veturi STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :yksiraiteisen veturin STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :maglev-veturin +STR_ENGINE_PREVIEW_ROAD_VEHICLE :ajoneuvon +STR_ENGINE_PREVIEW_TRAM_VEHICLE :raitiovaunun + +STR_ENGINE_PREVIEW_AIRCRAFT :ilma-aluksen +STR_ENGINE_PREVIEW_SHIP :laivan + 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}{}Lentokonetyyppi: {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}{}Lentokonetyyppi: {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}{}Lentokonetyyppi: {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}{}Lentokonetyyppi: {STRING} Toimintamatka: {COMMA} ruutua{}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 # Autoreplace window STR_REPLACE_VEHICLES_WHITE :{WHITE}Korvaa {STRING} – {STRING} @@ -3638,17 +3697,17 @@ STR_REPLACE_VEHICLE_AIRCRAFT :lentokoneita STR_REPLACE_VEHICLE_VEHICLES_IN_USE :{YELLOW}Käytössä olevat kulkuneuvot STR_REPLACE_VEHICLE_VEHICLES_IN_USE_TOOLTIP :{BLACK}Sarake kulkuneuvoille, jotka omistat STR_REPLACE_VEHICLE_AVAILABLE_VEHICLES :{YELLOW}Saatavilla olevat kulkuneuvot -STR_REPLACE_VEHICLE_AVAILABLE_VEHICLES_TOOLTIP :{BLACK}Sarake kulkuneuvoille, jotka voidaan uusia +STR_REPLACE_VEHICLE_AVAILABLE_VEHICLES_TOOLTIP :{BLACK}Sarake kulkuneuvoille, jotka voidaan uudistaa STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Valitse korvattava veturityyppi. STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Valitse vasemmalla näkyvän veturityypinn korvaava uusi veturityyppi. STR_REPLACE_VEHICLES_START :{BLACK}Aloita kulkuneuvojen korvaaminen -STR_REPLACE_VEHICLES_NOW :Korvaa kaikki liikennevälineet nyt -STR_REPLACE_VEHICLES_WHEN_OLD :Korvaa vain vanhat liikennevälineet +STR_REPLACE_VEHICLES_NOW :Korvaa kaikki kulkuneuvot heti +STR_REPLACE_VEHICLES_WHEN_OLD :Korvaa vain vanhat kulkuneuvot STR_REPLACE_HELP_START_BUTTON :{BLACK}Napsauta aloittaaksesi vasemmalta valitun veturityypin korvauksen oikealta valitulla veturityypillä. STR_REPLACE_NOT_REPLACING :{BLACK}Ei korvata -STR_REPLACE_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}Ei liikennevälinettä valittuna +STR_REPLACE_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}Ei kulkuneuvoa valittuna STR_REPLACE_REPLACING_WHEN_OLD :{ENGINE} kun vanha STR_REPLACE_VEHICLES_STOP :{BLACK}Lopeta kulkuneuvojen korvaaminen STR_REPLACE_HELP_STOP_BUTTON :{BLACK}Napsauta pysäyttääksesi vasemmalta valitun veturityypin korvauksen. @@ -3657,14 +3716,19 @@ STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK}Vaihda t STR_REPLACE_ENGINES :Veturit STR_REPLACE_WAGONS :Vaunut STR_REPLACE_ALL_RAILTYPE :Kaikki junat +STR_REPLACE_ALL_ROADTYPE :Kaikki ajoneuvot STR_REPLACE_HELP_RAILTYPE :{BLACK}Valitse rautatietyyppi, jolle veturikorvaukset tehdään. +STR_REPLACE_HELP_ROADTYPE :{BLACK}Valitse tien tyyppi, jolle ajoneuvojen korvaukset tehdään STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Näyttää, millä vasemmalta valittu veturi korvataan, jos millään. STR_REPLACE_RAIL_VEHICLES :Junat STR_REPLACE_ELRAIL_VEHICLES :Sähköjunat STR_REPLACE_MONORAIL_VEHICLES :Yksiraiteiset STR_REPLACE_MAGLEV_VEHICLES :Maglev-junat +STR_REPLACE_ROAD_VEHICLES :Ajoneuvot +STR_REPLACE_TRAM_VEHICLES :Raitiovaunut + STR_REPLACE_REMOVE_WAGON :{BLACK}Vaunun poisto: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Automaattikorvauksessa junapituus pidetään samana poistamalla vaunuja (edestä) jos veturi pidentäisi junaa @@ -3674,12 +3738,12 @@ STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE STR_VEHICLE_VIEW_TRAIN_LOCATION_TOOLTIP :{BLACK}Keskitä näkymä junan sijaintiin. Ctrl+Klik seuraa junaa näkymässä STR_VEHICLE_VIEW_ROAD_VEHICLE_LOCATION_TOOLTIP :{BLACK}Keskitä näkymä ajoneuvon sijaintiin. Ctrl+Klik seuraa ajoneuvoa päänäkymässä STR_VEHICLE_VIEW_SHIP_LOCATION_TOOLTIP :{BLACK}Keskitä näkymä laivan sijaintiin. Ctrl+Click seuraa laivaa näkymässä -STR_VEHICLE_VIEW_AIRCRAFT_LOCATION_TOOLTIP :{BLACK}Keskitä näkymä lentokoneen sijaintiin. Ctrl+Klik seuraa lentokonetta päänäkymässä +STR_VEHICLE_VIEW_AIRCRAFT_LOCATION_TOOLTIP :{BLACK}Keskitä näkymä ilma-aluksen sijaintiin. Ctrl+Klik seuraa ilma-alusta päänäkymässä STR_VEHICLE_VIEW_TRAIN_SEND_TO_DEPOT_TOOLTIP :{BLACK}Lähetä juna veturitalliin. Ctrl+Klik suorittaa vain huollon STR_VEHICLE_VIEW_ROAD_VEHICLE_SEND_TO_DEPOT_TOOLTIP :{BLACK}Lähetä ajoneuvo varikolle. Ctrl+Klik suorittaa vain huollon STR_VEHICLE_VIEW_SHIP_SEND_TO_DEPOT_TOOLTIP :{BLACK}Lähetä laiva telakalle. Ctrl+Klik suorittaa vain huollon -STR_VEHICLE_VIEW_AIRCRAFT_SEND_TO_DEPOT_TOOLTIP :{BLACK}Lähetä lentokone lentokonehalliin. Ctrl+Klik suorittaa vain huollon +STR_VEHICLE_VIEW_AIRCRAFT_SEND_TO_DEPOT_TOOLTIP :{BLACK}Lähetä ilma-alus lentokonehalliin. Ctrl+Klik suorittaa vain huollon STR_VEHICLE_VIEW_CLONE_TRAIN_INFO :{BLACK}Tämä ostaa kopion junasta vaunuineen. Ctrl+Klik jakaa komennot. Shift+Klik näyttää kustannusarvion ostamatta kopiota STR_VEHICLE_VIEW_CLONE_ROAD_VEHICLE_INFO :{BLACK}Tämä ostaa kopion ajoneuvosta. Ctrl+Klik jakaa komennot. Shift+Klik näyttää kustannusarvion ostamatta kopiota @@ -3691,7 +3755,7 @@ STR_VEHICLE_VIEW_TRAIN_IGNORE_SIGNAL_TOOLTIP :{BLACK}Anna jun STR_VEHICLE_VIEW_TRAIN_REFIT_TOOLTIP :{BLACK}Sovita juna kuljettamaan muuta rahtityyppiä STR_VEHICLE_VIEW_ROAD_VEHICLE_REFIT_TOOLTIP :{BLACK}Muuta ajoneuvo kuljettamaan muuta rahtityyppiä STR_VEHICLE_VIEW_SHIP_REFIT_TOOLTIP :{BLACK}Sovita laiva eri rahtityypille -STR_VEHICLE_VIEW_AIRCRAFT_REFIT_TOOLTIP :{BLACK}Sovita lentokone eri rahtityypille. +STR_VEHICLE_VIEW_AIRCRAFT_REFIT_TOOLTIP :{BLACK}Sovita ilma-alus kuljettamaan eri rahtityyppiä STR_VEHICLE_VIEW_TRAIN_REVERSE_TOOLTIP :{BLACK}Käännä junan suunta STR_VEHICLE_VIEW_ROAD_VEHICLE_REVERSE_TOOLTIP :{BLACK}Pakota ajoneuvo kääntymään ympäri @@ -3699,12 +3763,12 @@ STR_VEHICLE_VIEW_ROAD_VEHICLE_REVERSE_TOOLTIP :{BLACK}Pakota a STR_VEHICLE_VIEW_TRAIN_ORDERS_TOOLTIP :{BLACK}Näytä junan käskyt. Ctrl+Klik näyttää junan aikataulun STR_VEHICLE_VIEW_ROAD_VEHICLE_ORDERS_TOOLTIP :{BLACK}Näytä ajoneuvon käskyt. Ctrl+Klik näyttää ajoneuvon aikataulun STR_VEHICLE_VIEW_SHIP_ORDERS_TOOLTIP :{BLACK}Näytä laivan käskyt. Ctrl+Click näyttää laivan aikataulun -STR_VEHICLE_VIEW_AIRCRAFT_ORDERS_TOOLTIP :{BLACK}Näytä lentokoneen käskyt. Ctrl+Klik näyttää lentokoneen aikataulun +STR_VEHICLE_VIEW_AIRCRAFT_ORDERS_TOOLTIP :{BLACK}Näytä ilma-aluksen käskyt. Ctrl+Klik näyttää ilma-aluksen aikataulun STR_VEHICLE_VIEW_TRAIN_SHOW_DETAILS_TOOLTIP :{BLACK}Näytä junan tiedot STR_VEHICLE_VIEW_ROAD_VEHICLE_SHOW_DETAILS_TOOLTIP :{BLACK}Näytä ajoneuvon tiedot STR_VEHICLE_VIEW_SHIP_SHOW_DETAILS_TOOLTIP :{BLACK}Näytä laivan tiedot -STR_VEHICLE_VIEW_AIRCRAFT_SHOW_DETAILS_TOOLTIP :{BLACK}Näytä lentokoneen tiedot. +STR_VEHICLE_VIEW_AIRCRAFT_SHOW_DETAILS_TOOLTIP :{BLACK}Näytä ilma-aluksen tiedot STR_VEHICLE_VIEW_TRAIN_STATE_START_STOP_TOOLTIP :{BLACK}Valitun junan toiminnot – napsauta pysäyttääksesi/käynnistääksesi junan. Ctrl+Klik vierittääksesi kohteeseen STR_VEHICLE_VIEW_ROAD_VEHICLE_STATE_START_STOP_TOOLTIP :{BLACK}Nykyisen ajoneuvon toiminnot – napsauta pysäyttääksesi/käynnistääksesi ajoneuvon. Ctrl+Klik vierittääksesi kohteeseen @@ -3741,7 +3805,7 @@ STR_VEHICLE_NAME_BUTTON :{BLACK}Nimi STR_VEHICLE_DETAILS_TRAIN_RENAME :{BLACK}Nimeä juna STR_VEHICLE_DETAILS_ROAD_VEHICLE_RENAME :{BLACK}Nimeä ajoneuvo STR_VEHICLE_DETAILS_SHIP_RENAME :{BLACK}Nimeä laiva -STR_VEHICLE_DETAILS_AIRCRAFT_RENAME :{BLACK}Nimeä lentokone +STR_VEHICLE_DETAILS_AIRCRAFT_RENAME :{BLACK}Nimeä ilma-alus STR_VEHICLE_INFO_AGE_RUNNING_COST_YR :{BLACK}Ikä: {LTBLUE}{STRING}{BLACK} Käyttökustannukset: {LTBLUE}{CURRENCY_LONG}/yr # The next two need to stay in this order @@ -3749,8 +3813,8 @@ STR_VEHICLE_INFO_AGE :{COMMA} vuo{P s STR_VEHICLE_INFO_AGE_RED :{RED}{COMMA} vuo{P si tta} ({COMMA}) STR_VEHICLE_INFO_MAX_SPEED :{BLACK}Huippunopeus: {LTBLUE}{VELOCITY} -STR_VEHICLE_INFO_MAX_SPEED_TYPE :{BLACK}Maks. nopeus: {LTBLUE}{VELOCITY} {BLACK}Lentokonetyyppi: {LTBLUE}{STRING} -STR_VEHICLE_INFO_MAX_SPEED_TYPE_RANGE :{BLACK}Maks. nopeus: {LTBLUE}{VELOCITY} {BLACK}Lentokonetyyppi: {LTBLUE}{STRING} {BLACK}Toimintamatka: {LTBLUE}{COMMA} ruutua +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} @@ -3778,7 +3842,7 @@ STR_VEHICLE_DETAILS_PERCENT :Prosentteja STR_QUERY_RENAME_TRAIN_CAPTION :{WHITE}Nimeä juna STR_QUERY_RENAME_ROAD_VEHICLE_CAPTION :{WHITE}Nimeä ajoneuvo STR_QUERY_RENAME_SHIP_CAPTION :{WHITE}Nimeä laiva -STR_QUERY_RENAME_AIRCRAFT_CAPTION :{WHITE}Nimeä lentokone +STR_QUERY_RENAME_AIRCRAFT_CAPTION :{WHITE}Nimeä ilma-alus # Extra buttons for train details windows STR_VEHICLE_DETAILS_TRAIN_ENGINE_BUILT_AND_VALUE :{LTBLUE}{ENGINE}{BLACK} Rakennettu: {LTBLUE}{NUM}{BLACK} Arvo: {LTBLUE}{CURRENCY_LONG} @@ -3820,7 +3884,7 @@ STR_REFIT_AIRCRAFT_LIST_TOOLTIP :{BLACK}Valitse STR_REFIT_TRAIN_REFIT_BUTTON :{BLACK}Sovita juna STR_REFIT_ROAD_VEHICLE_REFIT_BUTTON :{BLACK}Korjaa ajoneuvo. STR_REFIT_SHIP_REFIT_BUTTON :{BLACK}Sovita laiva -STR_REFIT_AIRCRAFT_REFIT_BUTTON :{BLACK}Sovita lentokone +STR_REFIT_AIRCRAFT_REFIT_BUTTON :{BLACK}Sovita ilma-alus STR_REFIT_TRAIN_REFIT_TOOLTIP :{BLACK}Sovita juna kuljettamaan valittua rahtityyppiä STR_REFIT_ROAD_VEHICLE_REFIT_TOOLTIP :{BLACK}Muuta ajoneuvo rahtaamaan korostettua rahtityyppiä. @@ -4115,6 +4179,14 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Valitse STR_AI_LIST_CANCEL :{BLACK}Peruuta STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Älä vaihda skriptiä +STR_SCREENSHOT_CAPTION :{WHITE}Ota kuvakaappaus +STR_SCREENSHOT_SCREENSHOT :{BLACK}Tavallinen kuvakaappaus +STR_SCREENSHOT_ZOOMIN_SCREENSHOT :{BLACK}Täysin lähennetty kuvakaappaus +STR_SCREENSHOT_DEFAULTZOOM_SCREENSHOT :{BLACK}Kuvakaappaus oletuslähennyksellä +STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Koko kartan kuvakaappaus +STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Korkeuskartan kuvakaappaus +STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Pienoiskartan kuvakaappaus + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parametrit STR_AI_SETTINGS_CAPTION_AI :Tekoäly @@ -4317,7 +4389,6 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... kunt STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... tie on väärin päin STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... läpiajettavissa pysäkeissä ei voi olla mutkia STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... läpiajettavissa pysäkeissä ei voi olla risteyksiä -STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... tie on yksisuuntainen tai suljettu # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Aseman osaa ei voi poistaa... @@ -4369,7 +4440,7 @@ STR_ERROR_CAN_T_REVERSE_DIRECTION_RAIL_VEHICLE :{WHITE}Kulkuneu STR_ERROR_CAN_T_REVERSE_DIRECTION_RAIL_VEHICLE_MULTIPLE_UNITS :{WHITE}... koostuu useammista yksiköistä STR_ERROR_INCOMPATIBLE_RAIL_TYPES :Raiteet eivät ole yhteensopivia -STR_ERROR_CAN_T_MOVE_VEHICLE :{WHITE}Liikennevälinettä ei voi poistaa... +STR_ERROR_CAN_T_MOVE_VEHICLE :{WHITE}Kulkuneuvoa ei voi siirtää... STR_ERROR_REAR_ENGINE_FOLLOW_FRONT :{WHITE}Moottorivaunun takaosa seuraa aina etuosaansa STR_ERROR_UNABLE_TO_FIND_ROUTE_TO :{WHITE}Reittiä paikalliselle veturitallille ei löydy. STR_ERROR_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}Paikallista varikkoa ei löydy. @@ -4387,7 +4458,8 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Opastime STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Ei kelvollista rautatietä. STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Rautatie pitää poistaa ensin. STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Tie on yksisuuntainen tai suljettu -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Tasoristeykset eivät ole sallittu tälle raidetyypille +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Tasoristeykset eivät ole sallittu tälle raidetyypille +STR_ERROR_CROSSING_DISALLOWED_ROAD :{WHITE}Tasoristeykset eivät ole sallittuja tälle tietyypille STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Opastinta ei voi rakentaa. STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Rautatietä ei voi rakentaa. STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Rautatietä ei voi poistaa. @@ -4407,6 +4479,12 @@ STR_ERROR_CAN_T_REMOVE_ROAD_FROM :{WHITE}Tietä e STR_ERROR_CAN_T_REMOVE_TRAMWAY_FROM :{WHITE}Tästä ei voi poistaa raitiotietä. STR_ERROR_THERE_IS_NO_ROAD :{WHITE}... tässä ei ole tietä STR_ERROR_THERE_IS_NO_TRAMWAY :{WHITE}... tässä ei ole raitiotietä +STR_ERROR_CAN_T_CONVERT_ROAD :{WHITE}Tien tyyppiä ei voi muuntaa tässä... +STR_ERROR_CAN_T_CONVERT_TRAMWAY :{WHITE}Raitiotien tyyppiä ei voi muuntaa tässä... +STR_ERROR_NO_SUITABLE_ROAD :{WHITE}Ei sopivaa tietä +STR_ERROR_NO_SUITABLE_TRAMWAY :{WHITE}Ei sopivaa raitiotietä +STR_ERROR_INCOMPATIBLE_ROAD :{WHITE}... yhteensopimaton tie +STR_ERROR_INCOMPATIBLE_TRAMWAY :{WHITE}... yhteensopimaton raitiotie # Waterway construction errors STR_ERROR_CAN_T_BUILD_CANALS :{WHITE}Kanaalia ei voi rakentaa tähän... @@ -4459,6 +4537,7 @@ STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Ei voi l STR_ERROR_GROUP_CAN_T_DELETE :{WHITE}Ryhmää ei voi poistaa. STR_ERROR_GROUP_CAN_T_RENAME :{WHITE}Ryhmää ei voi nimetä. STR_ERROR_GROUP_CAN_T_SET_PARENT :{WHITE}Pääryhmää ei voi määrittää... +STR_ERROR_GROUP_CAN_T_SET_PARENT_RECURSION :{WHITE}... ryhmähierarkiassa ei saa olla silmukoita STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}Ryhmän kaikkia kulkuneuvoja ei voi poistaa. STR_ERROR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}Ei voi lisätä kulkuneuvoa ryhmään. STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}Ei voi lisätä jaettuja kulkuneuvoja ryhmään. @@ -4467,47 +4546,47 @@ STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}Ei voi l STR_ERROR_TRAIN_IN_THE_WAY :{WHITE}Juna on tiellä. STR_ERROR_ROAD_VEHICLE_IN_THE_WAY :{WHITE}Ajoneuvo tiellä. STR_ERROR_SHIP_IN_THE_WAY :{WHITE}Laiva on tiellä. -STR_ERROR_AIRCRAFT_IN_THE_WAY :{WHITE}Lentokone on tiellä. +STR_ERROR_AIRCRAFT_IN_THE_WAY :{WHITE}Ilma-alus on tiellä STR_ERROR_CAN_T_REFIT_TRAIN :{WHITE}Junaa ei voi sovittaa... STR_ERROR_CAN_T_REFIT_ROAD_VEHICLE :{WHITE}Ajoneuvoa ei voida korjata. STR_ERROR_CAN_T_REFIT_SHIP :{WHITE}Laivaa ei voi sovittaa... -STR_ERROR_CAN_T_REFIT_AIRCRAFT :{WHITE}Lentokonetta ei voi sovittaa... +STR_ERROR_CAN_T_REFIT_AIRCRAFT :{WHITE}Ilma-alusta ei voi sovittaa... STR_ERROR_CAN_T_RENAME_TRAIN :{WHITE}Junaa ei voi nimetä... STR_ERROR_CAN_T_RENAME_ROAD_VEHICLE :{WHITE}Ajoneuvoa ei voi nimetä... STR_ERROR_CAN_T_RENAME_SHIP :{WHITE}Laivaa ei voi nimetä... -STR_ERROR_CAN_T_RENAME_AIRCRAFT :{WHITE}Lentokonetta ei voi nimetä... +STR_ERROR_CAN_T_RENAME_AIRCRAFT :{WHITE}Ilma-aluta ei voi nimetä... STR_ERROR_CAN_T_STOP_START_TRAIN :{WHITE}Junaa ei voi pysäyttää/lähettää... STR_ERROR_CAN_T_STOP_START_ROAD_VEHICLE :{WHITE}Ajoneuvoa ei voi pysäyttää/laitta liikkeelle... STR_ERROR_CAN_T_STOP_START_SHIP :{WHITE}Laivaa ei voi pysäyttää/laittaa liikkeelle... -STR_ERROR_CAN_T_STOP_START_AIRCRAFT :{WHITE}Lentokonetta ei voi pysäyttää/laittaa liikkeelle... +STR_ERROR_CAN_T_STOP_START_AIRCRAFT :{WHITE}Ilma-alusta ei voi pysäyttää/laittaa liikkeelle... STR_ERROR_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}Junan lähettäminen veturitalliin ei onnistu... STR_ERROR_CAN_T_SEND_ROAD_VEHICLE_TO_DEPOT :{WHITE}Ajoneuvon lähettäminen varikolle ei onnistu... STR_ERROR_CAN_T_SEND_SHIP_TO_DEPOT :{WHITE}Laivaa ei voi lähettää telakalle... -STR_ERROR_CAN_T_SEND_AIRCRAFT_TO_HANGAR :{WHITE}Lentokonetta ei voi lähettää lentokonehalliin... +STR_ERROR_CAN_T_SEND_AIRCRAFT_TO_HANGAR :{WHITE}Ilma-alusta ei voi lähettää lentokonehalliin... STR_ERROR_CAN_T_BUY_TRAIN :{WHITE}Yksikköä ei voi ostaa... STR_ERROR_CAN_T_BUY_ROAD_VEHICLE :{WHITE}Ajoneuvoa ei voi ostaa... STR_ERROR_CAN_T_BUY_SHIP :{WHITE}Laivaa ei voi ostaa... -STR_ERROR_CAN_T_BUY_AIRCRAFT :{WHITE}Lentokonetta ei voi ostaa... +STR_ERROR_CAN_T_BUY_AIRCRAFT :{WHITE}Ilma-alusta ei voi ostaa... STR_ERROR_CAN_T_RENAME_TRAIN_TYPE :{WHITE}Juna(vaunu)n tyyppiä ei voi uudelleennimetä... STR_ERROR_CAN_T_RENAME_ROAD_VEHICLE_TYPE :{WHITE}Ajoneuvotyyppiä ei voi uudelleennimetä... STR_ERROR_CAN_T_RENAME_SHIP_TYPE :{WHITE}Laivatyyppin uudelleennimeäminen ei onnistu... -STR_ERROR_CAN_T_RENAME_AIRCRAFT_TYPE :{WHITE}Lentokonetyyppiä ei voi uudelleennimetä... +STR_ERROR_CAN_T_RENAME_AIRCRAFT_TYPE :{WHITE}Ilma-alustyyppiä ei voi uudelleennimetä... STR_ERROR_CAN_T_SELL_TRAIN :{WHITE}Yksikköä ei voi myydä... STR_ERROR_CAN_T_SELL_ROAD_VEHICLE :{WHITE}Ajoneuvoa ei voi myydä... STR_ERROR_CAN_T_SELL_SHIP :{WHITE}Laivaa ei voi myydä... -STR_ERROR_CAN_T_SELL_AIRCRAFT :{WHITE}Lentokonetta ei voi myydä... +STR_ERROR_CAN_T_SELL_AIRCRAFT :{WHITE}Ilma-alusta ei voi myydä... STR_ERROR_RAIL_VEHICLE_NOT_AVAILABLE :{WHITE}Juna tai vaunu ei ole saatavilla STR_ERROR_ROAD_VEHICLE_NOT_AVAILABLE :{WHITE}Ajoneuvo ei ole saatavilla STR_ERROR_SHIP_NOT_AVAILABLE :{WHITE}Laiva ei ole saatavilla -STR_ERROR_AIRCRAFT_NOT_AVAILABLE :{WHITE}Lentokone ei ole saatavilla +STR_ERROR_AIRCRAFT_NOT_AVAILABLE :{WHITE}Ilma-alus ei ole saatavilla STR_ERROR_TOO_MANY_VEHICLES_IN_GAME :{WHITE}Liian monta kulkuneuvoa pelissä. STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Huoltoväliä ei voi muuttaa. @@ -4526,7 +4605,7 @@ STR_ERROR_TRAIN_START_NO_POWER :Junalla ei ole STR_ERROR_CAN_T_MAKE_ROAD_VEHICLE_TURN :{WHITE}Ajoneuvoa ei voida kääntää... -STR_ERROR_AIRCRAFT_IS_IN_FLIGHT :{WHITE}Lentokone on lennossa. +STR_ERROR_AIRCRAFT_IS_IN_FLIGHT :{WHITE}Ilma-alus on lennossa # Order related errors STR_ERROR_NO_MORE_SPACE_FOR_ORDERS :{WHITE}Ei enää tilaa pysähdyksille. @@ -4545,7 +4624,7 @@ STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}Käskyj STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}Käskyjen jakamista ei voida lopettaa... STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}Käskyjä ei voida kopioida... STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... liian kaukana edellisestä määränpäästä -STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... lentokoneen toimintasäde ei ole tarpeeksi suuri +STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... ilma-aluksen toimintasäde ei riitä # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}Ei voi asettaa aikataulua. @@ -4657,7 +4736,7 @@ STR_SV_UNNAMED :Nimetön STR_SV_TRAIN_NAME :Juna {COMMA} STR_SV_ROAD_VEHICLE_NAME :Ajoneuvo {COMMA} STR_SV_SHIP_NAME :Laiva {COMMA} -STR_SV_AIRCRAFT_NAME :Lentokone {COMMA} +STR_SV_AIRCRAFT_NAME :Ilma-alus {COMMA} STR_SV_STNAME :{STRING} STR_SV_STNAME_NORTH :Pohjois-{STRING} @@ -5068,5 +5147,3 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) - -# Android strings diff --git a/src/lang/french.txt b/src/lang/french.txt index adb212fc83..97efad4d47 100644 --- a/src/lang/french.txt +++ b/src/lang/french.txt @@ -11,8 +11,6 @@ ##gender m m2 f -# $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. # 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. @@ -39,7 +37,7 @@ STR_CARGO_PLURAL_WOOD :Bois STR_CARGO_PLURAL_IRON_ORE :Minerai de fer STR_CARGO_PLURAL_STEEL :Acier STR_CARGO_PLURAL_VALUABLES :Objets de valeur -STR_CARGO_PLURAL_COPPER_ORE :Cuivre +STR_CARGO_PLURAL_COPPER_ORE :Minerai de cuivre STR_CARGO_PLURAL_MAIZE :Maïs STR_CARGO_PLURAL_FRUIT :Fruits STR_CARGO_PLURAL_DIAMONDS :Diamants @@ -73,7 +71,7 @@ STR_CARGO_SINGULAR_WOOD :Bois STR_CARGO_SINGULAR_IRON_ORE :Minerai de fer STR_CARGO_SINGULAR_STEEL :Acier STR_CARGO_SINGULAR_VALUABLES :Objets de valeur -STR_CARGO_SINGULAR_COPPER_ORE :Cuivre +STR_CARGO_SINGULAR_COPPER_ORE :Minerai de cuivre STR_CARGO_SINGULAR_MAIZE :Maïs STR_CARGO_SINGULAR_FRUIT :Fruit STR_CARGO_SINGULAR_DIAMOND :Diamant @@ -107,7 +105,7 @@ STR_QUANTITY_WOOD :{WEIGHT_LONG} d STR_QUANTITY_IRON_ORE :{WEIGHT_LONG} de minerai de fer STR_QUANTITY_STEEL :{WEIGHT_LONG} d'acier STR_QUANTITY_VALUABLES :{COMMA}{NBSP}sac{P "" s} d'objets de valeur -STR_QUANTITY_COPPER_ORE :{WEIGHT_LONG} de cuivre +STR_QUANTITY_COPPER_ORE :{WEIGHT_LONG} de minerai de cuivre STR_QUANTITY_MAIZE :{WEIGHT_LONG} de maïs STR_QUANTITY_FRUIT :{WEIGHT_LONG} de fruits STR_QUANTITY_DIAMONDS :{COMMA}{NBSP}sac{P "" s} de diamants @@ -238,6 +236,8 @@ STR_TOOLTIP_FILTER_CRITERIA :{BLACK}Choisir STR_BUTTON_SORT_BY :{BLACK}Trier par STR_BUTTON_LOCATION :{BLACK}Emplacement STR_BUTTON_RENAME :{BLACK}Renommer +STR_BUTTON_CATCHMENT :{BLACK}Couverture +STR_TOOLTIP_CATCHMENT :{BLACK}Basculer l'affichage de la zone couverte STR_TOOLTIP_CLOSE_WINDOW :{BLACK}Fermer la fenêtre STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Titre de fenêtre - Faire glisser pour déplacer la fenêtre @@ -266,6 +266,7 @@ STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT_TOOLTIP :{BLACK}En activ STR_BUTTON_DEFAULT :{BLACK}Défaut STR_BUTTON_CANCEL :{BLACK}Annuler STR_BUTTON_OK :{BLACK}OK +STR_WARNING_PASSWORD_SECURITY :{YELLOW}Attention{NBSP}: Les administrateurs du serveur pourraient lire tout texte entré ici. # On screen keyboard window STR_OSK_KEYBOARD_LAYOUT :²&é"'(-è_çà)= azertyuiop^$qsdfghjklmù* @@ -3098,6 +3124,8 @@ STR_TOWN_VIEW_RENAME_TOWN_BUTTON :Renommer la vil # Town local authority window STR_LOCAL_AUTHORITY_CAPTION :{WHITE}Municipalité de {TOWN} +STR_LOCAL_AUTHORITY_ZONE :{BLACK}Zone +STR_LOCAL_AUTHORITY_ZONE_TOOLTIP :{BLACK}Affiche la zone dans les limites de la municipalité STR_LOCAL_AUTHORITY_COMPANY_RATINGS :{BLACK}Qualité de service des compagnies{NBSP}: STR_LOCAL_AUTHORITY_COMPANY_RATING :{YELLOW}{COMPANY} {COMPANY_NUM}{NBSP}: {ORANGE}{STRING} STR_LOCAL_AUTHORITY_ACTIONS_TITLE :{BLACK}Actions disponibles{NBSP}: @@ -3355,8 +3383,7 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Infrastr STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Morceaux de voie ferrée{NBSP}: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Signaux STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Morceaux de route{NBSP}: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Route -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Tramway +STR_COMPANY_INFRASTRUCTURE_VIEW_TRAM_SECT :{GOLD}Morceaux de voie de tramway{NBSP}: STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Cases d'eau{NBSP}: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Canaux STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Stations{NBSP}: @@ -3367,10 +3394,17 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Industries STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}− Aucune − -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}{NBSP}% transporté{P "" s}) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}{NBSP}%/{COMMA}{NBSP}% transporté{P "" s}) +STR_INDUSTRY_DIRECTORY_ITEM_INFO :{BLACK}{CARGO_LONG}{STRING}{YELLOW} ({COMMA}% transporté{P "" s}){BLACK} STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} +STR_INDUSTRY_DIRECTORY_ITEM_PROD1 :{ORANGE}{INDUSTRY} {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PROD2 :{ORANGE}{INDUSTRY} {STRING}, {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PROD3 :{ORANGE}{INDUSTRY} {STRING}, {STRING}, {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PRODMORE :{ORANGE}{INDUSTRY} {STRING}, {STRING}, {STRING} et {NUM} autre{P "" s}... STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Noms des industries - Cliquer sur un nom pour centrer la vue principale sur l'industrie. Ctrl-clic pour ouvrir une nouvelle vue sur l'industrie. +STR_INDUSTRY_DIRECTORY_ACCEPTED_CARGO_FILTER :{BLACK}Cargaison acceptée{NBSP}: {SILVER}{STRING} +STR_INDUSTRY_DIRECTORY_PRODUCED_CARGO_FILTER :{BLACK}Cargaison produite{NBSP}: {SILVER}{STRING} +STR_INDUSTRY_DIRECTORY_FILTER_ALL_TYPES :Tous les types de cargaison +STR_INDUSTRY_DIRECTORY_FILTER_NONE :Aucune # Industry view STR_INDUSTRY_VIEW_CAPTION :{WHITE}{INDUSTRY} @@ -3436,6 +3470,8 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Véhicules rout STR_GROUP_DEFAULT_SHIPS :Navires non groupés STR_GROUP_DEFAULT_AIRCRAFTS :Aéronefs non groupés +STR_GROUP_COUNT_WITH_SUBGROUP :{TINY_FONT}{COMMA} (+{COMMA}) + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Groupes - Cliquer sur un groupe pour lister tous les véhicules de ce groupe. Glisser et déposer les groupes pour les hiérarchiser. STR_GROUP_CREATE_TOOLTIP :{BLACK}Créer un groupe de véhicules STR_GROUP_DELETE_TOOLTIP :{BLACK}Supprimer le groupe sélectionné @@ -3462,12 +3498,18 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Nouveaux véhic STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Nouveaux véhicules monorail STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Nouveaux véhicules magnétiques -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Véhicules sur rail STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Nouveaux véhicules +STR_BUY_VEHICLE_TRAM_VEHICLE_CAPTION :Nouveaux tramways + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Véhicules sur rail +STR_BUY_VEHICLE_ROAD_VEHICLE_ALL_CAPTION :Nouveaux véhicules routiers STR_BUY_VEHICLE_SHIP_CAPTION :Nouveaux navires STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Nouvel aéronef +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Prix{NBSP}: {GOLD}{CURRENCY_LONG}{BLACK} − Poids{NBSP}: {GOLD}{WEIGHT_SHORT} +STR_PURCHASE_INFO_COST_REFIT_WEIGHT :{BLACK}Coût{NBSP}: {GOLD}{CURRENCY_LONG}{BLACK} (Coût de réaménagement{NBSP}: {GOLD}{CURRENCY_LONG}{BLACK}) Poids{NBSP}: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Vitesse{NBSP}: {GOLD}{VELOCITY}{BLACK} − Puissance{NBSP}: {GOLD}{POWER} STR_PURCHASE_INFO_SPEED :{BLACK}Vitesse{NBSP}: {GOLD}{VELOCITY} STR_PURCHASE_INFO_SPEED_OCEAN :{BLACK}Vitesse sur l'océan{NBSP}: {GOLD}{VELOCITY} @@ -3478,8 +3520,10 @@ STR_PURCHASE_INFO_REFITTABLE :(réaménageabl STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Conçu en{NBSP}: {GOLD}{NUM}{BLACK} − Durée de vie{NBSP}: {GOLD}{COMMA} an{P "" s} STR_PURCHASE_INFO_RELIABILITY :{BLACK}Fiabilité max.{NBSP}: {GOLD}{COMMA}{NBSP}% STR_PURCHASE_INFO_COST :{BLACK}Prix{NBSP}: {GOLD}{CURRENCY_LONG} +STR_PURCHASE_INFO_COST_REFIT :{BLACK}Coût{NBSP}: {GOLD}{CURRENCY_LONG}{BLACK} (Coût de réaménagement{NBSP}: {GOLD}{CURRENCY_LONG}{BLACK}) STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Poids{NBSP}: {GOLD}{WEIGHT_SHORT} ({WEIGHT_SHORT}) STR_PURCHASE_INFO_COST_SPEED :{BLACK}Prix{NBSP}: {GOLD}{CURRENCY_LONG}{BLACK} − Vitesse{NBSP}: {GOLD}{VELOCITY} +STR_PURCHASE_INFO_COST_REFIT_SPEED :{BLACK}Coût{NBSP}: {GOLD}{CURRENCY_LONG}{BLACK} (Coût de réaménagement{NBSP}: {GOLD}{CURRENCY_LONG}{BLACK}) Vitesse{NBSP}: {GOLD}{VELOCITY} STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Capacité{NBSP}: {GOLD}{CARGO_LONG}, {CARGO_LONG} STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Wagons motorisés{NBSP}: {GOLD}+{POWER}{BLACK} − Poids{NBSP}: {GOLD}+{WEIGHT_SHORT} STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Réaménageable pour{NBSP}: {GOLD}{STRING} @@ -3500,11 +3544,21 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Acheter STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Acheter STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Acheter +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_BUTTON :Achat et réaménagement du véhicule +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Acheter et réaménager +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_BUTTON :Acheter et réaménager le bateau +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Acheter et réaménager + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Acheter le véhicule sélectionné.{}Shift-clic pour afficher seulement le coût estimé. STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Acheter le véhicule sélectionné.{}Shift-clic pour afficher seulement le coût estimé. STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Acheter le navire sélectionné.{}Shift-clic pour afficher seulement le coût estimé. STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Acheter l'aéronef sélectionné.{}Shift-clic pour afficher seulement le coût estimé. +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Acheter et réaménager le véhicule sélectionné.{}Shift-clic pour afficher seulement le coût estimé. +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Acheter et réaménager le véhicule sélectionné.{}Shift-clic pour afficher seulement le coût estimé. +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Acheter et réaménager le navire sélectionné.{}Shift-clic pour afficher seulement le coût estimé. +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Acheter et réaménager l'aéronef sélectionné.{}Shift-clic pour afficher seulement le coût estimé. + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Renommer STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Renommer STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Renommer @@ -3613,13 +3667,18 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Vous ê # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Communiqué du fabriquant de véhicules STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Nous venons juste d'inventer{NBSP}: {STRING} - Voulez-vous l'exclusivité de ce véhicule pendant un an, afin que nous puissions le tester avant sa mise sur le marché{NBSP}? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :{G=f}locomotive -STR_ENGINE_PREVIEW_ROAD_VEHICLE :{G=m}véhicule -STR_ENGINE_PREVIEW_AIRCRAFT :{G=m2}aéronef -STR_ENGINE_PREVIEW_SHIP :{G=m}navire +STR_ENGINE_PREVIEW_ELRAIL_LOCOMOTIVE :{G=f}locomotive électrique STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :{G=f}locomotive monorail STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :{G=f}locomotive Maglev +STR_ENGINE_PREVIEW_ROAD_VEHICLE :{G=m}véhicule +STR_ENGINE_PREVIEW_TRAM_VEHICLE :{G=m}tramway + +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_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 @@ -3657,14 +3716,19 @@ STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK}Alterner STR_REPLACE_ENGINES :Locomotives STR_REPLACE_WAGONS :Wagons STR_REPLACE_ALL_RAILTYPE :Tous le véhicules sur rail +STR_REPLACE_ALL_ROADTYPE :Tous les véhicules routiers STR_REPLACE_HELP_RAILTYPE :{BLACK}Choisir un type de rail pour le remplacement de locomotives +STR_REPLACE_HELP_ROADTYPE :{BLACK}Choisir un type de route pour le remplacement de véhicules STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Ceci affiche par quel type de véhicule sera remplacé celui sélectionné à gauche, si possible STR_REPLACE_RAIL_VEHICLES :Véhicules sur rail STR_REPLACE_ELRAIL_VEHICLES :Véhicules électriques sur rail STR_REPLACE_MONORAIL_VEHICLES :Véhicules sur monorail STR_REPLACE_MAGLEV_VEHICLES :Véhicules Maglev +STR_REPLACE_ROAD_VEHICLES :Véhicules routiers +STR_REPLACE_TRAM_VEHICLES :Tramways + STR_REPLACE_REMOVE_WAGON :{BLACK}Retrait de wagon{NBSP}: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Si l'autoremplacement de la locomotive provoque un accroissement de la longueur du train, alors sa longueur initiale sera retrouvée en retirant automatiquement des wagons (d'abord par la tête) @@ -3900,7 +3964,7 @@ STR_ORDER_CONDITIONAL_VALUE_TOOLTIP :{BLACK}La valeu STR_ORDER_CONDITIONAL_VALUE_CAPT :{WHITE}Entrer la valeur à comparer STR_ORDERS_SKIP_BUTTON :{BLACK}Suivant -STR_ORDERS_SKIP_TOOLTIP :{BLACK}Sauter l'ordre courant et passer au suivant.{}Ctrl-clic pour sauter l'ordre sélectionné. +STR_ORDERS_SKIP_TOOLTIP :{BLACK}Sauter l'ordre courant et passer au suivant.{}Ctrl-clic pour sauter à l'ordre sélectionné. STR_ORDERS_DELETE_BUTTON :{BLACK}Supprimer STR_ORDERS_DELETE_TOOLTIP :{BLACK}Supprimer l'ordre sélectionné @@ -4115,6 +4179,14 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Sélecti STR_AI_LIST_CANCEL :{BLACK}Annuler STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Ne pas modifier le script +STR_SCREENSHOT_CAPTION :{WHITE}Faire une capture d'écran +STR_SCREENSHOT_SCREENSHOT :{BLACK}Capture d'écran normale +STR_SCREENSHOT_ZOOMIN_SCREENSHOT :{BLACK}Capture d'écran au zoom maximum +STR_SCREENSHOT_DEFAULTZOOM_SCREENSHOT :{BLACK}Capture d'écran sans zoom +STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Capture d'écran de toute la carte +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 @@ -4317,7 +4389,6 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... cett STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... mauvaise orientation de la route STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... les arrêts ne peuvent pas avoir de virages STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... les arrêts ne peuvent pas avoir de jonctions -STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... la route est à sens unique ou bloquée # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Impossible de supprimer une partie de la gare... @@ -4387,7 +4458,8 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Vous dev STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Aucuns rails convenables STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Vous devez d'abord enlever les rails STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}La route est à sens unique ou bloquée -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Les passages à niveau ne sont pas authorisés pour ce type de rails +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Les passages à niveau ne sont pas autorisés pour ce type de rail +STR_ERROR_CROSSING_DISALLOWED_ROAD :{WHITE}Les passages à niveau ne sont pas autorisés pour ce type de route STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Impossible de construire des signaux ici... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Impossible de construire des rails ici... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Impossible de retirer les rails d'ici... @@ -4407,6 +4479,12 @@ STR_ERROR_CAN_T_REMOVE_ROAD_FROM :{WHITE}Impossib STR_ERROR_CAN_T_REMOVE_TRAMWAY_FROM :{WHITE}Impossible de retirer la section de voie de tramway d'ici... STR_ERROR_THERE_IS_NO_ROAD :{WHITE}... il n'y a pas de route STR_ERROR_THERE_IS_NO_TRAMWAY :{WHITE}... il n'y a pas de tramway +STR_ERROR_CAN_T_CONVERT_ROAD :{WHITE}Impossible de convertir le type de route... +STR_ERROR_CAN_T_CONVERT_TRAMWAY :{WHITE}Impossible de convertir le type de voie de tramway... +STR_ERROR_NO_SUITABLE_ROAD :{WHITE}Aucune route convenable +STR_ERROR_NO_SUITABLE_TRAMWAY :{WHITE}Aucune voie de tramway convenable +STR_ERROR_INCOMPATIBLE_ROAD :{WHITE}... route incompatible +STR_ERROR_INCOMPATIBLE_TRAMWAY :{WHITE}... voie de tramway incompatible # Waterway construction errors STR_ERROR_CAN_T_BUILD_CANALS :{WHITE}Impossible de construire un canal ici... @@ -4459,6 +4537,7 @@ STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Impossib STR_ERROR_GROUP_CAN_T_DELETE :{WHITE}Impossible de supprimer ce groupe... STR_ERROR_GROUP_CAN_T_RENAME :{WHITE}Impossible de renommer le groupe... STR_ERROR_GROUP_CAN_T_SET_PARENT :{WHITE}Impossible de définir le groupe parent... +STR_ERROR_GROUP_CAN_T_SET_PARENT_RECURSION :{WHITE}... les boucles ne sont pas autorisées dans la hiérarchie de groupe STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}Impossible de retirer tous les véhicules de ce groupe... STR_ERROR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}Impossible d'ajouter le véhicule à ce groupe... STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}Impossible d'ajouter les véhicules partagés à ce groupe... diff --git a/src/lang/gaelic.txt b/src/lang/gaelic.txt index 013a1f808f..ea82d30108 100644 --- a/src/lang/gaelic.txt +++ b/src/lang/gaelic.txt @@ -12,8 +12,6 @@ ##case nom gen dat voc -# $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. # 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. @@ -660,9 +658,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Toglaich a' chonsoil STR_ABOUT_MENU_AI_DEBUG :Dì-bhugaich IF/sgriobt geama STR_ABOUT_MENU_SCREENSHOT :Glacadh-sgrìn -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Glacadh-sgrìn le sùmadh a-steach as motha -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Glacadh-sgrìn le sùmadh a-steach bunaiteach -STR_ABOUT_MENU_GIANT_SCREENSHOT :Glacadh-sgrìn leis a' mhapa shlàn STR_ABOUT_MENU_ABOUT_OPENTTD :Mu dheidhinn “OpenTTD" STR_ABOUT_MENU_SPRITE_ALIGNER :Co-thaobhaichear nan sprite STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Toglaich bogsaichean-iadhaidh @@ -843,9 +838,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Gnàthaichte 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Àirde a' chiùil STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Àirde nan èifeachdan fuaime -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}As lugha -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}As motha -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -1063,6 +1055,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}Tha {STRING} ùr ri fhaighinn a-nis! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}Cha ghabh {STATION} ri {STRING} tuilleadh STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}Cha ghabh {STATION} ri {STRING} no {STRING} tuilleadh STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}Gabhaidh {STATION} ri {STRING} a-nis @@ -1894,7 +1887,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Sgaoile STR_CONFIG_SETTING_AI :{ORANGE}Co-farpaisichean STR_CONFIG_SETTING_AI_NPC :{ORANGE}Cluicheadairean coimpiutair -STR_CONFIG_SETTING_PATHFINDER_OPF :Tùsail STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(molta) @@ -1978,13 +1970,9 @@ STR_QUIT_NO :{BLACK}Chan eil # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -2625,6 +2613,7 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Tog tuna STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Toglaich togail/toirt air falbh airson togail rathaidean STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Toglaich togail/tort air falbh airson slighean trama + # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Comhair na garaids STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}Tagh comhair na garaids @@ -3539,8 +3528,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Am bun-s STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Earrannan rèile: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Comharran STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Earrannan rathaid: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Rathad -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Slighe-trama STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Leacan uisge: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Canalan STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Stèiseanan: @@ -3551,8 +3538,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Gnìomhachasan STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Gun ghnìomhachas - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% air a ghiùlan) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% air a ghiùlan) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Ainmean nan gnìomhachasan - briog air an ainm gus am prìomh-shealladh a mheadhanachadh air a' ghnìomhachais. Fosglaidh Ctrl+briogadh port-seallaidh ùr air ionad a' ghnìomhachais @@ -3617,6 +3602,7 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Carbadan-rathai STR_GROUP_DEFAULT_SHIPS :Longan gun bhuidheann STR_GROUP_DEFAULT_AIRCRAFTS :Carbadan-adhair gun bhuidheann + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Buidhnean - briog air buidheann gus a h-uile carbad a tha sa bhuidheann seo a shealltainn. Slaod buidhnean ’s leig às iad gus an rangachd atharrachadh. STR_GROUP_CREATE_TOOLTIP :{BLACK}Briog gus buidheann a chruthachadh STR_GROUP_DELETE_TOOLTIP :{BLACK}Sguab às dhan bhuidheann a thagh thu @@ -3642,10 +3628,13 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Carbadan-rèile STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Carbadan aona-rèile ùra STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Carbadan magnaiteach ùra -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Carbadan-rèile ùra STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Carbadan-rathaid ùra + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Carbadan-rèile ùra STR_BUY_VEHICLE_SHIP_CAPTION :Longan ùra STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Carbadan-adhair ùra +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Cosgais: {GOLD}{CURRENCY_LONG}{BLACK} Cuideam: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Luaths: {GOLD}{VELOCITY}{BLACK} Cumhachd: {GOLD}{POWER} @@ -3680,11 +3669,13 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Ceannaic STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Ceannaich long STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Ceannaich carbad-adhair + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Ceannaich an carbad-rèile a thagh thu. Seallaidh Shift+briogadh tuairmse air na cosgaisean gun a bhith a' ceannach dad STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Ceannaich an carbad-rathaid a thagh thu. Seallaidh Shift+briogadh tuairmse air na cosgaisean gun a bhith a' ceannach dad STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Ceannaich an long a thagh thu. Seallaidh Shift+briogadh tuairmse air na cosgaisean gun a bhith a' ceannach dad STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Ceannaich an carbad-adhair a thagh thu. Seallaidh Shift+briogadh tuairmse air na cosgaisean gun a bhith a' ceannach dad + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Thoir ainm ùr air STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Thoir ainm ùr air STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Thoir ainm ùr air @@ -3793,13 +3784,16 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Tha thu # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Brath bho dhèanadair a' charbaid STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Tha sinn air {STRING} ùr a dhealbhadh - a bheil ùidh agaibh ann ’s nach cleachd ach sibh fhèin e fad bliadhna ach am faic sinn dè cho math ’s a dh’obraicheas e mus reic sinn don a h-uile duine e? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :einnsean-rèile -STR_ENGINE_PREVIEW_ROAD_VEHICLE :carbad-rathaid -STR_ENGINE_PREVIEW_AIRCRAFT :carbad-adhair -STR_ENGINE_PREVIEW_SHIP :{G=f}long STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :einnsean aona-rèile STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :einnsean magnaiteach +STR_ENGINE_PREVIEW_ROAD_VEHICLE :carbad-rathaid + +STR_ENGINE_PREVIEW_AIRCRAFT :carbad-adhair +STR_ENGINE_PREVIEW_SHIP :{G=f}long + STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Cosgais: {CURRENCY_LONG} Cuideam: {WEIGHT_SHORT}{}Luaths: {VELOCITY} Cumhachd: {POWER}{}Cosgaisean ruith: {CURRENCY_LONG}/bliadhna{}Tomhas-lìonaidh: {CARGO_LONG} STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Cosgais: {CURRENCY_LONG} Cuideam: {WEIGHT_SHORT}{}Luaths: {VELOCITY} Cumhachd: {POWER} Neart: {6:FORCE}{}Cosgaisean ruith: {4:CURRENCY_LONG}/bliadhna{}Tomhas-lìonaidh: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Cosgais: {CURRENCY_LONG} Luaths as motha: {VELOCITY}{}Tomhas-lìonaidh: {CARGO_LONG}{}Cosgaisean ruith: {CURRENCY_LONG}/bliadhna @@ -3845,6 +3839,7 @@ STR_REPLACE_ELRAIL_VEHICLES :Carbadan-rèile STR_REPLACE_MONORAIL_VEHICLES :Carbadan aona-rèile STR_REPLACE_MAGLEV_VEHICLES :Carbadan magnaiteach + STR_REPLACE_REMOVE_WAGON :{BLACK}A' toirt air falbh carbad: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Glèidh faide aig trèan nuair a thèid fhèin-leasachadh le toirt air falbh nan carbadan (bho thoiseach na trèan a-mach) ma dh'fhàsas an trèan nas fhaide le einnsean ùr @@ -4294,6 +4289,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Cleachd STR_AI_LIST_CANCEL :{BLACK}Sguir dheth STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Na atharraich an sgriobt + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}Paramadairean aig {STRING} STR_AI_SETTINGS_CAPTION_AI :IF @@ -4496,7 +4492,6 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... tha STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... tha comhair an rathaid cearr STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... chan urrainn dha dh’oiseanan a bhith aig stèiseanan draibhidh troimhe STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... chan urrainn dha ghoibhlean a bhith aig stèiseanan draibhidh troimhe -STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... rathad aon-shligheach no bacte # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Cha ghabh pàirt dhen stèisean toirt air falbh... @@ -4566,7 +4561,7 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Feumaidh STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Chan eil slighe rèile iomchaidh ann STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Feumaidh tu an t-slighe rèile a thoirt air falbh an toiseach STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Rathad aon-shligheach no bacte -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Chan eil staranan-rèile ceadaichte leis an t-seòrsa dhe rèile seo +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Chan eil staranan-rèile ceadaichte leis an t-seòrsa dhe rèile seo STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Cha ghabh comharran togail an-seo... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Cha ghabh slighe-rèile togail an-seo... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Cha ghabh an t-slighe-rèile toirt air falbh an-seo... diff --git a/src/lang/galician.txt b/src/lang/galician.txt index 6c8e3bf181..5405fa2f06 100644 --- a/src/lang/galician.txt +++ b/src/lang/galician.txt @@ -11,8 +11,6 @@ ##gender m f n -# $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. # 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. @@ -190,6 +188,8 @@ STR_COLOUR_ORANGE :Laranxa STR_COLOUR_BROWN :Marrón STR_COLOUR_GREY :Gris STR_COLOUR_WHITE :Branco +STR_COLOUR_RANDOM :Ao chou +STR_COLOUR_DEFAULT :Por defecto # Units used in OpenTTD STR_UNITS_VELOCITY_IMPERIAL :{COMMA} mph @@ -236,6 +236,8 @@ STR_TOOLTIP_FILTER_CRITERIA :{BLACK}Seleccio STR_BUTTON_SORT_BY :{BLACK}Ordenar por STR_BUTTON_LOCATION :{BLACK}Situación STR_BUTTON_RENAME :{BLACK}Renomear +STR_BUTTON_CATCHMENT :{BLACK}Cobertura +STR_TOOLTIP_CATCHMENT :{BLACK}Alternar amosar área de cobertura STR_TOOLTIP_CLOSE_WINDOW :{BLACK}Pechar xanela STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Título da xanela - arrástrao para move-la xanela @@ -264,6 +266,7 @@ STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT_TOOLTIP :{BLACK}Habilita STR_BUTTON_DEFAULT :{BLACK}Por defecto STR_BUTTON_CANCEL :{BLACK}Cancelar STR_BUTTON_OK :{BLACK}OK +STR_WARNING_PASSWORD_SECURITY :{YELLOW}Ollo: Os administradores do servidor poderían ler calquer texto escrito aquí. # On screen keyboard window STR_OSK_KEYBOARD_LAYOUT :`1234567890-=\qwertyuiop[]asdfghjkl;' zxcvbnm,./ . @@ -337,6 +340,7 @@ STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN :{BLACK}Achega-l STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT :{BLACK}Alonxa-la vista STR_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Construír vía ferroviaria STR_TOOLBAR_TOOLTIP_BUILD_ROADS :{BLACK}Construír estradas +STR_TOOLBAR_TOOLTIP_BUILD_TRAMWAYS :{BLACK}Construír vías de tranvía STR_TOOLBAR_TOOLTIP_BUILD_SHIP_DOCKS :{BLACK}Construír portos STR_TOOLBAR_TOOLTIP_BUILD_AIRPORTS :{BLACK}Construír aeroportos STR_TOOLBAR_TOOLTIP_LANDSCAPING :{BLACK}Abri-la ferramenta de terreo para subir/baixar terreo, plantar árbores, etc. @@ -357,6 +361,7 @@ STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION :{BLACK}Xeració STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Xeración de cidades 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_PLACE_SIGN :{BLACK}Colocar rótulo STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Colocar obxecto. Shift alterna entre construir/amosar custo estimado @@ -465,6 +470,7 @@ STR_TOOLBAR_SOUND_MUSIC :Son/música ############ range for message menu starts STR_NEWS_MENU_LAST_MESSAGE_NEWS_REPORT :Última mensaxe/nova STR_NEWS_MENU_MESSAGE_HISTORY_MENU :Historial de mensaxes +STR_NEWS_MENU_DELETE_ALL_MESSAGES :Borrar tódalas mensaxes ############ range ends here ############ range for about menu starts @@ -473,9 +479,7 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :(Des)Activar consola STR_ABOUT_MENU_AI_DEBUG :Depuración IA/script do xogo STR_ABOUT_MENU_SCREENSHOT :Captura de pantalla -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Achegar área capturada -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Zoom de captura de pantalla por defecto -STR_ABOUT_MENU_GIANT_SCREENSHOT :Captura de pantalla do mapa completo +STR_ABOUT_MENU_SHOW_FRAMERATE :Mostrar frame rate STR_ABOUT_MENU_ABOUT_OPENTTD :Acerca de 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Aliñador de sprites STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Activa/desactiva caixas delimitadoras @@ -645,12 +649,10 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Persoal 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Volume da música STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Volume dos efectos de son -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}MÍN -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}MÁX -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ +STR_MUSIC_TITLE_NOMUSIC :{TINY_FONT}{DKGREEN}Non hai música dispoñible STR_MUSIC_TITLE_NAME :{TINY_FONT}{DKGREEN}"{STRING}" STR_MUSIC_TRACK :{TINY_FONT}{BLACK}Pista STR_MUSIC_XTITLE :{TINY_FONT}{BLACK}Título @@ -671,11 +673,14 @@ STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Activar/ STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Amosar a fiestra de selección de pista musical # Playlist window +STR_PLAYLIST_MUSIC_SELECTION_SETNAME :{WHITE}Programa de música - '{STRING}' STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Índice de pistas STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Programa - '{STRING}' STR_PLAYLIST_CLEAR :{TINY_FONT}{BLACK}Limpar +STR_PLAYLIST_CHANGE_SET :{BLACK}Mudar conxunto STR_PLAYLIST_TOOLTIP_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Limpa-lo programa actual (só Persoal 1 ou Persoal 2) +STR_PLAYLIST_TOOLTIP_CHANGE_SET :{BLACK}Cambia a música seleccionada por outra instalada STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK :{BLACK}Pincha nunha pista de música para engadila ao programa actual (só Persoal 1 ou Persoal 2) STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK :{BLACK}Pincha nunha pista de música para borrala do programa actual (só Persoal1 ou Persoal2) @@ -811,6 +816,7 @@ STR_NEWS_MERGER_TAKEOVER_TITLE :{BIG_FONT}{BLAC STR_PRESIDENT_NAME_MANAGER :{BLACK}{PRESIDENT_NAME}{}(Presidente) STR_NEWS_NEW_TOWN :{BLACK}{BIG_FONT}{STRING} promoveu a construción dunha nova cidade: {TOWN}! +STR_NEWS_NEW_TOWN_UNSPONSORED :{BLACK}{BIG_FONT}Unha nova vila chamada {TOWN} foi construída! STR_NEWS_INDUSTRY_CONSTRUCTION :{BIG_FONT}{BLACK}Nova {STRING} en construción cerca de {TOWN}! STR_NEWS_INDUSTRY_PLANTED :{BIG_FONT}{BLACK}Nova {STRING} asentada preto de {TOWN}! @@ -820,7 +826,7 @@ STR_NEWS_INDUSTRY_CLOSURE_SUPPLY_PROBLEMS :{BIG_FONT}{BLAC STR_NEWS_INDUSTRY_CLOSURE_LACK_OF_TREES :{BIG_FONT}{BLACK}A falta de árbores cercanos provoca que {STRING} anuncie o peche inminente! STR_NEWS_EURO_INTRODUCTION :{BIG_FONT}{BLACK}Unión Económica e Monetaria Europea!{}{}O Euro introdúcese como a única moeda para as transaccións diarias no teu país! -STR_NEWS_BEGIN_OF_RECESSION :{BLACK}{BIG_FONT}Recesión mundial!{}{}Os expertos financeiros temen o peor a medida que a economía afúndese! +STR_NEWS_BEGIN_OF_RECESSION :{BLACK}{BIG_FONT}Recesión mundial!{}{}Os expertos financieiros temen o peor a medida que a economía se afunde! STR_NEWS_END_OF_RECESSION :{BLACK}{BIG_FONT}Fin da recesión!{}{}A mellora no comercio inspira confianza nas industrias a media que a economía se reforza! STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL :{BIG_FONT}{BLACK}{INDUSTRY} incrementa a súa producción! @@ -859,6 +865,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}Nova {STRING} dispoñíbel! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} xa non acepta máis {STRING} STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} xa non acepta máis {STRING} nin {STRING} STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} agora acepta {STRING} @@ -878,10 +885,10 @@ STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION :{BIG_FONT}{BLAC # Extra view window STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Vista {COMMA} -STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Copiar á vista +STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Cambiar xanela STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Copia-la sitaución da vista principal a esta vista -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Pegar dende vista -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Pega-la a situación desta vista na vista principal +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Cambia a vista principal +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Copia a localización desta xanela na vista principal # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Opcións da partida @@ -923,6 +930,11 @@ STR_GAME_OPTIONS_CURRENCY_ZAR :Rand sudafrican STR_GAME_OPTIONS_CURRENCY_CUSTOM :Persoal... STR_GAME_OPTIONS_CURRENCY_GEL :Lari xeorxiano (GEL) STR_GAME_OPTIONS_CURRENCY_IRR :Real iraniano (IRR) +STR_GAME_OPTIONS_CURRENCY_RUB :Novo rublo ruso (RUB) +STR_GAME_OPTIONS_CURRENCY_MXN :Peso mexicano (MXN) +STR_GAME_OPTIONS_CURRENCY_NTD :Novo dólar taiwanés (NTD) +STR_GAME_OPTIONS_CURRENCY_CNY :Renminbi chinés (CNY) +STR_GAME_OPTIONS_CURRENCY_HKD :Dólar de Hong Kong (HKD) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Vehículos de estrada @@ -985,7 +997,12 @@ 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_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_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_BASE_GRF :{BLACK}Conxunto básico de gráficos STR_GAME_OPTIONS_BASE_GRF_TOOLTIP :{BLACK}Selecciona o conxunto de gráficos básico a empregar @@ -1144,7 +1161,7 @@ STR_CONFIG_SETTING_MAXIMUM_INITIAL_LOAN_HELPTEXT :Cantidade máxi 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 STR_CONFIG_SETTING_RUNNING_COSTS :Custos de explotación: {STRING} -STR_CONFIG_SETTING_RUNNING_COSTS_HELPTEXT :Fixa o nivel de mantemento e custo de operación de vehículos e infraestrutura +STR_CONFIG_SETTING_RUNNING_COSTS_HELPTEXT :Establece o nivel de mantemento e custo de operación de vehículos e infraestrutura STR_CONFIG_SETTING_CONSTRUCTION_SPEED :Velocidade de construción: {STRING} STR_CONFIG_SETTING_CONSTRUCTION_SPEED_HELPTEXT :Limita a cantidade de accións construtivas das IAs STR_CONFIG_SETTING_VEHICLE_BREAKDOWNS :Avarías en vehículos: {STRING} @@ -1169,6 +1186,8 @@ STR_CONFIG_SETTING_AUTOSLOPE :Permitir modifi STR_CONFIG_SETTING_AUTOSLOPE_HELPTEXT :Permite modificar o terreo baixo edificacións e vías sen retiralos STR_CONFIG_SETTING_CATCHMENT :Permitir áreas de captación máis realistas: {STRING} STR_CONFIG_SETTING_CATCHMENT_HELPTEXT :Áreas de influencia e captación de diferentes tamaños para os diferentes tipos de estacións e aeroportos +STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES :As estacións da compañía poden atender a industrias con estacións neutrais incorporadas: {STRING} +STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES_HELPTEXT :Cando se activa, as industrias con estacións incorporadas (coma plataformas petrolíferas) poden ser atendidas por estacións cercanas propiedade da compañía. Cando se desactiva, estas industrias só poden ser atendidas polas estacións incorporadas. Calquera estación cercana dunha compañía non poderá atendelas, e a estación incorporada non poderá servir a nada máis que á industria STR_CONFIG_SETTING_EXTRADYNAMITE :Permiti-la eliminación de máis estradas, pontes e túneis de titularidade municipal: {STRING} STR_CONFIG_SETTING_EXTRADYNAMITE_HELPTEXT :Facilita a destrución de infraestrutura e edificacións de titularidade municipal STR_CONFIG_SETTING_TRAIN_LENGTH :Lonxitude máxima dos trens: {STRING} @@ -1185,8 +1204,8 @@ STR_CONFIG_SETTING_TRAIN_SLOPE_STEEPNESS_HELPTEXT :Inclinación du STR_CONFIG_SETTING_PERCENTAGE :{COMMA}% STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS :Inclinación das pendentes para os vehículos de carretera: {STRING} STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS_HELPTEXT :Inclinación dun cadro en pendente para un vehículo de carretera. Valores máis elevados dificultan ascender unha colina -STR_CONFIG_SETTING_FORBID_90_DEG :Prohibir xiros de 90° a trens e barcos: {STRING} -STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :Os xiros de 90 graos ocorren cando unha vía horizontal vai seguida directamente dun tramo vertical no cadro adxancete, facendo que o tren vire 90 graos cando pasa o límite do cadro en vez dos 45 graos habituais noutras combinacións de vías. Esto tamén se aplica ao radio de xiro dos barcos +STR_CONFIG_SETTING_FORBID_90_DEG :Prohibir xiros de 90° a trens: {STRING} +STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :Os xiros de 90 graos ocorren cando unha vía horizontal vai seguida directamente dun tramo vertical no cadro adxancete, facendo que o tren vire 90 graos cando pasa o límite do cadro en vez dos 45 graos habituais noutras combinacións de vías. STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS :Permitir a unión de estacións non adxacentes {STRING} STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS_HELPTEXT :Permite engadir partes a unha estación sen que estén en contacto directo coas partes existente. Necesita facer Ctrl+Click ao colocar as partes novas STR_CONFIG_SETTING_INFLATION :Inflación: {STRING} @@ -1242,8 +1261,8 @@ STR_CONFIG_SETTING_PLANE_SPEED :Factor de veloc STR_CONFIG_SETTING_PLANE_SPEED_HELPTEXT :Fixa a velocidade relativa dos avións comparada coa dos outros tipos de vehículos, para reduci-los ingresos do transporte aéreo STR_CONFIG_SETTING_PLANE_SPEED_VALUE :1 / {COMMA} STR_CONFIG_SETTING_PLANE_CRASHES :Número de accidentes de avión: {STRING} -STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Fixa a posibilidade de que ocorra un accidente aéreo -STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Ningún +STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Establece a probabilidade de que ocorra un accidente aéreo.{}* Os avións de gran tamaño sempre teñen risco de accidente ao aterrar en aeroportos pequenos +STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Ningún* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Reducido STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normal STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Permiti-la construción de estacións pasantes nas rúas de titularidade municipal: {STRING} @@ -1254,6 +1273,8 @@ STR_CONFIG_SETTING_DYNAMIC_ENGINES_EXISTING_VEHICLES :{WHITE}Non é p STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE :Mantemento de infraestrutura: {STRING} STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE_HELPTEXT :Cando se activa, a infraestrutura provoca custos de mantemento. O custo aumenta sobre-proporcionadamente co tamaño da rede, e afecta máis ás compañías máis grandes cás pequenas +STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR :Cor inicial da compañía: {STRING} +STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR_HELPTEXT :Escolle a cor inicial da túa compañía STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS :Os aeroportos nunca caducan: {STRING} STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS_HELPTEXT :Activar esta opción fai que cada tipo de aeroporto siga estando dispoñíbel para sempre dende a súa aparición @@ -1300,7 +1321,7 @@ STR_CONFIG_SETTING_TERRAIN_TYPE_HELPTEXT :(TerraGenesis s STR_CONFIG_SETTING_INDUSTRY_DENSITY :Densidade industrial: {STRING} STR_CONFIG_SETTING_INDUSTRY_DENSITY_HELPTEXT :Establece cantas industrias deben xerarse e que nivel se debe manter durante o xogo STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE :Distancia máxima das refinarías ao borde do mundo: {STRING} -STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :As refinarías de petróleo só se constrúen preto do borde do mapa, isto é na costa para mapas de illas +STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :Limita a qué distancia dos bordes do mundo as refinerías e pozos petrolíferos poden construirse. En mapas con illas asegura que estean situadas preto da costa. En mapas maiores de 256 unidades, o valor escálase acorde ao tamaño do mapa. STR_CONFIG_SETTING_SNOWLINE_HEIGHT :Cota de neve: {STRING} STR_CONFIG_SETTING_SNOWLINE_HEIGHT_HELPTEXT :Controla a que altitude comeza a nevar en paisaxes subárticas. A neve afecta tamén á xeración industrial e aos requirimentos de crecemento dos pobos STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN :Desigualdade do terreo (só TerraGenesis) : {STRING} @@ -1338,8 +1359,14 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Cor do terreo n STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :Verde STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :Verde escuro STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Violeta +STR_CONFIG_SETTING_SCROLLMODE :Comportamento do desprazamento das xanelas: {STRING} +STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :Comportamento cando te desplazas polo mapa +STR_CONFIG_SETTING_SCROLLMODE_DEFAULT :Mover xanela co botón dereito do rato, posición do cursor bloqueada +STR_CONFIG_SETTING_SCROLLMODE_RMB_LOCKED :Mover mapa co botón dereito do rato, posición do cursor bloqueada +STR_CONFIG_SETTING_SCROLLMODE_RMB :Mover mapa co botón dereito do rato +STR_CONFIG_SETTING_SCROLLMODE_LMB :Move-lo mapa co botón esquerdo do rato STR_CONFIG_SETTING_SMOOTH_SCROLLING :Desprazamento de vista suave: {STRING} -STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Controla como a vista principal se despraza a unah posición específica cando se fai clic no minimapa ou cando se emprega un comando para desprazarse a un obxecto específico sobre o mapa. Se se activa, a vista desprázase suavemente, se se desactiva salta directamente +STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Controla como a vista principal se despraza a unha posición específica cando se fai clic no minimapa ou cando se emprega un comando para desprazarse a un obxecto específico sobre o mapa. Se se activa, a vista desprázase suavemente, se se desactiva salta directamente STR_CONFIG_SETTING_MEASURE_TOOLTIP :Mostrar medidas ao usar as ferramentas de construción: {STRING} STR_CONFIG_SETTING_MEASURE_TOOLTIP_HELPTEXT :Amosa as distancias en cadros e as diferencias de cota ao arrastrar durante as operacións de construción STR_CONFIG_SETTING_LIVERIES :Mostrar esquemas de cor das compañías: {STRING} @@ -1458,6 +1485,9 @@ STR_CONFIG_SETTING_AI_IN_MULTIPLAYER :Permitir IA en STR_CONFIG_SETTING_AI_IN_MULTIPLAYER_HELPTEXT :Permitir aos xogadores controlados pola computadora participar en partidas multixogador STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES :#opcodes antes de que os scripts sexan suspendidos: {STRING} STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES_HELPTEXT :Número máximo de operacións de computación que un scrpit pode realizar nun turno +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY :Uso máximo de memoria por script: {STRING} +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_HELPTEXT :Canta memoria pode consumir un só script antes de terminalo forzosamente. Pode que se necesite incrementar en mapas grandes +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_VALUE :{COMMA} MiB STR_CONFIG_SETTING_SERVINT_ISPERCENT :Intervalos de servizo en porcentaxes: {STRING} STR_CONFIG_SETTING_SERVINT_ISPERCENT_HELPTEXT :Permite escoller se o mantemento de vehículos comezará debido ao tempo transcurrido dende o último mantemento ou por unha redución da fiabilidade cando se sobrepase unha porcentaxe determinado @@ -1520,6 +1550,8 @@ STR_CONFIG_SETTING_SMOOTH_ECONOMY :Habilita-la eco STR_CONFIG_SETTING_SMOOTH_ECONOMY_HELPTEXT :Cando se activa, as producións industriais cambian máis frecuentemente, e a pasos máis curtos STR_CONFIG_SETTING_ALLOW_SHARES :Permiti-la compra de accións de outras compañías: {STRING} STR_CONFIG_SETTING_ALLOW_SHARES_HELPTEXT :Cando se activa, permite comprar ou vender accións da compañía. As accións só estarán dispoñíbeis para compañías que acaden certa idade +STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES :Idade mínima da compañía para compraventa de accións: {STRING} +STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES_HELPTEXT :Establece a idade mínima dunha compañía para que outros poidan comprar e vender accións dela. STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE :Porcentaxe do beneficio parcial a pagar en sistemas transitivos: {STRING} STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE_HELPTEXT :Porcentaxe dos beneficios asignados ás partes intermedias da ruta en sistemas transitivos, dando un maior control sobre os ingresos STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY :Colocar sinais cada {STRING} ao arrastrar @@ -1560,6 +1592,10 @@ STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :Activando esta STR_CONFIG_SETTING_TOWN_FOUNDING_FORBIDDEN :Prohibido STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED :Permitido STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED_CUSTOM_LAYOUT :Permitido, patrón de estradas personalizado +STR_CONFIG_SETTING_TOWN_CARGOGENMODE :Xeración de mercadorías da vila: {STRING} +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_HELPTEXT :Cantidade de mercadorías producidas nas casas da vila, segundo a poboación total da mesma.{}Crecemento cadrático: Unha vila o dobre de grande produce catro veces máis pasaxeiros.{}Linear growth: Unha vila o dobre de grande produce dúas veces máis pasaxeiros. +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_ORIGINAL :Cadrático (orixinal) +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_BITCOUNT :Lineal STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :Colocación de árbores durante a partida: {STRING} STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :Controla a aparición aleatoria de árbores durante a partida. Isto pode afectar ás industrias que dependan do crecemento arbóreo, por exemplo o serradoiro @@ -1687,7 +1723,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Distrib STR_CONFIG_SETTING_AI :{ORANGE}Competidores STR_CONFIG_SETTING_AI_NPC :{ORANGE}Xogadores da computadora -STR_CONFIG_SETTING_PATHFINDER_OPF :Orixinal STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Recomendado) @@ -1771,13 +1806,9 @@ STR_QUIT_NO :{BLACK}Non # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -1806,6 +1837,7 @@ STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Cambiar STR_CHEAT_SETUP_PROD :{LTBLUE}Permitir a modificación dos valores de producción: {ORANGE}{STRING} # Livery window +STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Novo esquema de cor STR_LIVERY_GENERAL_TOOLTIP :{BLACK}Mostra-los esquemas de cor xerais STR_LIVERY_TRAIN_TOOLTIP :{BLACK}Mostra-los esquemas de cor dos trens @@ -2065,6 +2097,7 @@ STR_NETWORK_CONNECTION_DISCONNECT :{BLACK}Desconec STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}O servidor está protexido. Introduce o contrasinal STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}A compañía está protexida. Introduce o contrasinal +STR_NETWORK_COMPANY_LIST_CLIENT_LIST_CAPTION :{WHITE}Lista de clientes # Network company list added strings STR_NETWORK_COMPANY_LIST_CLIENT_LIST :Lista de clientes @@ -2113,7 +2146,7 @@ STR_NETWORK_CHAT_ALL :[Todos] {STRING STR_NETWORK_CHAT_OSKTITLE :{BLACK}Escribe o texto para a parola en rede # Network messages -STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}Non se atoparon dispositivos de rede ou compilouse sen ENABLE_NETWORK +STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}Non se atoparon dispositivos de rede STR_NETWORK_ERROR_NOSERVER :{WHITE}Non se atoparon xogos en rede STR_NETWORK_ERROR_NOCONNECTION :{WHITE}O servidor non respondeu á solicitude STR_NETWORK_ERROR_NEWGRF_MISMATCH :{WHITE}Non se pode conectar debido a un problema cos NewGRF @@ -2280,6 +2313,7 @@ STR_LINKGRAPH_LEGEND_CAPTION :{BLACK}Lenda de STR_LINKGRAPH_LEGEND_ALL :{BLACK}Todos STR_LINKGRAPH_LEGEND_NONE :{BLACK}Ningún STR_LINKGRAPH_LEGEND_SELECT_COMPANIES :{BLACK}Selecciona as compañías para mostrar +STR_LINKGRAPH_LEGEND_COMPANY_TOOLTIP :{BLACK}{STRING}{}{COMPANY} # Linkgraph legend window and linkgraph legend in smallmap STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLACK}en desuso @@ -2364,9 +2398,9 @@ STR_BUILD_SIGNAL_ELECTRIC_COMBO_TOOLTIP :{BLACK}Sinal co STR_BUILD_SIGNAL_ELECTRIC_PBS_TOOLTIP :{BLACK}Sinal de ruta (eléctrico){}Un sinal de ruta permite entrar a máis dun tren nun cantón ao mesmo tempo, se o tren pode atopar unha ruta a un punto de parada seguro. Os sinais de ruta estándar poden rebasarse en sentido contrario. STR_BUILD_SIGNAL_ELECTRIC_PBS_OWAY_TOOLTIP :{BLACK}Sinal de ruta de sentido único (eléctrico){}Un sinal de ruta permite entrar a máis dun tren nun cantón ao mesmo tempo, se o tren pode atopar unha ruta a un punto de parada seguro. Os de un sentido non se poden atravesar en sentido contrario. STR_BUILD_SIGNAL_CONVERT_TOOLTIP :{BLACK}Convertir sinal{}Cando está seleccionado, convertirá o sinal no que se pinche ao tipo e variante seleccionados, Ctrl+click cambiará a variante existente. Shift+click amosa o custo estimado de conversión -STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP :{BLACK}Densidade de sinais ao arrastrar -STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_DECREASE_TOOLTIP :{BLACK}Diminuír a densidade de sinais ao arrastrar -STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Aumentar a densidade de sinais ao arrastrar +STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP :{BLACK}Distancia de sinais ao arrastrar +STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_DECREASE_TOOLTIP :{BLACK}Diminuír a distancia de sinais ao arrastrar +STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Aumentar a distancia de sinais ao arrastrar # Bridge selection window STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Selecciona ponte ferroviaria @@ -2404,6 +2438,11 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL :{BLACK}Constru STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Construír túnel de tranvía. Shift alterna entre construír/mostrar estimación de custo STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Intecambiar construír/eliminar para a construción de estradas STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Cambia entre construír/quitar para a construción de tranvías +STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_ROAD :{BLACK}Convertir/Actualizar o tipo de estrada. Shift alterna entre construír/amosar custo estimado +STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_TRAM :{BLACK}Convertir/Actualizar o tipo de tranvía. Shift conmuta entre construcción e mostrar unha estimación do coste + +STR_ROAD_NAME_ROAD :Estrada +STR_ROAD_NAME_TRAM :Tranvía # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Orientación do depósito de estrada @@ -2588,8 +2627,11 @@ STR_LAND_AREA_INFORMATION_NEWGRF_NAME :{BLACK}NewGRF: STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED :{BLACK}Carga aceptada: {LTBLUE} STR_LAND_AREA_INFORMATION_CARGO_EIGHTS :({COMMA}/8 {STRING}) STR_LANG_AREA_INFORMATION_RAIL_TYPE :{BLACK}Tipo de vía: {LTBLUE}{STRING} +STR_LANG_AREA_INFORMATION_ROAD_TYPE :{BLACK}Tipo de estrada: {LTBLUE}{STRING} +STR_LANG_AREA_INFORMATION_TRAM_TYPE :{BLACK}Tipo de tranvía: {LTBLUE}{STRING} STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT :{BLACK}Límite de velocidade da vía: {LTBLUE}{VELOCITY} STR_LANG_AREA_INFORMATION_ROAD_SPEED_LIMIT :{BLACK}Límite de velocidade da estrada: {LTBLUE}{VELOCITY} +STR_LANG_AREA_INFORMATION_TRAM_SPEED_LIMIT :{BLACK}Límite de velocidade do tranvía: {LTBLUE}{VELOCITY} # Description of land area of different tiles STR_LAI_CLEAR_DESCRIPTION_ROCKS :Cons @@ -2689,9 +2731,62 @@ STR_ABOUT_VERSION :{BLACK}OpenTTD STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2019 O equipo de OpenTTD # Framerate display window +STR_FRAMERATE_CAPTION :{WHITE}Frame rate +STR_FRAMERATE_CAPTION_SMALL :{STRING}{WHITE} ({DECIMAL}x) +STR_FRAMERATE_RATE_GAMELOOP :{BLACK}Velocidade de simulación: {STRING} +STR_FRAMERATE_RATE_GAMELOOP_TOOLTIP :{BLACK}Número de ticks do xogo simulados por segundo. +STR_FRAMERATE_RATE_BLITTER :{BLACK}Velocidade de refresco: {STRING} +STR_FRAMERATE_RATE_BLITTER_TOOLTIP :{BLACK}Número de frames renderizados por segundo. +STR_FRAMERATE_SPEED_FACTOR :{BLACK}Factor de velocidade do xogo actual: {DECIMAL}x +STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}Como de rápido está a correr o xogo, comparado coa velocidade esperada a unha velocidade de simulación normal. +STR_FRAMERATE_CURRENT :{WHITE}Actual +STR_FRAMERATE_AVERAGE :{WHITE}Media +STR_FRAMERATE_MEMORYUSE :{WHITE}Memoria +STR_FRAMERATE_DATA_POINTS :{BLACK}Datos baseados en {COMMA} medicións +STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL} ms +STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL} ms +STR_FRAMERATE_MS_BAD :{RED}{DECIMAL} ms +STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL} frames por segundo +STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL} frames por segundo +STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL} frames por segundo +STR_FRAMERATE_BYTES_GOOD :{LTBLUE}{BYTES} +STR_FRAMERATE_BYTES_WARN :{YELLOW}{BYTES} +STR_FRAMERATE_BYTES_BAD :{RED}{BYTES} +STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} ms +STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} s ############ Leave those lines in this order!! +STR_FRAMERATE_GAMELOOP :{BLACK}Total de loop do xogo: +STR_FRAMERATE_GL_ECONOMY :{BLACK} Manexo de mercadorías: +STR_FRAMERATE_GL_TRAINS :{BLACK} Marcas de vehículos ferroviarios: +STR_FRAMERATE_GL_ROADVEHS :{BLACK} Marcas de vehículos de estrada: +STR_FRAMERATE_GL_SHIPS :{BLACK} Marcas de barcos: +STR_FRAMERATE_GL_AIRCRAFT :{BLACK} Marcas na aeronave: +STR_FRAMERATE_GL_LANDSCAPE :{BLACK} Marcas no mundo: +STR_FRAMERATE_GL_LINKGRAPH :{BLACK} Retardo do gráfico de ligazóns +STR_FRAMERATE_DRAWING :{BLACK}Renderizado de gráficos: +STR_FRAMERATE_DRAWING_VIEWPORTS :{BLACK} Xanelas globais: +STR_FRAMERATE_VIDEO :{BLACK}Saída de vídeo: +STR_FRAMERATE_SOUND :{BLACK}Mestura de sons: +STR_FRAMERATE_ALLSCRIPTS :{BLACK} Total GS/AI: +STR_FRAMERATE_GAMESCRIPT :{BLACK} Script do xogo: +STR_FRAMERATE_AI :{BLACK} AI {NUM} {STRING} ############ End of leave-in-this-order ############ Leave those lines in this order!! +STR_FRAMETIME_CAPTION_GAMELOOP :Bucle do xogo +STR_FRAMETIME_CAPTION_GL_ECONOMY :Manexo de mercadorías +STR_FRAMETIME_CAPTION_GL_TRAINS :Marcas de vehículos ferroviarios +STR_FRAMETIME_CAPTION_GL_ROADVEHS :Marcas de vehículos de estrada +STR_FRAMETIME_CAPTION_GL_SHIPS :Marcas de barcos +STR_FRAMETIME_CAPTION_GL_AIRCRAFT :Marcas de avións +STR_FRAMETIME_CAPTION_GL_LANDSCAPE :Marcas do mundo +STR_FRAMETIME_CAPTION_GL_LINKGRAPH :Acoplar retardo gráfico +STR_FRAMETIME_CAPTION_DRAWING :Renderizado dos gráficos +STR_FRAMETIME_CAPTION_DRAWING_VIEWPORTS :Renderizado da xanela do mundo +STR_FRAMETIME_CAPTION_VIDEO :Saída de gráficos +STR_FRAMETIME_CAPTION_SOUND :Mestura de son +STR_FRAMETIME_CAPTION_ALLSCRIPTS :Scripts GS/AI totais +STR_FRAMETIME_CAPTION_GAMESCRIPT :Script do xogo +STR_FRAMETIME_CAPTION_AI :AI {NUM} {STRING} ############ End of leave-in-this-order @@ -2717,6 +2812,9 @@ 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_OVERWRITE_TITLE :{WHITE}Sobrescribir arquivo +STR_SAVELOAD_OVERWRITE_WARNING :{YELLOW}Estás seguro de que queres rescribir este arquivo? STR_SAVELOAD_OSKTITLE :{BLACK}Escribe un nome para a partida @@ -2834,7 +2932,12 @@ STR_NEWGRF_SETTINGS_VERSION :{BLACK}Versión STR_NEWGRF_SETTINGS_MIN_VERSION :{BLACK}Mínima versión compatíbel: {SILVER}{NUM} STR_NEWGRF_SETTINGS_MD5SUM :{BLACK}Suma MD5: {SILVER}{STRING} STR_NEWGRF_SETTINGS_PALETTE :{BLACK}Paleta: {SILVER}{STRING} +STR_NEWGRF_SETTINGS_PALETTE_DEFAULT :Por defecto (D) +STR_NEWGRF_SETTINGS_PALETTE_DEFAULT_32BPP :Por defecto (D) / 32 bpp +STR_NEWGRF_SETTINGS_PALETTE_LEGACY :Legado (W) +STR_NEWGRF_SETTINGS_PALETTE_LEGACY_32BPP :Legado (W) / 32 bpp STR_NEWGRF_SETTINGS_PARAMETER :{BLACK}Parámetros: {SILVER}{STRING} +STR_NEWGRF_SETTINGS_PARAMETER_NONE :Ningún STR_NEWGRF_SETTINGS_NO_INFO :{BLACK}Non hai información dispoñíbel STR_NEWGRF_SETTINGS_NOT_FOUND :{RED}Arquivo correspondente non atopado @@ -2915,6 +3018,8 @@ STR_NEWGRF_ERROR_READ_BOUNDS :Lectura máis a STR_NEWGRF_ERROR_GRM_FAILED :Os recursos GRF solicitados non están disponíbeis (sprite {3:NUM}) STR_NEWGRF_ERROR_FORCEFULLY_DISABLED :{1:STRING} foi desactivado por {2:STRING} STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT :Formato de colocación de sprites inválido ou descoñecido (sprite {3:NUM}) +STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG :Demasiados elementos na lista de valor de propiedades (sprite {3:NUM}, propiedade {4:HEX}) +STR_NEWGRF_ERROR_INDPROD_CALLBACK :Tipo de produción inválida (sprite {3:NUM}, "{2:STRING}") # NewGRF related 'general' warnings STR_NEWGRF_POPUP_CAUTION_CAPTION :{WHITE}Coidado! @@ -2946,6 +3051,7 @@ STR_NEWGRF_BUGGY :{WHITE}O NewGRF STR_NEWGRF_BUGGY_ARTICULATED_CARGO :{WHITE}Información de carga/reforma para '{1:ENGINE}' difiire da lista de compra despois da construción. Isto pode causar que a renovación/reemprazo automáticos non reformen correctamente STR_NEWGRF_BUGGY_ENDLESS_PRODUCTION_CALLBACK :{WHITE}'{1:STRING}' produciu un bucle sen fin na chamada de retorno de produción STR_NEWGRF_BUGGY_UNKNOWN_CALLBACK_RESULT :{WHITE}A chamada {1:HEX} devolveu o resultado inválido ou descoñecido {2:HEX} +STR_NEWGRF_BUGGY_INVALID_CARGO_PRODUCTION_CALLBACK :{WHITE}'{1:STRING}' tipo de produción inválido {2:HEX} # 'User removed essential NewGRFs'-placeholders for stuff without specs STR_NEWGRF_INVALID_CARGO : @@ -2979,6 +3085,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}Escribe STR_TOWN_DIRECTORY_CAPTION :{WHITE}Cidades STR_TOWN_DIRECTORY_NONE :{ORANGE}- Ningunha - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (Vila){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}Nomes de cidades - pincha no nome para centrar a vista na cidade. CTRL+Click abre unha nova fiestra na localización da cidade STR_TOWN_POPULATION :{BLACK}Poboación mundial: {COMMA} @@ -2986,6 +3093,7 @@ STR_TOWN_POPULATION :{BLACK}Poboaci STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (Cidade) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Poboación: {ORANGE}{COMMA}{BLACK} Casas: {ORANGE}{COMMA} +STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX :{BLACK}{CARGO_LIST} último mes: {ORANGE}{COMMA}{BLACK} máximo: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Carga necesaria para o crecemento da cidade: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} necesario STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} necesarios en inverno @@ -3010,6 +3118,8 @@ STR_TOWN_VIEW_RENAME_TOWN_BUTTON :Renomear cidade # Town local authority window STR_LOCAL_AUTHORITY_CAPTION :{WHITE}Autoridade local de {TOWN} +STR_LOCAL_AUTHORITY_ZONE :{BLACK}Zona +STR_LOCAL_AUTHORITY_ZONE_TOOLTIP :{BLACK}Amosar a zona dentro dos límites do concello STR_LOCAL_AUTHORITY_COMPANY_RATINGS :{BLACK}Puntuacións das compañías de transporte: STR_LOCAL_AUTHORITY_COMPANY_RATING :{YELLOW}{COMPANY} {COMPANY_NUM}: {ORANGE}{STRING} STR_LOCAL_AUTHORITY_ACTIONS_TITLE :{BLACK}Accións dispoñíbeis: @@ -3021,7 +3131,7 @@ 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 do propietario da compañía +STR_LOCAL_AUTHORITY_ACTION_STATUE_OF_COMPANY :Construír unha estatua a Manuel Fraga 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 @@ -3038,6 +3148,7 @@ STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}Suborna # Goal window STR_GOALS_CAPTION :{WHITE}{COMPANY} Obxectivos STR_GOALS_SPECTATOR_CAPTION :{WHITE}Obxectivos globais +STR_GOALS_SPECTATOR :Obxectivos globais STR_GOALS_GLOBAL_TITLE :{BLACK}Obxectivos globais: STR_GOALS_TEXT :{ORANGE}{STRING} STR_GOALS_NONE :{ORANGE}- Ningún - @@ -3086,6 +3197,7 @@ STR_SUBSIDIES_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Pincha n # Story book window STR_STORY_BOOK_CAPTION :{WHITE}{COMPANY} Historial STR_STORY_BOOK_SPECTATOR_CAPTION :{WHITE}Historial global +STR_STORY_BOOK_SPECTATOR :Álbum global STR_STORY_BOOK_TITLE :{YELLOW}{STRING} STR_STORY_BOOK_GENERIC_PAGE_ITEM :Páxina {NUM} STR_STORY_BOOK_SEL_PAGE_TOOLTIP :{BLACK}Vai a unha páxina específica seleccionandoa nesta lista despregable. @@ -3265,8 +3377,7 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Infraest STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Segmentos de vía de ferrocarril: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Sinais STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Segmentos de estrada: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Estrada -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE} Tranvía +STR_COMPANY_INFRASTRUCTURE_VIEW_TRAM_SECT :{GOLD}Partes de tranvía: STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Cadros de auga: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Canles STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Estacións: @@ -3277,9 +3388,12 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Industrias STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Ningunha - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% transportado) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% transportado) +STR_INDUSTRY_DIRECTORY_ITEM_INFO :{BLACK}{CARGO_LONG}{STRING}{YELLOW} ({COMMA}% transportado){BLACK} STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} +STR_INDUSTRY_DIRECTORY_ITEM_PROD1 :{ORANGE}{INDUSTRY} {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PROD2 :{ORANGE}{INDUSTRY} {STRING}, {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PROD3 :{ORANGE}{INDUSTRY} {STRING}, {STRING}, {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PRODMORE :{ORANGE}{INDUSTRY} {STRING}, {STRING}, {STRING} e {NUM} máis... STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Nomes das industrias - pincha nun nome para centrar a vista nela. Ctrl+Click abre una nova fiestra na situación da industria # Industry view @@ -3290,6 +3404,9 @@ STR_INDUSTRY_VIEW_LOCATION_TOOLTIP :{BLACK}Centrar STR_INDUSTRY_VIEW_PRODUCTION_LEVEL :{BLACK}Nivel de produción: {YELLOW}{COMMA}% STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE :{YELLOW}A industria anunció un peche inminente +STR_INDUSTRY_VIEW_REQUIRES_N_CARGO :{BLACK}Require: {YELLOW}{STRING}{STRING} +STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Produce: {YELLOW}{STRING}{STRING} +STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{STRING} STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Require: STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING} @@ -3343,10 +3460,13 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Vehículos de e STR_GROUP_DEFAULT_SHIPS :Barcos sen agrupar STR_GROUP_DEFAULT_AIRCRAFTS :Avións sen agrupar +STR_GROUP_COUNT_WITH_SUBGROUP :{TINY_FONT}{COMMA} (+{COMMA}) + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Grupos - Pincha nun grupo para ver unha lista de tódolos vehículos dese grupo STR_GROUP_CREATE_TOOLTIP :{BLACK}Pincha para crear un grupo STR_GROUP_DELETE_TOOLTIP :{BLACK}Borrar o grupo seleccionado STR_GROUP_RENAME_TOOLTIP :{BLACK}Renomear o grupo seleccionado +STR_GROUP_LIVERY_TOOLTIP :{BLACK}Mudar o deseño do grupo seleccionado STR_GROUP_REPLACE_PROTECTION_TOOLTIP :{BLACK}Pincha para protexer a este grupo da autosubstitución global STR_QUERY_GROUP_DELETE_CAPTION :{WHITE}Borrar Grupo @@ -3368,12 +3488,18 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Novos vehículo STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Novos vehículos de monorraíl STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Novos vehículos de levitación magnética (Maglev) -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Novos vehículos ferroviarios STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Novos vehículos de estrada +STR_BUY_VEHICLE_TRAM_VEHICLE_CAPTION :Novo material rodante para tranvías + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Novos vehículos ferroviarios +STR_BUY_VEHICLE_ROAD_VEHICLE_ALL_CAPTION :Novos vehículos de estrada STR_BUY_VEHICLE_SHIP_CAPTION :Novos barcos STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Novas aeronaves +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Custo: {GOLD}{CURRENCY_LONG}{BLACK} Peso: {GOLD}{WEIGHT_SHORT} +STR_PURCHASE_INFO_COST_REFIT_WEIGHT :BLACK}Custo: {GOLD}{CURRENCY_LONG}{BLACK} (Custo de redeseño: {GOLD}{CURRENCY_LONG}{BLACK}) Masa: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Velocidade: {GOLD}{VELOCITY}{BLACK} Potencia: {GOLD}{POWER} STR_PURCHASE_INFO_SPEED :{BLACK}Velocidade: {GOLD}{VELOCITY} STR_PURCHASE_INFO_SPEED_OCEAN :{BLACK}Velocidade no océano: {GOLD}{VELOCITY} @@ -3384,12 +3510,15 @@ STR_PURCHASE_INFO_REFITTABLE :(reformábel) STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Deseñado: {GOLD}{NUM}{BLACK} Vida útil: {GOLD}{COMMA} ano{P "" s} STR_PURCHASE_INFO_RELIABILITY :{BLACK}Fiabilidade máxima: {GOLD}{COMMA}% STR_PURCHASE_INFO_COST :{BLACK}Custo: {GOLD}{CURRENCY_LONG} +STR_PURCHASE_INFO_COST_REFIT :{BLACK}Custo: {GOLD}{CURRENCY_LONG}{BLACK} (Custo da reforma: {GOLD}{CURRENCY_LONG}{BLACK}) STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Peso: {GOLD}{WEIGHT_SHORT} ({WEIGHT_SHORT}) STR_PURCHASE_INFO_COST_SPEED :{BLACK}Custo: {GOLD}{CURRENCY_LONG}{BLACK} Velocidade: {GOLD}{VELOCITY} +STR_PURCHASE_INFO_COST_REFIT_SPEED :{BLACK}Custo: {GOLD}{CURRENCY_LONG}{BLACK} (Custo de reparación: {GOLD}{CURRENCY_LONG}{BLACK}) Velocidade: {GOLD}{VELOCITY} STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Capacidade: {GOLD}{CARGO_LONG}, {CARGO_LONG} STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Vagóns tractores: {GOLD}+{POWER}{BLACK} Peso: {GOLD}+{WEIGHT_SHORT} STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Reformábel a: {GOLD}{STRING} STR_PURCHASE_INFO_ALL_TYPES :Tódolos tipos de carga +STR_PURCHASE_INFO_NONE :Ningún STR_PURCHASE_INFO_ALL_BUT :Todos excepto {CARGO_LIST} STR_PURCHASE_INFO_MAX_TE :{BLACK}Esforzo máximo de tracción: {GOLD}{FORCE} STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Autonomía: {GOLD}{COMMA} cadros @@ -3405,11 +3534,21 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Mercar v STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Mercar barco STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Mercar aeronave -STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Mercar o vehículo ferroviario seleccionado. Shift+click mostra o custo estimado sen mercar -STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Mercar o vehículo de estrada seleccionado. Shift+click mostra o custo estimado sen mercar +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Mercar e modificar vehículo +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Mercar e modificar vehículo +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Mercar e redeseñar barco +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Mercar e redeseñar aeronave + +STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Mercar o vehículo ferroviario seleccionado. Shift+click mostra o custo estimado sen realizar a compra +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Mercar o vehículo de estrada seleccionado. Shift+click mostra o custo estimado sen realizar a compra STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Mercar o barco seleccionado. Shift+click mostra o custo estimado sen mercar STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Mercar a aeronave seleccionada. Shift+click mostra o custo estimado sen mercar +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Mercar e modificar o vehículo ferroviario seleccionado. Shift+click mostra o custo estimado sen realizar a compra +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Mercar e modificar o vehículo de estrada seleccionado. Shift+click mostra o custo estimado sen realizar a compra +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Merca e remodela o barco seleccionado. Shift+Click amosa o custo estimado sen mercar +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Merca e remodela a aeronave resaltada. Shift+Click amosa o custo estimado sen mercar + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Renomear STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Renomear STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Renomear @@ -3518,13 +3657,18 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Vas ven # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Mensaxe dun fabricante de vehículos STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Acabamos de deseñar un novo {STRING} - Interésache probar este vehículo en exclusiva durante un ano, para ve-lo seu rendemento antes de facelo universalmente dispoñíbel? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :locomotora de ferrocarril -STR_ENGINE_PREVIEW_ROAD_VEHICLE :vehículo de estrada -STR_ENGINE_PREVIEW_AIRCRAFT :avión -STR_ENGINE_PREVIEW_SHIP :barco +STR_ENGINE_PREVIEW_ELRAIL_LOCOMOTIVE :Locomotora eléctrica STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :locomotora de monorraíl STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :locomotora de maglev +STR_ENGINE_PREVIEW_ROAD_VEHICLE :vehículo de estrada +STR_ENGINE_PREVIEW_TRAM_VEHICLE :Vehículo de tranvía + +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_MAX_SPEED_CAP_RUNCOST :{BLACK}Custo: {CURRENCY_LONG} Velocidade máxima: {VELOCITY}{}Capacidade: {CARGO_LONG}{}Custo operativo: {CURRENCY_LONG}/ano @@ -3562,14 +3706,19 @@ STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK}Cambia e STR_REPLACE_ENGINES :Locomotoras STR_REPLACE_WAGONS :Vagóns STR_REPLACE_ALL_RAILTYPE :Todos os vehículos sobre raíl +STR_REPLACE_ALL_ROADTYPE :Tódolos vehículos de estrada STR_REPLACE_HELP_RAILTYPE :{BLACK}Selecciona o tipo de carril para o que queres substituír as locomotoras +STR_REPLACE_HELP_ROADTYPE :{BLACK}Escolle o tipo de estrada para o que queres remplazar os motores STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Mostra que máquina seleccionada á esquerda vai ser substituída, se é algunha. STR_REPLACE_RAIL_VEHICLES :Vehículos ferroviarios STR_REPLACE_ELRAIL_VEHICLES :Vehículos de ferrocarril eléctrico STR_REPLACE_MONORAIL_VEHICLES :Vehículos de monorraíl STR_REPLACE_MAGLEV_VEHICLES :Vehículos maglev +STR_REPLACE_ROAD_VEHICLES :Vehículos de estrada +STR_REPLACE_TRAM_VEHICLES :Tranvías + STR_REPLACE_REMOVE_WAGON :{BLACK}Eliminar os vagóns: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Facer que a autosubstitución manteña a lonxitude do tren quitando vagóns (empezando pola cabeza), se ao substituír a locomotora o tren se fixera máis longo. @@ -3789,6 +3938,7 @@ STR_ORDER_CONDITIONAL_AGE :Idade (anos) STR_ORDER_CONDITIONAL_REQUIRES_SERVICE :Require servizo STR_ORDER_CONDITIONAL_UNCONDITIONALLY :Sempre STR_ORDER_CONDITIONAL_REMAINING_LIFETIME :Vida útil restante (anos) +STR_ORDER_CONDITIONAL_MAX_RELIABILITY :Máxima fiabilidade STR_ORDER_CONDITIONAL_COMPARATOR_TOOLTIP :{BLACK}Como comparar os datos do vehículo co valor proporcionado STR_ORDER_CONDITIONAL_COMPARATOR_EQUALS :é igual a @@ -4019,6 +4169,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Seleccio STR_AI_LIST_CANCEL :{BLACK}Cancelar STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Non cambia-lo script + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parámetros STR_AI_SETTINGS_CAPTION_AI :IA @@ -4290,7 +4441,8 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Debes re STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Non hay vía de ferrocarril adecuada STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Debes elimina-la vía de ferrocarril primeiro STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}A estrada é de sentido único ou está bloqueada -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Non se permiten pasos a nivel con este tipo de carril +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Non se permiten pasos a nivel con este tipo de carril +STR_ERROR_CROSSING_DISALLOWED_ROAD :{WHITE}Pasos a nivel non permitidos para este tipo de estrada STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Non se poden construír sinais aquí... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Non se pode construír vía ferroviaria aquí... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Non se pode elimina-la vía ferroviaria de aquí... @@ -4310,6 +4462,12 @@ STR_ERROR_CAN_T_REMOVE_ROAD_FROM :{WHITE}Non se p STR_ERROR_CAN_T_REMOVE_TRAMWAY_FROM :{WHITE}Non se pode retira-lo tranvía de aquí... STR_ERROR_THERE_IS_NO_ROAD :{WHITE}... non hai ningunha estrada STR_ERROR_THERE_IS_NO_TRAMWAY :{WHITE}... non hai ningún tranvía +STR_ERROR_CAN_T_CONVERT_ROAD :{WHITE}Non se pode convertir o tipo de estrada aquí... +STR_ERROR_CAN_T_CONVERT_TRAMWAY :{WHITE}Non se pode converter o tipo de tranvía aquí... +STR_ERROR_NO_SUITABLE_ROAD :{WHITE}Estrada inválida +STR_ERROR_NO_SUITABLE_TRAMWAY :{WHITE}Vía de tranvía inadecuada +STR_ERROR_INCOMPATIBLE_ROAD :{WHITE}... estrada incompatíbel +STR_ERROR_INCOMPATIBLE_TRAMWAY :{WHITE}... tranvía incompatible # Waterway construction errors STR_ERROR_CAN_T_BUILD_CANALS :{WHITE}Non se poden construír canles aquí... @@ -4362,6 +4520,7 @@ STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Non se p STR_ERROR_GROUP_CAN_T_DELETE :{WHITE}Non se pode eliminar este grupo... STR_ERROR_GROUP_CAN_T_RENAME :{WHITE}Non se pode renomear o grupo... STR_ERROR_GROUP_CAN_T_SET_PARENT :{WHITE}Non se pode establecer o grupo superior... +STR_ERROR_GROUP_CAN_T_SET_PARENT_RECURSION :{WHITE}... non se permiten bucles na xerarquía do grupo STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}Non se pode borrar tódolos vehículos deste grupo... STR_ERROR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}Non se pode engadir o vehículo a este grupo... STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}Non se poden engadir vehículos compartidos ó grupo... @@ -4472,6 +4631,8 @@ STR_BASESOUNDS_DOS_DESCRIPTION :Sons da edició STR_BASESOUNDS_WIN_DESCRIPTION :Sons da edición orixinal de Transport Tycoon Deluxe para Windows. STR_BASESOUNDS_NONE_DESCRIPTION :Un conxunto de sons sen ningún son STR_BASEMUSIC_WIN_DESCRIPTION :Música da edición orixinal de Transport Tycoon Deluxe para Windows. +STR_BASEMUSIC_DOS_DESCRIPTION :Música da edición orixinal de Transport Tycoon Deluxe para DOS. +STR_BASEMUSIC_TTO_DESCRIPTION :Temazos orixinais da edición DOS de Transport Tycoon. STR_BASEMUSIC_NONE_DESCRIPTION :Un conxunto de músicas sen ningunha música. ##id 0x2000 diff --git a/src/lang/german.txt b/src/lang/german.txt index 1d7e4d8abb..fadffbecb3 100644 --- a/src/lang/german.txt +++ b/src/lang/german.txt @@ -11,8 +11,6 @@ ##gender m w n p -# $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. # 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. @@ -475,9 +473,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Konsole öffnen/schließen STR_ABOUT_MENU_AI_DEBUG :KI / Skript-Debug STR_ABOUT_MENU_SCREENSHOT :Screenshot (Standard: Strg+S) -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Screenshot in Nahaufnahme -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Screenshot mit normalem Zoom -STR_ABOUT_MENU_GIANT_SCREENSHOT :Riesiger Screenshot (Standard: Strg+G) STR_ABOUT_MENU_SHOW_FRAMERATE :Bildwiederholrate anzeigen STR_ABOUT_MENU_ABOUT_OPENTTD :Über OpenTTD STR_ABOUT_MENU_SPRITE_ALIGNER :Sprite-Ausrichtung @@ -648,9 +643,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Benutzerdef. 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Musiklautstärke STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Soundlautstärke -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}MIN -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}MAX -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -867,6 +859,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}Neue{G r "" s ""} {STRING} jetzt erhältlich! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} nimmt kein{G "en" "e" "" "e"} {STRING} mehr an STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} nimmt kein{G "en" "e" "" "e"} {STRING} und kein{G "en" "e" "" "e"} {STRING} mehr an STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} nimmt jetzt auch {STRING} an @@ -996,6 +989,7 @@ STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Doppelt STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Vierfach +STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Doppelt STR_GAME_OPTIONS_BASE_GRF :{BLACK}Basisgrafiken STR_GAME_OPTIONS_BASE_GRF_TOOLTIP :{BLACK}Zu benutzendes Set an Basisgrafiken auswählen @@ -1179,6 +1173,7 @@ STR_CONFIG_SETTING_AUTOSLOPE :Landschaftsbau STR_CONFIG_SETTING_AUTOSLOPE_HELPTEXT :Erlaube Erdbauarbeiten unter Gebäuden oder Infrastruktur ohne sie zu entfernen STR_CONFIG_SETTING_CATCHMENT :Verschiedene Stationstypen haben unterschiedlich große Einzugsgebiete: {STRING} STR_CONFIG_SETTING_CATCHMENT_HELPTEXT :Wird diese Option eingeschaltet, besitzen unterschiedliche Stationsarten bzw. Flughäfen unterschiedlich große Einzugsgebiete +STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES_HELPTEXT :Falls aktiv, können Industrien mit integrierter Haltestelle (wie Ölbohrtürme) auch von nahegelegenen Stationen der Spieler bedient werden. Falls inaktive, können diese Industrien ausschließlich mittels ihrer eigenen Stationen bedient werden. Die integrierten Stationen bedienen dabei keine anderen Industrien in der Nähe STR_CONFIG_SETTING_EXTRADYNAMITE :Entfernung von weiteren Straßen, Brücken usw. erlauben: {STRING} STR_CONFIG_SETTING_EXTRADYNAMITE_HELPTEXT :Erlaubt einfacheres Entfernen von städtischer Infrastruktur und Gebäuden STR_CONFIG_SETTING_TRAIN_LENGTH :Maximale Zuglänge: {STRING} @@ -1476,6 +1471,8 @@ STR_CONFIG_SETTING_AI_IN_MULTIPLAYER :KI im Mehrspiel STR_CONFIG_SETTING_AI_IN_MULTIPLAYER_HELPTEXT :Erlaube die Teilnahme von Computerspielern im Mehrspielermodus STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES :Rechenoperationen, bevor das Skript angehalten wird: {STRING} STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES_HELPTEXT :Maximale Anzahl Rechenschritte, die ein Skript in einer Runde zur Verfügung hat +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY :Maximaler Arbeitsspeicher pro Script: {STRING} +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_HELPTEXT :Wie viel Arbeitsspeicher ein Script maximal benutzen darf bevor es terminiert wird. Diese Wert muss eventuell vergrößert werden für größere Maps. STR_CONFIG_SETTING_SERVINT_ISPERCENT :Wartungsintervalle in Prozent: {STRING} STR_CONFIG_SETTING_SERVINT_ISPERCENT_HELPTEXT :Lege fest, ob Fahrzeuge zur Wartung geschickt werden basierend auf der verstrichenen Zeit seit der letzten Wartung oder dem Absinken der Zuverlässigkeit auf einen gewissen Prozentsatz der maximalen Zuverlässigkeit des Fahrzeugtyps @@ -1578,6 +1575,8 @@ STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :Erlaube Spieler STR_CONFIG_SETTING_TOWN_FOUNDING_FORBIDDEN :Verboten STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED :Erlaubt STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED_CUSTOM_LAYOUT :Erlaubt, mit wählbarem Straßenbauplan +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_ORIGINAL :Quadratisch (orginal) +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_BITCOUNT :Linear STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :Platzierung von Bäumen während des Spiels: {STRING} STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :Lege das Ausmaß des zufälligen Baumwachstums während des Spiels fest. Dies kann Industrien wie die Sägemühle beeinflussen, welche auf nachwachsende Bäume angewiesen sind @@ -1705,7 +1704,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Warenve STR_CONFIG_SETTING_AI :{ORANGE}Mitbewerber STR_CONFIG_SETTING_AI_NPC :{ORANGE}Computerspieler -STR_CONFIG_SETTING_PATHFINDER_OPF :Original STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(empfohlen) @@ -1789,13 +1787,9 @@ STR_QUIT_NO :{BLACK}Nein # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -2084,6 +2078,7 @@ STR_NETWORK_CONNECTION_DISCONNECT :{BLACK}Trennen STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Server ist geschützt. Passwort eingeben: STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Firma ist geschützt. Passwort eingeben: +STR_NETWORK_COMPANY_LIST_CLIENT_LIST_CAPTION :{WHITE}Teilnehmerliste # Network company list added strings STR_NETWORK_COMPANY_LIST_CLIENT_LIST :Teilnehmerliste @@ -2425,6 +2420,9 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Straßen STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Zwischen Bau und Abriss der Straße umschalten STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Zwischen Bau und Abriss von Straßenbahngleisen umschalten +STR_ROAD_NAME_ROAD :Straße +STR_ROAD_NAME_TRAM :Straßenbahngleis + # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Ausrichtung Depot STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}Ausrichtung des Fahrzeugdepots wählen @@ -2610,6 +2608,7 @@ STR_LAND_AREA_INFORMATION_CARGO_EIGHTS :({COMMA}/8 {STR STR_LANG_AREA_INFORMATION_RAIL_TYPE :{BLACK}Gleistyp: {LTBLUE}{STRING} STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT :{BLACK}Höchstgeschwindigkeit Schiene: {LTBLUE}{VELOCITY} STR_LANG_AREA_INFORMATION_ROAD_SPEED_LIMIT :{BLACK}Höchstgeschwindigkeit Straße: {LTBLUE}{VELOCITY} +STR_LANG_AREA_INFORMATION_TRAM_SPEED_LIMIT :{BLACK}Höchstgeschwindigkeit Straßenbahn: {LTBLUE}{VELOCITY} # Description of land area of different tiles STR_LAI_CLEAR_DESCRIPTION_ROCKS :Felsen @@ -2726,6 +2725,7 @@ STR_FRAMERATE_MS_BAD :{RED}{DECIMAL} STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL} Bilder/s STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL} Bilder/s STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL} Bilder/s +STR_FRAMERATE_BYTES_BAD :{RED}{BYTES} STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} ms STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} s ############ Leave those lines in this order!! @@ -2741,6 +2741,7 @@ STR_FRAMERATE_DRAWING :{BLACK}Grafik-R STR_FRAMERATE_DRAWING_VIEWPORTS :{BLACK}Kartenansichten: STR_FRAMERATE_VIDEO :{BLACK}Videoausgabe: STR_FRAMERATE_SOUND :{BLACK}Sound-Abmischung: +STR_FRAMERATE_GAMESCRIPT :{BLACK} Script: ############ End of leave-in-this-order ############ Leave those lines in this order!! STR_FRAMETIME_CAPTION_GAMELOOP :Spielschleife @@ -3085,6 +3086,8 @@ STR_TOWN_VIEW_RENAME_TOWN_BUTTON :Stadt umbenenne # Town local authority window STR_LOCAL_AUTHORITY_CAPTION :{WHITE}Stadtverwaltung {TOWN} +STR_LOCAL_AUTHORITY_ZONE :{BLACK}Zone +STR_LOCAL_AUTHORITY_ZONE_TOOLTIP :{BLACK}Zeige Zone der Stadtverwaltung STR_LOCAL_AUTHORITY_COMPANY_RATINGS :{BLACK}Bewertung der Transportfirma: STR_LOCAL_AUTHORITY_COMPANY_RATING :{YELLOW}{COMPANY} {COMPANY_NUM}: {ORANGE}{STRING} STR_LOCAL_AUTHORITY_ACTIONS_TITLE :{BLACK}Verfügbare Maßnahmen: @@ -3340,8 +3343,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Infrastr STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Schienenfelder: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Signale STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Straßenfelder: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Straße -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Straßenbahnfelder STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Wasserfelder: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Kanäle STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Stationen: @@ -3352,9 +3353,8 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Industrien STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Keine - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% transportiert) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% transportiert) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} +STR_INDUSTRY_DIRECTORY_ITEM_PROD2 :{ORANGE}{INDUSTRY} {STRING}, {STRING} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Industrienamen - Klick auf den Namen zentriert Hauptansicht auf die Industrie. Strg+Klick öffnet neue Zusatzansicht zentriert auf die Industrie # Industry view @@ -3421,6 +3421,8 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Ungruppierte St STR_GROUP_DEFAULT_SHIPS :Ungruppierte Schiffe STR_GROUP_DEFAULT_AIRCRAFTS :Ungruppierte Flugzeuge +STR_GROUP_COUNT_WITH_SUBGROUP :{TINY_FONT}{COMMA} (+{COMMA}) + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Gruppen - Klick auf eine Gruppe zeigt Liste aller Fahrzeuge der Gruppe an STR_GROUP_CREATE_TOOLTIP :{BLACK}Neue Gruppe erstellen STR_GROUP_DELETE_TOOLTIP :{BLACK}Ausgewählte Gruppe löschen @@ -3447,10 +3449,13 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Neue elektrisch STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Neue Einschienenbahnfahrzeuge STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Neue Magnetbahnfahrzeuge -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Neue Schienenfahrzeuge STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Neue Fahrzeuge + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Neue Schienenfahrzeuge STR_BUY_VEHICLE_SHIP_CAPTION :Neue Schiffe STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Neue Flugzeuge +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Kosten: {GOLD}{CURRENCY_LONG}{BLACK} Gewicht: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Geschw.: {GOLD}{VELOCITY}{BLACK} Leistung: {GOLD}{POWER} @@ -3465,6 +3470,7 @@ STR_PURCHASE_INFO_RELIABILITY :{BLACK}Max. Zuv STR_PURCHASE_INFO_COST :{BLACK}Kosten: {GOLD}{CURRENCY_LONG} STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Gewicht: {GOLD}{WEIGHT_SHORT} ({WEIGHT_SHORT}) STR_PURCHASE_INFO_COST_SPEED :{BLACK}Kosten: {GOLD}{CURRENCY_LONG}{BLACK} Geschw.: {GOLD}{VELOCITY} +STR_PURCHASE_INFO_COST_REFIT_SPEED :{BLACK}Kosten: {GOLD}{CURRENCY_LONG}{BLACK} (Kosten der Umrüstung: {GOLD}{CURRENCY_LONG}{BLACK}) Geschwindigkeit: {GOLD}{VELOCITY} STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Kapazität: {GOLD}{CARGO_LONG}, {CARGO_LONG} STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Angetriebene Waggons: {GOLD}+{POWER}{BLACK} Gewicht: {GOLD}+{WEIGHT_SHORT} STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Umrüstbar auf: {GOLD}{STRING} @@ -3485,11 +3491,13 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Fahrzeug STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Schiff kaufen STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Flugzeug kaufen + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Angewähltes Fahrzeug kaufen. Shift+Klick zeigt einen Kostenvoranschlag STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Ausgewähltes Fahrzeug kaufen. Shift+Klick zeigt einen Kostenvoranschlag STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Ausgewähltes Schiff kaufen. Shift+Klick zeigt einen Kostenvoranschlag STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Augewähltes Flugzeug kaufen. Shift schaltet zwischen Bauen und Kostenvoranschlag um + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Umbenennen STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Umbenennen STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Umbenennen @@ -3598,13 +3606,17 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Sollen # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Nachricht vom Fahrzeughersteller STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Wir haben {G "einen" "eine" "ein" ""} neue{G n "" s ""} {0:STRING} entwickelt.{}Besteht Interesse, {G 0 den die das die} {0:STRING} ein Jahr lang exklusiv zu nutzen, so dass wir die Funktionen testen können, bevor {G 0 er sie es sie} allgemein zur Verfügung gestellt {G 0 wird wird wird werden}? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :{G=w}Lokomotive -STR_ENGINE_PREVIEW_ROAD_VEHICLE :{G=n}Straßenfahrzeug -STR_ENGINE_PREVIEW_AIRCRAFT :{G=n}Flugzeug -STR_ENGINE_PREVIEW_SHIP :{G=n}Schiff +STR_ENGINE_PREVIEW_ELRAIL_LOCOMOTIVE :Elektrifizierte Lokomotive STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :{G=w}Einschienenbahn STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :{G=w}Magnetschwebebahn +STR_ENGINE_PREVIEW_ROAD_VEHICLE :{G=n}Straßenfahrzeug + +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}/yr{}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 @@ -3650,6 +3662,8 @@ STR_REPLACE_ELRAIL_VEHICLES :elektrische Sch STR_REPLACE_MONORAIL_VEHICLES :Einschienenbahn STR_REPLACE_MAGLEV_VEHICLES :Magnetschwebebahn +STR_REPLACE_TRAM_VEHICLES :Straßenbahnfahrzeuge + STR_REPLACE_REMOVE_WAGON :{BLACK}Waggon-Entfernung: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Ursprüngliche Länge des Zugs beibehalten, indem (vorne beginnend) Waggons entfernt werden, falls das Ersetzen der Lokomotive den Zug verlängern würde @@ -4100,6 +4114,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Ausgewä STR_AI_LIST_CANCEL :{BLACK}Abbrechen STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Skript nicht wechseln + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parameter STR_AI_SETTINGS_CAPTION_AI :KI @@ -4302,7 +4317,6 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... dies STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... Straße verläuft in die falsche Richtung STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... Bus- und Lkw-Haltestellen können nicht um die Kurve gehen STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... Bus- und Lkw-Haltestellen können keine Abzweigung haben -STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}...Einbahnstraße oder blockierter Weg # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Dieser Teil der Station kann nicht entfernt werden... @@ -4372,7 +4386,7 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Signal m STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Keine geeigneten Gleise STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Gleise müssen erst abgerissen werden STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Einbahnstraße oder blockierter Weg -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Bahnübergänge sind für diesen Schienentyp nicht erlaubt +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Bahnübergänge sind für diesen Schienentyp nicht erlaubt STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Signal kann hier nicht aufgestellt werden... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Gleise können hier nicht verlegt werden... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Gleise können nicht abgerissen werden... @@ -4392,6 +4406,7 @@ STR_ERROR_CAN_T_REMOVE_ROAD_FROM :{WHITE}Diese St STR_ERROR_CAN_T_REMOVE_TRAMWAY_FROM :{WHITE}Straßenbahngleise können hier nicht entfernt werden... STR_ERROR_THERE_IS_NO_ROAD :{WHITE}...hier ist keine Straße STR_ERROR_THERE_IS_NO_TRAMWAY :{WHITE}...hier ist kein Straßenbahngleis +STR_ERROR_CAN_T_CONVERT_TRAMWAY :{WHITE}Straßenbahngleistyp kann hier nicht geändert werden... # Waterway construction errors STR_ERROR_CAN_T_BUILD_CANALS :{WHITE}Kanal kann hier nicht gebaut werden... diff --git a/src/lang/greek.txt b/src/lang/greek.txt index d12be9ad74..a32ee99001 100644 --- a/src/lang/greek.txt +++ b/src/lang/greek.txt @@ -12,8 +12,6 @@ ##case subs date geniki -# $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. # 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. @@ -536,9 +534,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Εναλλαγή κονσόλας STR_ABOUT_MENU_AI_DEBUG :Αποσφαλμάτωση AI και δέσμης ενεργειών παιχνιδιού STR_ABOUT_MENU_SCREENSHOT :Στιγμιότυπο οθόνης -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Στιγμιότυπο οθόνης μέγιστης μεγέθυνσης -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Στιγμιότυπο οθόνης τυπικής μεγέθυνσης -STR_ABOUT_MENU_GIANT_SCREENSHOT :Στιγμιότυπο οθόνης για ολό τον χάρτη STR_ABOUT_MENU_SHOW_FRAMERATE :Εμφάνιση ρυθμού καρέ STR_ABOUT_MENU_ABOUT_OPENTTD :Σχετικά με το 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Ευθυγραμμιστής στοιχεών @@ -755,9 +750,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Προσαρμοσμένο 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Ένταση Μουσικής STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Ένταση Εφέ -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}ΕΛΑΧ -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}ΜΕΓ -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -974,6 +966,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}Ένα νέο {STRING} είναι πλέον διαθέσιμο! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}Ο σταθμός {STATION} δεν δέχεται πια {STRING} STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}Ο σταθμός {STATION} δεν δέχεται πια ούτε {STRING} ούτε {STRING} STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}Ο σταθμός {STATION} τώρα δέχεται {STRING} @@ -1291,6 +1284,8 @@ STR_CONFIG_SETTING_AUTOSLOPE :Να επιτρ 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 :Είναι ευκολότερη η αφαίρεση υποδομών και κτιρίων που κατέχονται από την πόλη STR_CONFIG_SETTING_TRAIN_LENGTH :Μέγιστο μήκος τρένων: {STRING} @@ -1307,7 +1302,7 @@ STR_CONFIG_SETTING_TRAIN_SLOPE_STEEPNESS_HELPTEXT :Η κλίση STR_CONFIG_SETTING_PERCENTAGE :{COMMA}% STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS :Κλίση εδάφους για τα οδικά οχήματα: {STRING} STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS_HELPTEXT :Η κλίση ενός κεκλιμένου τετραγωνίδιου για τα οδικά οχήματα. Μεγαλύτερες τιμές καθιστούν δυσκολότερο το ανέβασμα λόφων -STR_CONFIG_SETTING_FORBID_90_DEG :Απαγόρευση στα τρένα και πλοία να κάνουν στροφές 90°: {STRING} +STR_CONFIG_SETTING_FORBID_90_DEG :Απαγόρευση στα τρένα να κάνουν στροφές 90°: {STRING} STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :Στροφές 90 μοιρών προκύπτουν όταν μια οριζόντια σιδηροτροχιά ακολουθείται από μια κάθετη στο επόμενο τετραγωνίδιο, κάνοντας το τρένο να στρίψει κατά 90 μοίρες όταν αλλάζει τετραγωνίδιο, αντί για τις συνηθισμένες 45 μοίρες σε άλλους συνδυασμούς σιδηροτροχιών. Αυτό έχει επίσης εφαρμογή στην ακτίνα στροφής των πλοίων STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS :Να επιτρέπεται η συνένωση μη παρακείμενων σταθμών: {STRING} STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS_HELPTEXT :Επιτρέπεται η προσθήκη τμημάτων σε σταθμό χωρίς αυτά να αγγίζουν τα ήδη υπάρχοντα τμήματα. Χρειάζεται Ctrl+Κλικ κατά την τοποθέτηση των νέων τμημάτων @@ -1364,8 +1359,8 @@ STR_CONFIG_SETTING_PLANE_SPEED :Παράγον STR_CONFIG_SETTING_PLANE_SPEED_HELPTEXT :Ορίζεται η σχετική ταχύτητα των αεροπλάνων συγκριτικά με τους άλλους τύπους οχημάτων, ώστε να μειώνεται το ποσό του εισοδήματος από μεταφορές με αεροσκάφη STR_CONFIG_SETTING_PLANE_SPEED_VALUE :1 / {COMMA} STR_CONFIG_SETTING_PLANE_CRASHES :Αριθμός των αεροπορικών ατυχημάτων: {STRING} -STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Ορίστε την πιθανότητα συντριβής ενός αεροσκάφους -STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Καθόλου +STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Ορίστε την πιθανότητα συντριβής ενός τυχαίου αεροσκάφους.{}* Μεγάλα αεροσκάφη πάντα έχουν ένα ρίσκο συντριβής όταν προσγειώνονται σε μικρά αεροδρόμια. +STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Κανένα* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Μειωμένη STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Κανονική STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Επιτρέπονται οι στάσεις σε δρόμους που είναι ιδιοκτησία των πόλεων : {STRING} @@ -1690,6 +1685,10 @@ STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :Ενεργοπ STR_CONFIG_SETTING_TOWN_FOUNDING_FORBIDDEN :Δεν επιτρέπεται STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED :Επιτρέπεται STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED_CUSTOM_LAYOUT :Επιτρέπεται, προσαρμοσμένο σχέδιο πόλης +STR_CONFIG_SETTING_TOWN_CARGOGENMODE :Δημιουργία εμπορευμάτων πόλης: {STRING} +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_HELPTEXT :Η ποσότητα εμπορευμάτων που παράγεται απο σπίτια σε πόλεις, σε σχέση με τον πληθυσμό της πόλης.{}Τετραγωνική ανάπτυξη: Μια πόλη διπλού μεγέθους παράγει τετραπλάσιο αριθμό επιβατών.{}Γραμμική ανάπτυξη: Μια πόλη διπλού μεγέθους παράγει διπλάσιο αριθμό επιβατών. +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_ORIGINAL :Τετραγωνικός (αρχική έκδοση) +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_BITCOUNT :Γραμμικό STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :Τοποθέτηση δέντρων εντός παιχνιδιού: {STRING} STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :Έλεγχος της τυχαίας εμφάνισης δέντρων κατά τη διάρκεια του παιχνιδιού. Αυτό είναι πιθανό να επηρεάσει βιομηχανίες που εξαρτώνται από την ανάπτυξη των δέντρων, όπως για παράδειγμα οι υλοτομίες @@ -1817,7 +1816,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Κατ STR_CONFIG_SETTING_AI :{ORANGE}Ανταγωνιστές STR_CONFIG_SETTING_AI_NPC :{ORANGE}Παίκτες υπολογιστή -STR_CONFIG_SETTING_PATHFINDER_OPF :Αρχικό STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Συνίσταται) @@ -1901,13 +1899,9 @@ STR_QUIT_NO :{BLACK}Όχι # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -2245,7 +2239,7 @@ STR_NETWORK_CHAT_ALL :[Όλοι] {STR STR_NETWORK_CHAT_OSKTITLE :{BLACK}Εισάγετε το κείμενο για δικτυακή συζήτηση # Network messages -STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}Δεν βρέθηκε συσκευή δικτύου ή έγινε μεταγλώττιση χωρίς την παράμετρο ENABLE_NETWORK +STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}Δεν βρέθηκαν συσκευές δικτύου STR_NETWORK_ERROR_NOSERVER :{WHITE}Δεν βρέθηκε κάποιο δικτυακό παιχνίδι STR_NETWORK_ERROR_NOCONNECTION :{WHITE}Ο διακομιστής δεν απάντησε στο αίτημα STR_NETWORK_ERROR_NEWGRF_MISMATCH :{WHITE}Απέτυχε η σύνδεση λόγο ασυμφωνίας NewGRF @@ -2538,6 +2532,7 @@ 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}Εναλλαγή κτισίματος/αφαίρεσης της κατασκευής τροχιόδρομου + # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Προσανατολισμός Σταθμού Οχημάτων STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}Επιλογή προσανατολισμού αμαξοστασίου οχημάτων @@ -3462,8 +3457,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Υποδ STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Κομμάτια σιδηροτροχιάς: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Σήματα STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Κομμάτια δρόμου: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Δρόμος -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Τροχιόδρομος STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Τετραγωνίδια νερού: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Κανάλια STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Σταθμοί: @@ -3474,8 +3467,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Βιομηχανίες STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Τίποτα - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% μεταφέρθηκαν) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% μεταφέρθηκαν) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Ονόματα βιομηχανιών - πατήστε στο όνομα για κεντράρισμα στη βιομηχανία. Με Ctrl+Κλικ ανοίγει νέο παράθυρο προβολής στην τοποθεσία της βιομηχανίας @@ -3543,6 +3534,7 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Μη ομαδο STR_GROUP_DEFAULT_SHIPS :Μη ομαδοποιημένα πλοία STR_GROUP_DEFAULT_AIRCRAFTS :Μη ομαδοποιημένα αεροσκάφη + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Ομάδες - πατήστε σε μία ομάδα για να δείτε όλα τα οχήματα που της ανήκουν. Σύρετε ομάδες για να ρυθμίσετε την ιεραρχία. STR_GROUP_CREATE_TOOLTIP :{BLACK}Πατήστε για δημιουργήσετε ομάδα STR_GROUP_DELETE_TOOLTIP :{BLACK}Διαγραφή της επιλεγμένης ομάδας @@ -3569,12 +3561,16 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Νέα Οχήμ STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Νέα Οχήματα Μονοτρόχιου STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Νέα Οχήματα Maglev -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Νέα Οχήματα Σιδηρόδρομου STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Νέα Οχήματα Δρόμου + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Νέα Οχήματα Σιδηρόδρομου STR_BUY_VEHICLE_SHIP_CAPTION :Νέα Πλοία STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Νέα Αεροσκάφη +############ range for vehicle availability ends 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} @@ -3585,8 +3581,10 @@ STR_PURCHASE_INFO_REFITTABLE :(μετατρέ STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Έτος σχεδίασης: {GOLD}{NUM}{BLACK} Χρόνος ζωής: {GOLD}{COMMA} χρόν{P ο ια} STR_PURCHASE_INFO_RELIABILITY :{BLACK}Μέγ. Αξιοπιστία: {GOLD}{COMMA}% STR_PURCHASE_INFO_COST :{BLACK}Κόστος: {GOLD}{CURRENCY_LONG} +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} @@ -3607,11 +3605,21 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Αγορ STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Αγορά Πλοίου STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Αγορά Αεροσκάφους +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Αγορά και μετατροπή οχήματος +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Αγορά και μετατροπή οχήματος +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Αγορά και μετατροπή πλοίου +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Αγορά και μετατροπή του αεροσκάφους + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Αγορά του επιλεγμένου οχήματος τρένου. Με Shift+Κλικ εμφανίζεται το εκτιμώμενο κόστος χωρίς αγορά STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Αγορά του επιλεγμένου οχήματος δρόμου. Με Shift+Κλικ εμφανίζεται το εκτιμώμενο κόστος χωρίς αγορά STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Αγοράστε το επιλεγμένο πλοίο. Με Shift+Κλικ εμφανίζεται το εκτιμώμενο κόστος χωρίς αγορά STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Αγορά του επιλεγμένου αεροσκάφους. Με Shift+Κλικ εμφανίζεται το εκτιμώμενο κόστος χωρίς αγορά +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Αγορά και μετατροπή του επιλεγμένου οχήματος τρένου. Με Shift+Κλικ εμφανίζεται το εκτιμώμενο κόστος χωρίς αγορά +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Αγορά και μετατροπή του επιλεγμένου οχήματος δρόμου. Με Shift+Κλικ εμφανίζεται το εκτιμώμενο κόστος χωρίς αγορά +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Αγορά και μετατροπή του επιλεγμένου πλοίου. Με Shift+Κλικ εμφανίζεται το εκτιμώμενο κόστος χωρίς αγορά +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Αγορά και μετατροπή του επιλεγμένου αεροσκάφους. Με Shift+Κλικ εμφανίζεται το εκτιμώμενο κόστος χωρίς αγορά + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Μετονομασία STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Μετονομασία STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Μετονομασία @@ -3720,19 +3728,22 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Πρό # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Μήνυμα από κατασκευαστή οχημάτων STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Μόλις ολοκληρώσαμε την σχεδίαση {G ενός μίας ενός} {G νέου νέας νέου} {STRING.geniki} - θα ενδιαφερόσασταν για ενός έτους αποκλειστικής χρήσης αυτού του οχήματος, για να δούμε την απόδοση του πριν το κάνουμε ευρέως διαθέσιμο; + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :{G=f}ατμομηχανή STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE.geniki :ατμομηχανής -STR_ENGINE_PREVIEW_ROAD_VEHICLE :{G=n}οχήματος δρόμου -STR_ENGINE_PREVIEW_ROAD_VEHICLE.geniki :Οχήματος δρόμου -STR_ENGINE_PREVIEW_AIRCRAFT :{G=n}αεροσκάφους -STR_ENGINE_PREVIEW_AIRCRAFT.geniki :αεροσκάφους -STR_ENGINE_PREVIEW_SHIP :{G=n}πλοίου -STR_ENGINE_PREVIEW_SHIP.geniki :πλοίου STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :{G=f}μηχανής μονοτρόχιου STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE.geniki :μηχανής monorail STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :{G=f}μηχανής maglev STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE.geniki :μηχανής maglev +STR_ENGINE_PREVIEW_ROAD_VEHICLE :{G=n}οχήματος δρόμου +STR_ENGINE_PREVIEW_ROAD_VEHICLE.geniki :Οχήματος δρόμου + +STR_ENGINE_PREVIEW_AIRCRAFT :{G=n}αεροσκάφους +STR_ENGINE_PREVIEW_AIRCRAFT.geniki :αεροσκάφους +STR_ENGINE_PREVIEW_SHIP :{G=n}πλοίου +STR_ENGINE_PREVIEW_SHIP.geniki :πλοίου + STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Κόστος: {CURRENCY_LONG} Βάρος: {WEIGHT_SHORT}{}Ταχύτητα: {VELOCITY} Δύναμη Κινητήρα: {POWER}{}Λειτουργικό κόστος: {CURRENCY_LONG}/έτος{}Χωρητικότητα: {CARGO_LONG} STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Κόστος: {CURRENCY_LONG} Βάρος: {WEIGHT_SHORT}{}Ταχύτητα: {VELOCITY} Δύναμη Κινητήρα: {POWER} Μεγ. Ε.Δ: {6:FORCE}{}Λειτουργικό Κόστος: {4:CURRENCY_LONG}/έτος{}Χωρητικότητα: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Κόστος: {CURRENCY_LONG} Μέγ. Ταχύτητα: {VELOCITY}{}Χωρητικότητα: {CARGO_LONG}{}Λειτουργικό κόστος: {CURRENCY_LONG}/έτος @@ -3778,6 +3789,7 @@ STR_REPLACE_ELRAIL_VEHICLES :Οχήματα STR_REPLACE_MONORAIL_VEHICLES :Οχήματα Μονοτρόχιου STR_REPLACE_MAGLEV_VEHICLES :Οχήματα Maglev + STR_REPLACE_REMOVE_WAGON :{BLACK}Αφαίρεση βαγονιού: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Υποχρεώνει την αυτόματη αντικατάσταση να διατηρεί σταθερό το μήκος του τρένου αφαιρώντας βαγόνια (ξεκινώντας από μπροστά), όταν η αντικατάσταση της μηχανής κάνει το τρένο μεγαλύτερο @@ -4228,6 +4240,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Αποδ STR_AI_LIST_CANCEL :{BLACK}Άκυρωση STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Να μην γίνει αλλαγή δέσμης ενεργειών + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Παράμετροι STR_AI_SETTINGS_CAPTION_AI :AI @@ -4430,7 +4443,6 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... αυ STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... ο δρόμος βλέπει σε λάθος κατεύθυνση STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... οι μη τερματικοί σταθμοί δε μπορούν να έχουν στροφές STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... οι μη τερματικοί σταθμοί δε μπορούν να έχουν διασταυρώσεις -STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... ο δρόμος είναι μονόδρομος η μπλοκαρισμένος # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Δεν μπορεί να αφαιρεθεί μέρος του σταθμού... @@ -4500,7 +4512,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 :{WHITE}Δεν επιτρέπονται ισόπεδες διασταυρώσεις για αυτόν τον τύπο σιδηροδρόμου +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Δεν επιτρέπονται ισόπεδες διασταυρώσεις για αυτόν τον τύπο σιδηροδρόμου STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Δεν μπορούν να τοποθετοηθούν σηματοδότες εδώ... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Δεν μπορεί να κτιστεί σιδηρόδρομος εδώ... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Δεν μπορεί να αφαιρεθεί σιδηρόδρομος από εδώ... @@ -5185,5 +5197,3 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) - -# Android strings diff --git a/src/lang/hebrew.txt b/src/lang/hebrew.txt index f6d9a5eb82..17f0964d5a 100644 --- a/src/lang/hebrew.txt +++ b/src/lang/hebrew.txt @@ -12,8 +12,6 @@ ##case singular plural gen -# $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. # 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. @@ -486,9 +484,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :פתח/סגור קונסולה STR_ABOUT_MENU_AI_DEBUG :דיבאג של סקריפטים של בינה מלאכותית או של המשחק STR_ABOUT_MENU_SCREENSHOT :צילום מסך -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :צילום מסך בהגדלה מלאה -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :ברירת מחדל של תקריב צילום מסך -STR_ABOUT_MENU_GIANT_SCREENSHOT :צילום מסך ענק STR_ABOUT_MENU_SHOW_FRAMERATE :הצג קצב פריימים STR_ABOUT_MENU_ABOUT_OPENTTD :'OpenTTD'{NBSP}אודות STR_ABOUT_MENU_SPRITE_ALIGNER :מיישר ספרייטים @@ -659,9 +654,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}מותאם אישית 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}עוצמת מנגינת רקע STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}עוצמת הצלילים -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}מינ' -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}מקס' -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -876,6 +868,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}{STRING} חדש זמין כעת - {ENGINE}! + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} אינה מקבלת יותר {STRING} STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} אינה מקבלת יותר {STRING} או {STRING} STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} מקבלת כעת {STRING} @@ -1709,7 +1702,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}התפ STR_CONFIG_SETTING_AI :{ORANGE}מתחרים STR_CONFIG_SETTING_AI_NPC :{ORANGE}שחקני מחשב -STR_CONFIG_SETTING_PATHFINDER_OPF :מקורי STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(מומלץ) @@ -1793,13 +1785,9 @@ STR_QUIT_NO :{BLACK}לא # Supported OSes STR_OSNAME_WINDOWS :חלונות -STR_OSNAME_DOS :דוס STR_OSNAME_UNIX :יוניקס STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :מערכת הפעלה בי STR_OSNAME_HAIKU :הייקו -STR_OSNAME_MORPHOS :מערכת הפעלה מורפ -STR_OSNAME_AMIGAOS :מערכת הפעלה אניגמה STR_OSNAME_OS2 :מערכת הפעלה או.אס שתיים STR_OSNAME_SUNOS :סולריס @@ -2427,6 +2415,7 @@ 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}שנה מצב בנה\מחק למבני חשמלית + # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}כיוון המוסך STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}כיוון המוסך @@ -3318,8 +3307,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}תתיו STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}חלקי מסילה: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}רמזורים STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}חלקי כביש: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}כביש -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}מסילת רכבת קלה STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}משבצות מים: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}תעלות STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}תחנות: @@ -3330,8 +3317,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}תעשיות STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- אין - -STR_INDUSTRY_DIRECTORY_ITEM :{YELLOW}(שונעו {NBSP}{3:COMMA}%){BLACK} ({1:CARGO_LONG}{2:STRING}) {ORANGE}{0:INDUSTRY} -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{YELLOW}(שונעו {NBSP} {6:COMMA}%/{5:COMMA}%) {BLACK} ({3:CARGO_LONG}{4:STRING}/{1:CARGO_LONG}{2:STRING}) {ORANGE}{0:INDUSTRY} STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}רשימת תעשיות - לחץ על שם כדי להתמקד בתעשייה. Ctrl+לחיצה פותח חלונית תצוגה חדשה על מיקום התעשייה @@ -3396,6 +3381,7 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :רכבים לא STR_GROUP_DEFAULT_SHIPS :כלי שייט לא משוייכים STR_GROUP_DEFAULT_AIRCRAFTS :כלי טייס לא משוייכים + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}קבוצות – לחץ על קבוצה לצפייה בכל הכלים השייכים אליה. גרור כדי לסדר הירארכיה. STR_GROUP_CREATE_TOOLTIP :{BLACK}לחץ ליצירת קבוצה חדשה STR_GROUP_DELETE_TOOLTIP :{BLACK}מחק את הקבוצה שנבחרה @@ -3421,10 +3407,13 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :רכבות חש STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION ::רכבות חד-פס חדשות STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :רכבות פס מגנטי חדשות -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :רכבות זמינות STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :כלי רכב חדשים + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :רכבות זמינות STR_BUY_VEHICLE_SHIP_CAPTION :כלי שייט חדשים STR_BUY_VEHICLE_AIRCRAFT_CAPTION :כלי טייס חדש +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{GOLD}{1:WEIGHT_SHORT}{BLACK} :משקל {GOLD}{0:CURRENCY_LONG}{BLACK} :מחיר STR_PURCHASE_INFO_SPEED_POWER :{BLACK}מהירות: {GOLD}{VELOCITY}{BLACK} הספק: {GOLD}{POWER} @@ -3458,11 +3447,13 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}רכוש STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}רכוש כלי שייט STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}רכוש כלי טייס + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}רכוש את קרון הרכבת שמודגש. Shift+לחיצה מציג הערכת עלות ללא רכישה STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}רכוש את כלי הרכב שמודגש. Shift+לחיצה מציג הערכת עלות ללא רכישה STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}רכוש את כלי השייט שמודגש. Shift+לחיצה מציג הערכת עלות ללא רכישה STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}רכוש את כלי הטייס שמודגש. Shift+לחיצה מציג הערכת עלות ללא רכישה + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}שנה שם STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}שנה שם STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}החלף שם @@ -3571,13 +3562,16 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}?אתה # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}הודעה מיצרן הרכב STR_ENGINE_PREVIEW_MESSAGE :{GOLD}?חדש/ה! האם אתה מעוניין לבחון כלי זה באופן בלעדי לפני הוצאתו לשוק {STRING} זה עתה סיימנו את תכנונו של + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :קטר רכבת -STR_ENGINE_PREVIEW_ROAD_VEHICLE :כלי רכב -STR_ENGINE_PREVIEW_AIRCRAFT :כלי טיס -STR_ENGINE_PREVIEW_SHIP :כלי שייט STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :קטר חד-פס STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :קטר פס מגנטי +STR_ENGINE_PREVIEW_ROAD_VEHICLE :כלי רכב + +STR_ENGINE_PREVIEW_AIRCRAFT :כלי טיס +STR_ENGINE_PREVIEW_SHIP :כלי שייט + STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}{1:WEIGHT_SHORT} :משקל {NBSP}{0:CURRENCY_LONG} :מחיר{} {NBSP}{3:POWER} :עצמת מנוע {NBSP}{2:VELOCITY} :מהירות {NBSP}{}{5:CARGO_LONG} : קיבולת {NBSP} לשנה {NBSP}{4:CURRENCY_LONG} :עלות תפעולית STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}עלות: {CURRENCY_LONG} משקל: {WEIGHT_SHORT}{}מהירות: {VELOCITY} הספק: {POWER} מקסימלי T.E.: {6:FORCE}{}עלות תפעולית: {4:CURRENCY_LONG}/לשנה{}קיבולת: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}עלות: {CURRENCY_LONG} מהירות מקסימלית: {VELOCITY}{}קיבולת: {CARGO_LONG}{}הוצאה שוטפת: {CURRENCY_LONG}/לשנה @@ -3623,6 +3617,7 @@ STR_REPLACE_ELRAIL_VEHICLES :רכבות חש STR_REPLACE_MONORAIL_VEHICLES :רכבות חד-פס STR_REPLACE_MAGLEV_VEHICLES :רכבות פס-מגנטי + STR_REPLACE_REMOVE_WAGON :{ORANGE}{STRING}{BLACK} : הסרת קרונות STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}שמור על האורך המקורי של הרכבת בעת שימוש בהחלפה אוטומטית, במידה והקטר מאריך את הרכבת הסר קרונות מתחילת הרכבת @@ -4073,6 +4068,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK} בחר STR_AI_LIST_CANCEL :{BLACK}בטל STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}אל תשנה את התסריט + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} פרמטרים STR_AI_SETTINGS_CAPTION_AI :שחקן מחשב @@ -4275,7 +4271,6 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... כב STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}הכביש פונה לכיוון לא נכון... STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... לתחנות "על הדרך" לא יכולות להיות פינות STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... לתחנות "על הדרך" לא יכולות להיות צמתים -STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... הדרך חד כיוונית או חסומה # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}... לא ניתן לבטל חלק מהתחנה @@ -4345,7 +4340,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 :{WHITE}מפגשי כביש/מסילה אין אפשריים עבור סוג מסילה זה +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}מפגשי כביש/מסילה אין אפשריים עבור סוג מסילה זה STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}לא ניתן למקם רמזורים כאן... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}לא ניתן להניח פסי רכבת כאן... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}לא ניתן להסיר פסי רכבת ממשבצת זו... diff --git a/src/lang/hungarian.txt b/src/lang/hungarian.txt index 8ce4f446fb..d79f5ad1c4 100644 --- a/src/lang/hungarian.txt +++ b/src/lang/hungarian.txt @@ -11,8 +11,6 @@ ##case t ba -# $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. # 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. @@ -300,6 +298,8 @@ STR_TOOLTIP_FILTER_CRITERIA :{BLACK}Szűrés STR_BUTTON_SORT_BY :{BLACK}Rendezés STR_BUTTON_LOCATION :{BLACK}Megnéz STR_BUTTON_RENAME :{BLACK}Átnevez +STR_BUTTON_CATCHMENT :{BLACK}Lefedett terület +STR_TOOLTIP_CATCHMENT :{BLACK}Az állomás által lefedett terület mutatása STR_TOOLTIP_CLOSE_WINDOW :{BLACK}Ablak bezárása STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Ablak címsora - húzd ezt a mozgatáshoz @@ -328,6 +328,7 @@ STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT_TOOLTIP :{BLACK}Ezzel a STR_BUTTON_DEFAULT :{BLACK}Alapértelmezett STR_BUTTON_CANCEL :{BLACK}Mégsem STR_BUTTON_OK :{BLACK}OK +STR_WARNING_PASSWORD_SECURITY :{YELLOW}Figyelem: A szerver adminjai láthatják az itt beírt szöveget. # On screen keyboard window STR_OSK_KEYBOARD_LAYOUT :0123456789öüóqwertzuiopőúasdfghjkléáűíyxcvbnm,.- . @@ -401,6 +402,7 @@ STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN :{BLACK}Közelí STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT :{BLACK}Távolítás STR_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Vasúti pálya építése STR_TOOLBAR_TOOLTIP_BUILD_ROADS :{BLACK}Út építése +STR_TOOLBAR_TOOLTIP_BUILD_TRAMWAYS :{BLACK}Villamospálya építése STR_TOOLBAR_TOOLTIP_BUILD_SHIP_DOCKS :{BLACK}Vízi út építése STR_TOOLBAR_TOOLTIP_BUILD_AIRPORTS :{BLACK}Repülőtér építése STR_TOOLBAR_TOOLTIP_LANDSCAPING :{BLACK}Nyisd meg a tájrendező ablakot a talaj emeléséhez vagy süllyesztéséhez, faültetéshez stb. @@ -421,6 +423,7 @@ STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION :{BLACK}Táj sze STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Település-generálás STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Gazdasági épület-generálás STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Út építése +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 @@ -538,9 +541,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Átváltás konzolra STR_ABOUT_MENU_AI_DEBUG :MI / Játékszkript nyomkövetés STR_ABOUT_MENU_SCREENSHOT :Képmentés -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Teljes nagyítású képmentés -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Alapértelmezett nagyítású képmentés -STR_ABOUT_MENU_GIANT_SCREENSHOT :Képmentés teljes térképről STR_ABOUT_MENU_SHOW_FRAMERATE :FPS ablak STR_ABOUT_MENU_ABOUT_OPENTTD :Az 'OpenTTD'-ről STR_ABOUT_MENU_SPRITE_ALIGNER :Sprite elhelyező @@ -711,9 +711,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Saját 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Zene Hangereje STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Hangok Hangereje -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}MIN -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}MAX -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -931,6 +928,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}Új {STRING} elérhető! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} többé nem fogad el {STRING.t} STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} többé nem fogad el {STRING.t} és {STRING.t} STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} most már elfogad {STRING.t} @@ -997,6 +995,9 @@ STR_GAME_OPTIONS_CURRENCY_GEL :Grúz Lari (GEL STR_GAME_OPTIONS_CURRENCY_IRR :Iráni Riál (IRR) STR_GAME_OPTIONS_CURRENCY_RUB :Új Orosz Rubel (RUB) STR_GAME_OPTIONS_CURRENCY_MXN :Mexikói Peso (MXN) +STR_GAME_OPTIONS_CURRENCY_NTD :Új Tajvani Dollár (NTD) +STR_GAME_OPTIONS_CURRENCY_CNY :Kínai Renminbi (CNY) +STR_GAME_OPTIONS_CURRENCY_HKD :Hongkongi Dollár (HKD) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Közúti járművek @@ -1248,6 +1249,8 @@ STR_CONFIG_SETTING_AUTOSLOPE :Épületek, vá STR_CONFIG_SETTING_AUTOSLOPE_HELPTEXT :Tájrendezés engedélyezése épületek és utak alatt azok eltávolítása nélkül STR_CONFIG_SETTING_CATCHMENT :Élethűbben méretezett állomási vonzáskörzetek bekapcsolása: {STRING} STR_CONFIG_SETTING_CATCHMENT_HELPTEXT :A különböző állomások és repterek más vonzáskörzettel rendelkeznek +STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES :A vállalatok állomásai elláthatnak beépített semleges állomással rendelkező gazdasági épületeket: {STRING} +STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES_HELPTEXT :Ha be van kapcsolva, akkor az olyan gazdasági épületeket, amelyekhez beépített állomás tartozik (pl. olajfúró tornyok), el lehet látni a vállalatok által épített közeli állomásokkal is. Ha ki van kapcsolva, akkor csak a beépített állomásukkal lehet ellátni ezeket a gazdasági épületeket. A vállalatok közeli állomásai nem tudják őket ellátni, és a beépített állomások sem látnak el mást, csak az adott gazdasági épületet. STR_CONFIG_SETTING_EXTRADYNAMITE :Települési tulajdonú utak/hidak/alagutak rombolásának engedélyezése: {STRING} STR_CONFIG_SETTING_EXTRADYNAMITE_HELPTEXT :Városi tulajdonú infrastruktúra és épületek könnyebb eltávolíthatósága STR_CONFIG_SETTING_TRAIN_LENGTH :Vonatok maximális hossza: {STRING} @@ -1264,8 +1267,8 @@ STR_CONFIG_SETTING_TRAIN_SLOPE_STEEPNESS_HELPTEXT :Egy emelkedő m STR_CONFIG_SETTING_PERCENTAGE :{COMMA}% STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS :Emelkedő meredeksége közúti járműveknek: {STRING} STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS_HELPTEXT :Egy emelkedő mező meredeksége közúti járműveknek. Nagyobb érték esetén a jármű nehezebben mássza meg az emelkedőt -STR_CONFIG_SETTING_FORBID_90_DEG :Vonatok és hajók nem tehetnek 90 fokos kanyart: {STRING} -STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :90 fokos kanyarok akkor fordulnak elő, ha egy vízszintes pályaelemet egy függőleges elem követ közvetlenül a következő mezőn, ami által a vonat egy 90 fokos kanyart tesz a szokásos 45 fokos helyett. Ez ugyanígy előfordulhat hajók esetében is +STR_CONFIG_SETTING_FORBID_90_DEG :Vonatok nem tehetnek 90 fokos kanyart: {STRING} +STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :90 fokos kanyarok akkor fordulnak elő, ha egy vízszintes pályaelemet egy függőleges elem követ közvetlenül a következő mezőn, ami által a vonat egy 90 fokos kanyart tesz a szokásos 45 fokos helyett. STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS :Nem közvetlen szomszédos állomások egyesítése: {STRING} STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS_HELPTEXT :Állomásrészek hozzáadásának engedélyezése úgy, hogy az nem érinti közvetlenül a meglévő részeket. Ctrl+kattintás szükséges hozzá az új részek elhelyezése közben STR_CONFIG_SETTING_INFLATION :Infláció: {STRING} @@ -1321,8 +1324,8 @@ STR_CONFIG_SETTING_PLANE_SPEED :Repülőgép se STR_CONFIG_SETTING_PLANE_SPEED_HELPTEXT :Repülőgépek relatív sebességének beállítása más járműtípusokhoz viszonyítva, a légi szállítás bevételének csökkentéséhez STR_CONFIG_SETTING_PLANE_SPEED_VALUE :1 / {COMMA} STR_CONFIG_SETTING_PLANE_CRASHES :Repülőgép-szerencsétlenségek száma: {STRING} -STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Repülőgép-szerencsétlenség esélyének beállítása -STR_CONFIG_SETTING_PLANE_CRASHES_NONE :nincs +STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Repülőgép-szerencsétlenség esélyének beállítása.{}* Nagy repülőgépek esetén mindig fennáll a baleset veszélye, ha kis reptéren próbálnak leszállni! +STR_CONFIG_SETTING_PLANE_CRASHES_NONE :nincs* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :csökkentett STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :normál STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Áthaladó megállóhelyek engedélyezése települési tulajdonú utakon: {STRING} @@ -1380,8 +1383,8 @@ STR_CONFIG_SETTING_TERRAIN_TYPE :Tereptípus: {S STR_CONFIG_SETTING_TERRAIN_TYPE_HELPTEXT :A térkép domborzata STR_CONFIG_SETTING_INDUSTRY_DENSITY :Gazdasági épületek száma: {STRING} STR_CONFIG_SETTING_INDUSTRY_DENSITY_HELPTEXT :Mennyi gazdasági épület legyen, és mennyire legyenek fenntartva a játék folyamán -STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE :Olajfúró tornyok maximális távolsága a térkép szélétől: {STRING} -STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :Olajfinomítók csak a térkép határaihoz közel építhetőek, ami sziget jellegű térképeknél a partvidék +STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE :Olajfinomítók és olajfúró tornyok maximális távolsága a térkép szélétől: {STRING} +STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :Megadhatod, hogy a térkép szélétől milyen messze épülhetnek olajfinomítók és olajfúró tornyok. Sziget jellegű térképek esetén így a part közelében fognak épülni. 256 mezőnél szélesebb, ill. hosszabb térképek esetén ez az érték felszorzódik. STR_CONFIG_SETTING_SNOWLINE_HEIGHT :Hóhatár magassága: {STRING} STR_CONFIG_SETTING_SNOWLINE_HEIGHT_HELPTEXT :Ezzel a beállítással szabályozhatod a szub-arktikus táj hóhatárát. A hó befolyással lehet a gazdasági épületek generálására és a települések növekedésére. STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN :A terep durvasága: {STRING} @@ -1545,6 +1548,9 @@ STR_CONFIG_SETTING_AI_IN_MULTIPLAYER :Számítógépe STR_CONFIG_SETTING_AI_IN_MULTIPLAYER_HELPTEXT :Számítógép által irányított játékosok részvételének engedélyezése többjátékos játékokban STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES :Szkriptek felfüggesztéséhez szükséges opcode mennyiség: {STRING} STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES_HELPTEXT :Egy kör alatti maximális számítási lépések száma, amit egy szkript kiszámíthat +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY :A szkriptek maximális memóriahasználata: {STRING} +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_HELPTEXT :Mennyi memóriát használhat egy adott szkript, mielőtt leállításra kerül. Nagy térképek esetén lehet, hogy ezt az értéket növelni kell. +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_VALUE :{COMMA} MiB STR_CONFIG_SETTING_SERVINT_ISPERCENT :Javítási intervallumok százalékban: {STRING} STR_CONFIG_SETTING_SERVINT_ISPERCENT_HELPTEXT :A járművek javítási módjának kiválasztása, hogy az utolsó javítás óta eltelt idő, vagy a maximális megbízhatósághoz képesti százalékos csökkenés alapján kerüljelek javításra @@ -1647,6 +1653,10 @@ STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :Bekapcsolva a j STR_CONFIG_SETTING_TOWN_FOUNDING_FORBIDDEN :tiltott STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED :megengedett STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED_CUSTOM_LAYOUT :megengedett, egyéni városelrendezés +STR_CONFIG_SETTING_TOWN_CARGOGENMODE :Termelés a településeken: {STRING} +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_HELPTEXT :Azt adja meg, hogy mennyi rakományt termelnek a városi épületek a település lakosságának függvényében.{}Négyzetes növekedés: Egy kétszer nagyobb település négyszer több utast termel.{}Lineáris növekedés: Egy kétszer nagyobb település kétszer több utast termel. +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_ORIGINAL :Négyzetes (eredeti) +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_BITCOUNT :Lineáris STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :Játékbeli faelhelyezkedés: {STRING} STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :Fák véletlenszerű megjelenésének szabályozása a játék során. Ez befolyásolhatja a gazdasági épületeket, melyek a fák növekedésétől függnek, mint a favágók @@ -1774,7 +1784,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Rakomá STR_CONFIG_SETTING_AI :{ORANGE}Ellenfelek STR_CONFIG_SETTING_AI_NPC :{ORANGE}Számítógép által vezérelt ellenfelek -STR_CONFIG_SETTING_PATHFINDER_OPF :Eredeti STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Ajánlott) @@ -1858,13 +1867,9 @@ STR_QUIT_NO :{BLACK}Nem # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -2202,7 +2207,7 @@ STR_NETWORK_CHAT_ALL :[Mindenkinek] { STR_NETWORK_CHAT_OSKTITLE :{BLACK}Add meg a hálózati beszélgetéshez a neved # Network messages -STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}Nem található a hálózati csatoló, vagy a játékban nincs hálózati támogatás (ENABLE_NETWORK) +STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}Nem található a hálózati csatoló STR_NETWORK_ERROR_NOSERVER :{WHITE}Nem található semmilyen hálózati játék STR_NETWORK_ERROR_NOCONNECTION :{WHITE}A szerver nem válaszolt a kérésre STR_NETWORK_ERROR_NEWGRF_MISMATCH :{WHITE}NewGRF eltérés miatt nem sikerült kapcsolódni @@ -2494,6 +2499,11 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL :{BLACK}Közúti STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Villamos-alagút építése. Shift lenyomásával megmutatja a becsült építési költséget STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Építés és felszedés közötti váltás utaknál STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Építés és bontás közötti váltás villamospályáknál +STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_ROAD :{BLACK}Út átalakítása a kiválasztott típusra. Shift lenyomásával megmutatja a becsült építési költséget +STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_TRAM :{BLACK}Villamospálya átalakítása a kiválasztott típusra. Shift lenyomásával megmutatja a becsült építési költséget + +STR_ROAD_NAME_ROAD :Út +STR_ROAD_NAME_TRAM :Villamospálya # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Garázs helyzete @@ -2678,8 +2688,11 @@ STR_LAND_AREA_INFORMATION_NEWGRF_NAME :{BLACK}NewGRF: STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED :{BLACK}Elfogad: {LTBLUE} STR_LAND_AREA_INFORMATION_CARGO_EIGHTS :({COMMA}/8 {STRING}) STR_LANG_AREA_INFORMATION_RAIL_TYPE :{BLACK}Vasút típusa: {LTBLUE}{STRING} +STR_LANG_AREA_INFORMATION_ROAD_TYPE :{BLACK}Út típusa: {LTBLUE}{STRING} +STR_LANG_AREA_INFORMATION_TRAM_TYPE :{BLACK}Villamospálya típusa: {LTBLUE}{STRING} STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT :{BLACK}Vasúti pályasebesség: {LTBLUE}{VELOCITY} STR_LANG_AREA_INFORMATION_ROAD_SPEED_LIMIT :{BLACK}Közúti sebességkorlátozás: {LTBLUE}{VELOCITY} +STR_LANG_AREA_INFORMATION_TRAM_SPEED_LIMIT :{BLACK}Villamosok sebességkorlátozása: {LTBLUE}{VELOCITY} # Description of land area of different tiles STR_LAI_CLEAR_DESCRIPTION_ROCKS :Kövek @@ -2789,6 +2802,7 @@ STR_FRAMERATE_SPEED_FACTOR :{BLACK}A játé STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}Milyen gyorsan fut a játék, viszonyítva az elvárt sebességhez normál játéksebesség esetén. STR_FRAMERATE_CURRENT :{WHITE}Pillanatnyi STR_FRAMERATE_AVERAGE :{WHITE}Átlagos +STR_FRAMERATE_MEMORYUSE :{WHITE}Memória STR_FRAMERATE_DATA_POINTS :{BLACK}Adatok {COMMA} mérés alapján STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL} ms STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL} ms @@ -2796,6 +2810,9 @@ STR_FRAMERATE_MS_BAD :{RED}{DECIMAL} STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL} frame/s STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL} frame/s STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL} frame/s +STR_FRAMERATE_BYTES_GOOD :{LTBLUE}{BYTES} +STR_FRAMERATE_BYTES_WARN :{YELLOW}{BYTES} +STR_FRAMERATE_BYTES_BAD :{RED}{BYTES} STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} ms STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} s ############ Leave those lines in this order!! @@ -3162,6 +3179,8 @@ STR_TOWN_VIEW_RENAME_TOWN_BUTTON :Város átnevez # Town local authority window STR_LOCAL_AUTHORITY_CAPTION :{WHITE}{TOWN} önkormányzata +STR_LOCAL_AUTHORITY_ZONE :{BLACK}Terület +STR_LOCAL_AUTHORITY_ZONE_TOOLTIP :{BLACK}A helyi önkormányzathoz tartozó terület mutatása STR_LOCAL_AUTHORITY_COMPANY_RATINGS :{BLACK}Vélemény a szállítási vállalatokról: STR_LOCAL_AUTHORITY_COMPANY_RATING :{YELLOW}{COMPANY} {COMPANY_NUM}: {ORANGE}{STRING} STR_LOCAL_AUTHORITY_ACTIONS_TITLE :{BLACK}Lehetséges intézkedések: @@ -3419,8 +3438,7 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}{COMPANY STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Vasúti elemek: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Vasúti jelzők STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Közúti elemek: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Út -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Villamospálya +STR_COMPANY_INFRASTRUCTURE_VIEW_TRAM_SECT :{GOLD}Villamospálya elemek: STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Vízi elemek: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Csatornák STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Állomások: @@ -3431,9 +3449,8 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Gazdasági épületek STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Nincs - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% elszállítva) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% elszállítva) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} +STR_INDUSTRY_DIRECTORY_ITEM_PROD2 :{ORANGE}{INDUSTRY} {STRING}, {STRING} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Gazdasági épületek neve - a névre kattintva a fő nézetet a választott objektumra irányíthatod. Ctrl+kattintással új látképet nyit a gazdasági épület pozíciójára # Industry view @@ -3500,6 +3517,8 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Csoportosítatl STR_GROUP_DEFAULT_SHIPS :Csoportosítatlan hajók STR_GROUP_DEFAULT_AIRCRAFTS :Csoportosítatlan repülők +STR_GROUP_COUNT_WITH_SUBGROUP :{TINY_FONT}{COMMA} (+{COMMA}) + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Csoportok - Kattints a csoport nevére a járművek listázásához. Húzással a csoportokat hierarchiába rendezheted. STR_GROUP_CREATE_TOOLTIP :{BLACK}Csoport létrehozásához kattints ide STR_GROUP_DELETE_TOOLTIP :{BLACK}Kijelölt csoport törlése @@ -3526,12 +3545,18 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Új villamos va STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Új egysínű járművek STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Új Maglev járművek -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Új vasúti járművek STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Új közúti járművek +STR_BUY_VEHICLE_TRAM_VEHICLE_CAPTION :Új villamosok + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Új vasúti járművek +STR_BUY_VEHICLE_ROAD_VEHICLE_ALL_CAPTION :Új közúti járművek STR_BUY_VEHICLE_SHIP_CAPTION :Új hajók STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Új repülőgépek +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Ár: {GOLD}{CURRENCY_LONG}{BLACK} Súly: {GOLD}{WEIGHT_SHORT} +STR_PURCHASE_INFO_COST_REFIT_WEIGHT :{BLACK}Ár: {GOLD}{CURRENCY_LONG}{BLACK} (Átalakítás költsége: {GOLD}{CURRENCY_LONG}{BLACK}) Súly: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Sebesség: {GOLD}{VELOCITY}{BLACK} Telj.: {GOLD}{POWER} STR_PURCHASE_INFO_SPEED :{BLACK}Sebesség: {GOLD}{VELOCITY} STR_PURCHASE_INFO_SPEED_OCEAN :{BLACK}Sebesség óceánon: {GOLD}{VELOCITY} @@ -3542,8 +3567,10 @@ STR_PURCHASE_INFO_REFITTABLE :(átalakíthat STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Kifejlesztve: {GOLD}{NUM}{BLACK} Élettartam: {GOLD}{COMMA} év STR_PURCHASE_INFO_RELIABILITY :{BLACK}Max. megbízhatóság: {GOLD}{COMMA}% STR_PURCHASE_INFO_COST :{BLACK}Ár: {GOLD}{CURRENCY_LONG} +STR_PURCHASE_INFO_COST_REFIT :{BLACK}Ár: {GOLD}{CURRENCY_LONG}{BLACK} (Átalakítás költsége: {GOLD}{CURRENCY_LONG}{BLACK}) STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Súly: {GOLD}{WEIGHT_SHORT} ({WEIGHT_SHORT}) STR_PURCHASE_INFO_COST_SPEED :{BLACK}Ár: {GOLD}{CURRENCY_LONG}{BLACK} Sebesség: {GOLD}{VELOCITY} +STR_PURCHASE_INFO_COST_REFIT_SPEED :{BLACK}Ár: {GOLD}{CURRENCY_LONG}{BLACK} (Átalakítás költsége: {GOLD}{CURRENCY_LONG}{BLACK}) Végsebesség: {GOLD}{VELOCITY} STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Kapacitás: {GOLD}{CARGO_LONG}, {CARGO_LONG} STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Meghajtott vagonok: {GOLD}+{POWER}{BLACK} Súly: {GOLD}+{WEIGHT_SHORT} STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Átalakítható: {GOLD}{STRING} @@ -3564,11 +3591,21 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Megvesz STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Megvesz STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Megvesz +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Megvesz és átalakít +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Megvesz és átalakít +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Megvesz és átalakít +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Megvesz és átalakít + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}A kijelölt vasúti jármű megvétele. Shift+kattintással megmutatja a becsült költséget vásárlás nélkül STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}A kijelölt közúti jármű megvétele. Shift+kattintással megmutatja a becsült költséget vásárlás nélkül STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}A kijelölt hajó megvétele. Shift+kattintással megmutatja a becsült költséget vásárlás nélkül STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}A kijelölt repülőgép megvétele. Shift+kattintással megmutatja a becsült költséget vásárlás nélkül +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}A kijelölt vasúti jármű megvétele és átalakítása a kijelölt rakománytípusra. Shift+kattintással megmutatja a becsült költséget vásárlás nélkül +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}A kijelölt közúti jármű megvétele és átalakítása a kijelölt rakománytípusra. Shift+kattintással megmutatja a becsült költséget vásárlás nélkül +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}A kijelölt hajó megvétele és átalakítása a kijelölt rakománytípusra. Shift+kattintással megmutatja a becsült költséget vásárlás nélkül +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}A kijelölt repülőgép megvétele és átalakítása a kijelölt rakománytípusra. Shift+kattintással megmutatja a becsült költséget vásárlás nélkül + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Átnevez STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Átnevez STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Átnevez @@ -3677,13 +3714,18 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Biztosa # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Üzenet egy járműgyártótól STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Most készültek el egy új {STRING} tervei - érdekelne a jármű egy éves kizárólagos használata, hogy megnézhessük a képességeit, mielőtt mindenki számára elérhetővé tesszük? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :vasúti mozdony -STR_ENGINE_PREVIEW_ROAD_VEHICLE :közúti jármű -STR_ENGINE_PREVIEW_AIRCRAFT :repülőgép -STR_ENGINE_PREVIEW_SHIP :hajó +STR_ENGINE_PREVIEW_ELRAIL_LOCOMOTIVE :villamos vasúti mozdony STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :egysínű mozdony STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :Maglev mozdony +STR_ENGINE_PREVIEW_ROAD_VEHICLE :közúti jármű +STR_ENGINE_PREVIEW_TRAM_VEHICLE :villamos + +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_MAX_SPEED_CAP_RUNCOST :{BLACK}Ár: {CURRENCY_LONG} Végsebesség: {VELOCITY}{}Kapacitás: {CARGO_LONG}{}Üzemeltetés: {CURRENCY_LONG}/év @@ -3721,14 +3763,19 @@ STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK}Váltás STR_REPLACE_ENGINES :Mozdonyok STR_REPLACE_WAGONS :Vagonok STR_REPLACE_ALL_RAILTYPE :Minden vasúti jármű +STR_REPLACE_ALL_ROADTYPE :Minden típus STR_REPLACE_HELP_RAILTYPE :{BLACK}Cserélendő egységek vasúttípusának kiválasztása +STR_REPLACE_HELP_ROADTYPE :{BLACK}Cserélendő járművek úttípusának kiválasztása STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Megmutatja, hogy melyik bal oldali egységet akarod kicserélni STR_REPLACE_RAIL_VEHICLES :Normál vasúti járművek STR_REPLACE_ELRAIL_VEHICLES :Villamosított vasúti járművek STR_REPLACE_MONORAIL_VEHICLES :Egysínű Vasutak STR_REPLACE_MAGLEV_VEHICLES :Maglev Járművek +STR_REPLACE_ROAD_VEHICLES :Közúti járművek +STR_REPLACE_TRAM_VEHICLES :Villamosok + STR_REPLACE_REMOVE_WAGON :{BLACK}Vagon törlés: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Az automatikus cserénél a szerelvény hosszának a megtartása vagonok eltávolításával (mozdony utántól kezdve), ha a csere után a szerelvény hosszabb lenne @@ -4179,6 +4226,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}A kijel STR_AI_LIST_CANCEL :{BLACK}Mégsem STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Ne változtassa a szkriptet + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Paraméterek STR_AI_SETTINGS_CAPTION_AI :MI @@ -4381,7 +4429,6 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... ez e STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... az út a másik irányba vezet STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... áthaladó megállóhelyeken nem lehet kanyar STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... áthaladó megállóhelyeken nem lehet elágazás -STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... az út egyirányú vagy blokkolt # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Nem lehet eltávolítani az állomás részét... @@ -4451,7 +4498,8 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Előszö STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Nincs megfelelő vasúti pálya STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Előbb le kell rombolnod a vasúti pályát STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}... az út egyirányú vagy blokkolt -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Ehhez a síntipushoz nem megengedett vasúti átjárók építése +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Ehhez a síntipushoz nem megengedett vasúti átjárók építése +STR_ERROR_CROSSING_DISALLOWED_ROAD :{WHITE}Ehhez az úttípushoz nem megengedett vasúti átjárók építése STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Nem helyezhetsz ide jelzőt... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Nem építhetsz ide vasúti pályát... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Nem szedheted fel innen a vasúti pályát... @@ -4471,6 +4519,12 @@ STR_ERROR_CAN_T_REMOVE_ROAD_FROM :{WHITE}Nem romb STR_ERROR_CAN_T_REMOVE_TRAMWAY_FROM :{WHITE}Innen nem lehet villamospályát eltávolítani... STR_ERROR_THERE_IS_NO_ROAD :{WHITE}... nincs itt út STR_ERROR_THERE_IS_NO_TRAMWAY :{WHITE}... nincs itt villamospálya +STR_ERROR_CAN_T_CONVERT_ROAD :{WHITE}Nem lehet itt az út típusát átalakítani... +STR_ERROR_CAN_T_CONVERT_TRAMWAY :{WHITE}Nem lehet itt a villamospálya típusát átalakítani... +STR_ERROR_NO_SUITABLE_ROAD :{WHITE}Nincs megfelelő út +STR_ERROR_NO_SUITABLE_TRAMWAY :{WHITE}Nincs megfelelő villamospálya +STR_ERROR_INCOMPATIBLE_ROAD :{WHITE}... nem kompatibilis az út +STR_ERROR_INCOMPATIBLE_TRAMWAY :{WHITE}... nem kompatibilis a villamospálya # Waterway construction errors STR_ERROR_CAN_T_BUILD_CANALS :{WHITE}Ide nem lehet csatornát építeni... @@ -4523,6 +4577,7 @@ STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Csoport STR_ERROR_GROUP_CAN_T_DELETE :{WHITE}Csoport törlése sikertelen... STR_ERROR_GROUP_CAN_T_RENAME :{WHITE}Csoport átnevezése sikertelen... STR_ERROR_GROUP_CAN_T_SET_PARENT :{WHITE}Nem teheted ezt a csoportot a másik alcsoportjává... +STR_ERROR_GROUP_CAN_T_SET_PARENT_RECURSION :{WHITE}... kört okozna a csoporthierarchiában STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}Csoport járműveinek törlése sikertelen... STR_ERROR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}Jármű hozzáadása a csoporthoz sikertelen... STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}Megosztott jármű csoporthoz való hozzáadása sikertelen... diff --git a/src/lang/icelandic.txt b/src/lang/icelandic.txt index bcb6dabb4c..957213cb14 100644 --- a/src/lang/icelandic.txt +++ b/src/lang/icelandic.txt @@ -11,8 +11,6 @@ ##gender karlkyn kvenkyn hvorugkyn -# $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. # 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. @@ -450,9 +448,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Kveikja á stýriskjá STR_ABOUT_MENU_AI_DEBUG :Aflúsun gervigreindar/forskrifta STR_ABOUT_MENU_SCREENSHOT :Skjámynd -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Súmuð inn skjáskot -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Taka skjáskot af súmi -STR_ABOUT_MENU_GIANT_SCREENSHOT :Risa skjámynd STR_ABOUT_MENU_ABOUT_OPENTTD :Um 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Samstilla hreyfimynd STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Sýna/fela afmörkunar kassa @@ -622,9 +617,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Sérval 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Tónlistarstyrkur STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Hljóðstyrkur -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}LÆGST -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}HÆST -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}: STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -829,6 +821,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}Ný {STRING} er nú fáanleg! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} tekur ekki lengur við {STRING} STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} tekur ekki lengur við {STRING} eða {STRING} STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} tekur nú við {STRING} @@ -1551,7 +1544,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_INDUSTRIES :{ORANGE}Iðnað STR_CONFIG_SETTING_AI :{ORANGE}Mótherji STR_CONFIG_SETTING_AI_NPC :{ORANGE}Gervigreind -STR_CONFIG_SETTING_PATHFINDER_OPF :Upprunalegt STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Ráðlegt) @@ -1632,13 +1624,9 @@ STR_QUIT_NO :{BLACK}Nei # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -2251,6 +2239,7 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Grafa sp STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Skipta á milli byggja/fjarlægja fyrir vegagerð STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Skipta á milli þess að leggja leggja og fjarlægja sporvagnaspor + # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Bifreiðaskýli STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}Veldu legu bifreiðaskýlis @@ -3051,8 +3040,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Innviði STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Járnbrautarspor: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Umferðarmerki STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Vegir: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Vegir -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Sporvagnaspor STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Vatns reitir: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Skipaskurðir STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Stöðvar: @@ -3063,8 +3050,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Iðnaðir STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Enginn - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% flutt) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% flutt) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Iðnaðar nöfn - smella á nafn til að færa miðju sjónarhorns á iðnað. Ctrl+smella til að opna nýtt sjónarhorn yfir þessum iðnaði @@ -3126,6 +3111,7 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Hóplausar bifr STR_GROUP_DEFAULT_SHIPS :Hóplaus skip STR_GROUP_DEFAULT_AIRCRAFTS :Hóplausar flugvélar + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Hópar - Smelltu á hóp til að skrifa öll farartæki í þessum hóp STR_GROUP_CREATE_TOOLTIP :{BLACK}Smelltu til að búa til hóp STR_GROUP_DELETE_TOOLTIP :{BLACK}Eyða völdum hóp @@ -3145,10 +3131,13 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Nýjir rafdrifn STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Nýir einteinungsvagnar STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Nýir segulsvifvagnar -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Ný járnbrautarlest STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Bifreiðaúrval + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Ný járnbrautarlest STR_BUY_VEHICLE_SHIP_CAPTION :Skipaúrval STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Flugvélaúrval +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Verð: {GOLD}{CURRENCY_LONG}{BLACK} Þyngd: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Hámarkshraði: {GOLD}{VELOCITY}{BLACK} Afl: {GOLD}{POWER} @@ -3181,11 +3170,13 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Kaupa bi STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Kaupa skip STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Kaupa flugvél + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Kaupa valinn lestarvagn. Shift+smella sýnir áætlaðan kostnað án þess að kaupa STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Kaupa valda bifreið. Shift+smella sýnir áætlaðan kostnað án þess að kaupa STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Kaupa valið skip. Shift+smella sýnir áætlaðan kostnað án þess að kaupa STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Kaupa valda flugvél. Shift+smella sýnir áætlaðan kostnað án þess að kaupa + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Endurnefna STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Endurnefna STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Endurnefna @@ -3282,13 +3273,16 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Þú er # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Skilaboð frá farartækisframleiðanda STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Við höfum hannað nýja {STRING} - hefðir þú áhuga á árs einkaleyfi á notkun þessa farartækis, svo að við getum athugað frammistöðu þess? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :lest -STR_ENGINE_PREVIEW_ROAD_VEHICLE :bifreið -STR_ENGINE_PREVIEW_AIRCRAFT :flugvél -STR_ENGINE_PREVIEW_SHIP :sjóferju STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :einteinungs eimreið STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :Segulsvifvagn +STR_ENGINE_PREVIEW_ROAD_VEHICLE :bifreið + +STR_ENGINE_PREVIEW_AIRCRAFT :flugvél +STR_ENGINE_PREVIEW_SHIP :sjóferju + STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Verð: {CURRENCY_LONG} Þyngd: {WEIGHT_SHORT}{}Hraði: {VELOCITY} Afl: {POWER}{}Rekstrarkostnaður: {CURRENCY_LONG} á ári{}Burðargeta: {CARGO_LONG} STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Verð: {CURRENCY_LONG} Þyngd: {WEIGHT_SHORT}{}Hámarskhraði: {VELOCITY} Afl: {POWER} Hámarks kraftur: {6:FORCE}{}Running Cost: {4:CURRENCY_LONG}/ári{}Burðargeta: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Verð: {CURRENCY_LONG} Hámarkshraði: {VELOCITY}{}Burðargeta: {CARGO_LONG}{}Rekstrarkostnaður: {CURRENCY_LONG} á ári @@ -3325,6 +3319,7 @@ STR_REPLACE_ELRAIL_VEHICLES :Rafdrifnir lest STR_REPLACE_MONORAIL_VEHICLES :Einteinungsvagnar STR_REPLACE_MAGLEV_VEHICLES :Segulsvifvagnar + STR_REPLACE_REMOVE_WAGON :{BLACK}Selja lestarvagna: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Heldur lengd lestar með því að fjarlægja vagna (framan frá), ef útskipting dráttarvagna myndi lengja hana @@ -3767,6 +3762,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Velja me STR_AI_LIST_CANCEL :{BLACK}Hætta við STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Hætta við breytingar forskriftar + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} breytur STR_AI_SETTINGS_CAPTION_AI :Gervigreindar @@ -4033,7 +4029,7 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Verður STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Ekkert hentugt járnbrautarspor STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Verður að fjarlægja járnbrautarspor fyrst STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Vegurinn er einstefnuvegur eða stíflaður -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Gatnamót ekki leyfð fyrir þessa tegund járnbrautarspora +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Gatnamót ekki leyfð fyrir þessa tegund járnbrautarspora STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Get ekki byggt umferðarmerki hér... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Get ekki byggt járnbrautarspor hér... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Get ekki fjarlægt járnbrautarspor héðan... diff --git a/src/lang/indonesian.txt b/src/lang/indonesian.txt index 214c0d1de4..7bd0f802b3 100644 --- a/src/lang/indonesian.txt +++ b/src/lang/indonesian.txt @@ -10,8 +10,6 @@ ##grflangid 0x5a -# $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. # 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. @@ -235,6 +233,7 @@ STR_TOOLTIP_FILTER_CRITERIA :{BLACK}Pilih kr STR_BUTTON_SORT_BY :{BLACK}Urutkan STR_BUTTON_LOCATION :{BLACK}Lokasi STR_BUTTON_RENAME :{BLACK}Ubah nama +STR_BUTTON_CATCHMENT :{BLACK}Jangkauan STR_TOOLTIP_CLOSE_WINDOW :{BLACK}Tutup window STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Judul Jendela - klik dan tahan disini untuk memindahkan jendela @@ -464,6 +463,7 @@ STR_TOOLBAR_SOUND_MUSIC :Suara/musik ############ range for message menu starts STR_NEWS_MENU_LAST_MESSAGE_NEWS_REPORT :Pesan/Berita terakhir STR_NEWS_MENU_MESSAGE_HISTORY_MENU :Berita Lampau +STR_NEWS_MENU_DELETE_ALL_MESSAGES :Hapus semua pesan ############ range ends here ############ range for about menu starts @@ -472,9 +472,7 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Hidup/matikan Layar Konsol STR_ABOUT_MENU_AI_DEBUG :Debug skrip AI STR_ABOUT_MENU_SCREENSHOT :Ambil gambar -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Ambil gambar dengan diperbesar -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Ambil gambar dengan perbesaran normal -STR_ABOUT_MENU_GIANT_SCREENSHOT :Ambil gambar keseluruhan peta +STR_ABOUT_MENU_SHOW_FRAMERATE :Tampilkan laju bingkai STR_ABOUT_MENU_ABOUT_OPENTTD :Tentang 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Penjajar Sprite STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Hidup/Matikan kotak batas @@ -644,9 +642,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Bebas 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Volume Musik STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Volume Efek -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}MIN -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}MAKS -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -862,6 +857,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}{STRING} jenis baru telah diluncurkan! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} tidak lagi menerima {STRING} STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} tidak lagi menerima {STRING} atau {STRING} STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} Sekarang menerima {STRING} @@ -989,7 +985,10 @@ 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_FONT_ZOOM :{BLACK}Ukuran font +STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Normal +STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :4 kali STR_GAME_OPTIONS_BASE_GRF :{BLACK}Set Grafik Dasar STR_GAME_OPTIONS_BASE_GRF_TOOLTIP :{BLACK}Pilih grafik dasar yang digunakan @@ -1221,7 +1220,7 @@ STR_CONFIG_SETTING_NONSTOP_BY_DEFAULT :Tujuan baru sta STR_CONFIG_SETTING_NONSTOP_BY_DEFAULT_HELPTEXT :Biasanya, kendaraan akan berhenti di setiap stasiun yang di lewati. Dengan mengaktifkan pengaturan ini, maka kendaraan akan melewati semua stasiun dalam perjalanan ke tujuan akhir. Perhatikan, bahwa pengaturan ini hanya mendefinisikan nilai default. Perintah individu dapat diatur STR_CONFIG_SETTING_STOP_LOCATION :Order kereta yang baru aslinya berhenti {STRING} dari stasiun STR_CONFIG_SETTING_STOP_LOCATION_HELPTEXT :Tempat kereta akan berhenti di peron stasiun. 'Dekat akhir' berarti dekat dengan titik masuk, 'tengah' berarti di tengah-tengah peron, dan 'jauh dari akhir' berarti jauh dari titik masuk -STR_CONFIG_SETTING_STOP_LOCATION_NEAR_END :hampir selesai +STR_CONFIG_SETTING_STOP_LOCATION_NEAR_END :tepi terdekat STR_CONFIG_SETTING_STOP_LOCATION_MIDDLE :tengah STR_CONFIG_SETTING_STOP_LOCATION_FAR_END :jauh di belakang STR_CONFIG_SETTING_AUTOSCROLL :Geser tampilan saat mouse ada di tepi: {STRING} @@ -1258,6 +1257,7 @@ STR_CONFIG_SETTING_DYNAMIC_ENGINES_EXISTING_VEHICLES :{WHITE}Tidak di STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE :Pemeliharaan Infrastruktur: {STRING} STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE_HELPTEXT :Jika dinyalakan, infrastruktur membutuhkan biaya pemeliharaan. Biaya berkembang secara proporsional sesuai dengan ukuran jaringan, lebih berdampak pada perusahaan besar dari pada perusahaan kecil +STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR_HELPTEXT :Pilih warna awal perusahaan STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS :Bandara tidak kedaluarsa: {STRING} STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS_HELPTEXT :Menyalakan setelan ini membuat semua jenis bandara tetap ada selamanya sejak pendesainanya @@ -1567,6 +1567,8 @@ STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :Mengaktifkan se STR_CONFIG_SETTING_TOWN_FOUNDING_FORBIDDEN :Dilarang STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED :Diijinkan STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED_CUSTOM_LAYOUT :Diijinkan, layout kota sendiri +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_HELPTEXT :Seberapa banyak kargo dihasilkan oleh rumah di kota , relatif terhadap keseluruhan populasi kota.{}Pertumbuhan kuadrat: Kota yang membesar dua kali menghasilkan penumpang empat kali lipat.{}Pertumbuhan linier: Kota yang membesar dua kali menghasilkan penumpang dua kali lipat. +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_BITCOUNT :Linier STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :Penempatan pohon dalam permainan: {STRING} STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :Mengendalikan kemunculan pohon dalam permainan. Ini akan berefek pada industri yang memerlukan pohon, contohnya pengolahan kayu gelondongan @@ -1694,7 +1696,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Distrib STR_CONFIG_SETTING_AI :{ORANGE}Pesaing STR_CONFIG_SETTING_AI_NPC :{ORANGE}Pemain Komputer -STR_CONFIG_SETTING_PATHFINDER_OPF :Asli STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Recommended) @@ -1777,13 +1778,9 @@ STR_QUIT_NO :{BLACK}Tidak # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -1812,6 +1809,7 @@ STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Ubah tah STR_CHEAT_SETUP_PROD :{LTBLUE}Aktifkan modifikasi nilai produksi: {ORANGE}{STRING} # Livery window +STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Skema Warna STR_LIVERY_GENERAL_TOOLTIP :{BLACK}Tampilkan skema warna umum STR_LIVERY_TRAIN_TOOLTIP :{BLACK}Tampilkan skema warna kereta @@ -2412,6 +2410,7 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Membangu STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Bangun/Bongkar konstruksi jalanan STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Membangun/bongkar konstruksi jalur trem + # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Arah Bengkel Kendaraan STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}Pilih arah bengkel kendaraan @@ -2698,6 +2697,7 @@ STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD # Framerate display window STR_FRAMERATE_CAPTION_SMALL :{STRING}{WHITE} ({DECIMAL}x) STR_FRAMERATE_RATE_GAMELOOP :{WHITE}Rata simulasi: {STRING} +STR_FRAMERATE_RATE_GAMELOOP_TOOLTIP :{BLACK}Jumlah detak permainan tersimulasi per detik. STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}Beberapa cepat permainan lagi berjalan, dibanding dengan kecepatan diharapkan memakai rata simulasi biasa. STR_FRAMERATE_CURRENT :{WHITE}Sekarang STR_FRAMERATE_DATA_POINTS :{WHITE}Data tergantung oleh ukuran {COMMA} @@ -2713,7 +2713,9 @@ STR_FRAMERATE_GL_ROADVEHS :{WHITE} Titik k STR_FRAMERATE_GL_SHIPS :{WHITE} Titik kapal: STR_FRAMERATE_GL_AIRCRAFT :{WHITE} Titik pesawat: STR_FRAMERATE_GL_LANDSCAPE :{WHITE} Titik dunia: +STR_FRAMERATE_DRAWING :{BLACK}Render grafis: STR_FRAMERATE_DRAWING_VIEWPORTS :{WHITE} Viewport dunia: +STR_FRAMERATE_VIDEO :{BLACK}Keluaran Video: STR_FRAMERATE_SOUND :{WHITE}Mixing suara: ############ End of leave-in-this-order ############ Leave those lines in this order!! @@ -2724,6 +2726,7 @@ STR_FRAMETIME_CAPTION_GL_SHIPS :Titik kapal STR_FRAMETIME_CAPTION_GL_AIRCRAFT :Titik pesawat STR_FRAMETIME_CAPTION_GL_LANDSCAPE :Titik dunia STR_FRAMETIME_CAPTION_SOUND :Mixing suara +STR_FRAMETIME_CAPTION_AI :AI {NUM} {STRING} ############ End of leave-in-this-order @@ -2913,6 +2916,7 @@ 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 +STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Reset relatif STR_SPRITE_ALIGNER_PICKER_BUTTON :{BLACK}Pilih sprite STR_SPRITE_ALIGNER_PICKER_TOOLTIP :{BLACK}Pilih sebuah sprite di manapun pada layar @@ -3146,11 +3150,11 @@ STR_STATION_VIEW_ACCEPTS_TOOLTIP :{BLACK}Tampilka STR_STATION_VIEW_ACCEPTS_CARGO :{BLACK}Menerima: {WHITE}{CARGO_LIST} STR_STATION_VIEW_EXCLUSIVE_RIGHTS_SELF :{BLACK}Stasiun memiliki hak transportasi eksklusif di kota ini -STR_STATION_VIEW_EXCLUSIVE_RIGHTS_COMPANY :{YELLOW}{COMPANY}{BLACK} beli hak transportasi eksklusif di kota ini +STR_STATION_VIEW_EXCLUSIVE_RIGHTS_COMPANY :{YELLOW}{COMPANY}{BLACK} memiliki hak transportasi eksklusif di kota ini STR_STATION_VIEW_RATINGS_BUTTON :{BLACK}Peringkat STR_STATION_VIEW_RATINGS_TOOLTIP :{BLACK}Tampilkna peringkat dari stasiun -STR_STATION_VIEW_SUPPLY_RATINGS_TITLE :{BLACK}Asupan bulanan dan penilaian tempatan: +STR_STATION_VIEW_SUPPLY_RATINGS_TITLE :{BLACK}Asupan bulanan dan peringkat layanan: STR_STATION_VIEW_CARGO_SUPPLY_RATING :{WHITE}{STRING}: {YELLOW}{COMMA} / {STRING} ({COMMA}%) STR_STATION_VIEW_GROUP :{BLACK}Pengelompokkan @@ -3294,8 +3298,7 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Infrastr STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Bagian rel: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Sinyal STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Bagian jalan: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Jalan raya -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Rel Trem +STR_COMPANY_INFRASTRUCTURE_VIEW_TRAM_SECT :{GOLD}Bagian Trem: STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Perairan: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Kanal STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Stasiun: @@ -3306,8 +3309,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Industri STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Tidak Ada - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% terkirim) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% terkirim) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Nama-nama industri - klik di nama untuk mengarahkan pandangan utama pada industri. Ctrl+Click akan membuka viewport baru pada lokasi industri @@ -3371,6 +3372,8 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Kendaraan tanpa STR_GROUP_DEFAULT_SHIPS :Kapal tanpa kelompok STR_GROUP_DEFAULT_AIRCRAFTS :Pesawat tanpa kelompok +STR_GROUP_COUNT_WITH_SUBGROUP :{TINY_FONT}{COMMA} (+{COMMA}) + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Kelompok - Klik salah satu untuk melihat daftar kendaraan pada kelompok tersebut STR_GROUP_CREATE_TOOLTIP :{BLACK}Klik untuk membuat kelompok STR_GROUP_DELETE_TOOLTIP :{BLACK}Hapus kelompok terpilih @@ -3396,10 +3399,13 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Kereta listrik STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Monorel Baru STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Maglev Baru -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Kereta Baru STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Kendaraan Baru + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Kereta Baru STR_BUY_VEHICLE_SHIP_CAPTION :Kapal Baru STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Buat Pesawat +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Biaya: {GOLD}{CURRENCY_LONG}{BLACK} Berat: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Kecepatan: {GOLD}{VELOCITY}{BLACK} Daya: {GOLD}{POWER} @@ -3414,6 +3420,7 @@ STR_PURCHASE_INFO_RELIABILITY :{BLACK}Kehandal STR_PURCHASE_INFO_COST :{BLACK}Biaya: {GOLD}{CURRENCY_LONG} STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Berat: {GOLD}{WEIGHT_SHORT} ({WEIGHT_SHORT}) STR_PURCHASE_INFO_COST_SPEED :{BLACK}Biaya: {GOLD}{CURRENCY_LONG}{BLACK} Kecepatan: {GOLD}{VELOCITY} +STR_PURCHASE_INFO_COST_REFIT_SPEED :{BLACK}Biaya: {GOLD}{CURRENCY_LONG}{BLACK} (Biaya Karoseri: {GOLD}{CURRENCY_LONG}{BLACK}) Kecepatan: {GOLD}{VELOCITY} STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Daya Muat: {GOLD}{CARGO_LONG}, {CARGO_LONG} STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Daya Gerbong: {GOLD}+{POWER}{BLACK} Berat: {GOLD}+{WEIGHT_SHORT} STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Kargo dapat di ganti untuk: {GOLD}{STRING} @@ -3433,11 +3440,15 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Beli Ken STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Beli Kapal STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Beli Pesawat + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Beli kereta yang dipilih. Shift untuk menampilkan perkiraan biaya STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Beli kendaraan yang dipilih. Shift untuk menampilkan perkiraan biaya STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Beli kapal yang dipilih. Shift untuk menampilkan perkiraan biaya STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Beli pesawat yang dipilih. Shift untuk menampilkan perkiraan biaya +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Beli lalu karoseri kendaraan yang dipilih. Shift+Klik untuk menampilkan perkiraan biaya tanpa membelinya +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Beli lalu karoseri kapal yang dipilih. Shift+Klik untuk menampilkan perkiraan biaya tanpa membelinya + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Ubah Nama STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Ganti Nama STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Ubah Nama @@ -3546,13 +3557,16 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Anda ak # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Pesan dari pabrik kendaraan STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Kami telah mendesain {STRING} baru - apakah anda tertarik mempergunakan kendaraan ini secara eksklusif , sehingga kami dapat melihat bagaimana kemampuannya sebelum dijual secara masal? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :lokomotif kereta -STR_ENGINE_PREVIEW_ROAD_VEHICLE :kendaraan jalan raya -STR_ENGINE_PREVIEW_AIRCRAFT :pesawat -STR_ENGINE_PREVIEW_SHIP :kapal STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :lokomotif monorel STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :lokomotif maglev +STR_ENGINE_PREVIEW_ROAD_VEHICLE :kendaraan jalan raya + +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_MAX_SPEED_CAP_RUNCOST :{BLACK}Biaya: {CURRENCY_LONG} Kec. Max: {VELOCITY}{}Kapasitas: {CARGO_LONG}{}Bea Berjalan: {CURRENCY_LONG}/thn @@ -3598,6 +3612,7 @@ STR_REPLACE_ELRAIL_VEHICLES :Kereta Listrik STR_REPLACE_MONORAIL_VEHICLES :Kereta Monorel STR_REPLACE_MAGLEV_VEHICLES :Kereta Maglev + STR_REPLACE_REMOVE_WAGON :{BLACK}Membuang gerbong: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Membuat panjang kereta tetap sama saat penggantian secara otomatis dengan cara membuang gerbong(dihitung dari bagian depan), jika penggantian lokomotif membuat kereta lebih panjang @@ -4047,6 +4062,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Pilih sk STR_AI_LIST_CANCEL :{BLACK}Batal STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Jangan mengubah skrip AI + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parameter STR_AI_SETTINGS_CAPTION_AI :AI @@ -4249,7 +4265,6 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... jala STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... menghadap pada arah yang salah STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... terminal lintas-lalu tak bisa memiliki sudut STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... terminal lintas-lalu tak bisa memiliki simpangan -STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... jalannya satu arah atau terhalang # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Tidak dapat menghapus bagian dari stasiun... @@ -4319,7 +4334,7 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Sinyal h STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Tidak tersedia rel yang sesuai STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Harus membongkar rel terlebih dahulu STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Jalannya satu arah atau terhalang -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Perlintasan tingkat tidak diperbolehkan pada tipe rel ini +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Perlintasan tingkat tidak diperbolehkan pada tipe rel ini STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Tidak dapat membangun sinyal disini STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Tidak dapat membangun jalur rel disini STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Tidak dapat menghapus jalur rel dari sini diff --git a/src/lang/irish.txt b/src/lang/irish.txt index 112e9322da..2ebe18da5b 100644 --- a/src/lang/irish.txt +++ b/src/lang/irish.txt @@ -10,8 +10,6 @@ ##grflangid 0x08 -# $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. # 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. @@ -472,9 +470,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Scoránaigh consól STR_ABOUT_MENU_AI_DEBUG :Dífhabhtú AI/Scripteanna Cluiche STR_ABOUT_MENU_SCREENSHOT :Seat scáileáin -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Seat scáileáin zúmáilte isteach go hiomlán -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Seat scáileáin le zúm réamhshocraithe -STR_ABOUT_MENU_GIANT_SCREENSHOT :Seat scáileáin den léarscáil ar fad STR_ABOUT_MENU_ABOUT_OPENTTD :Maidir le 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Ailínóir spriteanna STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Scoránaigh boscaí imill @@ -644,9 +639,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Saincheaptha 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Airde Ceoil STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Airde na maisíochtaí -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}ÍOSTA -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}UASTA -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -858,6 +850,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}Tá {STRING} nua ar fáil anois! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}Ní ghlacann {STATION} le {STRING} a thuilleadh STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}Ní ghlacann {STATION} le {STRING} ná le {STRING} a thuilleadh STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}Glacann {STATION} le {STRING} anois @@ -1684,7 +1677,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Dáilea STR_CONFIG_SETTING_AI :{ORANGE}Iomaitheoirí STR_CONFIG_SETTING_AI_NPC :{ORANGE}Ríomh-imreoirí -STR_CONFIG_SETTING_PATHFINDER_OPF :Bunaidh STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Molta) @@ -1767,13 +1759,9 @@ STR_QUIT_NO :{BLACK}Níl # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -2401,6 +2389,7 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Tóg tol STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Athraigh idir tógáil/baint agus bóithre á dtógáil STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Athraigh idir tógáil/baint agus trambhealaí á dtógáil + # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Treosuíomh an Iosta Bhóthair STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}Roghnaigh treosuíomh an iosta feithiclí bóthair @@ -3260,8 +3249,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Bonneaga STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Píosaí iarnróid: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Comharthaí STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Píosaí bóthair: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Bóthar -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Trambhealach STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Tíleanna uisce: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Canálacha STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Stáisiúin: @@ -3272,8 +3259,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Tionscail STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Ceann ar bith - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} (iompraíodh {COMMA}%) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} (iompraíodh {COMMA}%/{COMMA}%) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Ainmneacha na dtionscal - cliceáil ar ainm chun an príomh-amharc a lárú ar thionscal. Osclaítear amharc nua ar shuíomh an tionscail le Ctrl+Cliceáil @@ -3335,6 +3320,7 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Feithiclí bót STR_GROUP_DEFAULT_SHIPS :Longa nach bhfuil i ngrúpa STR_GROUP_DEFAULT_AIRCRAFTS :Aerárthaigh nach bhfuil i ngrúpa + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Grúpaí - cliceáil ar ghrúpa le gach feithicil sa ghrúpa seo a liostú STR_GROUP_CREATE_TOOLTIP :{BLACK}Cliceáil le grúpa a chruthú STR_GROUP_DELETE_TOOLTIP :{BLACK}Scrios an grúpa roghnaithe @@ -3356,10 +3342,13 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Feithiclí Iarn STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Feithiclí Aonráille Nua STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Feithiclí Maglev Nua -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Feithiclí Iarnróid Nua STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Feithiclí Bóthair Nua + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Feithiclí Iarnróid Nua STR_BUY_VEHICLE_SHIP_CAPTION :Longa Nua STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Aerárthaigh Nua +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Costas: {GOLD}{CURRENCY_LONG}{BLACK} Meáchan: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Luas: {GOLD}{VELOCITY}{BLACK} Cumhacht: {GOLD}{POWER} @@ -3392,11 +3381,13 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Ceannaig STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Ceannaigh Long STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Ceannaigh Aerárthach + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Ceannaigh an fheithicil traenach aibhsithe STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Ceannaigh an fheithicil bóthair aibhsithe STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Ceannaigh an long aibhsithe STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Ceannaigh an t-aerárthach aibhsithe + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Athainmnigh STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Athainmnigh STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Athainmnigh @@ -3505,13 +3496,16 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Tá tú # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Teachtaireacht ó dhéantóir feithiclí STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Táimid díreach tar éis {STRING} nua a dhearadh - an mbeadh suim agat úsáid eisiach a bhaint as ar feadh bliana, le go mbeimid in ann a fheiceáil mar a fheidhmíonn sé sula gcuirfimid ar fáil do chách é? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :inneall gluaiste iarnróid -STR_ENGINE_PREVIEW_ROAD_VEHICLE :feithicil bóthair -STR_ENGINE_PREVIEW_AIRCRAFT :aerárthach -STR_ENGINE_PREVIEW_SHIP :long STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :inneall gluaiste aonráille STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :inneall gluaiste maglev +STR_ENGINE_PREVIEW_ROAD_VEHICLE :feithicil bóthair + +STR_ENGINE_PREVIEW_AIRCRAFT :aerárthach +STR_ENGINE_PREVIEW_SHIP :long + STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Costas {CURRENCY_LONG} Meáchan: {WEIGHT_SHORT}{}Luas: {VELOCITY} Cumhacht: {POWER}{}Costas Coinneála {CURRENCY_LONG}/bl{}Toilleadh: {CARGO_LONG} STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Costas: {CURRENCY_LONG} Meáchan: {WEIGHT_SHORT}{}Luas: {VELOCITY} Cumhacht: {POWER} T.E. uasta: {6:FORCE}{}Costas Coinneála: {4:CURRENCY_LONG}/bl{}Toilleadh: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Costas: {CURRENCY_LONG} Luas Uasta: {VELOCITY}{}Toilleadh: {CARGO_LONG}{}Costas Coinneála: {CURRENCY_LONG}/bl @@ -3552,6 +3546,7 @@ STR_REPLACE_ELRAIL_VEHICLES :Feithiclí Iarn STR_REPLACE_MONORAIL_VEHICLES :Feithiclí Aonráille STR_REPLACE_MAGLEV_VEHICLES :Feithiclí Maglev + STR_REPLACE_REMOVE_WAGON :{BLACK}Vaigíní a bhaint: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Ceangail ar uath-athsholáthar fad na traenach a choinneáil mar an gcéanna trí vaigíní a bhaint (ag tosú ag an tosach), má tharlaíonn sé go mbeadh an traein níos faide tar éis an t-inneall a athsholáthar. @@ -3999,6 +3994,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Roghnaig STR_AI_LIST_CANCEL :{BLACK}Cuir ar ceal STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Ná hathraigh an AI + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}Paraiméadair {STRING} STR_AI_SETTINGS_CAPTION_AI :AI @@ -4270,7 +4266,7 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Ní mór STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Níl ráillí iarnróid feiliúnacha ann STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Ní mór na ráillí iarnróid a bhaint ar dtús STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Is bóthar aonbhealaigh nó blocáilte é -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Ní cheadaítear crosairí comhréidh don chineál ráille seo +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Ní cheadaítear crosairí comhréidh don chineál ráille seo STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Ní féidir comharthaí a thógáil anseo... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Ní féidir ráillí iarnróid a thógáil anseo... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Ní féidir ráillí iarnróid a bhaint as seo... diff --git a/src/lang/italian.txt b/src/lang/italian.txt index c0c5a57871..79c2632936 100644 --- a/src/lang/italian.txt +++ b/src/lang/italian.txt @@ -12,8 +12,6 @@ ##case ms mp fs fp -# $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. # 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. @@ -239,6 +237,8 @@ STR_TOOLTIP_FILTER_CRITERIA :{BLACK}Selezion STR_BUTTON_SORT_BY :{BLACK}Ordina per STR_BUTTON_LOCATION :{BLACK}Posizione STR_BUTTON_RENAME :{BLACK}Rinomina +STR_BUTTON_CATCHMENT :{BLACK}Copertura +STR_TOOLTIP_CATCHMENT :{BLACK}Attiva/disattiva la visualizzazione dell'area di copertura STR_TOOLTIP_CLOSE_WINDOW :{BLACK}Chiude la finestra STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Titolo della finestra - trascinarlo per muovere la finestra @@ -267,6 +267,7 @@ STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT_TOOLTIP :{BLACK}Mostra a STR_BUTTON_DEFAULT :{BLACK}Predefinito STR_BUTTON_CANCEL :{BLACK}Annulla STR_BUTTON_OK :{BLACK}OK +STR_WARNING_PASSWORD_SECURITY :{YELLOW}Attenzione: gli amministratori del server potrebbero leggere il testo inserito qui. # On screen keyboard window STR_OSK_KEYBOARD_LAYOUT :\1234567890'ì qwertyuiopè+asdfghjklòàù @@ -3053,7 +3081,7 @@ STR_NEWGRF_SCAN_ARCHIVES :자료 검색 # Sign list window STR_SIGN_LIST_CAPTION :{WHITE}팻말 목록 - 팻말 {COMMA}개 STR_SIGN_LIST_MATCH_CASE :{BLACK}대소문자 구분 -STR_SIGN_LIST_MATCH_CASE_TOOLTIP :{BLACK}팻말의 이름을 비교할 때 검색 문자열의 대소문자 구분할지 여부를 선택합니다. +STR_SIGN_LIST_MATCH_CASE_TOOLTIP :{BLACK}팻말의 이름을 비교할 때 검색 문자열의 대소문자 구분할지 여부를 선택합니다 # Sign window STR_EDIT_SIGN_CAPTION :{WHITE}팻말 내용 고치기 @@ -3067,7 +3095,7 @@ STR_TOWN_DIRECTORY_CAPTION :{WHITE}도시 STR_TOWN_DIRECTORY_NONE :{ORANGE}(없음) STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (대도시){BLACK} ({COMMA}) -STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}도시 이름 - 이 도시로 시점을 변경하려면 클릭하세요. CTRL+클릭하면 이 도시 위치를 기준으로 새로운 외부 화면을 엽니다. +STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK}도시 이름 - 이 도시로 시점을 변경하려면 클릭하세요. CTRL+클릭하면 이 도시 위치를 기준으로 새로운 외부 화면을 엽니다 STR_TOWN_POPULATION :{BLACK}총 인구 수: {COMMA} # Town view window @@ -3085,9 +3113,9 @@ STR_TOWN_VIEW_TOWN_GROWS_EVERY :{BLACK}도시 STR_TOWN_VIEW_TOWN_GROWS_EVERY_FUNDED :{BLACK}도시가 {ORANGE}{COMMA}{BLACK}일마다 성장합니다. (투자됨) STR_TOWN_VIEW_TOWN_GROW_STOPPED :{BLACK}도시는 {RED}성장하지 않고{BLACK} 있습니다. STR_TOWN_VIEW_NOISE_IN_TOWN :{BLACK}현재 소음 수준: {ORANGE}{COMMA}{BLACK} 최대 허용 수준: {ORANGE}{COMMA} -STR_TOWN_VIEW_CENTER_TOOLTIP :{BLACK}이 도시의 위치로 시점을 변경합니다. CTRL+클릭하면 이 도시 위치를 기준으로 새로운 외부 화면을 엽니다. +STR_TOWN_VIEW_CENTER_TOOLTIP :{BLACK}이 도시의 위치로 시점을 변경합니다. CTRL+클릭하면 이 도시 위치를 기준으로 새로운 외부 화면을 엽니다 STR_TOWN_VIEW_LOCAL_AUTHORITY_BUTTON :{BLACK}지역 당국 -STR_TOWN_VIEW_LOCAL_AUTHORITY_TOOLTIP :{BLACK}지역 당국의 정보를 보여줍니다. +STR_TOWN_VIEW_LOCAL_AUTHORITY_TOOLTIP :{BLACK}지역 당국의 정보를 보여줍니다 STR_TOWN_VIEW_RENAME_TOOLTIP :{BLACK}이 도시 이름을 변경합니다. STR_TOWN_VIEW_EXPAND_BUTTON :{BLACK}확장 @@ -3099,6 +3127,8 @@ STR_TOWN_VIEW_RENAME_TOWN_BUTTON :도시 이름 # Town local authority window STR_LOCAL_AUTHORITY_CAPTION :{WHITE}{TOWN} 지역 당국 +STR_LOCAL_AUTHORITY_ZONE :{BLACK}구역 +STR_LOCAL_AUTHORITY_ZONE_TOOLTIP :{BLACK}지역 당국의 범위 안에 있는 구역을 보여줍니다 STR_LOCAL_AUTHORITY_COMPANY_RATINGS :{BLACK}회사에 대한 이 도시의 평판: STR_LOCAL_AUTHORITY_COMPANY_RATING :{YELLOW}{COMPANY} {COMPANY_NUM}: {ORANGE}{STRING} STR_LOCAL_AUTHORITY_ACTIONS_TITLE :{BLACK}가능한 행동: @@ -3135,13 +3165,13 @@ STR_GOALS_SPECTATOR_NONE :{ORANGE}- 적 STR_GOALS_PROGRESS :{ORANGE}{STRING} STR_GOALS_PROGRESS_COMPLETE :{GREEN}{STRING} STR_GOALS_COMPANY_TITLE :{BLACK}회사 목표: -STR_GOALS_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER :{BLACK}산업시설/마을/지도의 위치로 화면을 이동하려면 클릭하십시오. CTRL+클릭하면 산업시설/마을/지도를 표시하는 외부화면을 엽니다. +STR_GOALS_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER :{BLACK}산업시설/마을/칸의 위치로 화면을 이동하려면 클릭하십시오. CTRL+클릭하면 산업시설/마을/칸의 위치를 기준으로 새로운 외부 화면을 엽니다 # Goal question window STR_GOAL_QUESTION_CAPTION_QUESTION :{G=m}질문 STR_GOAL_QUESTION_CAPTION_INFORMATION :{G=f}정보 STR_GOAL_QUESTION_CAPTION_WARNING :{G=f}경고 -STR_GOAL_QUESTION_CAPTION_ERROR :오류 +STR_GOAL_QUESTION_CAPTION_ERROR :{G=f}오류 ############ Start of Goal Question button list STR_GOAL_QUESTION_BUTTON_CANCEL :취소 @@ -3171,7 +3201,7 @@ STR_SUBSIDIES_OFFERED_FROM_TO :{ORANGE}{1:STRI STR_SUBSIDIES_NONE :{ORANGE}없음 STR_SUBSIDIES_SUBSIDISED_TITLE :{BLACK}이미 지급 중인 보조금: STR_SUBSIDIES_SUBSIDISED_FROM_TO :{ORANGE}{1:STRING}에서 {2:STRING}까지 {0:STRING} 수송{YELLOW} ({3:COMPANY}{YELLOW}, {DATE_SHORT}까지) -STR_SUBSIDIES_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER :{BLACK}산업시설/도시의 위치로 시점을 변경하려면 클릭하세요. CTRL+클릭하면 이 산업시설/도시의 위치를 기준으로 새로운 외부 화면을 엽니다. +STR_SUBSIDIES_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER :{BLACK}산업시설/도시의 위치로 시점을 변경하려면 클릭하세요. CTRL+클릭하면 이 산업시설/도시의 위치를 기준으로 새로운 외부 화면을 엽니다 # Story book window STR_STORY_BOOK_CAPTION :{WHITE}{COMPANY}의 스토리 북 @@ -3179,15 +3209,15 @@ STR_STORY_BOOK_SPECTATOR_CAPTION :{WHITE}전체 STR_STORY_BOOK_SPECTATOR :전체 스토리 북 STR_STORY_BOOK_TITLE :{YELLOW}{STRING} STR_STORY_BOOK_GENERIC_PAGE_ITEM :{NUM}쪽 -STR_STORY_BOOK_SEL_PAGE_TOOLTIP :{BLACK}드롭 다운 목록에서 이동하고자 하는 쪽수를 선택하세요. +STR_STORY_BOOK_SEL_PAGE_TOOLTIP :{BLACK}드롭 다운 목록에서 이동하고자 하는 쪽수를 선택하세요 STR_STORY_BOOK_PREV_PAGE :{BLACK}이전 -STR_STORY_BOOK_PREV_PAGE_TOOLTIP :{BLACK}이전 쪽으로 이동합니다. +STR_STORY_BOOK_PREV_PAGE_TOOLTIP :{BLACK}이전 쪽으로 이동합니다 STR_STORY_BOOK_NEXT_PAGE :{BLACK}다음 -STR_STORY_BOOK_NEXT_PAGE_TOOLTIP :{BLACK}다음 쪽으로 이동합니다. +STR_STORY_BOOK_NEXT_PAGE_TOOLTIP :{BLACK}다음 쪽으로 이동합니다 STR_STORY_BOOK_INVALID_GOAL_REF :{RED}잘못된 목표 참조 # Station list window -STR_STATION_LIST_TOOLTIP :{BLACK}역 이름 - 이 역의 위치로 시점을 변경하려면 클릭하세요. CTRL+클릭하면 이 역 위치를 기준으로 새로운 외부 화면을 엽니다. +STR_STATION_LIST_TOOLTIP :{BLACK}역 이름 - 이 역의 위치로 시점을 변경하려면 클릭하세요. CTRL+클릭하면 이 역 위치를 기준으로 새로운 외부 화면을 엽니다 STR_STATION_LIST_USE_CTRL_TO_SELECT_MORE :{BLACK}1개 이상의 아이템을 선택하려면 CTRL 키를 누르세요 STR_STATION_LIST_CAPTION :{WHITE}{COMPANY} - {COMMA}개 역사 STR_STATION_LIST_STATION :{YELLOW}{STATION} {STATION_FEATURES} @@ -3249,36 +3279,36 @@ STR_CARGO_RATING_EXCELLENT :훌륭함 STR_CARGO_RATING_OUTSTANDING :매우 훌륭함 ############ range for rating ends -STR_STATION_VIEW_CENTER_TOOLTIP :{BLACK}이 역의 위치로 시점을 변경합니다. CTRL+클릭하면 이 역 위치를 기준으로 새로운 외부 화면을 엽니다. -STR_STATION_VIEW_RENAME_TOOLTIP :{BLACK}이 역의 이름을 변경합니다. +STR_STATION_VIEW_CENTER_TOOLTIP :{BLACK}이 역의 위치로 시점을 변경합니다. CTRL+클릭하면 이 역 위치를 기준으로 새로운 외부 화면을 엽니다 +STR_STATION_VIEW_RENAME_TOOLTIP :{BLACK}이 역의 이름을 변경합니다 -STR_STATION_VIEW_SCHEDULED_TRAINS_TOOLTIP :{BLACK}이 역을 거쳐가는 모든 열차를 표시합니다 -STR_STATION_VIEW_SCHEDULED_ROAD_VEHICLES_TOOLTIP :{BLACK}이 역을 거쳐가는 모든 자동차/전차를 보여줍니다. -STR_STATION_VIEW_SCHEDULED_AIRCRAFT_TOOLTIP :{BLACK}이 역을 거쳐가는 모든 항공기를 표시합니다 -STR_STATION_VIEW_SCHEDULED_SHIPS_TOOLTIP :{BLACK}이 역을 거쳐가는 모든 선박을 표시합니다 +STR_STATION_VIEW_SCHEDULED_TRAINS_TOOLTIP :{BLACK}이 역을 거쳐가는 모든 열차를 보여줍니다 +STR_STATION_VIEW_SCHEDULED_ROAD_VEHICLES_TOOLTIP :{BLACK}이 역을 거쳐가는 모든 차량을 보여줍니다 +STR_STATION_VIEW_SCHEDULED_AIRCRAFT_TOOLTIP :{BLACK}이 역을 거쳐가는 모든 항공기를 보여줍니다 +STR_STATION_VIEW_SCHEDULED_SHIPS_TOOLTIP :{BLACK}이 역을 거쳐가는 모든 선박을 보여줍니다 -STR_STATION_VIEW_RENAME_STATION_CAPTION :이 역의 이름을 변경합니다. +STR_STATION_VIEW_RENAME_STATION_CAPTION :이 역의 이름을 변경합니다 STR_STATION_VIEW_CLOSE_AIRPORT :{BLACK}공항 폐쇄 -STR_STATION_VIEW_CLOSE_AIRPORT_TOOLTIP :{BLACK}이 공항에 항공기가 착륙하는 것을 금지합니다. +STR_STATION_VIEW_CLOSE_AIRPORT_TOOLTIP :{BLACK}이 공항에 항공기가 착륙하는 것을 금지합니다 # Waypoint/buoy view window STR_WAYPOINT_VIEW_CAPTION :{WHITE}{WAYPOINT} -STR_WAYPOINT_VIEW_CENTER_TOOLTIP :{BLACK}이 경유지의 위치로 시점을 변경합니다. CTRL+클릭하면 이 경유지 위치를 기준으로 새로운 외부 화면을 엽니다. -STR_WAYPOINT_VIEW_CHANGE_WAYPOINT_NAME :{BLACK}이 경유지의 이름을 변경합니다. -STR_BUOY_VIEW_CENTER_TOOLTIP :{BLACK}이 부표의 위치로 시점을 변경합니다. CTRL+클릭하면 이 부표 위치를 기준으로 새로운 외부화면을 엽니다. +STR_WAYPOINT_VIEW_CENTER_TOOLTIP :{BLACK}이 경유지의 위치로 시점을 변경합니다. CTRL+클릭하면 이 경유지 위치를 기준으로 새로운 외부 화면을 엽니다 +STR_WAYPOINT_VIEW_CHANGE_WAYPOINT_NAME :{BLACK}이 경유지의 이름을 변경합니다 +STR_BUOY_VIEW_CENTER_TOOLTIP :{BLACK}이 부표의 위치로 시점을 변경합니다. CTRL+클릭하면 이 부표 위치를 기준으로 새로운 외부 화면을 엽니다 STR_BUOY_VIEW_CHANGE_BUOY_NAME :{BLACK}부표 이름 바꾸기 STR_EDIT_WAYPOINT_NAME :{WHITE}경유지 이름 설정 # Finances window STR_FINANCES_CAPTION :{WHITE}{COMPANY}의 재정 {BLACK}{COMPANY_NUM} -STR_FINANCES_EXPENDITURE_INCOME_TITLE :{WHITE}지출/수입 +STR_FINANCES_EXPENDITURE_INCOME_TITLE :{WHITE}수입/지출 STR_FINANCES_YEAR :{WHITE}{NUM} 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_ROAD_VEHICLE_RUNNING_COSTS :{GOLD}차량 유지비 STR_FINANCES_SECTION_AIRCRAFT_RUNNING_COSTS :{GOLD}항공기 유지비 STR_FINANCES_SECTION_SHIP_RUNNING_COSTS :{GOLD}선박 유지비 STR_FINANCES_SECTION_PROPERTY_MAINTENANCE :{GOLD}유지보수비 @@ -3296,9 +3326,9 @@ STR_FINANCES_LOAN_TITLE :{WHITE}대출 STR_FINANCES_MAX_LOAN :{WHITE}최대 대출: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} STR_FINANCES_BORROW_BUTTON :{BLACK}{CURRENCY_LONG} 빌리기 -STR_FINANCES_BORROW_TOOLTIP :{BLACK}돈을 빌립니다. CTRL+클릭하면 빌릴 수 있는만큼 빌립니다. +STR_FINANCES_BORROW_TOOLTIP :{BLACK}돈을 빌립니다. CTRL+클릭하면 빌릴 수 있는 만큼 빌립니다 STR_FINANCES_REPAY_BUTTON :{BLACK}{CURRENCY_LONG} 갚기 -STR_FINANCES_REPAY_TOOLTIP :{BLACK}돈을 갚습니다. CTRL+클릭하면 갚을 수 있는 만큼 갚습니다. +STR_FINANCES_REPAY_TOOLTIP :{BLACK}돈을 갚습니다. CTRL+클릭하면 갚을 수 있는 만큼 갚습니다 STR_FINANCES_INFRASTRUCTURE_BUTTON :{BLACK}기반시설 # Company view @@ -3324,27 +3354,27 @@ STR_COMPANY_VIEW_INFRASTRUCTURE_AIRPORT :{WHITE}공항 { STR_COMPANY_VIEW_INFRASTRUCTURE_NONE :{WHITE}없음 STR_COMPANY_VIEW_BUILD_HQ_BUTTON :{BLACK}본사 건설 -STR_COMPANY_VIEW_BUILD_HQ_TOOLTIP :{BLACK}회사 본사를 건설합니다. +STR_COMPANY_VIEW_BUILD_HQ_TOOLTIP :{BLACK}회사 본사를 건설합니다 STR_COMPANY_VIEW_VIEW_HQ_BUTTON :{BLACK}본사 보기 -STR_COMPANY_VIEW_VIEW_HQ_TOOLTIP :{BLACK}회사 본사 위치로 이동합니다. +STR_COMPANY_VIEW_VIEW_HQ_TOOLTIP :{BLACK}회사 본사 위치로 이동합니다 STR_COMPANY_VIEW_RELOCATE_HQ :{BLACK}본사 위치 변경 -STR_COMPANY_VIEW_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}회사가치의 1% 가격을 들여 본사를 다른 위치로 옮깁니다. SHIFT+클릭하면 예상 가격을 볼 수 있습니다. +STR_COMPANY_VIEW_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}회사가치의 1% 가격을 들여 본사를 다른 위치로 옮깁니다. SHIFT+클릭을 사용하면 예상 비용을 볼 수 있습니다 STR_COMPANY_VIEW_INFRASTRUCTURE_BUTTON :{BLACK}상세정보 -STR_COMPANY_VIEW_INFRASTRUCTURE_TOOLTIP :{BLACK}기반시설 상세정보 창을 엽니다. +STR_COMPANY_VIEW_INFRASTRUCTURE_TOOLTIP :{BLACK}기반시설 상세정보 창을 엽니다 STR_COMPANY_VIEW_NEW_FACE_BUTTON :{BLACK}새 얼굴 -STR_COMPANY_VIEW_NEW_FACE_TOOLTIP :{BLACK}사장의 얼굴을 선택합니다. +STR_COMPANY_VIEW_NEW_FACE_TOOLTIP :{BLACK}사장의 얼굴을 선택합니다 STR_COMPANY_VIEW_COLOUR_SCHEME_BUTTON :{BLACK}색상 -STR_COMPANY_VIEW_COLOUR_SCHEME_TOOLTIP :{BLACK}회사 차량의 색상을 변경합니다. +STR_COMPANY_VIEW_COLOUR_SCHEME_TOOLTIP :{BLACK}회사 차량의 색상을 변경합니다 STR_COMPANY_VIEW_COMPANY_NAME_BUTTON :{BLACK}회사 이름 -STR_COMPANY_VIEW_COMPANY_NAME_TOOLTIP :{BLACK}회사 이름을 변경합니다. +STR_COMPANY_VIEW_COMPANY_NAME_TOOLTIP :{BLACK}회사 이름을 변경합니다 STR_COMPANY_VIEW_PRESIDENT_NAME_BUTTON :{BLACK}사장 이름 -STR_COMPANY_VIEW_PRESIDENT_NAME_TOOLTIP :{BLACK}사장의 이름을 변경합니다. +STR_COMPANY_VIEW_PRESIDENT_NAME_TOOLTIP :{BLACK}사장의 이름을 변경합니다 STR_COMPANY_VIEW_BUY_SHARE_BUTTON :{BLACK}회사 지분의 25%를 매입 STR_COMPANY_VIEW_SELL_SHARE_BUTTON :{BLACK}회사 지분의 25%를 매도 -STR_COMPANY_VIEW_BUY_SHARE_TOOLTIP :{BLACK}이 회사 지분의 25%를 매입합니다. SHIFT+클릭으로 예상 매입 가격을 볼 수 있습니다. -STR_COMPANY_VIEW_SELL_SHARE_TOOLTIP :{BLACK}이 회사 지분의 25%를 매도합니다. SHIFT+클릭으로 예상 매도 가격을 볼 수 있습니다. +STR_COMPANY_VIEW_BUY_SHARE_TOOLTIP :{BLACK}이 회사 지분의 25%를 매입합니다. SHIFT+클릭으로 예상 매입 가격을 볼 수 있습니다 +STR_COMPANY_VIEW_SELL_SHARE_TOOLTIP :{BLACK}이 회사 지분의 25%를 매도합니다. SHIFT+클릭으로 예상 매도 가격을 볼 수 있습니다 STR_COMPANY_VIEW_COMPANY_NAME_QUERY_CAPTION :회사 이름 STR_COMPANY_VIEW_PRESIDENT_S_NAME_QUERY_CAPTION :사장 이름 @@ -3356,8 +3386,7 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}{COMPANY STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}철도 기반시설: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}신호기 STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}도로 기반시설: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}도로 -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}전찻길 +STR_COMPANY_INFRASTRUCTURE_VIEW_TRAM_SECT :{GOLD}전찻길: STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}해운 기반시설: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}운하 STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}정거장 시설: @@ -3368,16 +3397,23 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}산업시설 STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}(없음) -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% 운반됨) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}%가 각각 운반됨) +STR_INDUSTRY_DIRECTORY_ITEM_INFO :{BLACK}{CARGO_LONG}{STRING}{YELLOW} ({COMMA}% 수송됨){BLACK} STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} -STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}산업시설 이름 - 산업시설로 시점을 변경하려면 클릭하세요. CTRL+클릭하면 이 산업시설의 위치를 기준으로 새로운 외부 화면을 엽니다. +STR_INDUSTRY_DIRECTORY_ITEM_PROD1 :{ORANGE}{INDUSTRY} {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PROD2 :{ORANGE}{INDUSTRY} {STRING}, {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PROD3 :{ORANGE}{INDUSTRY} {STRING}, {STRING}, {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PRODMORE :{ORANGE}{INDUSTRY} {STRING}, {STRING}, {STRING} 및 {NUM}종의 화물 +STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}산업시설 이름 - 산업시설로 이동하려면 이름을 클릭하세요. CTRL+클릭하면 이 산업시설의 위치를 기준으로 새로운 외부 화면을 엽니다 +STR_INDUSTRY_DIRECTORY_ACCEPTED_CARGO_FILTER :{BLACK}받는 화물: {SILVER}{STRING} +STR_INDUSTRY_DIRECTORY_PRODUCED_CARGO_FILTER :{BLACK}생산 화물: {SILVER}{STRING} +STR_INDUSTRY_DIRECTORY_FILTER_ALL_TYPES :모든 화물 +STR_INDUSTRY_DIRECTORY_FILTER_NONE :없음 # Industry view STR_INDUSTRY_VIEW_CAPTION :{WHITE}{INDUSTRY} STR_INDUSTRY_VIEW_PRODUCTION_LAST_MONTH_TITLE :{BLACK}지난달 생산량: STR_INDUSTRY_VIEW_TRANSPORTED :{YELLOW}{CARGO_LONG}{STRING}{BLACK} ({COMMA}% 수송됨) -STR_INDUSTRY_VIEW_LOCATION_TOOLTIP :{BLACK}이 산업시설로 이동합니다. CTRL+클릭하면 이 산업시설을 기준으로 새로운 외부 화면을 엽니다. +STR_INDUSTRY_VIEW_LOCATION_TOOLTIP :{BLACK}이 산업시설로 이동합니다. CTRL+클릭하면 이 산업시설을 기준으로 새로운 외부 화면을 엽니다 STR_INDUSTRY_VIEW_PRODUCTION_LEVEL :{BLACK}생산 수준: {YELLOW}{COMMA}% STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE :{YELLOW}산업시설이 곧 폐쇄됩니다! @@ -3387,7 +3423,7 @@ STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{STRI STR_INDUSTRY_VIEW_REQUIRES :{BLACK}받는 화물: STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING} -STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} 대기중{STRING} +STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} 대기 중{STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}생산량 변경 (8의 배수, 최대 2040) STR_CONFIG_GAME_PRODUCTION_LEVEL :{WHITE}생산 등급 변경 (퍼센트, 800%까지) @@ -3398,21 +3434,21 @@ STR_VEHICLE_LIST_ROAD_VEHICLE_CAPTION :{WHITE}{STRING} STR_VEHICLE_LIST_SHIP_CAPTION :{WHITE}{STRING} - {COMMA}대의 선박 STR_VEHICLE_LIST_AIRCRAFT_CAPTION :{WHITE}{STRING} - {COMMA}대의 항공기 -STR_VEHICLE_LIST_TRAIN_LIST_TOOLTIP :{BLACK}열차 - 열차 정보를 보려면 클릭 -STR_VEHICLE_LIST_ROAD_VEHICLE_TOOLTIP :{BLACK}차량 - 자세히 보려면 클릭 -STR_VEHICLE_LIST_SHIP_TOOLTIP :{BLACK}선박 - 선박의 정보를 보려면 클릭하세요. -STR_VEHICLE_LIST_AIRCRAFT_TOOLTIP :{BLACK}항공기 - 항공기 정보를 보려면 클릭하세요. +STR_VEHICLE_LIST_TRAIN_LIST_TOOLTIP :{BLACK}열차 - 열차의 정보를 보려면 클릭하세요 +STR_VEHICLE_LIST_ROAD_VEHICLE_TOOLTIP :{BLACK}차량 - 차량의 정보를 보려면 클릭하세요 +STR_VEHICLE_LIST_SHIP_TOOLTIP :{BLACK}선박 - 선박의 정보를 보려면 클릭하세요 +STR_VEHICLE_LIST_AIRCRAFT_TOOLTIP :{BLACK}항공기 - 항공기 정보를 보려면 클릭하세요 -STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}올해 수입: {CURRENCY_LONG} (작년: {CURRENCY_LONG}) +STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}올해 이익: {CURRENCY_LONG} (작년: {CURRENCY_LONG}) -STR_VEHICLE_LIST_AVAILABLE_TRAINS :사용 가능 열차 +STR_VEHICLE_LIST_AVAILABLE_TRAINS :사용 가능한 열차 STR_VEHICLE_LIST_AVAILABLE_ROAD_VEHICLES :사용 가능한 차량 -STR_VEHICLE_LIST_AVAILABLE_SHIPS :사용 가능 선박 -STR_VEHICLE_LIST_AVAILABLE_AIRCRAFT :사용 가능 항공기 -STR_VEHICLE_LIST_AVAILABLE_ENGINES_TOOLTIP :{BLACK}이 차량 타입에 사용할 수 있는 기관차의 목록 보기 +STR_VEHICLE_LIST_AVAILABLE_SHIPS :사용 가능한 선박 +STR_VEHICLE_LIST_AVAILABLE_AIRCRAFT :사용 가능한 항공기 +STR_VEHICLE_LIST_AVAILABLE_ENGINES_TOOLTIP :{BLACK}이 차량 종류에 사용할 수 있는 기관차의 목록을 봅니다 STR_VEHICLE_LIST_MANAGE_LIST :{BLACK}관리 -STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}이 목록에 있는 모든 열차에게 지시 +STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}이 목록에 있는 모든 열차에 지시를 내려 관리합니다 STR_VEHICLE_LIST_REPLACE_VEHICLES :차량 교체 STR_VEHICLE_LIST_SEND_FOR_SERVICING :정비하러 보내기 @@ -3421,8 +3457,8 @@ STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :차고지로 STR_VEHICLE_LIST_SEND_SHIP_TO_DEPOT :정박소로 보내기 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_MASS_STOP_LIST_TOOLTIP :{BLACK}이 목록에 있는 모든 차량의 운행을 중지합니다 +STR_VEHICLE_LIST_MASS_START_LIST_TOOLTIP :{BLACK}이 목록에 있는 모든 차량의 운행을 시작합니다 STR_VEHICLE_LIST_SHARED_ORDERS_LIST_CAPTION :{WHITE}경로를 공유 중인 차량 {COMMA}대 @@ -3437,12 +3473,14 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :그룹에 속 STR_GROUP_DEFAULT_SHIPS :그룹에 속하지 않은 선박 STR_GROUP_DEFAULT_AIRCRAFTS :그룹에 속하지 않은 항공기 -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_GROUP_COUNT_WITH_SUBGROUP :{TINY_FONT}{COMMA} (+{COMMA}) + +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}그룹 삭제 STR_GROUP_DELETE_QUERY_TEXT :{WHITE}이 그룹과 하위 그룹을 정말 삭제하시겠습니까? @@ -3452,8 +3490,8 @@ STR_GROUP_REMOVE_ALL_VEHICLES :모든 차량 STR_GROUP_RENAME_CAPTION :{BLACK}그룹 이름 설정 -STR_GROUP_PROFIT_THIS_YEAR :올해 수익: -STR_GROUP_PROFIT_LAST_YEAR :작년 수익: +STR_GROUP_PROFIT_THIS_YEAR :올해 이익: +STR_GROUP_PROFIT_LAST_YEAR :작년 이익: STR_GROUP_OCCUPANCY :현재 사용량: STR_GROUP_OCCUPANCY_VALUE :{NUM}% @@ -3463,12 +3501,18 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :새 전기 열 STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :새 모노레일 열차 STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :새 자기부상열차 +STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :새 자동차 +STR_BUY_VEHICLE_TRAM_VEHICLE_CAPTION :새 전차 차량 + +############ range for vehicle availability starts STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :새 열차 -STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :새 차량 +STR_BUY_VEHICLE_ROAD_VEHICLE_ALL_CAPTION :새 차량 STR_BUY_VEHICLE_SHIP_CAPTION :새 선박 STR_BUY_VEHICLE_AIRCRAFT_CAPTION :새 항공기 +############ range for vehicle availability ends 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} @@ -3479,8 +3523,10 @@ STR_PURCHASE_INFO_REFITTABLE :(개조 가능) STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}개발: {GOLD}{NUM}{BLACK} 수명: {GOLD}{COMMA}년 STR_PURCHASE_INFO_RELIABILITY :{BLACK}최고 신뢰도: {GOLD}{COMMA}% STR_PURCHASE_INFO_COST :{BLACK}가격: {GOLD}{CURRENCY_LONG} +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} @@ -3488,33 +3534,43 @@ STR_PURCHASE_INFO_ALL_TYPES :모든 화물 STR_PURCHASE_INFO_NONE :없음 STR_PURCHASE_INFO_ALL_BUT :{CARGO_LIST} 이외의 모든 화물 STR_PURCHASE_INFO_MAX_TE :{BLACK}최고 견인력: {GOLD}{FORCE} -STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}항속거리: {GOLD}{COMMA} 칸 +STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}항속거리: {GOLD}{COMMA}칸 STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}항공기 종류: {GOLD}{STRING} -STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}열차 차량 구매 목록입니다. 차량의 정보를 보려면 클릭하세요. CTRL + 클릭하면 해당 차량을 숨김/표시 처리할 수 있습니다. -STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}자동차/전차 구매 목록입니다. 차량의 정보를 보려면 클릭하세요. CTRL + 클릭하면 해당 차량을 숨김/표시 처리할 수 있습니다. -STR_BUY_VEHICLE_SHIP_LIST_TOOLTIP :{BLACK}선박 구매 목록입니다. 선박의 정보를 보려면 선박을 클릭하세요. CTRL + 클릭하면 해당 선박을 숨김/표시 처리할 수 있습니다. -STR_BUY_VEHICLE_AIRCRAFT_LIST_TOOLTIP :{BLACK}항공기 구매 목록입니다. 항공기의 정보를 보려면 클릭하세요. CTRL + 클릭하면 해당 항공기를 숨김/표시 처리할 수 있습니다. +STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}열차 차량 구매 목록입니다. 차량의 정보를 보려면 클릭하세요. CTRL+클릭하면 해당 차량을 숨김/표시 처리할 수 있습니다 +STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}차량 구매 목록입니다. 차량의 정보를 보려면 클릭하세요. CTRL+클릭하면 해당 차량을 숨김/표시 처리할 수 있습니다 +STR_BUY_VEHICLE_SHIP_LIST_TOOLTIP :{BLACK}선박 구매 목록입니다. 선박의 정보를 보려면 선박을 클릭하세요. CTRL+클릭하면 해당 선박을 숨김/표시 처리할 수 있습니다 +STR_BUY_VEHICLE_AIRCRAFT_LIST_TOOLTIP :{BLACK}항공기 구매 목록입니다. 항공기의 정보를 보려면 클릭하세요. CTRL+클릭하면 해당 항공기를 숨김/표시 처리할 수 있습니다 STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_BUTTON :{BLACK}차량 구입 STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}차량 구입 STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}선박 구입 STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}항공기 구입 -STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}선택된 차량을 구입합니다. SHIFT+클릭으로 예상 구입 비용을 볼 수 있습니다. -STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}선택한 차량을 구입합니다. Shift+클릭하면 예상 구입 비용을 볼 수 있습니다. -STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}선택한 선박을 구입합니다. SHIFT+클릭으로 예상 구입 비용을 볼 수 있습니다. -STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}선택한 항공기를 구입합니다. SHIFT+클릭으로 예상 구입 비용을 볼 수 있습니다. +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_BUTTON :{BLACK}차량 구입 및 개조 +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_BUTTON :{BLACK}차량 구입 및 개조 +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_BUTTON :{BLACK}선박 구입 및 개조 +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_BUTTON :{BLACK}항공기 구입 및 개조 -STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}이름 +STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}선택된 차량을 구입합니다. SHIFT+클릭으로 예상 구입 비용을 볼 수 있습니다. +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}선택한 차량을 구입합니다. SHIFT+클릭하면 예상 구입 비용을 볼 수 있습니다 +STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}선택한 선박을 구입합니다. SHIFT+클릭으로 예상 구입 비용을 볼 수 있습니다 +STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}선택한 항공기를 구입합니다. SHIFT+클릭으로 예상 구입 비용을 볼 수 있습니다 + +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}선택한 차량을 구입하고 개조합니다. SHIFT+클릭하면 예상 비용을 볼 수 있습니다 +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}선택한 자동차를 구입하고 개조합니다. SHIFT+클릭하면 예상 비용을 볼 수 있습니다 +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}선택한 선박을 구입하고 개조합니다. SHIFT+클릭하면 예상 비용을 볼 수 있습니다 +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}선택한 항공기를 구입하고 개조합니다. SHIFT+클릭하면 예상 비용을 볼 수 있습니다 + +STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}이름 지정 STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}이름 지정 STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}이름 지정 STR_BUY_VEHICLE_AIRCRAFT_RENAME_BUTTON :{BLACK}이름 지정 -STR_BUY_VEHICLE_TRAIN_RENAME_TOOLTIP :{BLACK}열차의 차량 이름을 변경합니다. -STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_TOOLTIP :{BLACK}차량의 차종명을 변경합니다. -STR_BUY_VEHICLE_SHIP_RENAME_TOOLTIP :{BLACK}선박의 차량 이름을 변경합니다. -STR_BUY_VEHICLE_AIRCRAFT_RENAME_TOOLTIP :{BLACK}항공기의 차량 이름을 변경합니다. +STR_BUY_VEHICLE_TRAIN_RENAME_TOOLTIP :{BLACK}열차의 모델명을 변경합니다 +STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_TOOLTIP :{BLACK}차종의 이름을 변경합니다. +STR_BUY_VEHICLE_SHIP_RENAME_TOOLTIP :{BLACK}선박의 모델명을 변경합니다 +STR_BUY_VEHICLE_AIRCRAFT_RENAME_TOOLTIP :{BLACK}항공기의 모델명을 변경합니다 STR_BUY_VEHICLE_TRAIN_HIDE_TOGGLE_BUTTON :{BLACK}숨김 STR_BUY_VEHICLE_ROAD_VEHICLE_HIDE_TOGGLE_BUTTON :{BLACK}숨김 @@ -3526,20 +3582,20 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_SHOW_TOGGLE_BUTTON :{BLACK}보이 STR_BUY_VEHICLE_SHIP_SHOW_TOGGLE_BUTTON :{BLACK}보이기 STR_BUY_VEHICLE_AIRCRAFT_SHOW_TOGGLE_BUTTON :{BLACK}보이기 -STR_BUY_VEHICLE_TRAIN_HIDE_SHOW_TOGGLE_TOOLTIP :{BLACK}숨김 처리한 열차 차량을 목록에 보여주거나 숨깁니다. -STR_BUY_VEHICLE_ROAD_VEHICLE_HIDE_SHOW_TOGGLE_TOOLTIP :{BLACK}숨김 처리한 자동차/전차 차량을 목록에 보여주거나 숨깁니다. -STR_BUY_VEHICLE_SHIP_HIDE_SHOW_TOGGLE_TOOLTIP :{BLACK}숨김 처리한 선박을 목록에 보여주거나 숨깁니다. -STR_BUY_VEHICLE_AIRCRAFT_HIDE_SHOW_TOGGLE_TOOLTIP :{BLACK}숨김 처리한 항공기를 목록에 보여주거나 숨깁니다. +STR_BUY_VEHICLE_TRAIN_HIDE_SHOW_TOGGLE_TOOLTIP :{BLACK}숨김 처리한 열차 모델을 목록에 보여주거나 숨깁니다 +STR_BUY_VEHICLE_ROAD_VEHICLE_HIDE_SHOW_TOGGLE_TOOLTIP :{BLACK}숨김 처리한 차량 모델을 목록에 보여주거나 숨깁니다 +STR_BUY_VEHICLE_SHIP_HIDE_SHOW_TOGGLE_TOOLTIP :{BLACK}숨김 처리한 선박 모델을 목록에 보여주거나 숨깁니다 +STR_BUY_VEHICLE_AIRCRAFT_HIDE_SHOW_TOGGLE_TOOLTIP :{BLACK}숨김 처리한 항공기 모델을 목록에 보여주거나 숨깁니다 -STR_QUERY_RENAME_TRAIN_TYPE_CAPTION :{WHITE}열차의 차량 이름을 변경합니다. -STR_QUERY_RENAME_ROAD_VEHICLE_TYPE_CAPTION :{WHITE}차종명을 변경합니다. -STR_QUERY_RENAME_SHIP_TYPE_CAPTION :{WHITE}선박의 차량 이름을 변경합니다. -STR_QUERY_RENAME_AIRCRAFT_TYPE_CAPTION :{WHITE}항공기의 차량 이름을 변경합니다. +STR_QUERY_RENAME_TRAIN_TYPE_CAPTION :{WHITE}열차의 모델명을 변경합니다 +STR_QUERY_RENAME_ROAD_VEHICLE_TYPE_CAPTION :{WHITE}차종 이름을 변경합니다. +STR_QUERY_RENAME_SHIP_TYPE_CAPTION :{WHITE}선박의 모델명을 변경합니다 +STR_QUERY_RENAME_AIRCRAFT_TYPE_CAPTION :{WHITE}항공기의 모델명을 변경합니다 # Depot window STR_DEPOT_CAPTION :{WHITE}{DEPOT} -STR_DEPOT_RENAME_TOOLTIP :{BLACK}이 차량기지의 이름을 변경합니다. +STR_DEPOT_RENAME_TOOLTIP :{BLACK}이 차량기지의 이름을 변경합니다 STR_DEPOT_RENAME_DEPOT_CAPTION :차량기지 이름 변경 STR_DEPOT_NO_ENGINE :{BLACK}- @@ -3547,80 +3603,85 @@ STR_DEPOT_VEHICLE_TOOLTIP :{BLACK}{ENGINE} STR_DEPOT_VEHICLE_TOOLTIP_CHAIN :{BLACK}차량 {NUM}대{STRING} STR_DEPOT_VEHICLE_TOOLTIP_CARGO :{}{CARGO_LONG} ({CARGO_SHORT}) -STR_DEPOT_TRAIN_LIST_TOOLTIP :{BLACK}열차 - 열차에 차량을 추가하거나 제거하려면 차량을 왼쪽 클릭으로 드래그하시고, 열차 정보를 보려면 오른쪽 클릭하십시오. 두 기능을 해당 차량 뒤에 딸려오는 차량에 적용하고 싶다면 CTRL 키를 누르고 계십시오. -STR_DEPOT_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}차량을 오른쪽 클릭하면 해당 차량의 간단한 정보를 볼 수 있습니다. -STR_DEPOT_SHIP_LIST_TOOLTIP :{BLACK}선박 - 선박의 정보를 보려면 오른쪽 클릭하세요. -STR_DEPOT_AIRCRAFT_LIST_TOOLTIP :{BLACK}항공기 - 항공기의 정보를 보려면 오른쪽 클릭하세요. +STR_DEPOT_TRAIN_LIST_TOOLTIP :{BLACK}열차 - 열차에 차량을 추가하거나 제거하려면 차량을 왼쪽 클릭으로 드래그하시고, 열차 정보를 보려면 오른쪽 클릭하십시오. 두 기능을 해당 차량 뒤에 딸려오는 차량에 적용하고 싶다면 CTRL 키를 누르고 계십시오 +STR_DEPOT_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}차량 - 차량의 정보를 보려면 오른쪽 클릭하세요 +STR_DEPOT_SHIP_LIST_TOOLTIP :{BLACK}선박 - 선박의 정보를 보려면 오른쪽 클릭하세요 +STR_DEPOT_AIRCRAFT_LIST_TOOLTIP :{BLACK}항공기 - 항공기의 정보를 보려면 오른쪽 클릭하세요 -STR_DEPOT_TRAIN_SELL_TOOLTIP :{BLACK}기관차/객차/화물차 한량만 제거하려면 여기로 드래그하세요 -STR_DEPOT_ROAD_VEHICLE_SELL_TOOLTIP :{BLACK}차량을 팔려면 여기로 드래그하세요. -STR_DEPOT_SHIP_SELL_TOOLTIP :{BLACK}선박을 팔려면 여기로 드래그하세요. -STR_DEPOT_AIRCRAFT_SELL_TOOLTIP :{BLACK}항공기를 팔려면 여기로 드래그하세요. +STR_DEPOT_TRAIN_SELL_TOOLTIP :{BLACK}기관차/객차/화차 한 량만 팔려면 여기로 드래그하세요 +STR_DEPOT_ROAD_VEHICLE_SELL_TOOLTIP :{BLACK}차량을 팔려면 여기로 드래그하세요 +STR_DEPOT_SHIP_SELL_TOOLTIP :{BLACK}선박을 팔려면 여기로 드래그하세요 +STR_DEPOT_AIRCRAFT_SELL_TOOLTIP :{BLACK}항공기를 팔려면 여기로 드래그하세요 STR_DEPOT_DRAG_WHOLE_TRAIN_TO_SELL_TOOLTIP :{BLACK}열차 전체를 팔려면 기관차를 여기로 드래그하세요 -STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TOOLTIP :{BLACK}이 차량기지에 있는 모든 열차를 팝니다. -STR_DEPOT_SELL_ALL_BUTTON_ROAD_VEHICLE_TOOLTIP :{BLACK}이 차고지에 있는 모든 차량을 팝니다. -STR_DEPOT_SELL_ALL_BUTTON_SHIP_TOOLTIP :{BLACK}이 정박소에 있는 모든 선박을 팝니다. -STR_DEPOT_SELL_ALL_BUTTON_AIRCRAFT_TOOLTIP :{BLACK}이 격납고에 있는 모든 항공기를 팝니다. +STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TOOLTIP :{BLACK}이 차량기지에 있는 모든 열차를 팝니다 +STR_DEPOT_SELL_ALL_BUTTON_ROAD_VEHICLE_TOOLTIP :{BLACK}이 차고지에 있는 모든 차량을 팝니다 +STR_DEPOT_SELL_ALL_BUTTON_SHIP_TOOLTIP :{BLACK}이 정박소에 있는 모든 선박을 팝니다 +STR_DEPOT_SELL_ALL_BUTTON_AIRCRAFT_TOOLTIP :{BLACK}이 격납고에 있는 모든 항공기를 팝니다 -STR_DEPOT_AUTOREPLACE_TRAIN_TOOLTIP :{BLACK}이 차량기지에 있는 모든 열차를 자동으로 교체합니다. -STR_DEPOT_AUTOREPLACE_ROAD_VEHICLE_TOOLTIP :{BLACK}이 차고지에 있는 모든 차량을 자동으로 교체합니다. -STR_DEPOT_AUTOREPLACE_SHIP_TOOLTIP :{BLACK}이 정박소에 있는 모든 선박을 자동으로 교체합니다. -STR_DEPOT_AUTOREPLACE_AIRCRAFT_TOOLTIP :{BLACK}이 격납고에 있는 모든 항공기를 자동으로 교체합니다. +STR_DEPOT_AUTOREPLACE_TRAIN_TOOLTIP :{BLACK}이 차량기지에 있는 모든 열차를 자동으로 교체합니다 +STR_DEPOT_AUTOREPLACE_ROAD_VEHICLE_TOOLTIP :{BLACK}이 차고지에 있는 모든 차량을 자동으로 교체합니다 +STR_DEPOT_AUTOREPLACE_SHIP_TOOLTIP :{BLACK}이 정박소에 있는 모든 선박을 자동으로 교체합니다 +STR_DEPOT_AUTOREPLACE_AIRCRAFT_TOOLTIP :{BLACK}이 격납고에 있는 모든 항공기를 자동으로 교체합니다 STR_DEPOT_TRAIN_NEW_VEHICLES_BUTTON :{BLACK}새 열차 STR_DEPOT_ROAD_VEHICLE_NEW_VEHICLES_BUTTON :{BLACK}새 차량 STR_DEPOT_SHIP_NEW_VEHICLES_BUTTON :{BLACK}새 선박 STR_DEPOT_AIRCRAFT_NEW_VEHICLES_BUTTON :{BLACK}새 항공기 -STR_DEPOT_TRAIN_NEW_VEHICLES_TOOLTIP :{BLACK}새 열차를 구입합니다. -STR_DEPOT_ROAD_VEHICLE_NEW_VEHICLES_TOOLTIP :{BLACK}새 차량을 구입합니다. -STR_DEPOT_SHIP_NEW_VEHICLES_TOOLTIP :{BLACK}새 선박을 구입합니다. -STR_DEPOT_AIRCRAFT_NEW_VEHICLES_TOOLTIP :{BLACK}새 항공기를 구입합니다. +STR_DEPOT_TRAIN_NEW_VEHICLES_TOOLTIP :{BLACK}새 열차를 구입합니다 +STR_DEPOT_ROAD_VEHICLE_NEW_VEHICLES_TOOLTIP :{BLACK}새 차량을 구입합니다 +STR_DEPOT_SHIP_NEW_VEHICLES_TOOLTIP :{BLACK}새 선박을 구입합니다 +STR_DEPOT_AIRCRAFT_NEW_VEHICLES_TOOLTIP :{BLACK}새 항공기를 구입합니다 STR_DEPOT_CLONE_TRAIN :{BLACK}열차 복제 STR_DEPOT_CLONE_ROAD_VEHICLE :{BLACK}차량 복제 STR_DEPOT_CLONE_SHIP :{BLACK}선박 복제 STR_DEPOT_CLONE_AIRCRAFT :{BLACK}항공기 복제 -STR_DEPOT_CLONE_TRAIN_DEPOT_INFO :{BLACK}객차/화차를 포함한 열차 전체를 복제합니다. 이 버튼을 클릭하고 차량기지 안이나 밖에 있는 열차를 클릭하십시오. CTRL+클릭하면 경로를 같이 공유합니다. -STR_DEPOT_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}차량을 복제합니다. 이 버튼을 클릭하고 차고지 안이나 밖에 있는 차량을 클릭하십시오. CTRL+클릭하면 경로도 함께 공유합니다. -STR_DEPOT_CLONE_SHIP_DEPOT_INFO :{BLACK}선박을 복제합니다. 이 버튼을 누르고 정류소의 안이나 밖에 있는 선박을 클릭하십시오. CTRL+클릭하면 경로를 같이 공유합니다. -STR_DEPOT_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}항공기를 복제합니다. 격납고 안이나 밖에 있는 항공기를 선택하십시오. CTRL+클릭하면 경로를 같이 공유합니다. +STR_DEPOT_CLONE_TRAIN_DEPOT_INFO :{BLACK}객차/화차를 포함한 열차 전체를 복제합니다. 이 버튼을 클릭하고 차량기지 안이나 밖에 있는 열차를 클릭하십시오. CTRL+클릭하면 경로를 같이 공유합니다 +STR_DEPOT_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}차량을 복제합니다. 이 버튼을 클릭하고 차고지 안이나 밖에 있는 열차를 클릭하십시오. CTRL+클릭하면 경로를 같이 공유합니다 +STR_DEPOT_CLONE_SHIP_DEPOT_INFO :{BLACK}선박을 복제합니다. 이 버튼을 누르고 정류소의 안이나 밖에 있는 선박을 클릭하십시오. CTRL+클릭하면 경로를 같이 공유합니다 +STR_DEPOT_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}항공기를 복제합니다. 이 버튼을 누르고 격납고의 안이나 밖에 있는 항공기를 클릭하십시오. CTRL+클릭하면 경로를 같이 공유합니다 -STR_DEPOT_TRAIN_LOCATION_TOOLTIP :{BLACK}이 차량기지로 이동합니다. CTRL+클릭하면 이 차량기지의 위치를 기준으로 새로운 외부 화면을 엽니다. -STR_DEPOT_ROAD_VEHICLE_LOCATION_TOOLTIP :{BLACK}차고지가 있는 곳으로 화면을 이동합니다. CTRL+클릭하면 이 차고지의 위치를 기준으로 외부화면 창을 띄웁니다. -STR_DEPOT_SHIP_LOCATION_TOOLTIP :{BLACK}이 정박소로 이동합니다. CTRL+클릭하면 이 정박소의 위치를 기준으로 새로운 외부 화면을 엽니다. -STR_DEPOT_AIRCRAFT_LOCATION_TOOLTIP :{BLACK}이 격납고의 위치로 시점을 이동합니다. CTRL+클릭하면 이 격납고의 위치를 기준으로 새로운 외부 화면을 엽니다. +STR_DEPOT_TRAIN_LOCATION_TOOLTIP :{BLACK}이 차량기지로 이동합니다. CTRL+클릭하면 이 차량기지의 위치를 기준으로 새로운 외부 화면을 엽니다 +STR_DEPOT_ROAD_VEHICLE_LOCATION_TOOLTIP :{BLACK}이 차고지로 이동합니다. CTRL+클릭하면 이 차고지의 위치를 기준으로 새로운 외부 화면을 엽니다 +STR_DEPOT_SHIP_LOCATION_TOOLTIP :{BLACK}이 정박소로 이동합니다. CTRL+클릭하면 이 정박소의 위치를 기준으로 새로운 외부 화면을 엽니다 +STR_DEPOT_AIRCRAFT_LOCATION_TOOLTIP :{BLACK}이 격납고로 이동합니다. CTRL+클릭하면 이 격납고의 위치를 기준으로 새로운 외부 화면을 엽니다 -STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TOOLTIP :{BLACK}이 차량기지를 거쳐가는 모든 열차의 목록을 보여줍니다. -STR_DEPOT_VEHICLE_ORDER_LIST_ROAD_VEHICLE_TOOLTIP :{BLACK}이 차고지를 거쳐가는 모든 차량의 목록을 보여줍니다. -STR_DEPOT_VEHICLE_ORDER_LIST_SHIP_TOOLTIP :{BLACK}이 정박소를 거쳐가는 모든 선박의 목록을 보여줍니다. -STR_DEPOT_VEHICLE_ORDER_LIST_AIRCRAFT_TOOLTIP :{BLACK}이 격납고를 거쳐가는 모든 항공기의 목록을 보여줍니다. +STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TOOLTIP :{BLACK}이 차량기지를 거쳐가는 모든 열차의 목록을 보여줍니다 +STR_DEPOT_VEHICLE_ORDER_LIST_ROAD_VEHICLE_TOOLTIP :{BLACK}이 차고지를 거쳐가는 모든 차량의 목록을 보여줍니다 +STR_DEPOT_VEHICLE_ORDER_LIST_SHIP_TOOLTIP :{BLACK}이 정박소를 거쳐가는 모든 선박의 목록을 보여줍니다 +STR_DEPOT_VEHICLE_ORDER_LIST_AIRCRAFT_TOOLTIP :{BLACK}이 격납고를 거쳐가는 모든 항공기의 목록을 보여줍니다 -STR_DEPOT_MASS_STOP_DEPOT_TRAIN_TOOLTIP :{BLACK}이 차량기지 안에 있는 모든 열차의 운행을 중지시킵니다. -STR_DEPOT_MASS_STOP_DEPOT_ROAD_VEHICLE_TOOLTIP :{BLACK}이 차고지 안에 있는 모든 차량의 운행을 중지시키려면 클릭하세요. -STR_DEPOT_MASS_STOP_DEPOT_SHIP_TOOLTIP :{BLACK}이 정박소 안에 있는 모든 선박의 운행을 중지시킵니다. -STR_DEPOT_MASS_STOP_HANGAR_TOOLTIP :{BLACK}이 격납고 안에 있는 모든 항공기의 운행을 중지시킵니다. +STR_DEPOT_MASS_STOP_DEPOT_TRAIN_TOOLTIP :{BLACK}클릭하면 이 차량기지 안에 있는 모든 열차의 운행을 중지합니다 +STR_DEPOT_MASS_STOP_DEPOT_ROAD_VEHICLE_TOOLTIP :{BLACK}클릭하면 이 차고지 안에 있는 모든 차량의 운행을 중지합니다 +STR_DEPOT_MASS_STOP_DEPOT_SHIP_TOOLTIP :{BLACK}클릭하면 이 정박소 안에 있는 모든 선박의 운행을 중지합니다 +STR_DEPOT_MASS_STOP_HANGAR_TOOLTIP :{BLACK}클릭하면 이 격납고 안에 있는 모든 항공기의 운행을 중지합니다 -STR_DEPOT_MASS_START_DEPOT_TRAIN_TOOLTIP :{BLACK}이 차량기지 안에 있는 모든 열차의 운행을 시작합니다. -STR_DEPOT_MASS_START_DEPOT_ROAD_VEHICLE_TOOLTIP :{BLACK}이 차고지 안에 있는 모든 차량의 운행을 시작하려면 클릭하세요. -STR_DEPOT_MASS_START_DEPOT_SHIP_TOOLTIP :{BLACK}이 정박소 안에 있는 모든 선박의 운행을 시작합니다. -STR_DEPOT_MASS_START_HANGAR_TOOLTIP :{BLACK}이 격납고 안에 있는 모든 항공기의 운행을 시작합니다. +STR_DEPOT_MASS_START_DEPOT_TRAIN_TOOLTIP :{BLACK}이 차량기지 안에 있는 모든 열차의 운행을 시작합니다 +STR_DEPOT_MASS_START_DEPOT_ROAD_VEHICLE_TOOLTIP :{BLACK}이 차고지 안에 있는 모든 차량의 운행을 시작합니다 +STR_DEPOT_MASS_START_DEPOT_SHIP_TOOLTIP :{BLACK}이 정박소 안에 있는 모든 선박의 운행을 시작합니다 +STR_DEPOT_MASS_START_HANGAR_TOOLTIP :{BLACK}이 격납고 안에 있는 모든 항공기의 운행을 시작합니다 STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}이 안에 있는 모든 차량을 판매하려고 합니다. 계속하시겠습니까? # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}차량 개발자로부터의 메시지 STR_ENGINE_PREVIEW_MESSAGE :{GOLD}저희는 이제 막 새로운 {STRING}{G 0 "을" "를"} 개발했습니다. 1년 먼저 이 차량을 사용하셔서 모두에게 공개되기 전에 잘 작동하는지 확인해주시겠습니까? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :{G=f}철도 기관차 -STR_ENGINE_PREVIEW_ROAD_VEHICLE :{G=f}자동차/전차 -STR_ENGINE_PREVIEW_AIRCRAFT :{G=f}항공기 -STR_ENGINE_PREVIEW_SHIP :{G=m}선박 +STR_ENGINE_PREVIEW_ELRAIL_LOCOMOTIVE :{G=f}전기선로 기관차 STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :{G=f}모노레일 기관차 STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :{G=f}자기부상열차 +STR_ENGINE_PREVIEW_ROAD_VEHICLE :{G=f}자동차 +STR_ENGINE_PREVIEW_TRAM_VEHICLE :{G=f}전차 + +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_MAX_SPEED_CAP_RUNCOST :{BLACK}가격: {CURRENCY_LONG} 최고 속력: {VELOCITY}{}수송량: {CARGO_LONG}{}유지비: {CURRENCY_LONG}/년 @@ -3637,12 +3698,12 @@ STR_REPLACE_VEHICLE_SHIP :{G=m}선박 STR_REPLACE_VEHICLE_AIRCRAFT :{G=f}항공기 STR_REPLACE_VEHICLE_VEHICLES_IN_USE :{YELLOW}사용 중인 차량 -STR_REPLACE_VEHICLE_VEHICLES_IN_USE_TOOLTIP :{BLACK}이 열은 현재 사용 중인 차량 목록입니다. +STR_REPLACE_VEHICLE_VEHICLES_IN_USE_TOOLTIP :{BLACK}이 열은 현재 보유하고 있는 차량 목록입니다 STR_REPLACE_VEHICLE_AVAILABLE_VEHICLES :{YELLOW}교체할 수 있는 차량 -STR_REPLACE_VEHICLE_AVAILABLE_VEHICLES_TOOLTIP :{BLACK}이 열은 교체할 수 있는 차량 목록입니다. +STR_REPLACE_VEHICLE_AVAILABLE_VEHICLES_TOOLTIP :{BLACK}이 열은 교체할 수 있는 차량 목록입니다 -STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}교체할 기관차 종류를 선택하십시오. -STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}새로 교체될 기관차를 선택하십시오. +STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}교체할 기관차 종류를 선택하십시오 +STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}새로 교체될 기관차를 선택하십시오 STR_REPLACE_VEHICLES_START :{BLACK}차량 교체 시작 STR_REPLACE_VEHICLES_NOW :모든 차량을 지금 교체 @@ -3650,62 +3711,67 @@ STR_REPLACE_VEHICLES_WHEN_OLD :오래된 차 STR_REPLACE_HELP_START_BUTTON :{BLACK}왼쪽에서 선택한 기관차를 오른쪽의 새 기관차로 교체하려면 누르세요 STR_REPLACE_NOT_REPLACING :{BLACK}교체 안 됨 STR_REPLACE_NOT_REPLACING_VEHICLE_SELECTED :{BLACK}차량이 선택되지 않았음 -STR_REPLACE_REPLACING_WHEN_OLD :낡으면 {ENGINE}(으)로 교체 +STR_REPLACE_REPLACING_WHEN_OLD :낡으면 {ENGINE}{G 0 "으" ""}로 교체 STR_REPLACE_VEHICLES_STOP :{BLACK}차량 교체 중지 -STR_REPLACE_HELP_STOP_BUTTON :{BLACK}왼쪽에서 선택한 기관차 종류의 차량교체를 중지하려면 이 버튼을 누르세요. +STR_REPLACE_HELP_STOP_BUTTON :{BLACK}왼쪽에서 선택한 기관차의 차량교체를 중지하려면 이 버튼을 누르세요 -STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK}기관차/화물차 교체 창으로 전환합니다. +STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK}기관차/화물차 교체 창으로 전환합니다 STR_REPLACE_ENGINES :기관차 STR_REPLACE_WAGONS :화물차 STR_REPLACE_ALL_RAILTYPE :모든 철도 차량 +STR_REPLACE_ALL_ROADTYPE :모든 자동차 -STR_REPLACE_HELP_RAILTYPE :{BLACK}교체할 기관차의 철도 종류를 고르세요 -STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}왼쪽의 선택한 기관차가 어떤 기관차로 교체되고 있는지 표시합니다. +STR_REPLACE_HELP_RAILTYPE :{BLACK}교체할 기관차의 선로 종류를 고르세요 +STR_REPLACE_HELP_ROADTYPE :{BLACK}교체할 차량이 속한 도로 종류를 고르세요 +STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}왼쪽의 선택한 기관차가 어떤 기관차로 교체되고 있는지 표시합니다 STR_REPLACE_RAIL_VEHICLES :철도 차량 STR_REPLACE_ELRAIL_VEHICLES :전기철도 차량 STR_REPLACE_MONORAIL_VEHICLES :모노레일 차량 STR_REPLACE_MAGLEV_VEHICLES :자기부상 차량 +STR_REPLACE_ROAD_VEHICLES :자동차 +STR_REPLACE_TRAM_VEHICLES :전차 차량 + STR_REPLACE_REMOVE_WAGON :{BLACK}화물차 제거: {ORANGE}{STRING} -STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}자동 교체시 열차의 길이가 교체 전보다 길어지면 앞쪽부터 화물칸를 제거하여 열차의 전체 길이가 달라지지 않도록 합니다. +STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}자동 교체시 열차의 길이가 교체 전보다 길어지면 객차/화차를 (앞쪽부터) 제거하여 열차의 전체 길이가 달라지지 않도록 합니다 # Vehicle view STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE} -STR_VEHICLE_VIEW_TRAIN_LOCATION_TOOLTIP :{BLACK}이 열차가 있는 곳으로 이동합니다. CTRL+클릭하면 이 열차를 따라갑니다. -STR_VEHICLE_VIEW_ROAD_VEHICLE_LOCATION_TOOLTIP :{BLACK}이 차량이 있는 곳으로 이동합니다. CTRL+클릭하면 이 차량을 따라갑니다. -STR_VEHICLE_VIEW_SHIP_LOCATION_TOOLTIP :{BLACK}이 선박이 있는 곳으로 이동합니다. CTRL+클릭하면 이 선박을 따라갑니다. -STR_VEHICLE_VIEW_AIRCRAFT_LOCATION_TOOLTIP :{BLACK}이 항공기가 있는 곳으로 이동합니다. CTRL+클릭하면 이 항공기를 따라갑니다. +STR_VEHICLE_VIEW_TRAIN_LOCATION_TOOLTIP :{BLACK}이 열차가 있는 곳으로 이동합니다. CTRL+클릭하면 이 열차를 따라갑니다 +STR_VEHICLE_VIEW_ROAD_VEHICLE_LOCATION_TOOLTIP :{BLACK}이 차량이 있는 곳으로 이동합니다. CTRL+클릭하면 이 차량을 따라갑니다 +STR_VEHICLE_VIEW_SHIP_LOCATION_TOOLTIP :{BLACK}이 선박이 있는 곳으로 이동합니다. CTRL+클릭하면 이 선박을 따라갑니다 +STR_VEHICLE_VIEW_AIRCRAFT_LOCATION_TOOLTIP :{BLACK}이 항공기가 있는 곳으로 이동합니다. CTRL+클릭하면 이 항공기를 따라갑니다 -STR_VEHICLE_VIEW_TRAIN_SEND_TO_DEPOT_TOOLTIP :{BLACK}열차를 차량기지로 보냅니다. CTRL+클릭하면 점검만 합니다. -STR_VEHICLE_VIEW_ROAD_VEHICLE_SEND_TO_DEPOT_TOOLTIP :{BLACK}차량을 차고지로 보냅니다. CTRL+클릭하면 점검만 합니다. -STR_VEHICLE_VIEW_SHIP_SEND_TO_DEPOT_TOOLTIP :{BLACK}선박을 정박소로 보냅니다. CTRL+클릭하면 정비만 합니다. -STR_VEHICLE_VIEW_AIRCRAFT_SEND_TO_DEPOT_TOOLTIP :{BLACK}항공기를 격납고로 보냅니다. CTRL+클릭하면 점검만 합니다 +STR_VEHICLE_VIEW_TRAIN_SEND_TO_DEPOT_TOOLTIP :{BLACK}열차를 차량기지로 보냅니다. CTRL+클릭하면 정비를 하러 차량기지에 들르기만 합니다 +STR_VEHICLE_VIEW_ROAD_VEHICLE_SEND_TO_DEPOT_TOOLTIP :{BLACK}차량을 차고지로 보냅니다. CTRL+클릭하면 정비를 하러 차고지에 들르기만 합니다 +STR_VEHICLE_VIEW_SHIP_SEND_TO_DEPOT_TOOLTIP :{BLACK}선박을 정박소로 보냅니다. CTRL+클릭하면 정비를 하러 정박소에 들르기만 합니다 +STR_VEHICLE_VIEW_AIRCRAFT_SEND_TO_DEPOT_TOOLTIP :{BLACK}항공기를 격납고로 보냅니다. CTRL+클릭하면 정비를 하러 격납고에 들르기만 합니다 -STR_VEHICLE_VIEW_CLONE_TRAIN_INFO :{BLACK}객차/화차를 포함한 열차 전체를 복제합니다. CTRL+클릭하면 경로도 함께 공유됩니다. -STR_VEHICLE_VIEW_CLONE_ROAD_VEHICLE_INFO :{BLACK}차량을 복제합니다. CTRL+클릭하면 경로도 함께 공유됩니다. -STR_VEHICLE_VIEW_CLONE_SHIP_INFO :{BLACK}선박을 복제합니다. CTRL+클릭하면 경로도 함께 공유됩니다. -STR_VEHICLE_VIEW_CLONE_AIRCRAFT_INFO :{BLACK}항공기를 복제합니다. CTRL+클릭하면 경로도 함께 공유됩니다. +STR_VEHICLE_VIEW_CLONE_TRAIN_INFO :{BLACK}객차/화차를 포함한 열차 전체를 복제합니다. CTRL+클릭하면 경로도 함께 공유됩니다. SHIFT+클릭하면 예상 비용을 볼 수 있습니다 +STR_VEHICLE_VIEW_CLONE_ROAD_VEHICLE_INFO :{BLACK}차량을 복제합니다. CTRL+클릭하면 경로도 함께 공유됩니다. SHIFT+클릭하면 예상 비용을 볼 수 있습니다 +STR_VEHICLE_VIEW_CLONE_SHIP_INFO :{BLACK}선박을 복제합니다. CTRL+클릭하면 경로도 함께 공유됩니다. SHIFT+클릭하면 예상 비용을 볼 수 있습니다 +STR_VEHICLE_VIEW_CLONE_AIRCRAFT_INFO :{BLACK}항공기를 복제합니다. CTRL+클릭하면 경로도 함께 공유됩니다. SHIFT+클릭하면 예상 비용을 볼 수 있습니다 -STR_VEHICLE_VIEW_TRAIN_IGNORE_SIGNAL_TOOLTIP :{BLACK}신호를 무시하고 열차를 진행시킵니다. +STR_VEHICLE_VIEW_TRAIN_IGNORE_SIGNAL_TOOLTIP :{BLACK}신호를 무시하고 열차를 진행시킵니다 -STR_VEHICLE_VIEW_TRAIN_REFIT_TOOLTIP :{BLACK}다른 종류의 화물을 실을 수 있도록 열차를 개조 -STR_VEHICLE_VIEW_ROAD_VEHICLE_REFIT_TOOLTIP :{BLACK}차량이 다른 종류의 화물을 싣을 수 있도록 개조합니다. -STR_VEHICLE_VIEW_SHIP_REFIT_TOOLTIP :{BLACK}이 선박이 다른 종류의 화물을 실을 수 있도록 개조합니다. -STR_VEHICLE_VIEW_AIRCRAFT_REFIT_TOOLTIP :{BLACK}이 항공기가 다른 종류의 화물을 실을 수 있도록 개조합니다. +STR_VEHICLE_VIEW_TRAIN_REFIT_TOOLTIP :{BLACK}열차가 다른 종류의 화물을 실을 수 있도록 개조합니다 +STR_VEHICLE_VIEW_ROAD_VEHICLE_REFIT_TOOLTIP :{BLACK}차량이 다른 종류의 화물을 실을 수 있도록 개조합니다 +STR_VEHICLE_VIEW_SHIP_REFIT_TOOLTIP :{BLACK}선박이 다른 종류의 화물을 실을 수 있도록 개조합니다 +STR_VEHICLE_VIEW_AIRCRAFT_REFIT_TOOLTIP :{BLACK}항공기가 다른 종류의 화물을 실을 수 있도록 개조합니다 -STR_VEHICLE_VIEW_TRAIN_REVERSE_TOOLTIP :{BLACK}열차를 회차시킵니다. -STR_VEHICLE_VIEW_ROAD_VEHICLE_REVERSE_TOOLTIP :{BLACK}차량을 유턴시킵니다. +STR_VEHICLE_VIEW_TRAIN_REVERSE_TOOLTIP :{BLACK}열차를 회차시킵니다 +STR_VEHICLE_VIEW_ROAD_VEHICLE_REVERSE_TOOLTIP :{BLACK}차량을 유턴시킵니다 -STR_VEHICLE_VIEW_TRAIN_ORDERS_TOOLTIP :{BLACK}열차의 경로를 보여줍니다. CTRL+클릭하면 열차의 시간표를 보여줍니다. -STR_VEHICLE_VIEW_ROAD_VEHICLE_ORDERS_TOOLTIP :{BLACK}차량의 경로를 보여줍니다. CTRL+클릭하면 차량의 시간표를 보여줍니다. -STR_VEHICLE_VIEW_SHIP_ORDERS_TOOLTIP :{BLACK}선박의 경로를 보여줍니다. CTRL+클릭하면 선박의 시간표를 보여줍니다. -STR_VEHICLE_VIEW_AIRCRAFT_ORDERS_TOOLTIP :{BLACK}항공기의 경로를 보여줍니다. CTRL+클릭하면 항공기의 시간표를 보여줍니다. +STR_VEHICLE_VIEW_TRAIN_ORDERS_TOOLTIP :{BLACK}열차의 경로를 보여줍니다. CTRL+클릭하면 열차의 시간표를 보여줍니다 +STR_VEHICLE_VIEW_ROAD_VEHICLE_ORDERS_TOOLTIP :{BLACK}차량의 경로를 보여줍니다. CTRL+클릭하면 차량의 시간표를 보여줍니다 +STR_VEHICLE_VIEW_SHIP_ORDERS_TOOLTIP :{BLACK}선박의 경로를 보여줍니다. CTRL+클릭하면 선박의 시간표를 보여줍니다 +STR_VEHICLE_VIEW_AIRCRAFT_ORDERS_TOOLTIP :{BLACK}항공기의 경로를 보여줍니다. CTRL+클릭하면 항공기의 시간표를 보여줍니다 -STR_VEHICLE_VIEW_TRAIN_SHOW_DETAILS_TOOLTIP :{BLACK}열차의 상세정보를 보여줍니다. -STR_VEHICLE_VIEW_ROAD_VEHICLE_SHOW_DETAILS_TOOLTIP :{BLACK}차량 상세정보 보기 -STR_VEHICLE_VIEW_SHIP_SHOW_DETAILS_TOOLTIP :{BLACK}선박 상세정보 보기 -STR_VEHICLE_VIEW_AIRCRAFT_SHOW_DETAILS_TOOLTIP :{BLACK}항공기 상세정보 보기 +STR_VEHICLE_VIEW_TRAIN_SHOW_DETAILS_TOOLTIP :{BLACK}열차의 상세정보를 보여줍니다 +STR_VEHICLE_VIEW_ROAD_VEHICLE_SHOW_DETAILS_TOOLTIP :{BLACK}차량의 상세정보를 보여줍니다 +STR_VEHICLE_VIEW_SHIP_SHOW_DETAILS_TOOLTIP :{BLACK}선박의 상세정보를 보여줍니다 +STR_VEHICLE_VIEW_AIRCRAFT_SHOW_DETAILS_TOOLTIP :{BLACK}항공기의 상세정보를 보여줍니다 STR_VEHICLE_VIEW_TRAIN_STATE_START_STOP_TOOLTIP :{BLACK}현재 열차 행동 - 열차를 운행/정지시키려면 클릭하세요. CTRL+클릭하면 목적지를 볼 수 있습니다. STR_VEHICLE_VIEW_ROAD_VEHICLE_STATE_START_STOP_TOOLTIP :{BLACK}현재 차량 행동 - 운행/정지시키려면 클릭하세요. CTRL+클릭하면 목적지를 볼 수 있습니다. @@ -3714,14 +3780,14 @@ STR_VEHICLE_VIEW_AIRCRAFT_STATE_START_STOP_TOOLTIP :{BLACK}현재 # Messages in the start stop button in the vehicle view STR_VEHICLE_STATUS_LOADING_UNLOADING :{LTBLUE}싣는 중 / 내리는 중 -STR_VEHICLE_STATUS_LEAVING :{LTBLUE}떠남 -STR_VEHICLE_STATUS_CRASHED :{RED}충돌!! +STR_VEHICLE_STATUS_LEAVING :{LTBLUE}출발 중 +STR_VEHICLE_STATUS_CRASHED :{RED}충돌! STR_VEHICLE_STATUS_BROKEN_DOWN :{RED}고장 STR_VEHICLE_STATUS_STOPPED :{RED}정지함 STR_VEHICLE_STATUS_TRAIN_STOPPING_VEL :{RED}멈추는 중, {VELOCITY} -STR_VEHICLE_STATUS_TRAIN_NO_POWER :{RED}기관차 없음 +STR_VEHICLE_STATUS_TRAIN_NO_POWER :{RED}동력 없음 STR_VEHICLE_STATUS_TRAIN_STUCK :{ORANGE}빈 경로 탐색중 -STR_VEHICLE_STATUS_AIRCRAFT_TOO_FAR :{ORANGE}다음 목적지가 너무 멀리 있습니다. +STR_VEHICLE_STATUS_AIRCRAFT_TOO_FAR :{ORANGE}다음 목적지가 너무 멀리 있습니다 STR_VEHICLE_STATUS_HEADING_FOR_STATION_VEL :{LTBLUE}다음 목적지: {STATION} ({VELOCITY}) STR_VEHICLE_STATUS_NO_ORDERS_VEL :{LTBLUE}경로 없음 ({VELOCITY}) @@ -3755,7 +3821,7 @@ STR_VEHICLE_INFO_MAX_SPEED_TYPE_RANGE :{BLACK}최고 STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}무게: {LTBLUE}{WEIGHT_SHORT} {BLACK}힘: {LTBLUE}{POWER}{BLACK} 최고 속력: {LTBLUE}{VELOCITY} 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 :{BLACK}올해 이익: {LTBLUE}{CURRENCY_LONG} (작년: {CURRENCY_LONG}) 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} @@ -3768,10 +3834,10 @@ STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}환승 STR_VEHICLE_DETAILS_SERVICING_INTERVAL_DAYS :{BLACK}정비 간격: {LTBLUE}{COMMA}일마다{BLACK} 마지막 정비 날짜: {LTBLUE}{DATE_LONG} STR_VEHICLE_DETAILS_SERVICING_INTERVAL_PERCENT :{BLACK}정비 간격: {LTBLUE}{COMMA}%{BLACK} 이하일 때 마지막 정비 날짜: {LTBLUE}{DATE_LONG} -STR_VEHICLE_DETAILS_INCREASE_SERVICING_INTERVAL_TOOLTIP :{BLACK}점검 기준값을 10만큼 올립니다. CTRL+클릭하면 점검 기준값을 5만큼 올립니다. -STR_VEHICLE_DETAILS_DECREASE_SERVICING_INTERVAL_TOOLTIP :{BLACK}점검 기준값을 10만큼 내립니다. CTRL+클릭하면 점검 기준값을 5만큼 내립니다. +STR_VEHICLE_DETAILS_INCREASE_SERVICING_INTERVAL_TOOLTIP :{BLACK}점검 기준값을 10만큼 올립니다. CTRL+클릭하면 점검 기준값을 5만큼 올립니다 +STR_VEHICLE_DETAILS_DECREASE_SERVICING_INTERVAL_TOOLTIP :{BLACK}점검 기준값을 10만큼 내립니다. CTRL+클릭하면 점검 기준값을 5만큼 내립니다 -STR_SERVICE_INTERVAL_DROPDOWN_TOOLTIP :{BLACK}정비 기준 설정을 변경합니다. +STR_SERVICE_INTERVAL_DROPDOWN_TOOLTIP :{BLACK}정비 기준 설정을 변경합니다 STR_VEHICLE_DETAILS_DEFAULT :기본 STR_VEHICLE_DETAILS_DAYS :날짜 STR_VEHICLE_DETAILS_PERCENT :신뢰도 @@ -3794,13 +3860,13 @@ STR_VEHICLE_DETAILS_CARGO_FROM :{LTBLUE}{CARGO_ STR_VEHICLE_DETAILS_CARGO_FROM_MULT :{LTBLUE}{CARGO_LONG} (출발지: {STATION}) (x{NUM}) STR_VEHICLE_DETAIL_TAB_CARGO :{BLACK}화물 -STR_VEHICLE_DETAILS_TRAIN_CARGO_TOOLTIP :{BLACK}현재 싣고있는 화물 정보를 보여줌 +STR_VEHICLE_DETAILS_TRAIN_CARGO_TOOLTIP :{BLACK}현재 싣고 있는 화물 정보를 보여줍니다 STR_VEHICLE_DETAIL_TAB_INFORMATION :{BLACK}정보 -STR_VEHICLE_DETAILS_TRAIN_INFORMATION_TOOLTIP :{BLACK}각 차량의 상세 정보를 보여줌 +STR_VEHICLE_DETAILS_TRAIN_INFORMATION_TOOLTIP :{BLACK}각 차량의 상세 정보를 보여줍니다 STR_VEHICLE_DETAIL_TAB_CAPACITIES :{BLACK}수용량 -STR_VEHICLE_DETAILS_TRAIN_CAPACITIES_TOOLTIP :{BLACK}각 차량의 수송량 정보를 보여줌 +STR_VEHICLE_DETAILS_TRAIN_CAPACITIES_TOOLTIP :{BLACK}각 차량의 수송량 정보를 보여줍니다 STR_VEHICLE_DETAIL_TAB_TOTAL_CARGO :{BLACK}총 화물량 -STR_VEHICLE_DETAILS_TRAIN_TOTAL_CARGO_TOOLTIP :{BLACK}각 화물 종류에 따른 총 수송량 보여줌 +STR_VEHICLE_DETAILS_TRAIN_TOTAL_CARGO_TOOLTIP :{BLACK}각 화물 종류에 따른 총 수송량을 보여줍니다 STR_VEHICLE_DETAILS_TRAIN_ARTICULATED_RV_CAPACITY :{BLACK}수송량: {LTBLUE} @@ -3811,21 +3877,21 @@ STR_REFIT_NEW_CAPACITY_COST_OF_REFIT :{BLACK}변경 STR_REFIT_NEW_CAPACITY_INCOME_FROM_REFIT :{BLACK}변경 수송량: {GOLD}{CARGO_LONG}{}{BLACK}개조시 회수되는 비용: {GREEN}{CURRENCY_LONG} STR_REFIT_NEW_CAPACITY_COST_OF_AIRCRAFT_REFIT :{BLACK}변경 수송량: {GOLD}{CARGO_LONG}, {GOLD}{CARGO_LONG}{}{BLACK}개조 비용: {RED}{CURRENCY_LONG} STR_REFIT_NEW_CAPACITY_INCOME_FROM_AIRCRAFT_REFIT :{BLACK}변경 수송량: {GOLD}{CARGO_LONG}, {GOLD}{CARGO_LONG}{}{BLACK}개조시 회수되는 비용: {GREEN}{CURRENCY_LONG} -STR_REFIT_SELECT_VEHICLES_TOOLTIP :{BLACK}개조할 차량을 선택하십시오. 마우스로 드래그하면 여러 개의 차량을 선택 가능합니다. 빈 곳을 클릭하면 전체를 선택합니다. CTRL+클릭하면 차량 전체를 선택할 수 있습니다. +STR_REFIT_SELECT_VEHICLES_TOOLTIP :{BLACK}개조할 차량을 선택하십시오. 마우스로 드래그하면 여러 개의 차량을 선택 가능합니다. 빈 곳을 클릭하면 전체를 선택합니다. CTRL+클릭하면 차량 전체를 선택할 수 있습니다 -STR_REFIT_TRAIN_LIST_TOOLTIP :{BLACK}열차가 수송할 화물의 종류를 선택하세요. -STR_REFIT_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}차량이 수송할 화물의 종류를 선택하세요. -STR_REFIT_SHIP_LIST_TOOLTIP :{BLACK}선박이 운반할 화물의 종류를 선택하십시오 -STR_REFIT_AIRCRAFT_LIST_TOOLTIP :{BLACK}이 항공기가 수송할 화물의 종류를 선택하십시오 +STR_REFIT_TRAIN_LIST_TOOLTIP :{BLACK}열차가 수송할 화물의 종류를 선택하세요 +STR_REFIT_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}차량이 수송할 화물의 종류를 선택하세요 +STR_REFIT_SHIP_LIST_TOOLTIP :{BLACK}선박이 수송할 화물의 종류를 선택하세요 +STR_REFIT_AIRCRAFT_LIST_TOOLTIP :{BLACK}항공기가 수송할 화물의 종류를 선택하세요 STR_REFIT_TRAIN_REFIT_BUTTON :{BLACK}열차 개조 STR_REFIT_ROAD_VEHICLE_REFIT_BUTTON :{BLACK}차량 개조 STR_REFIT_SHIP_REFIT_BUTTON :{BLACK}선박 개조 STR_REFIT_AIRCRAFT_REFIT_BUTTON :{BLACK}항공기 개조 -STR_REFIT_TRAIN_REFIT_TOOLTIP :{BLACK}선택된 화물을 수송하도록 열차를 개조 -STR_REFIT_ROAD_VEHICLE_REFIT_TOOLTIP :{BLACK}선택한 화물을 싣도록 차량을 개조합니다. -STR_REFIT_SHIP_REFIT_TOOLTIP :{BLACK}선택한 화물을 운반하도록 선박을 개조 +STR_REFIT_TRAIN_REFIT_TOOLTIP :{BLACK}선택된 화물을 싣도록 열차를 개조합니다 +STR_REFIT_ROAD_VEHICLE_REFIT_TOOLTIP :{BLACK}선택한 화물을 싣도록 차량를 개조합니다 +STR_REFIT_SHIP_REFIT_TOOLTIP :{BLACK}선택된 화물을 싣도록 선박을 개조합니다 STR_REFIT_AIRCRAFT_REFIT_TOOLTIP :{BLACK}선택한 화물을 싣도록 항공기를 개조합니다 # Order view @@ -3833,7 +3899,7 @@ STR_ORDERS_CAPTION :{WHITE}{VEHICLE STR_ORDERS_TIMETABLE_VIEW :{BLACK}시간표 STR_ORDERS_TIMETABLE_VIEW_TOOLTIP :{BLACK}시간표 보기 전환 -STR_ORDERS_LIST_TOOLTIP :{BLACK}이 열차의 경로 - 선택하려면 클릭하세요. CTRL+클릭하시면 그 역이 있는 장소로 이동합니다. +STR_ORDERS_LIST_TOOLTIP :{BLACK}이 열차의 경로 - 선택하려면 클릭하세요. CTRL+클릭하시면 그 역이 있는 장소로 이동합니다 STR_ORDER_INDEX :{COMMA}:{NBSP} STR_ORDER_TEXT :{STRING} {STRING} {STRING} @@ -3866,16 +3932,16 @@ STR_ORDER_REFIT :{BLACK}개조 STR_ORDER_REFIT_TOOLTIP :{BLACK}이 경로에서 열차를 어떤 화물을 받을 수 있게 개조할 것인지 선택하십시오. CTRL+클릭하면 개조 설정을 해제합니다. STR_ORDER_REFIT_AUTO :{BLACK}개조 STR_ORDER_REFIT_AUTO_TOOLTIP :{BLACK}이 경로에서 개조할 화물의 종류를 선택하세요. CTRL+클릭하면 개조 설정을 해제합니다. 개조 기능은 개조 가능한 차량에서만 사용할 수 있습니다. -STR_ORDER_DROP_REFIT_AUTO :화물 종류 고정 -STR_ORDER_DROP_REFIT_AUTO_ANY :이용가능한 화물 +STR_ORDER_DROP_REFIT_AUTO :특정 화물로 +STR_ORDER_DROP_REFIT_AUTO_ANY :이용 가능한 화물로 STR_ORDER_SERVICE :{BLACK}정비 STR_ORDER_DROP_GO_ALWAYS_DEPOT :항상 감 STR_ORDER_DROP_SERVICE_DEPOT :필요하면 정비 STR_ORDER_DROP_HALT_DEPOT :멈춤 -STR_ORDER_SERVICE_TOOLTIP :{BLACK}정비가 필요하지 않으면 이 경로를 건너뜁니다. +STR_ORDER_SERVICE_TOOLTIP :{BLACK}정비가 필요하지 않으면 이 경로를 건너뜁니다 -STR_ORDER_CONDITIONAL_VARIABLE_TOOLTIP :{BLACK}경로를 건너뛰기 위한 비교조건을 선택합니다. +STR_ORDER_CONDITIONAL_VARIABLE_TOOLTIP :{BLACK}경로를 건너뛰기 위한 비교 조건을 선택합니다 # Conditional order variables, must follow order of OrderConditionVariable enum STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE :적재율 @@ -3887,7 +3953,7 @@ STR_ORDER_CONDITIONAL_UNCONDITIONALLY :항상 STR_ORDER_CONDITIONAL_REMAINING_LIFETIME :남은 수명 (년) STR_ORDER_CONDITIONAL_MAX_RELIABILITY :최대 신뢰도 -STR_ORDER_CONDITIONAL_COMPARATOR_TOOLTIP :{BLACK}왼쪽의 비교조건과 오른쪽의 입력값을 비교할 연산자를 선택합니다. +STR_ORDER_CONDITIONAL_COMPARATOR_TOOLTIP :{BLACK}왼쪽의 비교조건과 오른쪽의 입력값을 비교할 연산자를 선택합니다 STR_ORDER_CONDITIONAL_COMPARATOR_EQUALS := STR_ORDER_CONDITIONAL_COMPARATOR_NOT_EQUALS :≠ STR_ORDER_CONDITIONAL_COMPARATOR_LESS_THAN :< @@ -3897,24 +3963,24 @@ STR_ORDER_CONDITIONAL_COMPARATOR_MORE_EQUALS :≥ STR_ORDER_CONDITIONAL_COMPARATOR_IS_TRUE :이 있을 때 STR_ORDER_CONDITIONAL_COMPARATOR_IS_FALSE :이 없을 때 -STR_ORDER_CONDITIONAL_VALUE_TOOLTIP :{BLACK}비교조건에 대한 입력값입니다. -STR_ORDER_CONDITIONAL_VALUE_CAPT :{WHITE}비교할 값을 입력하세요. +STR_ORDER_CONDITIONAL_VALUE_TOOLTIP :{BLACK}비교 조건에 대한 입력값입니다 +STR_ORDER_CONDITIONAL_VALUE_CAPT :{WHITE}비교할 값을 입력하세요 STR_ORDERS_SKIP_BUTTON :{BLACK}건너뛰기 -STR_ORDERS_SKIP_TOOLTIP :{BLACK}현재 경로를 건너뜁니다, 그리고 다음 경로를 시작합니다. CTRL+클릭하면 선택한 경로로 건너뜁니다. +STR_ORDERS_SKIP_TOOLTIP :{BLACK}현재 경로를 건너뛰고, 다음 경로를 시작합니다. CTRL+클릭하면 현재 선택된 경로로 건너뜁니다 STR_ORDERS_DELETE_BUTTON :{BLACK}삭제 -STR_ORDERS_DELETE_TOOLTIP :{BLACK}선택된 경로를 삭제합니다. +STR_ORDERS_DELETE_TOOLTIP :{BLACK}선택된 경로를 삭제합니다 STR_ORDERS_DELETE_ALL_TOOLTIP :{BLACK}모든 경로 삭제 STR_ORDERS_STOP_SHARING_BUTTON :{BLACK}경로 공유 해제 -STR_ORDERS_STOP_SHARING_TOOLTIP :{BLACK}경로 공유를 해제합니다. CTRL+클릭하면 경로 공유를 해제하면서 모든 경로를 삭제합니다. +STR_ORDERS_STOP_SHARING_TOOLTIP :{BLACK}경로 공유를 해제합니다. CTRL+클릭하면 경로 공유를 해제하면서 모든 경로를 삭제합니다 STR_ORDERS_GO_TO_BUTTON :{BLACK}행선지 STR_ORDER_GO_TO_NEAREST_DEPOT :가까운 차량기지/차고지로 STR_ORDER_GO_TO_NEAREST_HANGAR :가까운 격납고로 STR_ORDER_CONDITIONAL :조건부 경로 건너뛰기 STR_ORDER_SHARE :경로 공유하기 -STR_ORDERS_GO_TO_TOOLTIP :{BLACK}선택된 경로 바로 전이나 목록 맨 끝에 새 경로를 삽입합니다. CTRL 키와 함께 누르면, 역에서는 '아무 화물이나 가득 싣기'로, 경유지에서는 '직행'으로, 차량기지에서는 '점검'으로 지정됩니다. '공유된 경로'를 클릭하거나 CTRL 키를 누르면 선택했던 차량과 이 차량의 경로를 공유하게 됩니다. 단순히 클릭하면 그 차량의 경로를 복사하기만 합니다. 차량기지를 경로에 포함시키면 이 차량은 자동 정비를 할 수 없게 됩니다. +STR_ORDERS_GO_TO_TOOLTIP :{BLACK}선택된 경로 바로 전이나 목록 맨 끝에 새 경로를 삽입합니다. CTRL 키와 함께 누르면, 역에서는 '아무 화물이나 가득 싣기'로, 경유지에서는 '직행'으로, 차량기지에서는 '점검'으로 지정됩니다. '공유된 경로'를 클릭하거나 CTRL 키를 누르면 선택했던 차량과 이 차량의 경로를 공유하게 됩니다. 단순히 클릭하면 그 차량의 경로를 복사하기만 합니다. 차량기지를 경로에 포함시키면 이 차량은 자동 정비를 할 수 없게 됩니다 STR_ORDERS_VEH_WITH_SHARED_ORDERS_LIST_TOOLTIP :{BLACK}이 경로를 공유하고 있는 모든 차량을 표시합니다. @@ -3989,7 +4055,7 @@ STR_TIMETABLE_TITLE :{WHITE}{VEHICLE STR_TIMETABLE_ORDER_VIEW :{BLACK}행선지표 STR_TIMETABLE_ORDER_VIEW_TOOLTIP :{BLACK}행선지표 창으로 전환 -STR_TIMETABLE_TOOLTIP :{BLACK}시간표 - 경로를 클릭하여 선택하세요. +STR_TIMETABLE_TOOLTIP :{BLACK}시간표 - 경로를 클릭하여 선택하세요 STR_TIMETABLE_NO_TRAVEL :운행정보 없음 STR_TIMETABLE_NOT_TIMETABLEABLE :이동 (자동; 다음 경로에 의해 시간표 작성) @@ -4009,36 +4075,36 @@ STR_TIMETABLE_TICKS :{COMMA}틱 STR_TIMETABLE_TOTAL_TIME :{BLACK}이 시간표는 완주하는데 {STRING}이 걸릴 것입니다. STR_TIMETABLE_TOTAL_TIME_INCOMPLETE :{BLACK}이 시간표를 완주하는데 최소 {STRING}이 필요합니다 (시간표가 일부만 지정됨) -STR_TIMETABLE_STATUS_ON_TIME :{BLACK}이 차량은 지금 정시운행 중입니다. +STR_TIMETABLE_STATUS_ON_TIME :{BLACK}이 차량은 지금 정시운행 중입니다 STR_TIMETABLE_STATUS_LATE :{BLACK}이 차량은 현재 {STRING} 늦게 운행하고 있습니다 STR_TIMETABLE_STATUS_EARLY :{BLACK}이 차량은 현재 {STRING} 빨리 운행하고 있습니다 -STR_TIMETABLE_STATUS_NOT_STARTED :{BLACK}이 시간표는 아직 시작되지 않았습니다. -STR_TIMETABLE_STATUS_START_AT :{BLACK}이 시간표는 {STRING}에 시작될 것입니다. +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}선택한 경로에서 소요되는 시간 값을 변경합니다 STR_TIMETABLE_CLEAR_TIME :{BLACK}시간값 초기화 -STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}선택한 경로의 시간 값을 초기화합니다. +STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}선택한 경로에서 소요되는 시간 값을 초기화합니다 STR_TIMETABLE_CHANGE_SPEED :{BLACK}속력 제한 -STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}선택한 경로의 최대 여행 속력을 제한합니다. +STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}선택한 경로의 최대 여행 속력을 제한합니다 STR_TIMETABLE_CLEAR_SPEED :{BLACK}속력 제한값 초기화 -STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}선택한 경로의 최대 여행 속력 제한값을 초기화합니다. +STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}선택한 경로의 최대 여행 속력 제한값을 초기화합니다 STR_TIMETABLE_RESET_LATENESS :{BLACK}지연 시간 초기화 -STR_TIMETABLE_RESET_LATENESS_TOOLTIP :{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}예정 소요시간 기준 -STR_TIMETABLE_EXPECTED_TOOLTIP :{BLACK}시간표 검사 기준을 도착 예정일과 도착 예정 시간 기준 중에서 선택합니다. +STR_TIMETABLE_EXPECTED_TOOLTIP :{BLACK}시간표 검사 기준을 도착 예정일과 도착 예정 시간 기준 중에서 선택합니다 STR_TIMETABLE_ARRIVAL_ABBREVIATION :도착: STR_TIMETABLE_DEPARTURE_ABBREVIATION :출발: @@ -4056,42 +4122,42 @@ STR_DATE_YEAR_TOOLTIP :{BLACK}년(年) # AI debug window STR_AI_DEBUG :{WHITE}인공지능/게임 스크립트 디버그 STR_AI_DEBUG_NAME_AND_VERSION :{BLACK}{STRING} (v{NUM}) -STR_AI_DEBUG_NAME_TOOLTIP :{BLACK}이 인공지능의 이름입니다. +STR_AI_DEBUG_NAME_TOOLTIP :{BLACK}이 인공지능의 이름입니다 STR_AI_DEBUG_SETTINGS :{BLACK}설정 -STR_AI_DEBUG_SETTINGS_TOOLTIP :{BLACK}인공지능과 관련된 설정을 변경합니다. +STR_AI_DEBUG_SETTINGS_TOOLTIP :{BLACK}인공지능과 관련된 설정을 변경합니다 STR_AI_DEBUG_RELOAD :{BLACK}인공지능 재시작 -STR_AI_DEBUG_RELOAD_TOOLTIP :{BLACK}인공지능을 종료시키고 스크립트를 다시 불러온 다음, 인공지능을 재시작합니다. -STR_AI_DEBUG_BREAK_STR_ON_OFF_TOOLTIP :{BLACK}인공지능 기록 메시지에서 중단 문구가 나타났을 때 인공지능을 중단할지 여부를 설정합니다. +STR_AI_DEBUG_RELOAD_TOOLTIP :{BLACK}인공지능을 종료시키고 스크립트를 다시 불러온 다음, 인공지능을 재시작합니다 +STR_AI_DEBUG_BREAK_STR_ON_OFF_TOOLTIP :{BLACK}인공지능 기록 메시지에서 중단 문구가 나타났을 때 인공지능을 중단할지 여부를 설정합니다 STR_AI_DEBUG_BREAK_ON_LABEL :{BLACK}중단 문구: STR_AI_DEBUG_BREAK_STR_OSKTITLE :{BLACK}중단 문구 -STR_AI_DEBUG_BREAK_STR_TOOLTIP :{BLACK}인공지능 로그 메시지가 이 문자열과 일치하면 게임을 일시 정지시킵니다. +STR_AI_DEBUG_BREAK_STR_TOOLTIP :{BLACK}인공지능 기록 메시지에 이 문자열과 일치하는 내용이 있으면 게임을 일시 정지시킵니다 STR_AI_DEBUG_MATCH_CASE :{BLACK}대소문자 구분 -STR_AI_DEBUG_MATCH_CASE_TOOLTIP :{BLACK}인공지능 기록 메시지에서 중단 문구를 검색할 때 대소문자를 구분할지 여부를 선택합니다. +STR_AI_DEBUG_MATCH_CASE_TOOLTIP :{BLACK}인공지능 기록 메시지에서 중단 문구를 검색할 때 대소문자를 구분할지 여부를 선택합니다 STR_AI_DEBUG_CONTINUE :{BLACK}계속 -STR_AI_DEBUG_CONTINUE_TOOLTIP :{BLACK}중단된 인공지능의 연산을 재개합니다. +STR_AI_DEBUG_CONTINUE_TOOLTIP :{BLACK}중단된 인공지능의 연산을 재개합니다 STR_AI_DEBUG_SELECT_AI_TOOLTIP :{BLACK}이 인공지능에서 출력된 기록 메시지를 보여줍니다. -STR_AI_GAME_SCRIPT :{G=f}{BLACK}게임 스크립트 +STR_AI_GAME_SCRIPT :{BLACK}게임 스크립트 STR_AI_GAME_SCRIPT_TOOLTIP :{BLACK}게임 스크립트 기록 체크 -STR_ERROR_AI_NO_AI_FOUND :사용할 수 있는 인공지능이 없습니다.{}따라서 이 경쟁사는 아무 것도 하지 못하는 회사입니다.{}'온라인 컨텐츠 다운로드'에서 새로운 인공지능을 다운로드받으세요. -STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}작동 중이던 스크립트 중 하나에서 오류가 발생하여 중단되었습니다. 인공지능 / 게임 스크립트 디버그 창에서 스크린샷을 찍어 스크립트 제작자에게 보고하십시오. +STR_ERROR_AI_NO_AI_FOUND :사용할 수 있는 인공지능이 없습니다.{}따라서 이 경쟁사는 아무 것도 하지 못하는 회사입니다.{}'온라인 컨텐츠 다운로드'에서 새로운 인공지능을 다운로드받으세요 +STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}작동 중이던 스크립트 중 하나에서 오류가 발생하여 중단되었습니다. 인공지능/게임 스크립트 디버그 창에서 스크린샷을 찍어 스크립트 제작자에게 보고하십시오 STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}인공지능/게임 스크립트 디버그창은 오직 서버만 사용 가능합니다 # AI configuration window STR_AI_CONFIG_CAPTION :{WHITE}인공지능 / 게임 스크립트 설정 -STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}다음에 게임을 시작할 때 이 게임 스크립트를 불러올 것입니다. +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_MOVE_UP :{BLACK}위로 이동 -STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}목록에서 선택한 인공지능의 순서를 한 칸 위로 옮깁니다. +STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}목록에서 선택한 인공지능의 순서를 한 칸 위로 옮깁니다 STR_AI_CONFIG_MOVE_DOWN :{BLACK}아래로 이동 -STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}목록에서 선택한 인공지능의 순서를 한 칸 아래로 옮깁니다. +STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}목록에서 선택한 인공지능의 순서를 한 칸 아래로 옮깁니다 -STR_AI_CONFIG_GAMESCRIPT :{G=f}{SILVER}게임 스크립트 -STR_AI_CONFIG_AI :{G=m}{SILVER}인공지능 +STR_AI_CONFIG_GAMESCRIPT :{SILVER}게임 스크립트 +STR_AI_CONFIG_AI :{SILVER}인공지능 STR_AI_CONFIG_CHANGE :{BLACK}{STRING} 선택하기 STR_AI_CONFIG_CHANGE_NONE : @@ -4099,23 +4165,31 @@ 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}인공지능의 매개 변수를 설정합니다. +STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}인공지능의 매개 변수를 설정합니다 # Available AIs window STR_AI_LIST_CAPTION :{WHITE}사용 가능한 {STRING} STR_AI_LIST_CAPTION_AI :인공지능 STR_AI_LIST_CAPTION_GAMESCRIPT :게임 스크립트 -STR_AI_LIST_TOOLTIP :{BLACK}스크립트를 선택하려면 클릭하세요. +STR_AI_LIST_TOOLTIP :{BLACK}스크립트를 선택하려면 클릭하세요 STR_AI_LIST_AUTHOR :{LTBLUE}저자: {ORANGE}{STRING} STR_AI_LIST_VERSION :{LTBLUE}버전: {ORANGE}{NUM} STR_AI_LIST_URL :{LTBLUE}주소: {ORANGE}{STRING} STR_AI_LIST_ACCEPT :{BLACK}적용 -STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}선택한 스크립트를 적용합니다. +STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}선택한 스크립트를 적용합니다 STR_AI_LIST_CANCEL :{BLACK}취소 STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}인공지능 스크립트를 바꾸지 않습니다 +STR_SCREENSHOT_CAPTION :{WHITE}스크린 샷 찍기 +STR_SCREENSHOT_SCREENSHOT :{BLACK}일반 스크린 샷 +STR_SCREENSHOT_ZOOMIN_SCREENSHOT :{BLACK}최대 확대 스크린 샷 (UI 없음) +STR_SCREENSHOT_DEFAULTZOOM_SCREENSHOT :{BLACK}기본 확대 스크린 샷 (UI 없음) +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 :인공지능 @@ -4162,34 +4236,34 @@ STR_MESSAGE_ESTIMATED_COST :{WHITE}예상 STR_MESSAGE_ESTIMATED_INCOME :{WHITE}예상 수익: {CURRENCY_LONG} # Saveload messages -STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}저장중입니다,{}끝날때까지 기다려주세요 +STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}저장 중입니다.{}끝날 때까지 기다려주세요! STR_ERROR_AUTOSAVE_FAILED :{WHITE}자동 저장 실패 -STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}드라이브를 읽을 수 없습니다. +STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}드라이브를 읽을 수 없습니다 STR_ERROR_GAME_SAVE_FAILED :{WHITE}게임 저장 실패{}{STRING} -STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}파일을 삭제할 수 없습니다. +STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}파일을 삭제할 수 없습니다 STR_ERROR_GAME_LOAD_FAILED :{WHITE}게임 불러오기 실패{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :내부 오류: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :손상된 게임 저장 파일 - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :상위 버전의 게임 저장 파일입니다 STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE :파일을 읽을 수 없습니다 STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE :파일을 쓸 수 없습니다 -STR_GAME_SAVELOAD_ERROR_DATA_INTEGRITY_CHECK_FAILED :데이터 무결성 검사 실패 +STR_GAME_SAVELOAD_ERROR_DATA_INTEGRITY_CHECK_FAILED :데이터 무결성 검사에 실패하였습니다 STR_GAME_SAVELOAD_NOT_AVAILABLE :<사용 불가능> STR_WARNING_LOADGAME_REMOVED_TRAMS :{WHITE}전차를 지원하지 않는 버전으로 게임이 저장되었습니다. 모든 전차는 제거되었습니다. # Map generation messages STR_ERROR_COULD_NOT_CREATE_TOWN :{WHITE}지도 생성이 중지되었습니다...{}... 도시를 건설할 적절한 곳이 존재하지 않습니다 -STR_ERROR_NO_TOWN_IN_SCENARIO :{WHITE}... 시나리오에 도시가 없습니다. +STR_ERROR_NO_TOWN_IN_SCENARIO :{WHITE}... 시나리오에 도시가 없습니다 -STR_ERROR_PNGMAP :{WHITE}PNG파일로부터 지형을 불러올 수 없습니다... -STR_ERROR_PNGMAP_FILE_NOT_FOUND :{WHITE}... 파일이 없습니다. -STR_ERROR_PNGMAP_IMAGE_TYPE :{WHITE}... 이미지 타입을 변경할 수 없습니다. 8 또는 24-bit의 PNG 이미지가 필요합니다. -STR_ERROR_PNGMAP_MISC :{WHITE}... 뭔가 잘못되었습니다. 죄송합니다. (손상된 파일로 추정됨) +STR_ERROR_PNGMAP :{WHITE}PNG 파일에서 지형을 불러올 수 없습니다... +STR_ERROR_PNGMAP_FILE_NOT_FOUND :{WHITE}... 파일이 없습니다 +STR_ERROR_PNGMAP_IMAGE_TYPE :{WHITE}... 이미지 타입을 변경할 수 없습니다. 8bit 또는 24bit의 PNG 이미지가 필요합니다 +STR_ERROR_PNGMAP_MISC :{WHITE}... 뭔가가 잘못되었습니다 (파일이 손상된 것으로 추정됨) -STR_ERROR_BMPMAP :{WHITE}BMP파일로부터 지형을 불러올 수 없습니다... -STR_ERROR_BMPMAP_IMAGE_TYPE :{WHITE}... 이미지 타입을 변경할 수 없습니다. +STR_ERROR_BMPMAP :{WHITE}BMP 파일에서 지형을 불러올 수 없습니다... +STR_ERROR_BMPMAP_IMAGE_TYPE :{WHITE}... 이미지 타입을 변경할 수 없습니다 -STR_ERROR_HEIGHTMAP_TOO_LARGE :{WHITE}... 이미지가 너무 큽니다. +STR_ERROR_HEIGHTMAP_TOO_LARGE :{WHITE}... 이미지가 너무 큽니다 STR_WARNING_HEIGHTMAP_SCALE_CAPTION :{WHITE}지도 크기 경고 STR_WARNING_HEIGHTMAP_SCALE_MESSAGE :{YELLOW}원본 지도의 크기를 너무 많이 조절하는 것은 좋지 않습니다. 그래도 계속하시겠습니까? @@ -4201,7 +4275,7 @@ STR_WARNING_FALLBACK_SOUNDSET :{WHITE}게임 STR_WARNING_SCREENSHOT_SIZE_CAPTION :{WHITE}대형 스크린 샷 STR_WARNING_SCREENSHOT_SIZE_MESSAGE :{YELLOW}스크린 샷의 이미지 크기는 {COMMA} x {COMMA} 픽셀이 될 것입니다. 스크린 샷을 찍는 데에는 시간이 다소 걸릴 수 있습니다. 계속하시겠습니까? -STR_MESSAGE_SCREENSHOT_SUCCESSFULLY :{WHITE}스크린 샷이 '{STRING}' 로 저장되었습니다. +STR_MESSAGE_SCREENSHOT_SUCCESSFULLY :{WHITE}스크린 샷이 '{STRING}'로 저장되었습니다 STR_ERROR_SCREENSHOT_FAILED :{WHITE}스크린 샷을 찍지 못했습니다! # Error message titles @@ -4209,18 +4283,18 @@ STR_ERROR_MESSAGE_CAPTION :{YELLOW}알림 STR_ERROR_MESSAGE_CAPTION_OTHER_COMPANY :{YELLOW}{STRING} 회사가 보낸 메시지 # Generic construction errors -STR_ERROR_OFF_EDGE_OF_MAP :{WHITE}지도 가장자리에서 너무 멉니다! -STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}지도 가장자리와 너무 가깝습니다! -STR_ERROR_NOT_ENOUGH_CASH_REQUIRES_CURRENCY :{WHITE}재정이 부족합니다 - {CURRENCY_LONG} 이(가) 필요합니다 -STR_ERROR_FLAT_LAND_REQUIRED :{WHITE}평지가 필요합니다! +STR_ERROR_OFF_EDGE_OF_MAP :{WHITE}지도 가장자리에서 너무 멉니다 +STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}지도 가장자리와 너무 가깝습니다 +STR_ERROR_NOT_ENOUGH_CASH_REQUIRES_CURRENCY :{WHITE}재정이 부족합니다 - {CURRENCY_LONG} 만큼의 돈이 필요합니다 +STR_ERROR_FLAT_LAND_REQUIRED :{WHITE}평지가 필요합니다 STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}잘못된 방향으로 땅이 기울어졌습니다 STR_ERROR_CAN_T_DO_THIS :{WHITE}그렇게 할 수 없습니다... -STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}건물을 먼저 제거하십시오. +STR_ERROR_BUILDING_MUST_BE_DEMOLISHED :{WHITE}건물을 먼저 제거해야 합니다 STR_ERROR_CAN_T_CLEAR_THIS_AREA :{WHITE}이 지역을 파괴할 수 없습니다... -STR_ERROR_SITE_UNSUITABLE :{WHITE}... 알맞지 않은 장소입니다! +STR_ERROR_SITE_UNSUITABLE :{WHITE}... 알맞지 않은 장소입니다 STR_ERROR_ALREADY_BUILT :{WHITE}... 이미 지어져있습니다 -STR_ERROR_OWNED_BY :{WHITE}... {STRING}의 소유입니다. -STR_ERROR_AREA_IS_OWNED_BY_ANOTHER :{WHITE}... 다른 회사의 소유지입니다! +STR_ERROR_OWNED_BY :{WHITE}... {STRING}의 소유입니다 +STR_ERROR_AREA_IS_OWNED_BY_ANOTHER :{WHITE}... 다른 회사의 소유지입니다 STR_ERROR_TERRAFORM_LIMIT_REACHED :{WHITE}... 지형 편집 제한에 다다랐습니다 STR_ERROR_CLEARING_LIMIT_REACHED :{WHITE}... 칸 제거 제한에 다다랐습니다 STR_ERROR_TREE_PLANT_LIMIT_REACHED :{WHITE}... 나무 심기 제한에 다다랐습니다 @@ -4230,28 +4304,28 @@ STR_ERROR_NOT_ALLOWED_WHILE_PAUSED :{WHITE}일시 # Local authority errors STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS :{WHITE}{TOWN} 지역 당국이 이 행동을 거부했습니다. -STR_ERROR_LOCAL_AUTHORITY_REFUSES_AIRPORT :{WHITE}{TOWN} 지역 당국이 이 도시에 다른 공항이 들어서는 것을 거부하였습니다! +STR_ERROR_LOCAL_AUTHORITY_REFUSES_AIRPORT :{WHITE}{TOWN} 지역 당국이 이 도시에 다른 공항이 들어서는 것을 거부하였습니다 STR_ERROR_LOCAL_AUTHORITY_REFUSES_NOISE :{WHITE}{TOWN} 지역 당국이 소음 문제로 인해 공항 건설을 거부하였습니다 -STR_ERROR_BRIBE_FAILED :{WHITE}당신의 뇌물 수수 행위가 지역 당국에 의해 발각되었습니다! +STR_ERROR_BRIBE_FAILED :{WHITE}당신의 뇌물 수수 행위가 지역 당국에 의해 발각되었습니다 # Levelling errors STR_ERROR_CAN_T_RAISE_LAND_HERE :{WHITE}이곳의 땅을 올릴 수 없습니다... STR_ERROR_CAN_T_LOWER_LAND_HERE :{WHITE}이곳의 땅을 내릴 수 없습니다... STR_ERROR_CAN_T_LEVEL_LAND_HERE :{WHITE}이 땅의 높이를 조절할 수 없습니다... -STR_ERROR_EXCAVATION_WOULD_DAMAGE :{WHITE}터널 때문에 지형을 편집할 수 없습니다. -STR_ERROR_ALREADY_AT_SEA_LEVEL :{WHITE}이미 해수면에 도달했습니다 -STR_ERROR_TOO_HIGH :{WHITE}너무 높습니다! -STR_ERROR_ALREADY_LEVELLED :{WHITE}... 이미 평평합니다. -STR_ERROR_BRIDGE_TOO_HIGH_AFTER_LOWER_LAND :{WHITE}다리가 끝나는 부분의 높이가 너무 높습니다. +STR_ERROR_EXCAVATION_WOULD_DAMAGE :{WHITE}터널 때문에 지형을 편집할 수 없습니다 +STR_ERROR_ALREADY_AT_SEA_LEVEL :{WHITE}... 이미 해수면에 도달했습니다 +STR_ERROR_TOO_HIGH :{WHITE}... 너무 높습니다 +STR_ERROR_ALREADY_LEVELLED :{WHITE}... 이미 평평합니다 +STR_ERROR_BRIDGE_TOO_HIGH_AFTER_LOWER_LAND :{WHITE}다리가 끝나는 부분의 높이가 너무 높습니다 # Company related errors STR_ERROR_CAN_T_CHANGE_COMPANY_NAME :{WHITE}회사 이름을 바꿀 수 없습니다... STR_ERROR_CAN_T_CHANGE_PRESIDENT :{WHITE}사장의 이름을 바꿀 수 없습니다... -STR_ERROR_MAXIMUM_PERMITTED_LOAN :{WHITE}... 허용된 최대 대출금은 {CURRENCY_LONG} 입니다. -STR_ERROR_CAN_T_BORROW_ANY_MORE_MONEY :{WHITE}더이상 돈을 빌릴 수 없습니다... -STR_ERROR_LOAN_ALREADY_REPAYED :{WHITE}... 값아야 할 대출금이 없습니다. -STR_ERROR_CURRENCY_REQUIRED :{WHITE}...{CURRENCY_LONG} 필요합니다. +STR_ERROR_MAXIMUM_PERMITTED_LOAN :{WHITE}... 최대로 빌릴 수 있는 대출금은 {CURRENCY_LONG} 입니다 +STR_ERROR_CAN_T_BORROW_ANY_MORE_MONEY :{WHITE}돈을 더 빌릴 수 없습니다... +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_BUY_COMPANY :{WHITE}회사를 인수할 수 없습니다... @@ -4261,159 +4335,165 @@ STR_ERROR_CAN_T_SELL_25_SHARE_IN :{WHITE}이 회 STR_ERROR_PROTECTED :{WHITE}이 회사는 지분을 거래할 수 있을 만큼 오래되지 않았습니다... # Town related errors -STR_ERROR_CAN_T_GENERATE_TOWN :{WHITE}도시를 만들 수 없습니다! +STR_ERROR_CAN_T_GENERATE_TOWN :{WHITE}도시를 만들 수 없습니다 STR_ERROR_CAN_T_RENAME_TOWN :{WHITE}도시 이름을 바꿀 수 없습니다... STR_ERROR_CAN_T_FOUND_TOWN_HERE :{WHITE}여기에 도시를 건설할 수 없습니다... STR_ERROR_CAN_T_EXPAND_TOWN :{WHITE}도시를 확장할 수 없습니다... -STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... 지도 가장자리와 너무 가깝습니다! -STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... 다른 도시와 너무 가깝습니다! -STR_ERROR_TOO_MANY_TOWNS :{WHITE}... 도시가 너무 많습니다! -STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... 지도에 더이상 공간이 없습니다! +STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... 지도 가장자리와 너무 가깝습니다 +STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... 다른 도시와 너무 가깝습니다 +STR_ERROR_TOO_MANY_TOWNS :{WHITE}... 도시가 너무 많습니다 +STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... 지도에 더 이상 공간이 없습니다 STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}도시가 도로를 짓지 않을 것입니다. [설정→환경→도시]에서 도로를 지을 수 있도록 설정을 변경하실 수 있습니다. -STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}도로 작업이 진행중입니다 +STR_ERROR_ROAD_WORKS_IN_PROGRESS :{WHITE}도로 작업이 진행 중입니다 STR_ERROR_TOWN_CAN_T_DELETE :{WHITE}이 도시를 삭제할 수 없습니다...{}도시나 도시 소유의 땅에 역, 정류장, 항구, 공항 또는 차량기지, 차고지, 정박소 등이 존재하면 도시를 삭제할 수 없습니다. -STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... 이 도시의 중심에 동상을 세우기 적합한 장소가 없습니다. +STR_ERROR_STATUE_NO_SUITABLE_PLACE :{WHITE}... 이 도시의 중심에 동상을 세우기 적합한 장소가 없습니다 # Industry related errors -STR_ERROR_TOO_MANY_INDUSTRIES :{WHITE}... 산업시설이 너무 많습니다! +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_INDUSTRY_TOO_CLOSE :{WHITE}... 다른 산업시설과 너무 가깝습니다. -STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... 도시를 먼저 만드십시오 -STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... 한 도시에 하나만 건설 가능합니다! -STR_ERROR_CAN_ONLY_BE_BUILT_IN_TOWNS_WITH_POPULATION_OF_1200 :{WHITE}... 인구 1200명 이상의 도시에만 건설할 수 있습니다! -STR_ERROR_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}... 열대우림 지역에만 건설할 수 있습니다! -STR_ERROR_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}... 사막 지역에만 건설할 수 있습니다! -STR_ERROR_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}... 도시에만 건설할 수 있습니다! (집이 있는 위치에만) -STR_ERROR_CAN_ONLY_BE_BUILT_NEAR_TOWN_CENTER :{WHITE}... 도시의 가운데 근처에만 설치할 수 있습니다. -STR_ERROR_CAN_ONLY_BE_BUILT_IN_LOW_AREAS :{WHITE}... 낮은 지역에만 건설할 수 있습니다! -STR_ERROR_CAN_ONLY_BE_POSITIONED :{WHITE}... 지도 가장자리에만 위치할 수 있습니다. -STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... 숲은 만년설 높이 이상의 고도에만 심을 수 있습니다. +STR_ERROR_CAN_T_CONSTRUCT_THIS_INDUSTRY :{WHITE}여기에 산업시설을 건설할 수 없습니다... +STR_ERROR_INDUSTRY_TOO_CLOSE :{WHITE}... 다른 산업시설과 너무 가깝습니다 +STR_ERROR_MUST_FOUND_TOWN_FIRST :{WHITE}... 도시를 먼저 만들어야 합니다 +STR_ERROR_ONLY_ONE_ALLOWED_PER_TOWN :{WHITE}... 한 도시에 하나만 지을 수 있습니다 +STR_ERROR_CAN_ONLY_BE_BUILT_IN_TOWNS_WITH_POPULATION_OF_1200 :{WHITE}... 인구 1200명 이상의 도시에만 지을 수 있습니다 +STR_ERROR_CAN_ONLY_BE_BUILT_IN_RAINFOREST :{WHITE}... 열대우림 지역에만 지을 수 있습니다 +STR_ERROR_CAN_ONLY_BE_BUILT_IN_DESERT :{WHITE}... 사막 지역에만 지을 수 있습니다 +STR_ERROR_CAN_ONLY_BE_BUILT_IN_TOWNS :{WHITE}... 도시 안의 집이 있는 위치에만 지을 수 있습니다 +STR_ERROR_CAN_ONLY_BE_BUILT_NEAR_TOWN_CENTER :{WHITE}... 도시의 가운데 근처에만 지을 수 있습니다 +STR_ERROR_CAN_ONLY_BE_BUILT_IN_LOW_AREAS :{WHITE}... 낮은 지역에만 지을 수 있습니다 +STR_ERROR_CAN_ONLY_BE_POSITIONED :{WHITE}... 지도 가장자리 근처에만 놓을 수 있습니다 +STR_ERROR_FOREST_CAN_ONLY_BE_PLANTED :{WHITE}... 숲은 만년설 높이 이상의 고도에만 지을 수 있습니다 STR_ERROR_CAN_ONLY_BE_BUILT_ABOVE_SNOW_LINE :{WHITE}... 만년설 고도 위에만 지을 수 있습니다 STR_ERROR_CAN_ONLY_BE_BUILT_BELOW_SNOW_LINE :{WHITE}... 만년설 고도 아래에만 지을 수 있습니다 -STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}적당한 장소가 없어 '{STRING}'{G 0 "이" "가"} 지어지지 않았습니다. -STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}더 나은 지도가 생성되도록 설정 값을 변경해보십시오. +STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES :{WHITE}적당한 장소가 없어 '{STRING}'{G 0 "이" "가"} 지어지지 않았습니다 +STR_ERROR_NO_SUITABLE_PLACES_FOR_INDUSTRIES_EXPLANATION :{WHITE}더 나은 지도가 생성되도록 설정 값을 변경해보십시오 # Station construction related errors -STR_ERROR_CAN_T_BUILD_RAILROAD_STATION :{WHITE}여기에 역을 건설할 수 없습니다... +STR_ERROR_CAN_T_BUILD_RAILROAD_STATION :{WHITE}여기에 역을 지을 수 없습니다... STR_ERROR_CAN_T_BUILD_BUS_STATION :{WHITE}버스 정류장을 지을 수 없습니다... STR_ERROR_CAN_T_BUILD_TRUCK_STATION :{WHITE}트럭 적하장을 지을 수 없습니다... -STR_ERROR_CAN_T_BUILD_PASSENGER_TRAM_STATION :{WHITE}여기에 여객 전차역을 건설할 수 없습니다... -STR_ERROR_CAN_T_BUILD_CARGO_TRAM_STATION :{WHITE}여기에 화물 전차역을 건설할 수 없습니다... -STR_ERROR_CAN_T_BUILD_DOCK_HERE :{WHITE}여기에 항구를 건설할 수 없습니다... -STR_ERROR_CAN_T_BUILD_AIRPORT_HERE :{WHITE}여기에 공항을 만들 수 없습니다... +STR_ERROR_CAN_T_BUILD_PASSENGER_TRAM_STATION :{WHITE}여기에 여객 전차역을 지을 수 없습니다... +STR_ERROR_CAN_T_BUILD_CARGO_TRAM_STATION :{WHITE}여기에 화물 전차역을 지을 수 없습니다... +STR_ERROR_CAN_T_BUILD_DOCK_HERE :{WHITE}여기에 항구를 지을 수 없습니다... +STR_ERROR_CAN_T_BUILD_AIRPORT_HERE :{WHITE}여기에 공항을 지을 수 없습니다... -STR_ERROR_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}2개 이상의 역이 인접합니다 -STR_ERROR_STATION_TOO_SPREAD_OUT :{WHITE}... 역이 너무 큽니다. +STR_ERROR_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}두 개 이상의 역이 인접합니다 +STR_ERROR_STATION_TOO_SPREAD_OUT :{WHITE}... 역이 너무 크게 퍼져있습니다 STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}역이 너무 많습니다 STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}철도역 조각이 너무 많습니다 STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}버스 정류장이 너무 많습니다 STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}트럭 적하장이 너무 많습니다 -STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}다른 항구와 너무 가깝습니다! -STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}다른 공항과 너무 가깝습니다! +STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}다른 항구와 너무 가깝습니다 +STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}다른 공항과 너무 가깝습니다 STR_ERROR_CAN_T_RENAME_STATION :{WHITE}역 이름을 바꿀 수 없습니다... STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... 여기는 도시 소유의 도로 입니다 -STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... 도로의 방향과 일치하지 않습니다. -STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... 도로 통과 정류장은 곡선도로에 건설할 수 없습니다. -STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... 도로 통과 정류장은 교차로에 건설할 수 없습니다. -STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... 도로가 일방통행이거나 막혔습니다 +STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... 도로의 방향과 일치하지 않습니다 +STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... 통과식 도로 정류장은 굽은 도로에 건설할 수 없습니다 +STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... 통과식 도로 정류장은 교차로에 건설할 수 없습니다 # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}역의 일부를 제거할 수 없습니다... STR_ERROR_MUST_REMOVE_RAILWAY_STATION_FIRST :{WHITE}먼저 철도역을 제거해야 합니다 -STR_ERROR_CAN_T_REMOVE_BUS_STATION :{WHITE}버스 정류장을 철거할 수 없습니다... +STR_ERROR_CAN_T_REMOVE_BUS_STATION :{WHITE}버스 정류장을 제거할 수 없습니다... STR_ERROR_CAN_T_REMOVE_TRUCK_STATION :{WHITE}트럭 터미널을 제거할 수 없습니다... -STR_ERROR_CAN_T_REMOVE_PASSENGER_TRAM_STATION :{WHITE}여객 전차역을 철거할 수 없습니다... -STR_ERROR_CAN_T_REMOVE_CARGO_TRAM_STATION :{WHITE}화물 전차역을 철거할 수 없습니다... -STR_ERROR_MUST_REMOVE_ROAD_STOP_FIRST :{WHITE}정류장을 먼저 제거하십시오. -STR_ERROR_THERE_IS_NO_STATION :{WHITE}... 여기에는 정거장이 없습니다. +STR_ERROR_CAN_T_REMOVE_PASSENGER_TRAM_STATION :{WHITE}여객 전차역을 제거할 수 없습니다... +STR_ERROR_CAN_T_REMOVE_CARGO_TRAM_STATION :{WHITE}화물 전차역을 제거할 수 없습니다... +STR_ERROR_MUST_REMOVE_ROAD_STOP_FIRST :{WHITE}정류장을 먼저 제거하십시오 +STR_ERROR_THERE_IS_NO_STATION :{WHITE}... 여기에는 정거장이 없습니다 -STR_ERROR_MUST_DEMOLISH_RAILROAD :{WHITE}철도역을 먼저 철거하십시오. -STR_ERROR_MUST_DEMOLISH_BUS_STATION_FIRST :{WHITE}버스 정류장을 먼저 철거하십시오. -STR_ERROR_MUST_DEMOLISH_TRUCK_STATION_FIRST :{WHITE}트럭 적하장을 먼저 제거하십시오. -STR_ERROR_MUST_DEMOLISH_PASSENGER_TRAM_STATION_FIRST :{WHITE}여객 전차역을 먼저 제거하십시오. -STR_ERROR_MUST_DEMOLISH_CARGO_TRAM_STATION_FIRST :{WHITE}화물 전차역을 먼저 제거하십시오. -STR_ERROR_MUST_DEMOLISH_DOCK_FIRST :{WHITE}항구를 먼저 제거하십시오! -STR_ERROR_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}공항을 먼저 제거하십시오! +STR_ERROR_MUST_DEMOLISH_RAILROAD :{WHITE}철도역을 먼저 제거하십시오 +STR_ERROR_MUST_DEMOLISH_BUS_STATION_FIRST :{WHITE}버스 정류장을 먼저 제거하십시오 +STR_ERROR_MUST_DEMOLISH_TRUCK_STATION_FIRST :{WHITE}트럭 적하장을 먼저 제거하십시오 +STR_ERROR_MUST_DEMOLISH_PASSENGER_TRAM_STATION_FIRST :{WHITE}여객 전차역을 먼저 제거하십시오 +STR_ERROR_MUST_DEMOLISH_CARGO_TRAM_STATION_FIRST :{WHITE}화물 전차역을 먼저 제거하십시오 +STR_ERROR_MUST_DEMOLISH_DOCK_FIRST :{WHITE}항구를 먼저 제거하십시오 +STR_ERROR_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}공항을 먼저 제거하십시오 # Waypoint related errors -STR_ERROR_WAYPOINT_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}최소한 하나 이상의 경유지와 연결하십시오. +STR_ERROR_WAYPOINT_ADJOINS_MORE_THAN_ONE_EXISTING :{WHITE}최소한 하나 이상의 경유지와 연결하십시오 STR_ERROR_TOO_CLOSE_TO_ANOTHER_WAYPOINT :{WHITE}다른 경유지와 너무 가깝습니다! -STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT :{WHITE}여기에 열차 경유지를 건설할 수 없습니다. +STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT :{WHITE}여기에 열차 경유지를 건설할 수 없습니다 STR_ERROR_CAN_T_POSITION_BUOY_HERE :{WHITE}여기에 부표를 설치할 수 없습니다... STR_ERROR_CAN_T_CHANGE_WAYPOINT_NAME :{WHITE}경유지의 이름을 변경할 수 없습니다... -STR_ERROR_CAN_T_REMOVE_TRAIN_WAYPOINT :{WHITE}이 열차 경유지를 제거할 수 없습니다. -STR_ERROR_MUST_REMOVE_RAILWAYPOINT_FIRST :{WHITE}열차 경유지를 먼저 제거하십시오. -STR_ERROR_BUOY_IN_THE_WAY :{WHITE}... 도중에 부표가 있습니다. +STR_ERROR_CAN_T_REMOVE_TRAIN_WAYPOINT :{WHITE}이 열차 경유지를 제거할 수 없습니다 +STR_ERROR_MUST_REMOVE_RAILWAYPOINT_FIRST :{WHITE}열차 경유지를 먼저 제거하십시오 +STR_ERROR_BUOY_IN_THE_WAY :{WHITE}... 도중에 부표가 있습니다 STR_ERROR_BUOY_IS_IN_USE :{WHITE}... 다른 회사에서 사용 중인 부표입니다! # Depot related errors -STR_ERROR_CAN_T_BUILD_TRAIN_DEPOT :{WHITE}여기에 차량기지를 건설할 수 없습니다... +STR_ERROR_CAN_T_BUILD_TRAIN_DEPOT :{WHITE}여기에 차량기지를 지을 수 없습니다... STR_ERROR_CAN_T_BUILD_ROAD_DEPOT :{WHITE}여기에 차고지를 지을 수 없습니다... -STR_ERROR_CAN_T_BUILD_TRAM_DEPOT :{WHITE}여기에 차량기지를 건설할 수 없습니다... +STR_ERROR_CAN_T_BUILD_TRAM_DEPOT :{WHITE}여기에 차량기지를 지을 수 없습니다... STR_ERROR_CAN_T_BUILD_SHIP_DEPOT :{WHITE}여기에 정박소를 지을 수 없습니다... STR_ERROR_CAN_T_RENAME_DEPOT :{WHITE}차량기지의 이름을 바꿀 수 없습니다... -STR_ERROR_TRAIN_MUST_BE_STOPPED_INSIDE_DEPOT :{WHITE}... 차량기지 안에 정지되어 있어야 합니다 +STR_ERROR_TRAIN_MUST_BE_STOPPED_INSIDE_DEPOT :{WHITE}... 차량기지 안에 정지해 있어야 합니다 STR_ERROR_ROAD_VEHICLE_MUST_BE_STOPPED_INSIDE_DEPOT :{WHITE}... 차고지 안에 정지해 있어야 합니다 -STR_ERROR_SHIP_MUST_BE_STOPPED_INSIDE_DEPOT :{WHITE}... 정박소 내에 정지해 있어야 합니다! -STR_ERROR_AIRCRAFT_MUST_BE_STOPPED_INSIDE_HANGAR :{WHITE}... 격납고 내에서 정지되어 있어야합 니다 +STR_ERROR_SHIP_MUST_BE_STOPPED_INSIDE_DEPOT :{WHITE}... 정박소 안에 정지해 있어야 합니다 +STR_ERROR_AIRCRAFT_MUST_BE_STOPPED_INSIDE_HANGAR :{WHITE}... 격납고 안에 정지해 있어야 합니다 STR_ERROR_TRAINS_CAN_ONLY_BE_ALTERED_INSIDE_A_DEPOT :{WHITE}차량기지 내에서 정지한 경우에만 개조할 수 있습니다 STR_ERROR_TRAIN_TOO_LONG :{WHITE}열차가 너무 깁니다! -STR_ERROR_CAN_T_REVERSE_DIRECTION_RAIL_VEHICLE :{WHITE}차량의 방향을 뒤집을 수 없습니다... +STR_ERROR_CAN_T_REVERSE_DIRECTION_RAIL_VEHICLE :{WHITE}차량을 유턴시킬 수 없습니다... STR_ERROR_CAN_T_REVERSE_DIRECTION_RAIL_VEHICLE_MULTIPLE_UNITS :{WHITE}여러 대가 연결된 차량은 뒤집을 수 없습니다... -STR_ERROR_INCOMPATIBLE_RAIL_TYPES :알맞지 않은 철도 타입 +STR_ERROR_INCOMPATIBLE_RAIL_TYPES :알맞지 않은 철도 타입입니다 STR_ERROR_CAN_T_MOVE_VEHICLE :{WHITE}차량을 옮길 수 없습니다... -STR_ERROR_REAR_ENGINE_FOLLOW_FRONT :{WHITE}뒷쪽 기관차는 앞쪽것을 항상 따라다닐 것입니다. +STR_ERROR_REAR_ENGINE_FOLLOW_FRONT :{WHITE}뒷쪽 기관차는 앞쪽 기관차를 항상 따라다닐 것입니다 STR_ERROR_UNABLE_TO_FIND_ROUTE_TO :{WHITE}근처에 있는 차량기지로 가는 길을 찾을 수 없습니다 STR_ERROR_UNABLE_TO_FIND_LOCAL_DEPOT :{WHITE}근처에 있는 차고지를 찾을 수 없습니다 -STR_ERROR_DEPOT_WRONG_DEPOT_TYPE :잘못된 차량기지 종류 +STR_ERROR_DEPOT_WRONG_DEPOT_TYPE :잘못된 차량기지 종류입니다 # Autoreplace related errors -STR_ERROR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}{VEHICLE} : 교체된지 너무 오래되었습니다. -STR_ERROR_AUTOREPLACE_NOTHING_TO_DO :{WHITE}자동 교체/갱신 규칙이 적용되지 않았습니다. -STR_ERROR_AUTOREPLACE_MONEY_LIMIT :(자금 제한) +STR_ERROR_TRAIN_TOO_LONG_AFTER_REPLACEMENT :{WHITE}{VEHICLE} : 교체된지 너무 오래되었습니다 +STR_ERROR_AUTOREPLACE_NOTHING_TO_DO :{WHITE}자동 교체/갱신 규칙이 적용되지 않았습니다 +STR_ERROR_AUTOREPLACE_MONEY_LIMIT :(자금 부족) # Rail construction errors STR_ERROR_IMPOSSIBLE_TRACK_COMBINATION :{WHITE}불가능한 트랙 조합입니다 STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}신호기를 먼저 제거하십시오 -STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}알맞지 않은 선로입니다. -STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{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 :{WHITE}이 철도 타입에서는 건널목을 만들 수 없습니다. +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}이 선로에는 건널목을 만들 수 없습니다. +STR_ERROR_CROSSING_DISALLOWED_ROAD :{WHITE}이 도로에는 건널목을 만들 수 없습니다 STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}여기에 신호기를 건설할 수 없습니다... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}여기에 선로를 건설할 수 없습니다... -STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}이 선로를 철거할 수 없습니다... +STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}이 선로를 제거할 수 없습니다... STR_ERROR_CAN_T_REMOVE_SIGNALS_FROM :{WHITE}이곳의 신호기를 제거할 수 없습니다... -STR_ERROR_SIGNAL_CAN_T_CONVERT_SIGNALS_HERE :{WHITE}이곳의 신호기를 변환할 수 없습니다... -STR_ERROR_THERE_IS_NO_RAILROAD_TRACK :{WHITE}... 선로가 없습니다. -STR_ERROR_THERE_ARE_NO_SIGNALS :{WHITE}... 신호기가 없습니다. +STR_ERROR_SIGNAL_CAN_T_CONVERT_SIGNALS_HERE :{WHITE}이곳의 신호기를 바꿀 수 없습니다... +STR_ERROR_THERE_IS_NO_RAILROAD_TRACK :{WHITE}... 선로가 없습니다 +STR_ERROR_THERE_ARE_NO_SIGNALS :{WHITE}... 신호기가 없습니다 -STR_ERROR_CAN_T_CONVERT_RAIL :{WHITE}이 선로의 형식을 바꿀 수 없습니다... +STR_ERROR_CAN_T_CONVERT_RAIL :{WHITE}이곳의 선로를 바꿀 수 없습니다... # Road construction errors STR_ERROR_MUST_REMOVE_ROAD_FIRST :{WHITE}도로를 먼저 제거하십시오 STR_ERROR_ONEWAY_ROADS_CAN_T_HAVE_JUNCTION :{WHITE}... 일방통행로에는 교차로를 만들 수 없습니다. STR_ERROR_CAN_T_BUILD_ROAD_HERE :{WHITE}도로를 건설할 수 없습니다... STR_ERROR_CAN_T_BUILD_TRAMWAY_HERE :{WHITE}여기에 전찻길을 건설할 수 없습니다... -STR_ERROR_CAN_T_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_REMOVE_ROAD_FROM :{WHITE}이 도로를 제거할 수 없습니다... +STR_ERROR_CAN_T_REMOVE_TRAMWAY_FROM :{WHITE}이 전찻길을 제거할 수 없습니다... +STR_ERROR_THERE_IS_NO_ROAD :{WHITE}... 도로가 없습니다 +STR_ERROR_THERE_IS_NO_TRAMWAY :{WHITE}... 전찻길이 없습니다 +STR_ERROR_CAN_T_CONVERT_ROAD :{WHITE}이곳의 도로를 바꿀 수 없습니다... +STR_ERROR_CAN_T_CONVERT_TRAMWAY :{WHITE}이곳의 전찻길을 바꿀 수 없습니다... +STR_ERROR_NO_SUITABLE_ROAD :{WHITE}적합한 도로가 없습니다 +STR_ERROR_NO_SUITABLE_TRAMWAY :{WHITE}적합한 전찻길이 없습니다 +STR_ERROR_INCOMPATIBLE_ROAD :{WHITE}... 적합하지 않은 도로입니다 +STR_ERROR_INCOMPATIBLE_TRAMWAY :{WHITE}... 적합하지 않은 전찻길입니다 # Waterway construction errors STR_ERROR_CAN_T_BUILD_CANALS :{WHITE}여기에 운하를 건설할 수 없습니다... STR_ERROR_CAN_T_BUILD_LOCKS :{WHITE}여기에 갑문을 지을 수 없습니다... STR_ERROR_CAN_T_PLACE_RIVERS :{WHITE}여기에 강을 만들 수 없습니다... -STR_ERROR_MUST_BE_BUILT_ON_WATER :{WHITE}... 물 위에 지어져야 합니다! +STR_ERROR_MUST_BE_BUILT_ON_WATER :{WHITE}... 물 위에 지어야 합니다! STR_ERROR_CAN_T_BUILD_ON_WATER :{WHITE}... 물 위에 지을 수 없습니다 STR_ERROR_CAN_T_BUILD_ON_SEA :{WHITE}... 바다 위에 지을 수 없습니다 STR_ERROR_CAN_T_BUILD_ON_CANAL :{WHITE}... 운하 위에 지을 수 없습니다 @@ -4422,8 +4502,8 @@ STR_ERROR_MUST_DEMOLISH_CANAL_FIRST :{WHITE}운하 STR_ERROR_CAN_T_BUILD_AQUEDUCT_HERE :{WHITE}여기에 수도교를 지을 수 없습니다... # Tree related errors -STR_ERROR_TREE_ALREADY_HERE :{WHITE}... 이미 나무가 심어져 있습니다. -STR_ERROR_TREE_WRONG_TERRAIN_FOR_TREE_TYPE :{WHITE}... 지형에 맞지 않는 나무타입입니다. +STR_ERROR_TREE_ALREADY_HERE :{WHITE}... 이미 나무가 심어져 있습니다 +STR_ERROR_TREE_WRONG_TERRAIN_FOR_TREE_TYPE :{WHITE}... 지형에 맞지 않는 나무 종류입니다 STR_ERROR_CAN_T_PLANT_TREE_HERE :{WHITE}여기에 나무를 심을 수 없습니다... # Bridge related errors @@ -4431,42 +4511,43 @@ STR_ERROR_CAN_T_BUILD_BRIDGE_HERE :{WHITE}여기 STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}다리를 먼저 제거하십시오 STR_ERROR_CAN_T_START_AND_END_ON :{WHITE}같은 위치에서 시작하고 끝낼 수 없습니다 STR_ERROR_BRIDGEHEADS_NOT_SAME_HEIGHT :{WHITE}다리는 같은 높이를 연결해야 합니다 -STR_ERROR_BRIDGE_TOO_LOW_FOR_TERRAIN :{WHITE}그 지형은 다리를 건설하기에 너무 낮습니다 +STR_ERROR_BRIDGE_TOO_LOW_FOR_TERRAIN :{WHITE}이 지형에 다리를 설치하기에는 고도가 너무 낮습니다. STR_ERROR_BRIDGE_TOO_HIGH_FOR_TERRAIN :{WHITE}이 지형에 다리를 설치하기에는 고도가 너무 높습니다. -STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}시작과 끝은 한 줄 위에 있어야 합니다 -STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... 다리의 양 끝은 모두 땅이어야합니다. +STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}시작과 끝 지점은 일직선 상에 있어야 합니다 +STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... 다리의 양 끝은 모두 땅이어야 합니다 STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... 다리가 너무 깁니다! STR_ERROR_BRIDGE_THROUGH_MAP_BORDER :{WHITE}다리 끝이 지도 밖을 넘어갑니다 # Tunnel related errors STR_ERROR_CAN_T_BUILD_TUNNEL_HERE :{WHITE}여기에 터널을 지을 수 없습니다... -STR_ERROR_SITE_UNSUITABLE_FOR_TUNNEL :{WHITE}터널 입구에 알맞지 않은 장소입니다 +STR_ERROR_SITE_UNSUITABLE_FOR_TUNNEL :{WHITE}터널 입구를 짓기에 적절하지 않은 장소입니다 STR_ERROR_MUST_DEMOLISH_TUNNEL_FIRST :{WHITE}터널을 먼저 제거하십시오 -STR_ERROR_ANOTHER_TUNNEL_IN_THE_WAY :{WHITE}도중에 다른 터널이 있습니다 -STR_ERROR_TUNNEL_THROUGH_MAP_BORDER :{WHITE}터널이 지도 맨끝을 통과합니다 +STR_ERROR_ANOTHER_TUNNEL_IN_THE_WAY :{WHITE}중간에 다른 터널이 있습니다 +STR_ERROR_TUNNEL_THROUGH_MAP_BORDER :{WHITE}터널을 지도 맨 끝까지 건설할 수 없습니다 STR_ERROR_UNABLE_TO_EXCAVATE_LAND :{WHITE}지형 문제로 터널의 반대쪽 출구를 만들 수 없습니다 STR_ERROR_TUNNEL_TOO_LONG :{WHITE}... 터널이 너무 깁니다! # Object related errors -STR_ERROR_TOO_MANY_OBJECTS :{WHITE}... 오브젝트가 너무 많습니다. +STR_ERROR_TOO_MANY_OBJECTS :{WHITE}... 오브젝트가 너무 많습니다 STR_ERROR_CAN_T_BUILD_OBJECT :{WHITE}오브젝트를 건설할 수 없습니다... STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}중간에 오브젝트가 있습니다 -STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... 중간에 회사 본사가 있습니다. +STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... 중간에 회사 본사가 있습니다 STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}이 지역을 매입할 수 없습니다... STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... 이미 소유중입니다! # Group related errors STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}그룹을 만들 수 없습니다... STR_ERROR_GROUP_CAN_T_DELETE :{WHITE}이 그룹을 지울 수 없습니다... -STR_ERROR_GROUP_CAN_T_RENAME :{WHITE}그룹의 이름을 바꿀 수 없습니다. +STR_ERROR_GROUP_CAN_T_RENAME :{WHITE}그룹의 이름을 바꿀 수 없습니다 STR_ERROR_GROUP_CAN_T_SET_PARENT :{WHITE}상위 그룹으로 설정할 수 없습니다... -STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}이 그룹의 모든 차량을 제거할 수 없습니다. +STR_ERROR_GROUP_CAN_T_SET_PARENT_RECURSION :{WHITE}... 상위 그룹을 하위 그룹 아래로 옮길 수 없습니다 +STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}이 그룹의 모든 차량을 제거할 수 없습니다 STR_ERROR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}이 그룹에 차량을 추가할 수 없습니다... STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}이 그룹에 공유된 차량을 추가할 수 없습니다... # Generic vehicle errors STR_ERROR_TRAIN_IN_THE_WAY :{WHITE}중간에 열차가 있습니다 -STR_ERROR_ROAD_VEHICLE_IN_THE_WAY :{WHITE}중간에 차량이 있습니다. +STR_ERROR_ROAD_VEHICLE_IN_THE_WAY :{WHITE}중간에 차량이 있습니다 STR_ERROR_SHIP_IN_THE_WAY :{WHITE}중간에 선박이 있습니다 STR_ERROR_AIRCRAFT_IN_THE_WAY :{WHITE}중간에 항공기가 있습니다 @@ -4475,15 +4556,15 @@ STR_ERROR_CAN_T_REFIT_ROAD_VEHICLE :{WHITE}차량 STR_ERROR_CAN_T_REFIT_SHIP :{WHITE}선박을 개조할 수 없습니다... STR_ERROR_CAN_T_REFIT_AIRCRAFT :{WHITE}항공기를 개조할 수 없습니다... -STR_ERROR_CAN_T_RENAME_TRAIN :{WHITE}열차 이름을 지정할 수 없습니다... -STR_ERROR_CAN_T_RENAME_ROAD_VEHICLE :{WHITE}차량의 이름을 지정할 수 없습니다... +STR_ERROR_CAN_T_RENAME_TRAIN :{WHITE}열차 이름을 바꿀 수 없습니다... +STR_ERROR_CAN_T_RENAME_ROAD_VEHICLE :{WHITE}차량의 이름을 바꿀 수 없습니다... STR_ERROR_CAN_T_RENAME_SHIP :{WHITE}선박의 이름을 바꿀 수 없습니다... -STR_ERROR_CAN_T_RENAME_AIRCRAFT :{WHITE}항공기의 이름을 지정할 수 없습니다... +STR_ERROR_CAN_T_RENAME_AIRCRAFT :{WHITE}항공기의 이름을 바꿀 수 없습니다... STR_ERROR_CAN_T_STOP_START_TRAIN :{WHITE}열차를 운행/정지시킬 수 없습니다... STR_ERROR_CAN_T_STOP_START_ROAD_VEHICLE :{WHITE}차량을 운행/정지시킬 수 없습니다... -STR_ERROR_CAN_T_STOP_START_SHIP :{WHITE}선박을 운행/중지시킬 수 없습니다... -STR_ERROR_CAN_T_STOP_START_AIRCRAFT :{WHITE}항공기를 운행/중지시킬 수 없습니다... +STR_ERROR_CAN_T_STOP_START_SHIP :{WHITE}선박을 운행/정지시킬 수 없습니다... +STR_ERROR_CAN_T_STOP_START_AIRCRAFT :{WHITE}항공기를 운행/정지시킬 수 없습니다... STR_ERROR_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}열차를 차량기지로 보낼 수 없습니다... STR_ERROR_CAN_T_SEND_ROAD_VEHICLE_TO_DEPOT :{WHITE}차량을 차고지로 보낼 수 없습니다... @@ -4495,8 +4576,8 @@ STR_ERROR_CAN_T_BUY_ROAD_VEHICLE :{WHITE}차량 STR_ERROR_CAN_T_BUY_SHIP :{WHITE}선박을 구입할 수 없습니다... STR_ERROR_CAN_T_BUY_AIRCRAFT :{WHITE}항공기를 구입할 수 없습니다... -STR_ERROR_CAN_T_RENAME_TRAIN_TYPE :{WHITE}열차의 차량 이름을 다시 지정할 수 없습니다... -STR_ERROR_CAN_T_RENAME_ROAD_VEHICLE_TYPE :{WHITE}차종명을 다시 지정할 수 없습니다... +STR_ERROR_CAN_T_RENAME_TRAIN_TYPE :{WHITE}열차의 모델명을 다시 지정할 수 없습니다... +STR_ERROR_CAN_T_RENAME_ROAD_VEHICLE_TYPE :{WHITE}차종의 이름을 바꿀 수 없습니다... STR_ERROR_CAN_T_RENAME_SHIP_TYPE :{WHITE}선박의 차량 이름을 다시 지정할 수 없습니다... STR_ERROR_CAN_T_RENAME_AIRCRAFT_TYPE :{WHITE}항공기의 차량 이름을 다시 지정할 수 없습니다... @@ -4505,15 +4586,15 @@ STR_ERROR_CAN_T_SELL_ROAD_VEHICLE :{WHITE}차량 STR_ERROR_CAN_T_SELL_SHIP :{WHITE}선박을 팔 수 없습니다... STR_ERROR_CAN_T_SELL_AIRCRAFT :{WHITE}항공기를 팔 수 없습니다... -STR_ERROR_RAIL_VEHICLE_NOT_AVAILABLE :{WHITE}이 열차는 사용할 수 없는 상태입니다. -STR_ERROR_ROAD_VEHICLE_NOT_AVAILABLE :{WHITE}이 차량은 사용할 수 없는 상태입니다. -STR_ERROR_SHIP_NOT_AVAILABLE :{WHITE}이 선박은 사용할 수 없는 상태입니다. -STR_ERROR_AIRCRAFT_NOT_AVAILABLE :{WHITE}이 항공기는 사용할 수 없는 상태입니다. +STR_ERROR_RAIL_VEHICLE_NOT_AVAILABLE :{WHITE}이 열차는 사용할 수 없는 상태입니다 +STR_ERROR_ROAD_VEHICLE_NOT_AVAILABLE :{WHITE}이 차량은 사용할 수 없는 상태입니다 +STR_ERROR_SHIP_NOT_AVAILABLE :{WHITE}이 선박은 사용할 수 없는 상태입니다 +STR_ERROR_AIRCRAFT_NOT_AVAILABLE :{WHITE}이 항공기는 사용할 수 없는 상태입니다 STR_ERROR_TOO_MANY_VEHICLES_IN_GAME :{WHITE}게임에 차량이 너무 많습니다! STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}정비 간격 설정을 바꿀 수 없습니다... -STR_ERROR_VEHICLE_IS_DESTROYED :{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 설정을 변경하십시오 @@ -4525,12 +4606,12 @@ STR_ERROR_CAN_T_MAKE_TRAIN_PASS_SIGNAL :{WHITE}너무 STR_ERROR_CAN_T_REVERSE_DIRECTION_TRAIN :{WHITE}열차를 회차시킬 수 없습니다... STR_ERROR_TRAIN_START_NO_POWER :동력차가 없습니다 -STR_ERROR_CAN_T_MAKE_ROAD_VEHICLE_TURN :{WHITE}차량을 U턴시킬 수 없습니다... +STR_ERROR_CAN_T_MAKE_ROAD_VEHICLE_TURN :{WHITE}차량을 유턴시킬 수 없습니다... STR_ERROR_AIRCRAFT_IS_IN_FLIGHT :{WHITE}항공기가 운항중입니다 # Order related errors -STR_ERROR_NO_MORE_SPACE_FOR_ORDERS :{WHITE}더이상 경로를 지정할 공간이 없습니다 +STR_ERROR_NO_MORE_SPACE_FOR_ORDERS :{WHITE}더 이상 경로를 지정할 공간이 없습니다 STR_ERROR_TOO_MANY_ORDERS :{WHITE}경로가 너무 많습니다! STR_ERROR_CAN_T_INSERT_NEW_ORDER :{WHITE}새 경로를 삽입할 수 없습니다... STR_ERROR_CAN_T_DELETE_THIS_ORDER :{WHITE}이 경로를 제거할 수 없습니다... @@ -4539,19 +4620,19 @@ STR_ERROR_CAN_T_MOVE_THIS_ORDER :{WHITE}이 경 STR_ERROR_CAN_T_SKIP_ORDER :{WHITE}현재 경로를 건너 뛸 수 없습니다... 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_ADD_ORDER :{WHITE}... 차량이 그 정거장에 갈 수 없습니다 +STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}... 경로를 공유하고 있는 차량이 그 정거장에 갈 수 없습니다 STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}경로를 공유할 수 없습니다... STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}경로 공유를 중단할 수 없습니다... STR_ERROR_CAN_T_COPY_ORDER_LIST :{WHITE}경로를 복사할 수 없습니다... -STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... 이전의 목적지로부터 너무 멉니다 +STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION :{WHITE}... 이전 목적지에서 너무 멀리 떨어져 있습니다 STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE :{WHITE}... 항공기의 항속거리가 충분하지 않습니다. # Timetable related errors STR_ERROR_CAN_T_TIMETABLE_VEHICLE :{WHITE}차량의 시간표를 정할 수 없습니다... -STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}차량은 정거장에서만 기다릴 수 있습니다. -STR_ERROR_TIMETABLE_NOT_STOPPING_HERE :{WHITE}이 차량은 이 정거장에 서지 않습니다. +STR_ERROR_TIMETABLE_ONLY_WAIT_AT_STATIONS :{WHITE}차량은 정거장에서만 기다릴 수 있습니다 +STR_ERROR_TIMETABLE_NOT_STOPPING_HERE :{WHITE}이 차량은 이 정거장에 서지 않습니다 # Sign related errors STR_ERROR_TOO_MANY_SIGNS :{WHITE}... 팻말 수가 너무 많습니다 @@ -4565,14 +4646,14 @@ STR_DESKTOP_SHORTCUT_COMMENT :트랜스포트 # Translatable descriptions in media/baseset/*.ob* files STR_BASEGRAPHICS_DOS_DESCRIPTION :오리지널 트랜스포트 타이쿤 디럭스 도스 에디션의 그래픽입니다. STR_BASEGRAPHICS_DOS_DE_DESCRIPTION :오리지널 트랜스포트 타이쿤 디럭스 도스 에디션(독일)의 그래픽입니다. -STR_BASEGRAPHICS_WIN_DESCRIPTION :오리지널 트랜스포트 타이쿤 디럭스 윈도 에디션의 그래픽입니다. +STR_BASEGRAPHICS_WIN_DESCRIPTION :오리지널 트랜스포트 타이쿤 디럭스 Windows 에디션의 그래픽입니다. STR_BASESOUNDS_DOS_DESCRIPTION :오리지널 트랜스포트 타이쿤 디럭스 도스 에디션의 효과음입니다. -STR_BASESOUNDS_WIN_DESCRIPTION :오리지널 트랜스포트 타이쿤 디럭스 윈도 에디션의 효과음입니다. +STR_BASESOUNDS_WIN_DESCRIPTION :오리지널 트랜스포트 타이쿤 디럭스 Windows 에디션의 효과음입니다. STR_BASESOUNDS_NONE_DESCRIPTION :아무런 효과음도 없는 효과음 팩입니다. -STR_BASEMUSIC_WIN_DESCRIPTION :오리지널 트랜스포트 타이쿤 디럭스 윈도 에디션의 음악입니다. +STR_BASEMUSIC_WIN_DESCRIPTION :오리지널 트랜스포트 타이쿤 디럭스 Windows 에디션의 음악입니다. STR_BASEMUSIC_DOS_DESCRIPTION :오리지널 트랜스포트 타이쿤 디럭스 DOS 에디션의 음악입니다. STR_BASEMUSIC_TTO_DESCRIPTION :오리지널 트랜스포트 타이쿤 (오리지널/월드 에디터) DOS 에디션의 음악입니다. -STR_BASEMUSIC_NONE_DESCRIPTION :실제 음악이 없는 음악 목록입니다. +STR_BASEMUSIC_NONE_DESCRIPTION :실제 음악이 없는 음악 팩입니다. ##id 0x2000 # Town building names @@ -4608,7 +4689,7 @@ STR_TOWN_BUILDING_NAME_SHOPPING_MALL_1 :쇼핑몰 STR_TOWN_BUILDING_NAME_IGLOO_1 :이글루 STR_TOWN_BUILDING_NAME_TEPEES_1 :천막 STR_TOWN_BUILDING_NAME_TEAPOT_HOUSE_1 :찻잔 집 -STR_TOWN_BUILDING_NAME_PIGGY_BANK_1 :돼지 저금통 +STR_TOWN_BUILDING_NAME_PIGGY_BANK_1 :돼지 은행 ##id 0x4800 # industry names @@ -4667,7 +4748,7 @@ STR_SV_STNAME_EAST :동{STRING} STR_SV_STNAME_WEST :서{STRING} STR_SV_STNAME_CENTRAL :{STRING}중앙 STR_SV_STNAME_TRANSFER :{STRING} 환승 -STR_SV_STNAME_HALT :{STRING} 정류장 +STR_SV_STNAME_HALT :{STRING} 간이역 STR_SV_STNAME_VALLEY :{STRING} 계곡 STR_SV_STNAME_HEIGHTS :{STRING} 언덕 STR_SV_STNAME_WOODS :{STRING} 숲 @@ -4776,10 +4857,10 @@ STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_TOY_VAN :장난감 수 STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_BATTERY_TRUCK :건전지 수송차량 STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_FIZZY_DRINK_TRUCK :탄산음료 수송차량 STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_PLASTIC_TRUCK :플라스틱 수송차량 -STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Leviathan' (전기) -STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_LEV2_CYCLOPS_ELECTRIC :Lev2 'Cyclops' (전기) -STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_LEV3_PEGASUS_ELECTRIC :Lev3 'Pegasus' (전기) -STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_LEV4_CHIMAERA_ELECTRIC :Lev4 'Chimaera' (전기) +STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_LEV1_LEVIATHAN_ELECTRIC :Lev1 '레비아탄' (전기) +STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_LEV2_CYCLOPS_ELECTRIC :Lev2 '사이클롭스' (전기) +STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_LEV3_PEGASUS_ELECTRIC :Lev3 '페가수스' (전기) +STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_LEV4_CHIMAERA_ELECTRIC :Lev4 '키메라' (전기) STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_WIZZOWOW_ROCKETEER :Wizzowow Rocketeer STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_PASSENGER_CAR :승객 수송차량 STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_MAIL_VAN :우편 수송차량 @@ -5069,41 +5150,3 @@ STR_PLANE :{G=f}{BLACK}{PL STR_SHIP :{G=f}{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) - -# Android strings -STR_ABOUT_MENU_TUTORIAL : {BLACK}튜토리얼 -STR_SMALLMAP_TOOLTIP_SHOW_LEGEND :{BLACK}지도 범례 / 기호 설명을 보여줌 -STR_CONFIG_SETTING_VERTICAL_TOOLBAR :수직 작업창: {STRING} -STR_CONFIG_SETTING_VERTICAL_TOOLBAR_HELPTEXT :메인 작업창이 두 개의 화면 양쪽 두개의 수직 작업창으로 나뉨 -STR_CONFIG_SETTING_COMPACT_VERTICAL_TOOLBAR :소형 수직 작업창: {STRING} -STR_CONFIG_SETTING_COMPACT_VERTICAL_TOOLBAR_HELPTEXT :수직 작업창에 '작업창 바꾸기'메뉴가 없지만, 부 메뉴가 추가로 있음 -STR_CONFIG_SETTING_BUTTON_SIZE : {BLACK}버튼 크기 -STR_CONFIG_SETTING_BUTTON_SIZE_TOOLTIP : {BLACK}모든 사용자 인터페이스의 크기 -STR_CONFIG_SETTING_FONT_SIZE :{BLACK}글씨 크기 -STR_CONFIG_SETTING_FONT_SIZE_TOOLTIP :{BLACK}모든 게임 글씨의 크기 -STR_CONFIG_SETTING_BUILD_CONFIRMATION :명령 확인: {STRING} -STR_CONFIG_SETTING_BUILD_CONFIRMATION_HELPTEXT :도로와 정류장을 건설시 확인 팝업을 보임 -STR_CONFIG_SETTING_WINDOWS_TITLEBARS :이름 창 -STR_CONFIG_SETTING_WINDOWS_TITLEBARS_HELPTEXT :{BLACK}모든 창에 대해 이름을 보여주거나, 화면 공간 절약을 위해 이름을 가리기 -STR_CONFIG_SETTING_WINDOWS_DECORATIONS :창 꾸미기: {STRING} -STR_CONFIG_SETTING_WINDOWS_DECORATIONS_HELPTEXT :창 모서리에 꾸밈 효과 -STR_CONFIG_SETTING_VIDEO_8BPP : {BLACK}8비트 -STR_CONFIG_SETTING_VIDEO_8BPP_HELPTEXT :그래픽 색상 심도를 픽셀당 8비트로 설정합니다. 이 그래픽 모드는 물이 흐르는 애니메이션 효과를 표현할 수 있습니다. -STR_CONFIG_SETTING_VIDEO_16BPP : {BLACK}16비트 -STR_CONFIG_SETTING_VIDEO_16BPP_HELPTEXT :{BLACK}그래픽 색상 심도를 픽셀당 16비트로 설정합니다. 이 그래픽 모드는 물이 흐르는 애니메이션 효과를 표현할 수 있습니다. -STR_CONFIG_SETTING_VIDEO_24BPP :{BLACK}24비트 -STR_CONFIG_SETTING_VIDEO_24BPP_HELPTEXT :그래픽 색상 심도를 픽셀당 24비트로 설정합니다. 이 그래픽 모드는 물이 흐르는 애니메이션 효과를 표현할 수 있습니다. -STR_TABLET_CLOSE_TOOLTIP :{BLACK}열려있는 모든 창 닫기 (고정된 창 제외) -STR_TABLET_SHIFT_TOOLTIP :{BLACK}이 행동을 하기 위한 예상 비용을 알아보려면 누르세요. -STR_TABLET_CTRL_TOOLTIP :{BLACK}"컨트롤"키를 이용하는 명령을 위해 사용 -STR_TUTORIAL_WINDOW_TITLE :{BLACK}튜토리얼 영상 -STR_TUTORIAL_WINDOW_TOOLTIP :{BLACK}튜토리얼 영상을 보기 위해 비디오 플레이어를 열기 -STR_TUTORIAL_ROADS_AND_STATIONS :{BLACK}도로, 역 건설 및 차량 구입 -STR_TUTORIAL_RAILWAYS :{BLACK}선로 및 열차 -STR_TUTORIAL_ROAD_VEHICLES :{BLACK}차량 -STR_TUTORIAL_SHIPS :{BLACK}선박과 항구 -STR_TUTORIAL_CARGO :{BLACK}화물 종류 -STR_SAVELOAD_LOAD_NETWORK_BUTTON :{BLACK}네트워크에서 불러오기 -STR_SAVELOAD_LOAD_NETWORK_TOOLTIP :{BLACK}네트워크 저장소에서 불러오기 -STR_SAVELOAD_SAVE_NETWORK_BUTTON :{BLACK}네트워크에 저장 -STR_SAVELOAD_SAVE_NETWORK_TOOLTIP :{BLACK}네트워크 저장소로 게임을 백업 diff --git a/src/lang/latin.txt b/src/lang/latin.txt index 6c082af525..89da7bafcd 100644 --- a/src/lang/latin.txt +++ b/src/lang/latin.txt @@ -12,8 +12,6 @@ ##case gen acc abl dat -# $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. # 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. @@ -663,9 +661,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Monstrare celareve consolam STR_ABOUT_MENU_AI_DEBUG :Emendatio IA/Ludi scriptorum STR_ABOUT_MENU_SCREENSHOT :Imago conspectus -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Imago conspectus maxime amplificata -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Imago conspectus solite amplificata -STR_ABOUT_MENU_GIANT_SCREENSHOT :Imago cunctae tabulae geographicae STR_ABOUT_MENU_ABOUT_OPENTTD :De 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Norma spiritus STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Monstrare celareve arcas finitionum @@ -835,9 +830,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Propria II STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Amplitudo Musicae STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Amplitido Sonorum -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}MIN -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}MAX -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -1054,6 +1046,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}Nov{G us a um i ae a} {STRING} parabil{G 0 is is e es es ia}! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} non diutius {STRING.acc} accipit STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} non diutius {STRING.acc} {STRING.acc}que accipit STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} nunc {STRING.acc} accipit @@ -1370,6 +1363,7 @@ STR_CONFIG_SETTING_AUTOSLOPE :Sinere terram p STR_CONFIG_SETTING_AUTOSLOPE_HELPTEXT :Sinere terram plasmare sub aedificia et vias; tum necesse non est aedificia viasve removere STR_CONFIG_SETTING_CATCHMENT :Sinere magnitudines regionum acceptionis magis realisticas esse: {STRING} STR_CONFIG_SETTING_CATCHMENT_HELPTEXT :Si electa, aeroportus et alii stationum typi habent meliores regiones acceptionis +STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES :Stationes societatum licet operari industriis quae proprias stationes habent: {STRING} STR_CONFIG_SETTING_EXTRADYNAMITE :Sinere plures vias, pontes, et cuniculos removere in oppidis: {STRING} STR_CONFIG_SETTING_EXTRADYNAMITE_HELPTEXT :Si electa, infrastructura et aedificia oppidorum sunt magis facilia remotu STR_CONFIG_SETTING_TRAIN_LENGTH :Longitudo traminum maxima: {STRING} @@ -1386,8 +1380,8 @@ STR_CONFIG_SETTING_TRAIN_SLOPE_STEEPNESS_HELPTEXT :Arduitas tegula STR_CONFIG_SETTING_PERCENTAGE :{COMMA}% STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS :Arduitas clivorum vehiculis viariis: {STRING} STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS_HELPTEXT :Arduitas tegulae clivosae vehiculo viario. Arduitate maiore, difficultas ascendendi maior est vehiculis -STR_CONFIG_SETTING_FORBID_90_DEG :Vetare tramina et naves cursum flectere 90°: {STRING} -STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :Tramina possunt cursum flectere in astariis aut 45° (diagonale deinde horizontale/verticale) aut 90° (horizontale deinde verticale); quoque naves possunt cursum 90° aut 45° cursum flectere. Hac electa, tantum 45° licet +STR_CONFIG_SETTING_FORBID_90_DEG :Vetare traminum cursum flectere 90°: {STRING} +STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :Tramina possunt cursum flectere in astariis aut 45° (diagonale deinde horizontale/verticale) aut 90° (horizontale deinde verticale). Hac electa, tantum 45° licet. STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS :Sinere stationes iungi quae non contigua sunt: {STRING} STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS_HELPTEXT :Sinere partes stationi addere quae non prorsus contigua sunt. Necesse est Ctrl premere dum novae partes adduntur. STR_CONFIG_SETTING_INFLATION :Inflatio: {STRING} @@ -1443,8 +1437,8 @@ STR_CONFIG_SETTING_PLANE_SPEED :Multiplicator v STR_CONFIG_SETTING_PLANE_SPEED_HELPTEXT :Eligere si aeroplana eant lentius quam alia vehicula, ut reditus aeroplanorum minuatur STR_CONFIG_SETTING_PLANE_SPEED_VALUE :1 / {COMMA} STR_CONFIG_SETTING_PLANE_CRASHES :Calamitates aeroplanicae accidunt: {STRING} -STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Eligere crebritatem calamitatum aeroplanicarum -STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Numquam +STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Eligere crebritatem calamitatum aeroplanicarum.{}* Aeroplana magna tamen semper corruere possunt si aeroportui parvo appellant. +STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Numquam* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Raro STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Mediocriter STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Sinere stationes viarias pervias esse in viis oppidorum: {STRING} @@ -1769,6 +1763,10 @@ STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :Electa, licet l STR_CONFIG_SETTING_TOWN_FOUNDING_FORBIDDEN :Non licet STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED :Licet STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED_CUSTOM_LAYOUT :Licet, atque propria dispositio oppidi +STR_CONFIG_SETTING_TOWN_CARGOGENMODE :Productionis urbani modus: {STRING} +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_HELPTEXT :Quot onera aedificia oppidorum faciunt.{}Modus quadraticus: Oppidum duplarum incolarum, quadruplex faciat vectores.{}Modus linearis: Oppidum duplarum incolarum, duplex faciat vectores. +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_ORIGINAL :Quadraticus (originalis) +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_BITCOUNT :Linearis STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :Positio arborum in ludo: {STRING} STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :Quomodo arbores apparent intra ludum. Forsitan industriae afficiuntur quibus necesse sunt arbores, e.g. castra lignatorum @@ -1896,7 +1894,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Partiti STR_CONFIG_SETTING_AI :{ORANGE}Competitores STR_CONFIG_SETTING_AI_NPC :{ORANGE}Lusores computatrales -STR_CONFIG_SETTING_PATHFINDER_OPF :Originale STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Commendatum) @@ -1980,13 +1977,9 @@ STR_QUIT_NO :{BLACK}Non # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -2324,7 +2317,7 @@ STR_NETWORK_CHAT_ALL :[Omnibus] {STRI STR_NETWORK_CHAT_OSKTITLE :{BLACK}Inscribere nuntium ad retis colloquium # Network messages -STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}Nullae res retis inventae vel compilata sine ENABLE_NETWORK +STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}Nullae res retis inventae STR_NETWORK_ERROR_NOSERVER :{WHITE}Nulli ludi in rete inventi STR_NETWORK_ERROR_NOCONNECTION :{WHITE}Nulla responsa a servatro STR_NETWORK_ERROR_NEWGRF_MISMATCH :{WHITE}Non potest iungere propter NewGRF imparia @@ -2631,6 +2624,7 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Struere STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Mutare inter vias struendas/removendas STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Mutare inter ferrivias stratarias struendas/removendas + # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Directio receptaculi viarii STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}Eligere directionem receptaculi viarii @@ -3515,8 +3509,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Infrastr STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Partes ferriviariae: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Signalia STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Partes viariae: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Viariae -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Ferriviae stratariae STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Tegulae aquariae: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Canales STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Stationes: @@ -3527,8 +3519,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Industriae STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Nullae - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% translat{G 1 us a um i ae a}) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% translat{G 3 us a um i ae a}) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Nomina industriarum - preme in nomen ut conspectus moveatur supra industriam. Ctrl+Preme ut nova fenestra conspectus aperiatur supra industriam @@ -3596,6 +3586,8 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Vehicula viaria STR_GROUP_DEFAULT_SHIPS :Naves sine grege STR_GROUP_DEFAULT_AIRCRAFTS :Aeroplana sine grege +STR_GROUP_COUNT_WITH_SUBGROUP :{TINY_FONT}{COMMA} (+{COMMA}) + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Greges - preme in gregem ut index vehiculorum huius gregis ostendeatur. Trahe poneque greges ut ordinentur. STR_GROUP_CREATE_TOOLTIP :{BLACK}Preme ut grex creatur STR_GROUP_DELETE_TOOLTIP :{BLACK}Delere gregem electam @@ -3622,12 +3614,16 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Vehicula Ferriv STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Vehicula Monoorbitalia Nova STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Vehicula Maglev Nova -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Vehicula Ferriviaria Nova STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Vehicula Viaria Nova + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Vehicula Ferriviaria Nova STR_BUY_VEHICLE_SHIP_CAPTION :Naves Novae STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Aeroplana Nova +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Pretium: {GOLD}{CURRENCY_LONG}{BLACK} Pondus: {GOLD}{WEIGHT_SHORT} +STR_PURCHASE_INFO_COST_REFIT_WEIGHT :{BLACK}Pretium: {GOLD}{CURRENCY_LONG}{BLACK} (Pretium Reficiendi: {GOLD}{CURRENCY_LONG}{BLACK}) Pondus: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Velocitas: {GOLD}{VELOCITY}{BLACK} Potestas: {GOLD}{POWER} STR_PURCHASE_INFO_SPEED :{BLACK}Velocitas: {GOLD}{VELOCITY} STR_PURCHASE_INFO_SPEED_OCEAN :{BLACK}Velocitas in mare: {GOLD}{VELOCITY} @@ -3638,8 +3634,10 @@ STR_PURCHASE_INFO_REFITTABLE :(refectabilis) STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Productum: {GOLD}{NUM}{BLACK} Aetas: {GOLD}{COMMA} ann{P us i} STR_PURCHASE_INFO_RELIABILITY :{BLACK}Constantia Maxima: {GOLD}{COMMA}% STR_PURCHASE_INFO_COST :{BLACK}Pretium: {GOLD}{CURRENCY_LONG} +STR_PURCHASE_INFO_COST_REFIT :{BLACK}Pretium: {GOLD}{CURRENCY_LONG}{BLACK} (Pretium Reficiendi: {GOLD}{CURRENCY_LONG}{BLACK}) STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Pondus: {GOLD}{WEIGHT_SHORT} ({WEIGHT_SHORT}) STR_PURCHASE_INFO_COST_SPEED :{BLACK}Pretium: {GOLD}{CURRENCY_LONG}{BLACK} Velocitas: {GOLD}{VELOCITY} +STR_PURCHASE_INFO_COST_REFIT_SPEED :{BLACK}Pretium: {GOLD}{CURRENCY_LONG}{BLACK} (Pretium Reficiendi: {GOLD}{CURRENCY_LONG}{BLACK}) Velocitas: {GOLD}{VELOCITY} STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Capacitas: {GOLD}{CARGO_LONG}, {CARGO_LONG} STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Currus Potentiati: {GOLD}+{POWER}{BLACK} Pondus: {GOLD}+{WEIGHT_SHORT} STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Refectabilis: {GOLD}{STRING.dat} @@ -3660,11 +3658,21 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Emere Ve STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Emere Navem STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Emere Aeroplanum +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Emere Reficereque Vehiculum +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Emere Reficereque Vehiculum +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Emere Reficereque Navem +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Emere Reficereque Aeroplanum + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Emere vehiculum ferriviarium electum. Shift+Preme ut pretium monstretur sine emptione STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Emere vehiculum viarium electum. Shift+Preme ut pretium monstretur sine emptione STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Emere navem electam. Shift+Preme ut pretium monstretur sine emptione STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Emere aeroplanum electum. Shift+Preme ut pretium monstretur sine emptione +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Emere et reficere vehiculum ferriviarium electum. Shift+Preme ut pretium monstretur sine emptione +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Emere et reficere vehiculum viarium electum. Shift+Preme ut pretium monstretur sine emptione +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Emere et reficere navem electam. Shift+Preme ut pretium monstretur sine emptione +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Emere et reficere aeroplanum electum. Shift+Preme ut pretium monstretur sine emptione + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Renominare STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Renominare STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Renominare @@ -3773,13 +3781,16 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Omnia v # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Nuntium a fabricatore vehiculorum STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Nuper fabricamus nov{G um am um os as a} {STRING} - visne uti hoc vehiculo unum annum, ut videamus quomodo operatur antequam omnibus venum damus? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :{G=f}hamaxam -STR_ENGINE_PREVIEW_ROAD_VEHICLE :{G=n}vehiculum viarium -STR_ENGINE_PREVIEW_AIRCRAFT :{G=n}aeroplanum -STR_ENGINE_PREVIEW_SHIP :{G=f}navem STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :{G=f}hamaxam monoorbitalem STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :{G=f}hamaxam maglev +STR_ENGINE_PREVIEW_ROAD_VEHICLE :{G=n}vehiculum viarium + +STR_ENGINE_PREVIEW_AIRCRAFT :{G=n}aeroplanum +STR_ENGINE_PREVIEW_SHIP :{G=f}navem + STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Pretium: {CURRENCY_LONG} Pondus: {WEIGHT_SHORT}{}Velocitas: {VELOCITY} Potestas: {POWER}{}Pretium Operandi: {CURRENCY_LONG} per annum{}Capacitas: {CARGO_LONG} STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Pretium: {CURRENCY_LONG} Pondus: {WEIGHT_SHORT}{}Velocitas: {VELOCITY} Potestas: {POWER} V.T. Max.: {6:FORCE}{}Pretium Operandi: {4:CURRENCY_LONG} per annum{}Capacitas: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Pretium: {CURRENCY_LONG} Velocitas Maxima: {VELOCITY}{}Capacitas: {CARGO_LONG}{}Pretium Operandi: {CURRENCY_LONG} per annum @@ -3825,6 +3836,7 @@ STR_REPLACE_ELRAIL_VEHICLES :Vehicula Ferriv STR_REPLACE_MONORAIL_VEHICLES :Vehicula Monoorbitalia STR_REPLACE_MAGLEV_VEHICLES :Vehicula Maglev + STR_REPLACE_REMOVE_WAGON :{BLACK}Ablatio curruum: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Facere ut automutatio longitudinem traminis contineat ablatione curruum (primo primorum), si tramen longius fiat mutatione hamaxae @@ -4277,6 +4289,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Eligere STR_AI_LIST_CANCEL :{BLACK}Cancellare STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Non scriptum mutare + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parametra STR_AI_SETTINGS_CAPTION_AI :IA @@ -4479,7 +4492,6 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... via STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... viae directio non convenit STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... stationi perviae non licet esse curva STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... stationi perviae non licet compita habere -STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... via est monodromus vel obstructa # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Non licet partem stationis removere... @@ -4549,7 +4561,7 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Necesse STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Nulla astaria idonea STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Necesse est ferriviam removere STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Via est monodromus vel obstructa -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Non licet huic typo ferriviae habere transitus +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Non licet huic typo ferriviae habere transitus STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Non licet signalia hic struere... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Non licet ferriviam hic struere... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Non licet ferriviam removere hic... diff --git a/src/lang/latvian.txt b/src/lang/latvian.txt index 56839cf783..65c5fc7f0f 100644 --- a/src/lang/latvian.txt +++ b/src/lang/latvian.txt @@ -12,8 +12,6 @@ ##case kas -# $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. # 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. @@ -472,9 +470,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Atvērt/aizvērt konsoli STR_ABOUT_MENU_AI_DEBUG :MI/spēles skriptu atkļūdošana STR_ABOUT_MENU_SCREENSHOT :Ekrānuzņēmums -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Pilnībā pietuvināts ekrānuzņēmums -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Noklusējuma mēroga ekrānuzņēmums -STR_ABOUT_MENU_GIANT_SCREENSHOT :Visas kartes ekrānuzņēmums STR_ABOUT_MENU_SHOW_FRAMERATE :Rādīt kadru ātrumu STR_ABOUT_MENU_ABOUT_OPENTTD :Par 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Gariņu līdzinātājs @@ -645,9 +640,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Pielāgotā 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Mūzikas skaļums STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Efektu skaļums -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}MIN -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}MAKS -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -857,6 +849,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}Tagad ir pieejams jauns {STRING}! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} vairs nepieņem {STRING} STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} vairs nepieņem {STRING} vai {STRING} STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} pieņem {STRING} @@ -1632,7 +1625,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Kravu s STR_CONFIG_SETTING_AI :{ORANGE}Sāncenši STR_CONFIG_SETTING_AI_NPC :{ORANGE}Nespēlētāju tēli (datora vadīti) -STR_CONFIG_SETTING_PATHFINDER_OPF :Sākotnējais STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(ieteicamais) @@ -1714,13 +1706,9 @@ STR_QUIT_NO :{BLACK}Nē # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -2346,6 +2334,7 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Būvēt STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Pārslēgties starp ceļa būvēšanas/nojaukšanas režīmiem STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Pārslēgt būvēt/novākt tramvaju būvei + # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Autotransporta depo virziens STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}Izvēlēties autotransporta depo virzienu @@ -3203,8 +3192,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}{COMPANY STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Sliežu gabali: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Signālierīces STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Ceļa gabali: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Ceļš -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Tramvajs STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Ūdens lauciņi: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Kanāli STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Stacijas: @@ -3216,8 +3203,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Ražotnes STR_INDUSTRY_DIRECTORY_NONE :{G=m}{ORANGE}- Neviens - STR_INDUSTRY_DIRECTORY_NONE.kas :{ORANGE}- Neviena - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% pārvadāts) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% pārvadāts) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Ražotņu nosaukumi - klikšķināt uz nosaukuma, lai centrētu skatu uz ražotni. Ctrl+klikšķis atvērs jaunu skatvietu pie ražotnes @@ -3279,6 +3264,7 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Negrupēti auto STR_GROUP_DEFAULT_SHIPS :Negrupēti kuģi STR_GROUP_DEFAULT_AIRCRAFTS :Negrupēti lidaparāti + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Grupas - klikšķināt uz grupas, lai iegūtu tās transportlīdzekļu sarakstu STR_GROUP_CREATE_TOOLTIP :{BLACK}Klikšķināt, lai izveidotu grupu STR_GROUP_DELETE_TOOLTIP :{BLACK}Dzēst izvēlēto grupu @@ -3300,10 +3286,13 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Jauni elektrifi STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Jauni viensliedes vilcieni STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Jauni magleva vilcieni -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Jauni vilcieni STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Jauni autotransporta līdzekļi + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Jauni vilcieni STR_BUY_VEHICLE_SHIP_CAPTION :Jauni kuģi STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Jauns lidaparāts +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Cena: {GOLD}{CURRENCY_LONG}{BLACK} Svars: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Ātrums: {GOLD}{VELOCITY}{BLACK} Jauda: {GOLD}{POWER} @@ -3336,11 +3325,13 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Pirkt au STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Pirkt kuģi STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Pirkt lidaparātu + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Pirkt atzīmēto vilciena vagonu. Shift+klikšķis rāda izmaksu novērtējumu, neveicot pirkumu STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Pirkt atzīmēto transportlīdzekli. Shift+klikšķis rāda izmaksu novērtējumu, neveicot pirkumu STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Pirkt atzīmēto kuģi. Shift+klikšķis rāda izmaksu novērtējumu, neveicot pirkumu STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Pirkt izvēlēto lidaparātu. Shift+klikšķis rāda izmaksu novērtējumu, neveicot pirkumu + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Pārdēvēt STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Pārdēvēt STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Pārdēvēt @@ -3449,13 +3440,16 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Jūs gr # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Ziņojums no transportlīdzekļu ražotāja STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Mēs tikko esam izstrādājuši jaunu transportlīdzekli - {STRING}. Vai esat ieinteresēts iegūt izņēmuma tiesības izmantot šo transportlīdzekli uz vienu gadu, lai mēs redzētu tā iespējas pirms padaram pieejamu visiem? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :dzelzceļa lokomotīve -STR_ENGINE_PREVIEW_ROAD_VEHICLE :autotransporta līdzeklis -STR_ENGINE_PREVIEW_AIRCRAFT :lidaparāts -STR_ENGINE_PREVIEW_SHIP :kuģis STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :viensliedes lokomotīve STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :magleva lokomotīve +STR_ENGINE_PREVIEW_ROAD_VEHICLE :autotransporta līdzeklis + +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_MAX_SPEED_CAP_RUNCOST :{BLACK}Cena: {CURRENCY_LONG} Maks. ātrums: {VELOCITY}{}Ietilpība: {CARGO_LONG}{}Kārtējās izmaksas: {CURRENCY_LONG} gadā @@ -3494,6 +3488,7 @@ STR_REPLACE_ELRAIL_VEHICLES :Elektrificētā STR_REPLACE_MONORAIL_VEHICLES :Viensliedes transportlīdzekļi STR_REPLACE_MAGLEV_VEHICLES :Magleva transportlīdzekļi + STR_REPLACE_REMOVE_WAGON :{BLACK}Vagona noņemšana: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Automātiskā aizvietošana saglabās esošo vilciena garumu noņemot vagonus (sākot no priekšgala), ja mainot lokomotīvi tas kļūtu garāks @@ -3936,6 +3931,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Izvēlē STR_AI_LIST_CANCEL :{BLACK}Atcelt STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Nemainīt skriptu + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} parametri STR_AI_SETTINGS_CAPTION_AI :MI @@ -4201,7 +4197,7 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Vispirms STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Nav piemērota sliežu ceļa STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Vispirms ir jānoņem dzelzceļa sliedes STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Ceļs ir bloķēts vai vienvirziena -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Vienlīmeņa krustojumi šīm sliedēm nav atļauti +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Vienlīmeņa krustojumi šīm sliedēm nav atļauti STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Šeit nevar būvēt signālierīces... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Šeit nevar būvēt dzelzceļa posmu... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Šeit nevar nojaukt dzelzceļa posmu... diff --git a/src/lang/lithuanian.txt b/src/lang/lithuanian.txt index b04f991d6f..077a34487b 100644 --- a/src/lang/lithuanian.txt +++ b/src/lang/lithuanian.txt @@ -12,8 +12,6 @@ ##case kas ko kam ka kuo kur kreip -# $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. # 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. @@ -667,9 +665,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Perjungti konsolę STR_ABOUT_MENU_AI_DEBUG :AI / GameScript derinimas STR_ABOUT_MENU_SCREENSHOT :Ekrano nuotrauka -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Ekrano nuotrauka iš arti -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Nepriartintas ekrano vaizdas -STR_ABOUT_MENU_GIANT_SCREENSHOT :Fotografuoti viso ekrano vaizdą STR_ABOUT_MENU_ABOUT_OPENTTD :Apie „OpenTTD“ STR_ABOUT_MENU_SPRITE_ALIGNER :Spruklių lygiuoklė STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Rodyti/slėpti apvadus @@ -839,9 +834,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Speciali 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Muzikos garsas STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Efektų garsas -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}MIN -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}MAX -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -1063,6 +1055,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}Naujas{STRING} - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} nebepriima {STRING} STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} nebepriima {STRING} arba {STRING} STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} jau priima {STRING} @@ -1903,7 +1896,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Krovini STR_CONFIG_SETTING_AI :{ORANGE}Konkurentai STR_CONFIG_SETTING_AI_NPC :{ORANGE}Kompiuterio žaidėjai -STR_CONFIG_SETTING_PATHFINDER_OPF :Originalus STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Rekomenduojama) @@ -1986,13 +1978,9 @@ STR_QUIT_NO :{BLACK}Ne # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -2620,6 +2608,7 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Statyti STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Aktyvinti automobilių kelių ir stotelių šalinimo veikseną STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Aktyvinti tramvajaus bėgių ir stotelių šalinimo veikseną + # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Pasirinkite garažo kryptį STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}Pasirinkite automobilių garažo kryptį @@ -3479,8 +3468,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}{COMPANY STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Bėgių dalys: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Signalai STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Kelio dalys: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Kelias -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Tramvajus STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Vandens langeliai: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Kanalai STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Stotys: @@ -3491,8 +3478,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Gamyklos STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Nieko - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% transportuota) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% transportuota) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Pramonės pavadinimai - spragtelėjus ant pavadinimo, pramonė rodoma ekrano centre. Ctrl+Paspaudimas atidaro nauja langą su pramonės vaizdu @@ -3554,6 +3539,7 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Nesugrupuoti au STR_GROUP_DEFAULT_SHIPS :Nesugrupuoti laivai STR_GROUP_DEFAULT_AIRCRAFTS :Nesugrupuoti lėktuvai + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Grupės - Spragtelk ant grupės jai priklausančių transporto priemonių peržiūrai STR_GROUP_CREATE_TOOLTIP :{BLACK}Spragtelk, kad sukurti grupę STR_GROUP_DELETE_TOOLTIP :{BLACK}Pašalinti pasirinktą grupę @@ -3575,10 +3561,13 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Nauji elektrini STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Nauji vienbėgiai lokomotyvai STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Nauji „Maglev“ lokomotyvai -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Nauji lokomotyvai STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Nauji automobiliai + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Nauji lokomotyvai STR_BUY_VEHICLE_SHIP_CAPTION :Nauji laivai STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Nauji lėktuvai +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Kaina: {GOLD}{CURRENCY_LONG}{BLACK} Svoris: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Greitis: {GOLD}{VELOCITY}{BLACK} Galia: {GOLD}{POWER} @@ -3611,11 +3600,13 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Pirkti STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Pirkti STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Pirkti + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Pirkti pažymėtą lokomotyvą ir/ar vagonus. Spragtelėjus laikant nuspaustą Shift klavišą, bus parodyta pirkinio kaina nieko realiai nenuperkant STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Pirkti pažymėtą automobilį. Spragtelėjus laikant nuspaustą Shift klavišą, bus parodyta pirkinio kaina nieko realiai nenuperkant STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Pirkti pažymėtą laivą. Spragtelėjus laikant nuspaustą Shift klavišą, bus parodyta pirkinio kaina nieko realiai nenuperkant STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Pirkti pažymėtą lėktuvą. Spragtelėjus laikant nuspaustą Shift klavišą, bus parodyta pirkinio kaina nieko realiai nenuperkant + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Pervardinti STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Pervardinti STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Pervardinti @@ -3724,6 +3715,7 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Ar tikr # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Žinutė nuo transporto priemonių gamintojo STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Mes ką tik sukūrėme naują {STRING.ka}! Ar norėtumėte vienerius metus išskirtinėmis teisėmis bandyti šią transporto priemonę, kol dar nepradėta jos serijinė gamyba? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :lokomotyvas STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE.kas :lokomotyvas STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE.ko :lokomotyvo @@ -3731,27 +3723,6 @@ STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE.kam :lokomotyvui STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE.ka :lokomotyvą STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE.kuo :lokomotyvu STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE.kur :lokomotyve -STR_ENGINE_PREVIEW_ROAD_VEHICLE :automobilis -STR_ENGINE_PREVIEW_ROAD_VEHICLE.kas :automobilis -STR_ENGINE_PREVIEW_ROAD_VEHICLE.ko :automobilio -STR_ENGINE_PREVIEW_ROAD_VEHICLE.kam :automobiliui -STR_ENGINE_PREVIEW_ROAD_VEHICLE.ka :automobilį -STR_ENGINE_PREVIEW_ROAD_VEHICLE.kuo :automobiliu -STR_ENGINE_PREVIEW_ROAD_VEHICLE.kur :automobilyje -STR_ENGINE_PREVIEW_AIRCRAFT :lėktuvas -STR_ENGINE_PREVIEW_AIRCRAFT.kas :lėktuvas -STR_ENGINE_PREVIEW_AIRCRAFT.ko :lėktuvo -STR_ENGINE_PREVIEW_AIRCRAFT.kam :lėktuvui -STR_ENGINE_PREVIEW_AIRCRAFT.ka :lėktuvą -STR_ENGINE_PREVIEW_AIRCRAFT.kuo :lėktuvu -STR_ENGINE_PREVIEW_AIRCRAFT.kur :lėktuve -STR_ENGINE_PREVIEW_SHIP :laivas -STR_ENGINE_PREVIEW_SHIP.kas :laivas -STR_ENGINE_PREVIEW_SHIP.ko :laivo -STR_ENGINE_PREVIEW_SHIP.kam :laivui -STR_ENGINE_PREVIEW_SHIP.ka :laivą -STR_ENGINE_PREVIEW_SHIP.kuo :laivu -STR_ENGINE_PREVIEW_SHIP.kur :laive STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :vienbėgis lokomotyvas STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE.kas :vienbėgis lokomotyvas STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE.ko :vienbėgio lokomotyvo @@ -3767,6 +3738,29 @@ STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE.ka :„Maglev“ lo STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE.kuo :„Maglev“ lokomotyvu STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE.kur :„Maglev“ lokomotyve +STR_ENGINE_PREVIEW_ROAD_VEHICLE :automobilis +STR_ENGINE_PREVIEW_ROAD_VEHICLE.kas :automobilis +STR_ENGINE_PREVIEW_ROAD_VEHICLE.ko :automobilio +STR_ENGINE_PREVIEW_ROAD_VEHICLE.kam :automobiliui +STR_ENGINE_PREVIEW_ROAD_VEHICLE.ka :automobilį +STR_ENGINE_PREVIEW_ROAD_VEHICLE.kuo :automobiliu +STR_ENGINE_PREVIEW_ROAD_VEHICLE.kur :automobilyje + +STR_ENGINE_PREVIEW_AIRCRAFT :lėktuvas +STR_ENGINE_PREVIEW_AIRCRAFT.kas :lėktuvas +STR_ENGINE_PREVIEW_AIRCRAFT.ko :lėktuvo +STR_ENGINE_PREVIEW_AIRCRAFT.kam :lėktuvui +STR_ENGINE_PREVIEW_AIRCRAFT.ka :lėktuvą +STR_ENGINE_PREVIEW_AIRCRAFT.kuo :lėktuvu +STR_ENGINE_PREVIEW_AIRCRAFT.kur :lėktuve +STR_ENGINE_PREVIEW_SHIP :laivas +STR_ENGINE_PREVIEW_SHIP.kas :laivas +STR_ENGINE_PREVIEW_SHIP.ko :laivo +STR_ENGINE_PREVIEW_SHIP.kam :laivui +STR_ENGINE_PREVIEW_SHIP.ka :laivą +STR_ENGINE_PREVIEW_SHIP.kuo :laivu +STR_ENGINE_PREVIEW_SHIP.kur :laive + STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Kaina: {CURRENCY_LONG} Svoris: {WEIGHT_SHORT}{}Greitis: {VELOCITY} Galia: {POWER}{}Eksploatavimo išlaidos: {CURRENCY_LONG} per metus{}Talpa: {CARGO_LONG} STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Kaina: {CURRENCY_LONG} Svoris: {WEIGHT_SHORT}{}Greitis: {VELOCITY} Galia: {POWER} Maks. T.E.: {6:FORCE}{}Einamosios išlaidos: {4:CURRENCY_LONG}/yr{}Talpa: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Kaina: {CURRENCY_LONG} Didž. Greitis: {VELOCITY}{}Talpa: {CARGO_LONG}{}Eksploatacijos išlaidos: {CURRENCY_LONG}/metams @@ -3809,6 +3803,7 @@ STR_REPLACE_ELRAIL_VEHICLES :Elektrifikuoti STR_REPLACE_MONORAIL_VEHICLES :Vienbegiai traukiniai STR_REPLACE_MAGLEV_VEHICLES :„Maglev“ traukiniai + STR_REPLACE_REMOVE_WAGON :{BLACK}Vagono pašalinimas: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Pakeitimo metu išlaikyti traukinio ilgį atjungiant vagonus (pradedant nuo priekio), jeigu pakeitus garvežį traukinys pailgėtų @@ -4274,6 +4269,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Pasirink STR_AI_LIST_CANCEL :{BLACK}Atšaukti STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Nekeisti skripto + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parametrai STR_AI_SETTINGS_CAPTION_AI :DI @@ -4545,7 +4541,7 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Pirma re STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Netinkamas bėgis STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Pirmiau pašalinkite geležinkelio bėgius STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Kelias vienpusis ar užblokuotas -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Sankryžos tame pačiame aukštyje neleidžiamos šiam bėgių tipui +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Sankryžos tame pačiame aukštyje neleidžiamos šiam bėgių tipui STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Šviesoforo čia statyti negalima ... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Begių čia statyti negalima... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Šių bėgių pašalinti negalima... diff --git a/src/lang/luxembourgish.txt b/src/lang/luxembourgish.txt index 58fb597536..af1f380672 100644 --- a/src/lang/luxembourgish.txt +++ b/src/lang/luxembourgish.txt @@ -10,8 +10,6 @@ ##grflangid 0x23 -# $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. # 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. @@ -226,8 +224,8 @@ 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_TITLE :{BLACK}Filter-String: +STR_LIST_FILTER_OSKTITLE :{BLACK}Filter-String STR_LIST_FILTER_TOOLTIP :{BLACK}Filter d'Lëscht op e Wuert STR_TOOLTIP_GROUP_ORDER :{BLACK}Wiel Gruppéierreihefollëg @@ -237,6 +235,8 @@ STR_TOOLTIP_FILTER_CRITERIA :{BLACK}Filterkr STR_BUTTON_SORT_BY :{BLACK}Sortéier no STR_BUTTON_LOCATION :{BLACK}Plaz STR_BUTTON_RENAME :{BLACK}Ëmbenennen +STR_BUTTON_CATCHMENT :{BLACK}Reechwäit +STR_TOOLTIP_CATCHMENT :{BLACK}Reechwäit uweisen un/ausschalten STR_TOOLTIP_CLOSE_WINDOW :{BLACK}Fënster zoumaachen STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Fënstertitel - hei zéien fir d'Fënster ze bewegen @@ -265,6 +265,7 @@ STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT_TOOLTIP :{BLACK}Mat dës STR_BUTTON_DEFAULT :{BLACK}Standard STR_BUTTON_CANCEL :{BLACK}Ofbriechen STR_BUTTON_OK :{BLACK}OK +STR_WARNING_PASSWORD_SECURITY :{YELLOW}Warnung: Server-Administratoren kënnen all Text aus desem Feld liesen. # On screen keyboard window STR_OSK_KEYBOARD_LAYOUT :§1234567890'^\qwertzuiopè¨asdfghjkléà yxcvbnm,.- . @@ -338,6 +339,7 @@ STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN :{BLACK}Vergréi STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT :{BLACK}Verklenger d'Sicht STR_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Schinne bauen STR_TOOLBAR_TOOLTIP_BUILD_ROADS :{BLACK}Stroosse bauen +STR_TOOLBAR_TOOLTIP_BUILD_TRAMWAYS :{BLACK}Tramway bauen STR_TOOLBAR_TOOLTIP_BUILD_SHIP_DOCKS :{BLACK}Schëffhafe bauen STR_TOOLBAR_TOOLTIP_BUILD_AIRPORTS :{BLACK}Fluchhafe bauen STR_TOOLBAR_TOOLTIP_LANDSCAPING :{BLACK}Landschafts-Toolbar opman fir Land ze erhéijen/senken, Beem planzen, etc. @@ -358,6 +360,7 @@ STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION :{BLACK}Landscha STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Stiederstellung 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_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 @@ -475,9 +478,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Konsole un/aus STR_ABOUT_MENU_AI_DEBUG :KI / Spill-Script Debug STR_ABOUT_MENU_SCREENSHOT :Screenshot (Ctrl+S) -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Voll eragezoomte Screenshot -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Standard Zoom Screenshot -STR_ABOUT_MENU_GIANT_SCREENSHOT :Screenshot vun der ganzer Kaart STR_ABOUT_MENU_SHOW_FRAMERATE :Biller pro Sekonn uweisen STR_ABOUT_MENU_ABOUT_OPENTTD :Iwwert 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Sprite Alignéirer @@ -648,9 +648,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Benotzerdéf. 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Musikvolume STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Volume vun den Effekter -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}MIN -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}MAX -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -675,6 +672,7 @@ STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Schalt d STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Weis d'Fënster fir Musik ze wielen # Playlist window +STR_PLAYLIST_MUSIC_SELECTION_SETNAME :{WHITE}Musik-Programm - '{STRING}' STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Lidder Index STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Programm - '{STRING}' @@ -791,11 +789,11 @@ STR_NEWS_FIRST_CARGO_TRAM_ARRIVAL :{BIG_FONT}{BLAC STR_NEWS_FIRST_SHIP_ARRIVAL :{BIG_FONT}{BLACK}Bierger feieren . . .{}Éischt Schëff kënnt zu {STATION} un! STR_NEWS_FIRST_AIRCRAFT_ARRIVAL :{BIG_FONT}{BLACK}Bierger feieren . . .{}Éischte Fliger kënnt zu {STATION} un! -STR_NEWS_TRAIN_CRASH :{BIG_FONT}{BLACK}Zuchakzident!{}{COMMA} Leit stiewen an der Explosioun nom Akzident -STR_NEWS_ROAD_VEHICLE_CRASH_DRIVER :{BIG_FONT}{BLACK}Stroossenakzident!{}Fuerer stierft an der Explosioun no Akzident mat Zuch -STR_NEWS_ROAD_VEHICLE_CRASH :{BIG_FONT}{BLACK}Stroossegefierakzident!{}{COMMA} Leit stiewen an der Explosioun no Akzident mam Zuch -STR_NEWS_AIRCRAFT_CRASH :{BIG_FONT}{BLACK}Fligerakzident!{}{COMMA} Leit stiewen an der Explosioun bei {STATION} -STR_NEWS_PLANE_CRASH_OUT_OF_FUEL :{BIG_FONT}{BLACK}Fligerakzident!{}Fliger hat kee Bensin méi, {COMMA} Leit stiewen an Explosioun! +STR_NEWS_TRAIN_CRASH :{BIG_FONT}{BLACK}Zuchaccident!{}{COMMA} Leit stiewen an der Explosioun nom Accident +STR_NEWS_ROAD_VEHICLE_CRASH_DRIVER :{BIG_FONT}{BLACK}Stroossenaccident!{}Fuerer stierft an der Explosioun no Accident mat Zuch +STR_NEWS_ROAD_VEHICLE_CRASH :{BIG_FONT}{BLACK}Stroossegefieraccident!{}{COMMA} Leit stiewen an der Explosioun no Accident mam Zuch +STR_NEWS_AIRCRAFT_CRASH :{BIG_FONT}{BLACK}Fligeraccident!{}{COMMA} Leit stiewen an der Explosioun bei {STATION} +STR_NEWS_PLANE_CRASH_OUT_OF_FUEL :{BIG_FONT}{BLACK}Fligeraccident!{}Fliger hat kee Bensin méi, {COMMA} Leit stiewen an Explosioun! STR_NEWS_DISASTER_ZEPPELIN :{BIG_FONT}{BLACK}Zeppelinkatastroph zu {STATION}! STR_NEWS_DISASTER_SMALL_UFO :{BIG_FONT}{BLACK}Stroossegefier bei 'UFO'-Zesummestouss zerstéiert! @@ -866,6 +864,8 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}Neie/Neit {STRING} verfügbar! - {ENGINE} +STR_NEWS_SHOW_VEHICLE_GROUP_TOOLTIP :{BLACK}Maach d'Gruppefenster op, fokusséiert op der Gefiergrupp + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} akzeptéiert {STRING} net méi STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} akzeptéiert {STRING} oder {STRING} net méi STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} akzeptéiert elo {STRING} @@ -885,9 +885,9 @@ STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION :{BIG_FONT}{BLAC # Extra view window STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Usiicht {COMMA} -STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Kopéiert op d'Usiicht +STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Ännert d'Usiicht STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Kopéiert d'Plaz vun der globaler Usiicht op des Usiicht -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Vun der Usiicht drasetzen +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Haptusiicht änneren STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Setzt d'Plaz vun dëser Usiicht op déi global Usiicht # Game options window @@ -932,6 +932,9 @@ STR_GAME_OPTIONS_CURRENCY_GEL :Georgesche Lari STR_GAME_OPTIONS_CURRENCY_IRR :Iranësche Rial (IRR) STR_GAME_OPTIONS_CURRENCY_RUB :Neie Russesche Rubel (RUB) STR_GAME_OPTIONS_CURRENCY_MXN :Mexikanesche Peso (MXN) +STR_GAME_OPTIONS_CURRENCY_NTD :New Taiwan Dollar (NTD) +STR_GAME_OPTIONS_CURRENCY_CNY :Chinesesch Renminbi (CNY) +STR_GAME_OPTIONS_CURRENCY_HKD :Hong Kong Dollar (HKD) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Stroossegefierer @@ -995,6 +998,7 @@ STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Duebel STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Véierfach 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_NORMAL :Normal STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Duebel Gréisst @@ -1177,11 +1181,13 @@ STR_CONFIG_SETTING_CITY_APPROVAL_HELPTEXT :Wielt aus, wéi STR_CONFIG_SETTING_MAX_HEIGHTLEVEL :Maximal Kaartenhéicht: {STRING} STR_CONFIG_SETTING_MAX_HEIGHTLEVEL_HELPTEXT :Setzt déi maximal erlabten Héicht fir Bierger op dëser Kaart -STR_CONFIG_SETTING_TOO_HIGH_MOUNTAIN :{WHITE}Du kanns d'maximal Kaartenhéischt net op dësen Wäert setzen. Op manst ee Bierg op der Kaart ass méi héich +STR_CONFIG_SETTING_TOO_HIGH_MOUNTAIN :{WHITE}Du kanns d'maximal Kaartenhéicht net op dëse Wäert setzen. Op manst ee Bierg op der Kaart ass méi héich STR_CONFIG_SETTING_AUTOSLOPE :Erlaabt Landformung ënnert Gebaier, Stroossen, etc.: {STRING} STR_CONFIG_SETTING_AUTOSLOPE_HELPTEXT :Erlaabt Terraintransformatioun ënnert Gebaier an Schinnen ouni dës ewechzehuelen STR_CONFIG_SETTING_CATCHMENT :Erlaabt méi realistësch Einzugsberäicher: {STRING} STR_CONFIG_SETTING_CATCHMENT_HELPTEXT :Statiounen a Fluchhäfen hunn verschidde grouss Einzugsberäicher +STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES :Gare vun der Firma kënnen Industrie beliwwere mat neutrale Statiounen: {STRING} +STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES_HELPTEXT :Wann ugeschalt dierefen Industrien mat agebaute Statiounen (z.b Buerinselen) och vu Firmestatiounen déi an der Géigend gebaut goufen beliwwert ginn. Wann ausgeschalt, dierfen se just vun den agebaute Statioune benotzt ginn. An der Géigend gebaute Firmestatiounen wärten se net benotzen an déi agebaute Statiounen beliwweren och keen ausser d'Industrie selwer. STR_CONFIG_SETTING_EXTRADYNAMITE :Erlaabt d'Ewechhuelen vu méi Stroossen, Brécken, etc. vun der Stad: {STRING} STR_CONFIG_SETTING_EXTRADYNAMITE_HELPTEXT :Mach et méi einfach fir Infrastruktur oder Gebaier ewechzehuelen déi enger Stad gehéiren STR_CONFIG_SETTING_TRAIN_LENGTH :Maximal Längt vun Zich: {STRING} @@ -1198,8 +1204,8 @@ STR_CONFIG_SETTING_TRAIN_SLOPE_STEEPNESS_HELPTEXT :Steigung vun en STR_CONFIG_SETTING_PERCENTAGE :{COMMA}% STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS :Hangsteigung fir Stroossegefierer: {STRING} STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS_HELPTEXT :Steigung vun engem Hang fir Stroossegefierer. Méi grouss Wäerter mécht et méi schwéier den Hang ropzefueren -STR_CONFIG_SETTING_FORBID_90_DEG :Verbidd Zich an Schëffer fir 90°-Kéieren ze maachen: {STRING} -STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :90°-Kéieren entsti wann eng horizontal Spur direkt op eng vertikal trëfft, sou dass den Zuch misst ëm 90 Grad dréinen fir op dat nächst Stéck ze kommen, amplaz vun den üblechen 45 Grad. Dëst zielt och fir d'Weeër vu Schëffer +STR_CONFIG_SETTING_FORBID_90_DEG :Verbidd Zich fir 90°-Kéieren ze maachen: {STRING} +STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :90°-Kéieren entsti wann eng horizontal Spur direkt op eng vertikal trëfft, sou dass den Zuch misst ëm 90 Grad dréinen fir op dat nächst Stéck ze kommen, amplaz vun den üblechen 45 Grad. STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS :Erlaabt Statiounen zesummen ze setzen och wann se net direkt uneneen leien: {STRING} STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS_HELPTEXT :Erlaabt Statiounsdeeler un eng Statioun unzehenken ouni déi existéiernd Statioun ze beréiren. Ctr+Klick fir déi nei Deeler unzehenken STR_CONFIG_SETTING_INFLATION :Inflatioun: {STRING} @@ -1254,9 +1260,9 @@ STR_CONFIG_SETTING_FREIGHT_TRAINS_HELPTEXT :Leet den Impakt STR_CONFIG_SETTING_PLANE_SPEED :Fligergeschwindegkeetsfaktor: {STRING} STR_CONFIG_SETTING_PLANE_SPEED_HELPTEXT :Leet d'relativ Geschwindegkeet vu Fligeren am Verglach mat anere Gefierer fest, fir d'Akomme vum Transport vu Fligeren ze reduzéiren STR_CONFIG_SETTING_PLANE_SPEED_VALUE :1 / {COMMA} -STR_CONFIG_SETTING_PLANE_CRASHES :Unzuel Fligerakzidenter: {STRING} -STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Leet d'Chance fir en Fligerakzident fest -STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Keng +STR_CONFIG_SETTING_PLANE_CRASHES :Unzuel Fligeraccidenter: {STRING} +STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Leet d'Chance fir enzoufällegen Fligeraccident fest.{}* Grouss Fligeren hunn emmer en Accidents-Risiko wann se op engem klenge Fluchhafen landen +STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Keng* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Reduzéiert STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normal STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Erlaabt d'Iwwerfueren vu Stopschëlder op Stroossen vun der Stad: {STRING} @@ -1268,6 +1274,7 @@ STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE :Infrastrukturë STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE_HELPTEXT :Wann ugeschalt, kaschten Infrastrukturen Ennerhaltskäschten. D'Käschten wuessen iwwerproportional zu der Netzwierkgréisst, an treffen sou grouss Firmen méi wéi klenger STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR :Firmefaarw um Start: {STRING} +STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR_HELPTEXT :Wiel d'Startfaarw vun der Firma STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS :Fluchhäfen lafen nie of: {STRING} STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS_HELPTEXT :Wann ugeschalt, bleift all Fluchhafentyp säit senger Aféierung bestoen @@ -1313,8 +1320,8 @@ STR_CONFIG_SETTING_TERRAIN_TYPE :Terraintyp: {ST STR_CONFIG_SETTING_TERRAIN_TYPE_HELPTEXT :(Nëmmen TerraGenesis) Hiwwelegkeet vun der Landschaft STR_CONFIG_SETTING_INDUSTRY_DENSITY :Industriedicht: {STRING} STR_CONFIG_SETTING_INDUSTRY_DENSITY_HELPTEXT :Definéiert wéivill Industrien generéiert sollen ginn an wéivill der während dem Spill sollen behalen ginn. -STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE :Maximal Distanz vum Kaartenenn bis zu enger Uelegraffinerie: {STRING} -STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :Uelëgraffinerien ginn nëmmen um Rand gebaut, dat ass un der Küst fir Inselkaarten +STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE :Maximal Distanz vum Kaarterand bis zu enger Uelegindustrie: {STRING} +STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :Limitéiert wéi wäit vum Bord Uelegraffinerien an Buerinsele dierfe gebaut ginn. Op Inselkaarten garantéiert dest dass se um Rand gebaut ginn. Op Kaarten mat méi wéi 256 Felder, gett dese Wert skaléiert STR_CONFIG_SETTING_SNOWLINE_HEIGHT :Schnéigrenz Héicht: {STRING} STR_CONFIG_SETTING_SNOWLINE_HEIGHT_HELPTEXT :Kontrolléiert ab welcher Héicht de Schnéi ufenkt an der subarktëscher Landschaft. Schnéi affektéiert och Industriegeneratioun an de Wuesstum vu Stied. STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN :Knubbelegkeet vum Terrain (nëmmen TerraGenesis) : {STRING} @@ -1355,6 +1362,8 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :Mof STR_CONFIG_SETTING_SCROLLMODE :Usiicht-Scrollverhalen: {STRING} STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :Verhalen beim Scrolle vun der Kaart STR_CONFIG_SETTING_SCROLLMODE_DEFAULT :D'Usiicht mat der rietser Maustast bewegen, Maus-Positioun gespaart +STR_CONFIG_SETTING_SCROLLMODE_RMB_LOCKED :Beweg d'Kaart mat der rietser Maustast, Maus-Positioun gespaart +STR_CONFIG_SETTING_SCROLLMODE_RMB :D'Kaart mat der rietser Maustast bewegen STR_CONFIG_SETTING_SCROLLMODE_LMB :Kaart mat der lénker Maustast bewegen STR_CONFIG_SETTING_SMOOTH_SCROLLING :Feine Scrolling: {STRING} STR_CONFIG_SETTING_SMOOTH_SCROLLING_HELPTEXT :Kontrolléiert wéi d'Haptusiicht op eng bestëmmten Positioun scrollt, wann een op déi kléng Kaart klickt oder en Befehl fir ob en spezifescht Objet ze scrollen gëtt. Wann ugeschalt, gëtt bis dohin gescrollt, wann ausgeschalt, spréngt d'Vue op den Zielobjet @@ -1439,8 +1448,8 @@ STR_CONFIG_SETTING_SOUND_CONFIRM :Konstruktioun: STR_CONFIG_SETTING_SOUND_CONFIRM_HELPTEXT :Spill Soundeffekter of wa Konstruktiounen an aner Aktiounen ausgefouert goufen STR_CONFIG_SETTING_SOUND_CLICK :Kneppercherklicks: {STRING} STR_CONFIG_SETTING_SOUND_CLICK_HELPTEXT :Beep beim Klicken vu Kneppercher -STR_CONFIG_SETTING_SOUND_DISASTER :Katastrophen/Akzidenter: {STRING} -STR_CONFIG_SETTING_SOUND_DISASTER_HELPTEXT :Spill Soundeffekter vun Akzidenter a Katastrophen of +STR_CONFIG_SETTING_SOUND_DISASTER :Katastrophen/Accidenter: {STRING} +STR_CONFIG_SETTING_SOUND_DISASTER_HELPTEXT :Spill Soundeffekter vun Accidenter a Katastrophen of STR_CONFIG_SETTING_SOUND_VEHICLE :Gefierer: {STRING} STR_CONFIG_SETTING_SOUND_VEHICLE_HELPTEXT :Spill Soundeffekter vu Gefierer of STR_CONFIG_SETTING_SOUND_AMBIENT :Ambiance: {STRING} @@ -1476,6 +1485,9 @@ STR_CONFIG_SETTING_AI_IN_MULTIPLAYER :Erlaabt KI am M STR_CONFIG_SETTING_AI_IN_MULTIPLAYER_HELPTEXT :Erlaabt Computergéigner a Multiplayer Spiller matzeman STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES :#opcodes befier de Script suspendéiert gëtt: {STRING} STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES_HELPTEXT :Maximal Unzuel u Rechenschrëtt déi e Script kann an engem Tuer man +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY :Max Späicherverbrauch pro Script: {STRING} +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_HELPTEXT :Wéivill Späicher en eenzelne Script dierf benotzen befier en gezwongenerweis gestopt gëtt. Dese Wert muss eventuell erhéigt ginn fir grouss Kaarten. +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_VALUE :{COMMA} MiB STR_CONFIG_SETTING_SERVINT_ISPERCENT :Revisiounsintervallen a Prozenter: {STRING} STR_CONFIG_SETTING_SERVINT_ISPERCENT_HELPTEXT :Wiel op eng Revisioun ausgeléist gëtt durch Zäit déi säit der leschter Revisioun vergangen ass oder well Zouverlessëgkeet en gewëssen Prozentsaz vun der maximaler Zouverlässëgkeet erofgaang ass @@ -1500,8 +1512,8 @@ STR_CONFIG_SETTING_NEWS_ARRIVAL_FIRST_VEHICLE_OWN :Ukonft vum éis STR_CONFIG_SETTING_NEWS_ARRIVAL_FIRST_VEHICLE_OWN_HELPTEXT :Weis d'Zeitung wann dat éischt Gefier op enger eegener Statioun ukënnt STR_CONFIG_SETTING_NEWS_ARRIVAL_FIRST_VEHICLE_OTHER :Ukonft vum éischten Gefier op enger Géigenspillerstatioun: {STRING} STR_CONFIG_SETTING_NEWS_ARRIVAL_FIRST_VEHICLE_OTHER_HELPTEXT :Weis d'Zeitung wann dat éischt Gefier op enger géignerescher Statioun ukënnt -STR_CONFIG_SETTING_NEWS_ACCIDENTS_DISASTERS :Akzidenter / Katastrophen: {STRING} -STR_CONFIG_SETTING_NEWS_ACCIDENTS_DISASTERS_HELPTEXT :Weis d'Zeitung wann Akzidenter oder Katastrophen passéiren +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_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 STR_CONFIG_SETTING_NEWS_INDUSTRY_OPEN :Grënnung vun enger Industrie: {STRING} @@ -1534,10 +1546,16 @@ STR_CONFIG_SETTING_NEWS_MESSAGES_FULL :Ganz STR_CONFIG_SETTING_COLOURED_NEWS_YEAR :Faarweg News ab: {STRING} STR_CONFIG_SETTING_COLOURED_NEWS_YEAR_HELPTEXT :Joer vun dem uns d'Zeitung farweg erauskënnt. Firun dësem Joer ass se schwarz/wäiss STR_CONFIG_SETTING_STARTING_YEAR :Startjoer: {STRING} +STR_CONFIG_SETTING_ENDING_YEAR :End-Joer vum Scoring: {STRING} +STR_CONFIG_SETTING_ENDING_YEAR_HELPTEXT :Joer wou d'Spill opgrond vum Scoring ophält. Um Enn vun desem Joer gëtt der Firma hiere Score gespäichert an an der Highscore-Lëscht ugewisen, mee de Spiller kann dono weider spillen.{}Wann dese Wert virum Startjoer ass, gëtt d'Highscorelëscht nie ugewisen. +STR_CONFIG_SETTING_ENDING_YEAR_VALUE :{NUM} +STR_CONFIG_SETTING_ENDING_YEAR_ZERO :Nie STR_CONFIG_SETTING_SMOOTH_ECONOMY :Gläichméisseg Wiertschaft aschalten (méi oft an kleng Wiessel): {STRING} STR_CONFIG_SETTING_SMOOTH_ECONOMY_HELPTEXT :Wann ugeschalt, ännert d'Industrieproduktioun méi oft, an méi kléngen Schrëtter. Dës Astellung huet keng Auswierkung op NewGRF-Industrien 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_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. STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE :Prozentsaz vum Etappenprofit den am Feeder-System bezuelt gëtt: {STRING} STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE_HELPTEXT :Prozentsaz vum Akommes déi un d'Zwëschenetappen an engem Feeder-System gi ginn, wat méi Kontroll iwwert d'Akommes erméiglegt STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY :Wa gezunn gëtt, setz en Signal all: {STRING} @@ -1569,7 +1587,7 @@ STR_CONFIG_SETTING_TOWN_LAYOUT_3X3_GRID :3x3 Gitter STR_CONFIG_SETTING_TOWN_LAYOUT_RANDOM :Zoufälleg STR_CONFIG_SETTING_ALLOW_TOWN_ROADS :Stied däerfen Stroossen bauen: {STRING} STR_CONFIG_SETTING_ALLOW_TOWN_ROADS_HELPTEXT :Erlaabt Stied Stroossen ze bauen fir ze wuessen. Ausschalten fir d'Stiedréid dorun ze hënneren fir Stroossen selwer ze bauen -STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS :Stied dierfen Barrièren bauen: {STRING} +STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS :Stied dierfe Barrière bauen: {STRING} STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS_HELPTEXT :Wann dës Astellung ugeschalt ass, kënnen Stied Stroossen iwwert Schinne bauen STR_CONFIG_SETTING_NOISE_LEVEL :Erlab e stadkontrolléierte Kaméidisniveau fir Fluchhäfen: {STRING} STR_CONFIG_SETTING_NOISE_LEVEL_HELPTEXT :Wann dës Astellung ausgeschalt ass, kënnen zwee Fluchhäfen an all Stad gebaut ginn. Wann dës Astellung ugeschalt ass, henkt et vun der Fluchhafengréisst, Distanz, Kaméidisniveau of wéivill Fluchhäfen kënne gebaut ginn @@ -1578,6 +1596,10 @@ STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :Wann dës Astel STR_CONFIG_SETTING_TOWN_FOUNDING_FORBIDDEN :Verbueden STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED :Erlaabt STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED_CUSTOM_LAYOUT :Erlaabt, custom Stad-Layout +STR_CONFIG_SETTING_TOWN_CARGOGENMODE :Duerfwuerengeneratioun: {STRING} +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_HELPTEXT :Wéivill Wuere produzéiert ginn, relativ zur Bevölkerung vum Duerf.{}Quadratesche Wuesstum: En duebel sou grousst Duerf, generéiert véier mol souvill Passagéier.{}Lineare Wuesstum: En duebel sou grousst Duerf, generéiert duebel souvill Passagéier. +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_ORIGINAL :Quadratesch (original) +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_BITCOUNT :Linear STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :Bamplazéirung: {STRING} STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :Kontrolléiert zoufälleg Optauche vu Beem während dem Spill. Dëst kann Industrie beaflossen, déi op d'Wuessen vu Beem ugewisen sinn @@ -1695,7 +1717,7 @@ STR_CONFIG_SETTING_VEHICLES :{ORANGE}Gefiere STR_CONFIG_SETTING_VEHICLES_PHYSICS :{ORANGE}Physik STR_CONFIG_SETTING_VEHICLES_ROUTING :{ORANGE}Routeplangung STR_CONFIG_SETTING_LIMITATIONS :{ORANGE}Limitatiounen -STR_CONFIG_SETTING_ACCIDENTS :{ORANGE}Katastrophen / Akzidenter +STR_CONFIG_SETTING_ACCIDENTS :{ORANGE}Katastrophen / Accidenter STR_CONFIG_SETTING_GENWORLD :{ORANGE}Welt Generatioun STR_CONFIG_SETTING_ENVIRONMENT :{ORANGE}Emwelt STR_CONFIG_SETTING_ENVIRONMENT_AUTHORITIES :{ORANGE}Autoritéiten @@ -1705,7 +1727,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Wuereve STR_CONFIG_SETTING_AI :{ORANGE}Géigner STR_CONFIG_SETTING_AI_NPC :{ORANGE}Computerspiller -STR_CONFIG_SETTING_PATHFINDER_OPF :Original STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(recommandéiert) @@ -1737,7 +1758,7 @@ STR_CONFIG_ERROR_INVALID_SAVEGAME_COMPRESSION_ALGORITHM :{WHITE}... Spil 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 -STR_CONFIG_ERROR_OUT_OF_MEMORY :{WHITE}Net genuch Mémoire +STR_CONFIG_ERROR_OUT_OF_MEMORY :{WHITE}Net genuch Späicher STR_CONFIG_ERROR_SPRITECACHE_TOO_BIG :{WHITE}Reservéirung vun {BYTES} Spritecache versot. De Spritecache gouf reduzéiert op {BYTES}. Dëst reduzéiert d'Performance vun OpenTTD. Fir Späicher ze spueren kann een probéiren 32bpp Grafiken auszeschalten an/oder Zoom-Eran Stufen # Intro window @@ -1789,19 +1810,15 @@ STR_QUIT_NO :{BLACK}Nee # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS # 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_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 ? # Cheat window @@ -1812,7 +1829,7 @@ STR_CHEAT_MONEY :{LTBLUE}Suen ë 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} STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}Tunnelle kënne sech kräizen: {ORANGE}{STRING} -STR_CHEAT_NO_JETCRASH :{LTBLUE}Jet'en maachen net regelméisseg en Akzident op klenge Fluchhäfen: {ORANGE} {STRING} +STR_CHEAT_NO_JETCRASH :{LTBLUE}Jete maache net regelméisseg en Accident op klenge Fluchhäfen: {ORANGE} {STRING} STR_CHEAT_EDIT_MAX_HL :{LTBLUE}Änner d'Maximalhéicht vu Bierger op der Kaart: {ORANGE}{NUM} STR_CHEAT_EDIT_MAX_HL_QUERY_CAPT :{WHITE}Änner d'Maximalhéicht vu Bierger op der Kaart STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Gemässegt Klima Landschaft @@ -2084,6 +2101,7 @@ STR_NETWORK_CONNECTION_DISCONNECT :{BLACK}Verbindu STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Server ass geschützt. Passwuert aginn STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Firma ass geschützt. Passwuert aginn +STR_NETWORK_COMPANY_LIST_CLIENT_LIST_CAPTION :{WHITE}Spillerlëscht # Network company list added strings STR_NETWORK_COMPANY_LIST_CLIENT_LIST :Spillerlëscht @@ -2132,7 +2150,7 @@ STR_NETWORK_CHAT_ALL :[All] {STRING}: STR_NETWORK_CHAT_OSKTITLE :{BLACK}Text fir Chat aginn # Network messages -STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}Keng Netzwierkgeräter fonnt oder compiléiert ouni ENABLE_NETWORK +STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}Keng Netzwierkgeräter fonnt STR_NETWORK_ERROR_NOSERVER :{WHITE}Konnt keng Netzwierkspiller fannen STR_NETWORK_ERROR_NOCONNECTION :{WHITE}De Server huet net op d'Ufro geäntwert STR_NETWORK_ERROR_NEWGRF_MISMATCH :{WHITE}Konnt sech wéinst ënnerscheedlechen NewGRF net connectéieren @@ -2256,7 +2274,7 @@ STR_CONTENT_TYPE_NEWGRF :NewGRF STR_CONTENT_TYPE_AI :KI STR_CONTENT_TYPE_AI_LIBRARY :KI Librairie STR_CONTENT_TYPE_SCENARIO :Szenario -STR_CONTENT_TYPE_HEIGHTMAP :Héischtekaart +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 @@ -2299,6 +2317,7 @@ STR_LINKGRAPH_LEGEND_CAPTION :{BLACK}Cargo Fl STR_LINKGRAPH_LEGEND_ALL :{BLACK}All STR_LINKGRAPH_LEGEND_NONE :{BLACK}Keng STR_LINKGRAPH_LEGEND_SELECT_COMPANIES :{BLACK}Wiel d'Firmen aus déi ugewise ginn +STR_LINKGRAPH_LEGEND_COMPANY_TOOLTIP :{BLACK}{STRING}{}{COMPANY} # Linkgraph legend window and linkgraph legend in smallmap STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLACK}onbenotzt @@ -2383,9 +2402,9 @@ STR_BUILD_SIGNAL_ELECTRIC_COMBO_TOOLTIP :{BLACK}Combo-Si STR_BUILD_SIGNAL_ELECTRIC_PBS_TOOLTIP :{BLACK}Wee-Signal (Elektresch){}E Wee-Signal erlaabt méi wéi engem Zuch an e Block eranzefueren, wann den Zuch e Wee op en Stop-Punkt reservéiren kann. Standard Wee-Signaler kënne vu béide Säiten duerchfuer ginn STR_BUILD_SIGNAL_ELECTRIC_PBS_OWAY_TOOLTIP :{BLACK}Einbahn-Wee-Signal (Elektresch){}En Einbahn-Signal erlaabt méi wéi een Zuch zur selwechter Zäit an engem Block ze sin, wann den Zuch en Wee op en sécheren Stop-Punkt reservéiren kann. Einbahn-Signaler kënnen net vun der falscher Säit duerchfuer ginn STR_BUILD_SIGNAL_CONVERT_TOOLTIP :{BLACK}Signal konvertéiren{}Wann gewielt, gëtt en geklickten Signal an dat gewielten Signal konvertéiert, Ctrl+Klick wiesselt tëscht de Varianten. Shift weist ongeféier Konvertéirungskäschten -STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP :{BLACK}Dicht vu Signaler beim Zéien +STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP :{BLACK}Distanz vu Signaler beim Zéien STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_DECREASE_TOOLTIP :{BLACK}Setzt Signaldistanz erof -STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Setzt Signaldicht erop +STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Setzt Signaldistanz erop # Bridge selection window STR_SELECT_RAIL_BRIDGE_CAPTION :{WHITE}Zuchbréck auswielen @@ -2407,7 +2426,7 @@ STR_BRIDGE_TUBULAR_SILICON :Rouer, Silikon STR_ROAD_TOOLBAR_ROAD_CONSTRUCTION_CAPTION :{WHITE}Stroossebau STR_ROAD_TOOLBAR_TRAM_CONSTRUCTION_CAPTION :{WHITE}Tramkonstruktioun STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_SECTION :{BLACK}Baut Stroossen.Ctrl+Klick wiësselt tëscht Stroosse bauen/ofrappen. Shift wiesselt tëscht bauen/ongeféier Käschten uweisen -STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION :{BLACK}Tramschinne bauen. Ctrl+Klick wiësselt tëscht Tramschinne bauen/ofrappen. Shift wiesselt tëscht bauen/ongeféier Käschten uweisen +STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION :{BLACK}Tramwayschinne bauen. Ctrl+Klick wiësselt tëscht Tramwayschinne bauen/ofrappen. Shift wiesselt tëscht bauen/ongeféier Käschten uweisen STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOROAD :{BLACK}D'Strooss mat der Bau-Automatik bauen. Ctrl wiësselt tëscht Stroossen bauen/ofrappen. Shift wiesselt tëscht bauen/ongeféier Käschten uweisen STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOTRAM :{BLACK}Tramschinne mam "Autotram" Modus bauen. Ctrl wiesselt tëscht Tramschinne bauen/ofrappen. Shift wiesselt tëschtbauen/ongeféier Käschten uweisen STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}Baut Stroossendepot (fir Gefierer ze kafen an ze flécken). Shift wiesselt tëscht bauen/ongeféier Käschten uweisen @@ -2423,6 +2442,11 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL :{BLACK}Baut Str STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Tramtunnel bauen. Shift wiesselt tëscht bauen/ongeféier Käschten uweisen STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Wiesselt bauen/ofrappen vu Stroossekonstruktiounen STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Wiesselt tëscht bauen/ofrappen beim Trambau +STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_ROAD :{BLACK}Konvertéier/upgrade den Typ vu Strooss. Shift wiesselt tëscht bauen/ongeféier Käschten uweisen +STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_TRAM :{BLACK}Konvertéiert/upgrade den Typ vun Tram. Shift wiesselt tëscht bauen/ongeféier Käschten uweisen + +STR_ROAD_NAME_ROAD :Strooss +STR_ROAD_NAME_TRAM :Tramway # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Ausriichtung vum Stroossendepot @@ -2523,7 +2547,7 @@ STR_TERRAFORM_RESET_LANDSCAPE :{BLACK}Setz d'L STR_TERRAFORM_RESET_LANDSCAPE_TOOLTIP :{BLACK}Huel all Grondstécker vun der Firma ewech STR_QUERY_RESET_LANDSCAPE_CAPTION :{WHITE}Setz d'Landschaft zeréck -STR_RESET_LANDSCAPE_CONFIRMATION_TEXT :{WHITE}Bass du sécher dass du all Grondstécker vun der Firma ewechhuelen wëlls? +STR_RESET_LANDSCAPE_CONFIRMATION_TEXT :{WHITE}Bass du sécher, dass du all Grondstécker vun der Firma ewechhuele wëlls? # Town generation window (SE) STR_FOUND_TOWN_CAPTION :{WHITE}Staderstellung @@ -2607,8 +2631,11 @@ STR_LAND_AREA_INFORMATION_NEWGRF_NAME :{BLACK}NewGRF: STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED :{BLACK}Akzeptéiert Wuer: {LTBLUE} STR_LAND_AREA_INFORMATION_CARGO_EIGHTS :({COMMA}/8 {STRING}) STR_LANG_AREA_INFORMATION_RAIL_TYPE :{BLACK}Schinnentyp: {LTBLUE}{STRING} +STR_LANG_AREA_INFORMATION_ROAD_TYPE :{BLACK}Stroossentyp: {LTBLUE}{STRING} +STR_LANG_AREA_INFORMATION_TRAM_TYPE :{BLACK}Tramtyp: {LTBLUE}{STRING} STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT :{BLACK}Schinne-Geschw.-Limit: {LTBLUE}{VELOCITY} STR_LANG_AREA_INFORMATION_ROAD_SPEED_LIMIT :{BLACK}Stroosse-Geschw.-Limit: {LTBLUE}{VELOCITY} +STR_LANG_AREA_INFORMATION_TRAM_SPEED_LIMIT :{BLACK}Tram-Geschw.-Limit: {LTBLUE}{VELOCITY} # Description of land area of different tiles STR_LAI_CLEAR_DESCRIPTION_ROCKS :Fielsen @@ -2648,7 +2675,7 @@ STR_LAI_ROAD_DESCRIPTION_ROAD_WITH_STREETLIGHTS :Strooss mat Luu STR_LAI_ROAD_DESCRIPTION_TREE_LINED_ROAD :Strooss mat Beem STR_LAI_ROAD_DESCRIPTION_ROAD_VEHICLE_DEPOT :Stroossendepot STR_LAI_ROAD_DESCRIPTION_ROAD_RAIL_LEVEL_CROSSING :Zuche/Stroosse-Barrière -STR_LAI_ROAD_DESCRIPTION_TRAMWAY :Tram +STR_LAI_ROAD_DESCRIPTION_TRAMWAY :Tramway # Houses come directly from their building names STR_LAI_TOWN_INDUSTRY_DESCRIPTION_UNDER_CONSTRUCTION :{STRING} (gëtt gebaut) @@ -2709,33 +2736,61 @@ STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD # Framerate display window STR_FRAMERATE_CAPTION :{WHITE}Biller pro Sekonn +STR_FRAMERATE_CAPTION_SMALL :{STRING}{WHITE} ({DECIMAL}x) +STR_FRAMERATE_RATE_GAMELOOP :{BLACK}Simulationsrat: {STRING} STR_FRAMERATE_RATE_GAMELOOP_TOOLTIP :{BLACK}Unzuel Gameticks déi pro Sekonn simuléiert ginn. +STR_FRAMERATE_RATE_BLITTER :{BLACK}Grafikframerate: {STRING} +STR_FRAMERATE_RATE_BLITTER_TOOLTIP :{BLACK}Unzuel u Videobiller déi pro Sekonn gerendert ginn. +STR_FRAMERATE_SPEED_FACTOR :{BLACK}Aktuelle Spillgeschw.-Faktor: {DECIMAL}x +STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}Wéi séier d'Spill aktuell leeft, am Verglach mat der Geschw. vun der normaler Simulatioun. STR_FRAMERATE_CURRENT :{WHITE}Aktuell STR_FRAMERATE_AVERAGE :{WHITE}Mëttel +STR_FRAMERATE_MEMORYUSE :{WHITE}Späicher +STR_FRAMERATE_DATA_POINTS :{BLACK}Date baséiert op {COMMA} Miessungen STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL} ms STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL} ms STR_FRAMERATE_MS_BAD :{RED}{DECIMAL} ms STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL} Biller/s +STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL} Biller/s STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL} Biller/s +STR_FRAMERATE_BYTES_GOOD :{LTBLUE}{BYTES} +STR_FRAMERATE_BYTES_WARN :{YELLOW}{BYTES} +STR_FRAMERATE_BYTES_BAD :{RED}{BYTES} +STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} ms STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} s ############ Leave those lines in this order!! STR_FRAMERATE_GAMELOOP :{BLACK}Spill total: -STR_FRAMERATE_GL_TRAINS :{BLACK} Zuchticks: -STR_FRAMERATE_GL_ROADVEHS :{BLACK} Stroossegefierer Ticken: +STR_FRAMERATE_GL_ECONOMY :{BLACK} Wuerenhandling: +STR_FRAMERATE_GL_TRAINS :{BLACK} Zuchticker: +STR_FRAMERATE_GL_ROADVEHS :{BLACK} Stroossegefier-Ticker: +STR_FRAMERATE_GL_SHIPS :{BLACK} Schëffticker: +STR_FRAMERATE_GL_AIRCRAFT :{BLACK} Fligerticker: +STR_FRAMERATE_GL_LANDSCAPE :{BLACK} Weltticker: STR_FRAMERATE_GL_LINKGRAPH :{BLACK} Linkgrafik-Verzögerung: -STR_FRAMERATE_DRAWING :{BLACK}Graphikrendering: +STR_FRAMERATE_DRAWING :{BLACK}Grafikrendering: STR_FRAMERATE_DRAWING_VIEWPORTS :{BLACK} Welt-Usiichten: STR_FRAMERATE_VIDEO :{BLACK}Video-output: +STR_FRAMERATE_SOUND :{BLACK}Soundmixing: +STR_FRAMERATE_ALLSCRIPTS :{BLACK} GS/KI Total: STR_FRAMERATE_GAMESCRIPT :{BLACK} Gamescript: +STR_FRAMERATE_AI :{BLACK} KI {NUM} {STRING} ############ End of leave-in-this-order ############ Leave those lines in this order!! STR_FRAMETIME_CAPTION_GAMELOOP :Spill-Loop STR_FRAMETIME_CAPTION_GL_ECONOMY :Wuerenhandling -STR_FRAMETIME_CAPTION_GL_TRAINS :Zuchticks +STR_FRAMETIME_CAPTION_GL_TRAINS :Zuchticker STR_FRAMETIME_CAPTION_GL_ROADVEHS :Stroossegefierer Ticken STR_FRAMETIME_CAPTION_GL_SHIPS :Schëffticker +STR_FRAMETIME_CAPTION_GL_AIRCRAFT :Fligerticker +STR_FRAMETIME_CAPTION_GL_LANDSCAPE :Weltticker +STR_FRAMETIME_CAPTION_GL_LINKGRAPH :Linkgrafik Verzögerung +STR_FRAMETIME_CAPTION_DRAWING :Grafikrendering +STR_FRAMETIME_CAPTION_DRAWING_VIEWPORTS :Weltusiicht-Rendering +STR_FRAMETIME_CAPTION_VIDEO :Video-output STR_FRAMETIME_CAPTION_SOUND :Soundmixing +STR_FRAMETIME_CAPTION_ALLSCRIPTS :GS/KI Scripttotaler STR_FRAMETIME_CAPTION_GAMESCRIPT :Spill-Script +STR_FRAMETIME_CAPTION_AI :KI {NUM} {STRING} ############ End of leave-in-this-order @@ -2761,7 +2816,9 @@ 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_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_OSKTITLE :{BLACK}Gëff dem Spillstand en Numm @@ -2789,7 +2846,7 @@ STR_MAPGEN_VARIETY :{BLACK}Vielfalt STR_MAPGEN_GENERATE :{WHITE}Generéiren # Strings for map borders at game generation -STR_MAPGEN_BORDER_TYPE :{BLACK}Kaartenenner: +STR_MAPGEN_BORDER_TYPE :{BLACK}Kaarteränner: STR_MAPGEN_NORTHWEST :{BLACK}Nordwest STR_MAPGEN_NORTHEAST :{BLACK}Nordost STR_MAPGEN_SOUTHEAST :{BLACK}Südost @@ -2879,8 +2936,10 @@ STR_NEWGRF_SETTINGS_VERSION :{BLACK}Versioun STR_NEWGRF_SETTINGS_MIN_VERSION :{BLACK}Min. kompatibel Versioun: {SILVER}{NUM} STR_NEWGRF_SETTINGS_MD5SUM :{BLACK}MD5sum: {SILVER}{STRING} STR_NEWGRF_SETTINGS_PALETTE :{BLACK}Palette: {SILVER}{STRING} +STR_NEWGRF_SETTINGS_PALETTE_DEFAULT :Standard (S) STR_NEWGRF_SETTINGS_PALETTE_DEFAULT_32BPP :Standard (S) / 32 bpp STR_NEWGRF_SETTINGS_PALETTE_LEGACY :Legacy (W) +STR_NEWGRF_SETTINGS_PALETTE_LEGACY_32BPP :Legacy (W) / 32 bpp STR_NEWGRF_SETTINGS_PARAMETER :{BLACK}Parameter: {SILVER}{STRING} STR_NEWGRF_SETTINGS_PARAMETER_NONE :Keng @@ -2964,6 +3023,7 @@ STR_NEWGRF_ERROR_GRM_FAILED :Ugefroten GRF R STR_NEWGRF_ERROR_FORCEFULLY_DISABLED :{1:STRING} gouf ausgeschalt vun {STRING} STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT :Invalid/onbekannten Sprite Layout Format (Sprite {3:NUM}) STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG :Zevill Elementer an der Eegeschaftewert-Lëscht (Sprite {3:NUM}, Eegeschaft {4:HEX}) +STR_NEWGRF_ERROR_INDPROD_CALLBACK :Ongültegen Industrie-production callback (sprite {3:NUM}, "{2:STRING}") # NewGRF related 'general' warnings STR_NEWGRF_POPUP_CAUTION_CAPTION :{WHITE}Opgepasst! @@ -2995,6 +3055,7 @@ STR_NEWGRF_BUGGY :{WHITE}NewGRF ' STR_NEWGRF_BUGGY_ARTICULATED_CARGO :{WHITE}Cargo/refit Informatioun fir '{1:ENGINE}' ass anescht wéi an der Kaflëscht no der Constructioun. Dëst kann en Autoerneirung/-ersetzen Fehler oprufen STR_NEWGRF_BUGGY_ENDLESS_PRODUCTION_CALLBACK :{WHITE}'{1:STRING}' huet eng Endlosschläif am Production callback verursaacht STR_NEWGRF_BUGGY_UNKNOWN_CALLBACK_RESULT :{WHITE}Callback {1:HEX} huet en onbekannten/invalid Resultat {2:HEX} +STR_NEWGRF_BUGGY_INVALID_CARGO_PRODUCTION_CALLBACK :{WHITE}'{1:STRING}' huet en ongültegen Wuerentyp am Production-callback bei {2:HEX} # 'User removed essential NewGRFs'-placeholders for stuff without specs STR_NEWGRF_INVALID_CARGO : @@ -3037,7 +3098,7 @@ STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (Stad) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}Awunner: {ORANGE}{COMMA}{BLACK} Haiser: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX :{BLACK}{CARGO_LIST} leschte Mount: {ORANGE}{COMMA}{BLACK} Max: {ORANGE}{COMMA} -STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Gidder gebraucht fir Stadwuesstem: +STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}Gidder gebraucht fir Stadwuesstum: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} gebraucht STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} gebraucht am Wanter STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_DELIVERED_GENERAL :{ORANGE}{STRING}{GREEN} geliwwert @@ -3061,6 +3122,8 @@ STR_TOWN_VIEW_RENAME_TOWN_BUTTON :Stad ëmbenenne # Town local authority window STR_LOCAL_AUTHORITY_CAPTION :{WHITE}Gemeng {TOWN} +STR_LOCAL_AUTHORITY_ZONE :{BLACK}Zone +STR_LOCAL_AUTHORITY_ZONE_TOOLTIP :{BLACK}Weis d'Zone vun de Gemengegrenzen STR_LOCAL_AUTHORITY_COMPANY_RATINGS :{BLACK}Transportfirme-Bewäertung: STR_LOCAL_AUTHORITY_COMPANY_RATING :{YELLOW}{COMPANY} {COMPANY_NUM}: {ORANGE}{STRING} STR_LOCAL_AUTHORITY_ACTIONS_TITLE :{BLACK}Verfügbar Aktiounen: @@ -3089,6 +3152,7 @@ STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}D'Gemen # Goal window STR_GOALS_CAPTION :{WHITE}{COMPANY} Ziler STR_GOALS_SPECTATOR_CAPTION :{WHITE}Global Ziler +STR_GOALS_SPECTATOR :Global Ziler STR_GOALS_GLOBAL_TITLE :{BLACK}Global Ziler: STR_GOALS_TEXT :{ORANGE}{STRING} STR_GOALS_NONE :{ORANGE}- Keng - @@ -3317,8 +3381,7 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Infrastr STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Schinnestécker: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Signaler STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Stroossestécker: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Strooss -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Tram +STR_COMPANY_INFRASTRUCTURE_VIEW_TRAM_SECT :{GOLD}Tramdeeler: STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Waasserfelder: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Kanäl STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Statiounen: @@ -3329,9 +3392,12 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Industrien STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Keng - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% transportéiert) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% transportéiert) +STR_INDUSTRY_DIRECTORY_ITEM_INFO :{BLACK}{CARGO_LONG}{STRING}{YELLOW} ({COMMA}% transportéiert){BLACK} STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} +STR_INDUSTRY_DIRECTORY_ITEM_PROD1 :{ORANGE}{INDUSTRY} {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PROD2 :{ORANGE}{INDUSTRY} {STRING}, {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PROD3 :{ORANGE}{INDUSTRY} {STRING}, {STRING}, {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PRODMORE :{ORANGE}{INDUSTRY} {STRING}, {STRING}, {STRING} an nach {NUM} méi... 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 # Industry view @@ -3342,6 +3408,8 @@ STR_INDUSTRY_VIEW_LOCATION_TOOLTIP :{BLACK}Zentréi STR_INDUSTRY_VIEW_PRODUCTION_LEVEL :{BLACK}Produktiounslevel: {YELLOW}{COMMA}% STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE :{YELLOW}D'Industrie annoncéiert dass se zougemaach gëtt +STR_INDUSTRY_VIEW_REQUIRES_N_CARGO :{BLACK}Brauch: {YELLOW}{STRING}{STRING} +STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Produzéiert: {YELLOW}{STRING}{STRING} STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{STRING} STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Brauch: @@ -3396,6 +3464,8 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Ongruppéiert S STR_GROUP_DEFAULT_SHIPS :Ongruppéiert Schëffer STR_GROUP_DEFAULT_AIRCRAFTS :Ongruppéiert Fligeren +STR_GROUP_COUNT_WITH_SUBGROUP :{TINY_FONT}{COMMA} (+{COMMA}) + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Gruppen - klick op eng Grupp fir d'Gefierer aus der Grupp ze gesinn. Per Drag and Drop d'Hierarchie änneren. STR_GROUP_CREATE_TOOLTIP :{BLACK}Klick fir eng Grupp ze maachen STR_GROUP_DELETE_TOOLTIP :{BLACK}Déi ungewielte Grupp läschen @@ -3422,12 +3492,18 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Nei Elektrozich STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Nei Monorailgefierer STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Nei Magnéitbunngefierer -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Nei Zich STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Nei Stroossegefierer +STR_BUY_VEHICLE_TRAM_VEHICLE_CAPTION :Nei Tramgefierer + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Nei Zich +STR_BUY_VEHICLE_ROAD_VEHICLE_ALL_CAPTION :Nei Stroossegefierer STR_BUY_VEHICLE_SHIP_CAPTION :Nei Schëffer STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Neie Fliger +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Käschten: {GOLD}{CURRENCY_LONG}{BLACK} Gewiicht: {GOLD}{WEIGHT_SHORT} +STR_PURCHASE_INFO_COST_REFIT_WEIGHT :{BLACK}Käschten: {GOLD}{CURRENCY_LONG}{BLACK} (Embaukäschten: {GOLD}{CURRENCY_LONG}{BLACK}) Gewiicht: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Geschw.: {GOLD}{VELOCITY}{BLACK} Kraaft: {GOLD}{POWER} STR_PURCHASE_INFO_SPEED :{BLACK}Geschw.: {GOLD}{VELOCITY} STR_PURCHASE_INFO_SPEED_OCEAN :{BLACK}Geschwindegkeet um Ozean: {GOLD}{VELOCITY} @@ -3438,12 +3514,15 @@ STR_PURCHASE_INFO_REFITTABLE :(ëmbaubar) STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Designt: {GOLD}{NUM}{BLACK} Liewenszäit: {GOLD}{COMMA} Joer STR_PURCHASE_INFO_RELIABILITY :{BLACK}Max. Zouverläss.: {GOLD}{COMMA}% STR_PURCHASE_INFO_COST :{BLACK}Käschten: {GOLD}{CURRENCY_LONG} +STR_PURCHASE_INFO_COST_REFIT :{BLACK}Käschten: {GOLD}{CURRENCY_LONG}{BLACK} (Embaukäschten: {GOLD}{CURRENCY_LONG}{BLACK}) STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Gewiicht: {GOLD}{WEIGHT_SHORT} ({WEIGHT_SHORT}) STR_PURCHASE_INFO_COST_SPEED :{BLACK}Käschten: {GOLD}{CURRENCY_LONG}{BLACK} Geschw.: {GOLD}{VELOCITY} +STR_PURCHASE_INFO_COST_REFIT_SPEED :{BLACK}Käschten: {GOLD}{CURRENCY_LONG}{BLACK} (Embaukäschten: {GOLD}{CURRENCY_LONG}{BLACK}) Geschw.: {GOLD}{VELOCITY} STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Kapazitéit: {GOLD}{CARGO_LONG}, {CARGO_LONG} STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Ugedriwwen Waggonen: {GOLD}+{POWER}{BLACK} Gewiicht: {GOLD}+{WEIGHT_SHORT} STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Embaubar zu: {GOLD}{STRING} STR_PURCHASE_INFO_ALL_TYPES :All Wuerentyp +STR_PURCHASE_INFO_NONE :Keng STR_PURCHASE_INFO_ALL_BUT :Alles ausser {CARGO_LIST} STR_PURCHASE_INFO_MAX_TE :{BLACK}Max. Zéikraaft: {GOLD}{FORCE} STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Distanz: {GOLD}{COMMA} Felder @@ -3459,11 +3538,21 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Gefier k STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Schëff kafen STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Fliger kafen +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Gefierer kafen an ëmbauen +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Gefierer kafen an ëmbauen +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Schëff kafen an ëmbauen +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Fligeren kafen an ëmbauen + 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_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 +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Gewielten Zuch/Waggon kafen an ëmbauen. Shift+Klick weist ongeféier Käschten ouni Kaf +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Gewielte Gefier kafen an ëmbauen. Shift+Klick weist ongeféier Käschten ouni Kaf +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Gewielte Schëff kafen an ëmbauen. Shift+Klick weist ongeféier Käschten ouni Kaf +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Gewielte Fliger kafen an ëmbauen. Shift+Klick weist ongeféier Käschten ouni Kaf + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Ëmbenennen STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Ëmbenennen STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Ëmbenennen @@ -3572,13 +3661,18 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Du verk # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Meldung vum Gefierkonstrukteur STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Mir hunn elo en neien {STRING} gebaut - bass du dorun interesséiert dëst Gefier 1 Joer exklusiv ze notzen, fir ze testen op et komplett maarträif ass? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :Lokomotiv -STR_ENGINE_PREVIEW_ROAD_VEHICLE :Stroossegefier -STR_ENGINE_PREVIEW_AIRCRAFT :Fliger -STR_ENGINE_PREVIEW_SHIP :Schëff +STR_ENGINE_PREVIEW_ELRAIL_LOCOMOTIVE :Elektresch Lokomotiv STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :Monorail Lokomotiv STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :Magnéitbunnlokomotiv +STR_ENGINE_PREVIEW_ROAD_VEHICLE :Stroossegefier +STR_ENGINE_PREVIEW_TRAM_VEHICLE :Tram-Gefier + +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_MAX_SPEED_CAP_RUNCOST :{BLACK}Käschten: {CURRENCY_LONG} Max. Geschwindegkeet: {VELOCITY}{}Kapazitéit: {CARGO_LONG}{}Betribskäschten: {CURRENCY_LONG}/Jr @@ -3616,14 +3710,19 @@ STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK}Wiessel STR_REPLACE_ENGINES :Lokomotiven STR_REPLACE_WAGONS :Waggonen STR_REPLACE_ALL_RAILTYPE :All Zich +STR_REPLACE_ALL_ROADTYPE :All Stroossegefierer STR_REPLACE_HELP_RAILTYPE :{BLACK}Wielt de Schinnentyp fir déi Lokomotiven ausgetosch ginn +STR_REPLACE_HELP_ROADTYPE :{BLACK}Wielt de Stroossentyp fir déi d'Maschinnen ausgetosch ginn STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Weist un wellech Lokomotiv vun der lénks ugewielter Lokomotiv ausgetosch soll ginn, wann et zoutrëfft STR_REPLACE_RAIL_VEHICLES :Zich STR_REPLACE_ELRAIL_VEHICLES :Elektresch Zich STR_REPLACE_MONORAIL_VEHICLES :Monorail Gefierer STR_REPLACE_MAGLEV_VEHICLES :Magnéitbunn Gefierer +STR_REPLACE_ROAD_VEHICLES :Stroossegefierer +STR_REPLACE_TRAM_VEHICLES :Tram-Gefierer + STR_REPLACE_REMOVE_WAGON :{BLACK}Waggon raushuelen: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Mécht dass d'automatescht Austauschen d'Längt vum Zuch behält, an dem e Waggonen (vu lénks un) wechhëllt, wann d'Lok den Zuch ze laang mécht @@ -3673,7 +3772,7 @@ STR_VEHICLE_VIEW_AIRCRAFT_STATE_START_STOP_TOOLTIP :{BLACK}Momentan # Messages in the start stop button in the vehicle view STR_VEHICLE_STATUS_LOADING_UNLOADING :{LTBLUE}Lueden / Entlueden STR_VEHICLE_STATUS_LEAVING :{LTBLUE}Verloossen -STR_VEHICLE_STATUS_CRASHED :{RED}Akzident! +STR_VEHICLE_STATUS_CRASHED :{RED}Accident! STR_VEHICLE_STATUS_BROKEN_DOWN :{RED}Pann STR_VEHICLE_STATUS_STOPPED :{RED}Gestoppt STR_VEHICLE_STATUS_TRAIN_STOPPING_VEL :{RED}Stoppt, {VELOCITY} @@ -3820,7 +3919,7 @@ STR_ORDER_DROP_TRANSFER :Transferéieren STR_ORDER_DROP_NO_UNLOADING :Net entlueden STR_ORDER_TOOLTIP_UNLOAD :{BLACK}Wiesselt d'Entluedverhale vun dem ungewielten Optrag -STR_ORDER_REFIT :{BLACK}Ëmbauen +STR_ORDER_REFIT :{BLACK}Embauen STR_ORDER_REFIT_TOOLTIP :{BLACK}Wielt an wéi een Luedungstyp sollt emgebaut ginn. Ctrl+Klick fir den Ëmbau ze läschen STR_ORDER_REFIT_AUTO :{BLACK}Embauen an der Statioun STR_ORDER_REFIT_AUTO_TOOLTIP :{BLACK}Wiel wellëch Wuerentypen sollen auto-ersat ginn an dësem Optrag. Ctrl+Klick fir all Auto-Erneierungen wechzehuelen. Auto-Erneiern geht just wann d'Gefier ët erlaabt @@ -3916,8 +4015,8 @@ STR_ORDER_NO_UNLOAD_FULL_LOAD_ANY :(Net entlueden STR_ORDER_NO_UNLOAD_NO_LOAD :(Keen Ent- an Belueden) STR_ORDER_AUTO_REFIT :(Embauen op {STRING}) -STR_ORDER_FULL_LOAD_REFIT :(Voll lueden mat Embauen op {STRING}) -STR_ORDER_FULL_LOAD_ANY_REFIT :(Voll lueden mat all Wueren mat Embauen op {STRING}) +STR_ORDER_FULL_LOAD_REFIT :(Voll lueden mat ëmbauen op {STRING}) +STR_ORDER_FULL_LOAD_ANY_REFIT :(Voll lueden mat all Wueren mat ëmbauen op {STRING}) STR_ORDER_UNLOAD_REFIT :(Entlueden an Wueren lueden mat Embauen op {STRING}) STR_ORDER_UNLOAD_FULL_LOAD_REFIT :(Entlueden an op voll Luedung waarden mat Embauen op {STRING}) STR_ORDER_UNLOAD_FULL_LOAD_ANY_REFIT :(Entlueden an waard op iergendeng Volluedung mat Embauen op {STRING}) @@ -3962,7 +4061,7 @@ STR_TIMETABLE_AND_TRAVEL_FOR_ESTIMATED :(fuer während STR_TIMETABLE_STAY_FOR :an bleif fir {STRING} STR_TIMETABLE_AND_TRAVEL_FOR :an ënnerwee während {STRING} STR_TIMETABLE_DAYS :{COMMA}{NBSP}D{P ag eeg} -STR_TIMETABLE_TICKS :{COMMA}{NBSP}Tick{P "" en} +STR_TIMETABLE_TICKS :{COMMA}{NBSP}Tick{P "" er} STR_TIMETABLE_TOTAL_TIME :{BLACK}Dësen Zäitplang brauch {STRING} fir faërdeg ze ginn STR_TIMETABLE_TOTAL_TIME_INCOMPLETE :{BLACK}Dësen Zäitplang brauch op manst {STRING} (net all geplangt) @@ -4074,6 +4173,13 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Wiel de STR_AI_LIST_CANCEL :{BLACK}Ofbriechen STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Script net änneren +STR_SCREENSHOT_CAPTION :{WHITE}E Screenshot maachen +STR_SCREENSHOT_SCREENSHOT :{BLACK}Normale Screenshot +STR_SCREENSHOT_ZOOMIN_SCREENSHOT :{BLACK}Voll gezoomte Screenshot +STR_SCREENSHOT_DEFAULTZOOM_SCREENSHOT :{BLACK}Standard Zoom-Screenshot +STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Screenshot vun der ganzer Kaart +STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Héichtekaartscreenshot + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parameter STR_AI_SETTINGS_CAPTION_AI :KI @@ -4168,7 +4274,7 @@ STR_ERROR_MESSAGE_CAPTION_OTHER_COMPANY :{YELLOW}Matdeel # Generic construction errors STR_ERROR_OFF_EDGE_OF_MAP :{WHITE}Ausserhalb vun der Kaart -STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}Ze noo um Rand vun der Kaart +STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP :{WHITE}Ze no um Rand vun der Kaart STR_ERROR_NOT_ENOUGH_CASH_REQUIRES_CURRENCY :{WHITE}Net genuch Geld - des Aktioun kascht {CURRENCY_LONG} STR_ERROR_FLAT_LAND_REQUIRED :{WHITE}D'Land muss flaach sinn STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION :{WHITE}Land ass an déi falsch Richtung geneigt @@ -4223,8 +4329,8 @@ STR_ERROR_CAN_T_GENERATE_TOWN :{WHITE}Ka keng STR_ERROR_CAN_T_RENAME_TOWN :{WHITE}Kann d'Stad net ëmbenennen... STR_ERROR_CAN_T_FOUND_TOWN_HERE :{WHITE}Kann d'Stad hei net bauen... STR_ERROR_CAN_T_EXPAND_TOWN :{WHITE}Kann d'Stad net vergréisseren... -STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... ze noo um Enn vun der Kaart -STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... ze noo un enger anerer Stad +STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP_SUB :{WHITE}... ze no um Rand vun der Kaart +STR_ERROR_TOO_CLOSE_TO_ANOTHER_TOWN :{WHITE}... ze no un enger anerer Stad STR_ERROR_TOO_MANY_TOWNS :{WHITE}... ze vill Stied STR_ERROR_NO_SPACE_FOR_TOWN :{WHITE}... et ass keng Plaz méi op der Kaart STR_ERROR_TOWN_EXPAND_WARN_NO_ROADS :{WHITE}Stied bauen keng Stroossen. Du kanns de Bau iwwert Astellungen->Economie->Stied aschalten @@ -4237,7 +4343,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_INDUSTRY_TOO_CLOSE :{WHITE}... ze noo bei enger anerer Fabrik +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 STR_ERROR_CAN_ONLY_BE_BUILT_IN_TOWNS_WITH_POPULATION_OF_1200 :{WHITE}... kann nëmmen an Stied mat op mannst 1200 Anwunner gebaut ginn @@ -4269,14 +4375,13 @@ STR_ERROR_TOO_MANY_STATIONS_LOADING :{WHITE}Ze vill STR_ERROR_TOO_MANY_STATION_SPECS :{WHITE}Ze vill Garesdeeler STR_ERROR_TOO_MANY_BUS_STOPS :{WHITE}Ze vill Busarrêten STR_ERROR_TOO_MANY_TRUCK_STOPS :{WHITE}Ze vill Camionsgaren -STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Ze noo un engem aanerem Hafen -STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Ze noo un engem aaneren Fluchhafen +STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK :{WHITE}Ze no un engem aaneren Hafen +STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT :{WHITE}Ze no un engem aanere Fluchhafen STR_ERROR_CAN_T_RENAME_STATION :{WHITE}Kann d'Statioun net ëmbenennen... STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... d'Strooss ass am Besëtz vun der Stad STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... Strooss geet an dei falsch Richtung STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... Duerchfahrtstops kënnen keng Kéiren hunn STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... Duerchfahrtstops kënnen keng Kräizungen hunn -STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... Einbahnstrooss oder blockéiert # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Kann den Deel vun der Gare net ofrappen... @@ -4346,7 +4451,8 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Signaler STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Keng gëeegent Schinnen STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}D'Schinne musse fir d'éischt ewech STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}D'Strooss ass eng Einbahn oder blockéiert -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Barrièren si fir dësen Schinnentyp net erlaabt +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Barrière si fir dëse Schinnentyp net erlaabt +STR_ERROR_CROSSING_DISALLOWED_ROAD :{WHITE}Barrière si fir dëse Stroossentyp net erlaabt STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Kann d'Signaler hei net bauen... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Kann d'Schinnen hei net bauen... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Kann d'Schinnen hei net ewech huelen... @@ -4361,11 +4467,17 @@ STR_ERROR_CAN_T_CONVERT_RAIL :{WHITE}Kann de STR_ERROR_MUST_REMOVE_ROAD_FIRST :{WHITE}Muss d'Strooss ewech huelen STR_ERROR_ONEWAY_ROADS_CAN_T_HAVE_JUNCTION :{WHITE}... Einbahnstroossen kënnen keng Kräizung hunn STR_ERROR_CAN_T_BUILD_ROAD_HERE :{WHITE}Kann d'Strooss hei net bauen... -STR_ERROR_CAN_T_BUILD_TRAMWAY_HERE :{WHITE}Kann den Tram hei net bauen... +STR_ERROR_CAN_T_BUILD_TRAMWAY_HERE :{WHITE}Kann Tramway hei net bauen... STR_ERROR_CAN_T_REMOVE_ROAD_FROM :{WHITE}Kann d'Strooss hei net ewech huelen... -STR_ERROR_CAN_T_REMOVE_TRAMWAY_FROM :{WHITE}Kann den Tram net ewech huelen... +STR_ERROR_CAN_T_REMOVE_TRAMWAY_FROM :{WHITE}Kann den Tramway net ewech huelen... STR_ERROR_THERE_IS_NO_ROAD :{WHITE}... et ass keng Strooss do -STR_ERROR_THERE_IS_NO_TRAMWAY :{WHITE}... et ass keen Tram do +STR_ERROR_THERE_IS_NO_TRAMWAY :{WHITE}... et ass keen Tramway do +STR_ERROR_CAN_T_CONVERT_ROAD :{WHITE}Kann den Gefiertyp hei net konvertéiren... +STR_ERROR_CAN_T_CONVERT_TRAMWAY :{WHITE}Kann den Tramwaytyp hei net konvertéiren... +STR_ERROR_NO_SUITABLE_ROAD :{WHITE}Keng geeegent Strooss +STR_ERROR_NO_SUITABLE_TRAMWAY :{WHITE}Kee passenden Tramway +STR_ERROR_INCOMPATIBLE_ROAD :{WHITE}... inkompatibel Strooss +STR_ERROR_INCOMPATIBLE_TRAMWAY :{WHITE}... inkompatiblen Tramway # Waterway construction errors STR_ERROR_CAN_T_BUILD_CANALS :{WHITE}Kann hei keen Kanal bauen... @@ -4418,6 +4530,7 @@ STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Kann d'G STR_ERROR_GROUP_CAN_T_DELETE :{WHITE}Kann d'Grupp net läschen... STR_ERROR_GROUP_CAN_T_RENAME :{WHITE}Kann d'Grupp net ëmbenennen... STR_ERROR_GROUP_CAN_T_SET_PARENT :{WHITE}Kann iwwergeuerdent Grupp net setzen... +STR_ERROR_GROUP_CAN_T_SET_PARENT_RECURSION :{WHITE}... Schläifen an der Gruppenhierarchie si net erlabt STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}Kann net all d'Gefierer aus der Grupp läschen... STR_ERROR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}Kann d'Gefier net bei d'Grupp bäisetzen... STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}Kann dei gedeelten Gefierer net bei d'Grupp bäisetzen... @@ -5027,5 +5140,3 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) - -# Android strings diff --git a/src/lang/malay.txt b/src/lang/malay.txt index 1e0f962f3a..099ed57504 100644 --- a/src/lang/malay.txt +++ b/src/lang/malay.txt @@ -10,8 +10,6 @@ ##grflangid 0x3c -# $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. # 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. @@ -454,9 +452,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Papar atau padamkan konsol STR_ABOUT_MENU_AI_DEBUG :Al/Skrip pepijat permainan STR_ABOUT_MENU_SCREENSHOT :Tangkapan skrin (Ctrl+S) -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Zum sepenuhnya di pembidik skrin -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Tangkapan skrin di zum asal -STR_ABOUT_MENU_GIANT_SCREENSHOT :Tangkap gambar skrin besar (Ctrl+G) STR_ABOUT_MENU_ABOUT_OPENTTD :Tentang 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Penjajar peperi STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Papar atau padamkan kotak @@ -626,9 +621,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Pilihan Diri 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Volum Muzik STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Volum Kesan Bunyi -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}MIN -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}MAKS -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -834,6 +826,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}{STRING} baru kini boleh boleh dibeli! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} tidak lagi menerima {STRING} STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} tidak lagi menerima {STRING} or {STRING} STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} kini menerima {STRING} @@ -1450,7 +1443,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_INDUSTRIES :{ORANGE}Industr STR_CONFIG_SETTING_AI :{ORANGE}Pesaing STR_CONFIG_SETTING_AI_NPC :{ORANGE}Pemain komputer -STR_CONFIG_SETTING_PATHFINDER_OPF :Asal STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Disyorkan) @@ -1528,13 +1520,9 @@ STR_QUIT_NO :{BLACK}Tidak # Supported OSes STR_OSNAME_WINDOWS :Tetingkap -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -2148,6 +2136,7 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Bina ter STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Bina atau buang untuk pembinaan jalanraya STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Bina atau buang untuk pembinaan laluan trem + # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Penghalaan Depoh Kenderaan Jalanraya STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}Pilih penghalaan depoh kenderaan jalanraya @@ -2960,8 +2949,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Infrastr STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Cebisan landasan: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Isyarat STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Cebisan jalanraya: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Jalanraya -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Laluan Trem STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Petak air: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Terusan STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Stesen: @@ -2972,8 +2959,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Industri STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Tiada - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% dihantar) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% dihantar) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Nama industri - klik pada nama untuk memusatkan pemandangan ke industri. Ctrl+Klik membuka tetingkap pemandangan di lokasi industri @@ -3036,6 +3021,7 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Kenderaan jalan STR_GROUP_DEFAULT_SHIPS :Kapal yang belum berkumpulan STR_GROUP_DEFAULT_AIRCRAFTS :Pesawat yang belum berkumpulan + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Kumpulan - klik sebuah kumpulan untuk menyenaraikan semua kenderaan di dalam kumpulan tersebut. Tarik dan lepaskan kumpulan untuk menyusun kumpulan mengikut heirarki STR_GROUP_CREATE_TOOLTIP :{BLACK}Klik untuk mewujudkan kumpulan STR_GROUP_DELETE_TOOLTIP :{BLACK}Padamkan kumpulan yang telah dipilih @@ -3055,10 +3041,13 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Keretapi Elektr STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Monorel Baru STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Maglev Baru -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Keretapi Baru STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Kenderaan Jalanraya Baru + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Keretapi Baru STR_BUY_VEHICLE_SHIP_CAPTION :Kapal Baru STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Pesawat Baru +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Kos: {GOLD}{CURRENCY_LONG}{BLACK} Berat: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Kelajuan: {GOLD}{VELOCITY}{BLACK} Kuasa: {GOLD}{POWER} @@ -3091,11 +3080,13 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Beli Ken STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Beli Kapal STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Beli Pesawat + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Beli gerabak keretapi yang terpilih. Shift+Klik menunjukkan anggaran kos tanpa membeli STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Beli kenderaan jalanraya yang terpilih. Shift+Klik menunjukkan anggaran kos tanpa membeli STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Beli kapal yang terpilih. Shift+Klik menunjukkan anggaran kos tanpa membeli STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Beli pesawat yang terpilih. Shift+Klik menunjukkan anggaran kos tanpa membeli + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Namakan semula STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Namakan semula STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Namakan semula @@ -3204,13 +3195,16 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Anda ak # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Pesanan daripada pengusaha kenderaan STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Kami baru sahaja mereka {STRING} yang baru - adakah anda berminat untuk menggunakan kenderaan ini secara eksklusif, supaya kami dapat menilai tahap kelancarannya sebelum kami menjualnya kepada pihak awam? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :keretapi -STR_ENGINE_PREVIEW_ROAD_VEHICLE :kenderaan jalanraya -STR_ENGINE_PREVIEW_AIRCRAFT :pesawat -STR_ENGINE_PREVIEW_SHIP :kapal STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :keretapi monorel STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :keretapi maglev +STR_ENGINE_PREVIEW_ROAD_VEHICLE :kenderaan jalanraya + +STR_ENGINE_PREVIEW_AIRCRAFT :pesawat +STR_ENGINE_PREVIEW_SHIP :kapal + STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Kos: {CURRENCY_LONG} Berat: {WEIGHT_SHORT}{}Kelajuan: {VELOCITY} Kuasa: {POWER}{}Kos Pengendalian: {CURRENCY_LONG}/thn{}Kapasiti: {CARGO_LONG} STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Kos: {CURRENCY_LONG} Berat: {WEIGHT_SHORT}{}Kelajuan: {VELOCITY} Kuasa: {POWER} Maks. E.K.: {6:FORCE}{}Kos Pengendalian: {4:CURRENCY_LONG}/thn{}Kapasiti: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Kos: {CURRENCY_LONG} Kelajuan Maks.: {VELOCITY}{}Kapasiti: {CARGO_LONG}{}Kos Pengendalian: {CURRENCY_LONG}/thn @@ -3244,6 +3238,7 @@ STR_REPLACE_ELRAIL_VEHICLES :Kenderaan Keret STR_REPLACE_MONORAIL_VEHICLES :Monorel Kenderaan STR_REPLACE_MAGLEV_VEHICLES :Kenderaan Maglev + STR_REPLACE_REMOVE_WAGON :{BLACK}Penghapusan wagon: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Membuat penukaran secara automatik menyimpan kepanjangan keretapi yang sama dengan mengeluarkan gerabak (bermula dari bahagian hadapan), sekiranya menyebabkan kereta api lebih panjang @@ -3684,6 +3679,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Pilih sk STR_AI_LIST_CANCEL :{BLACK}Batal STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Jangan ubah skrip + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parameter STR_AI_SETTINGS_CAPTION_AI :AI @@ -3946,7 +3942,7 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Tanda-ta STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Tiada landasan keretapi yang sesuai STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Landasan keretapi mesti dibuang terlebih dahulu STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Jalanraya adalah sehala atau telah disekat -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Persimpangan bertingkat adalah tidak dibenarkan untuk jenis landasan ini +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Persimpangan bertingkat adalah tidak dibenarkan untuk jenis landasan ini STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Isyarat tidak dapat dibina di sini... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Landasan keretapi tidak dapat dibina di sini... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Landasan keretapi tidak dapat dibuang... diff --git a/src/lang/norwegian_bokmal.txt b/src/lang/norwegian_bokmal.txt index 6abb6441db..880a777bce 100644 --- a/src/lang/norwegian_bokmal.txt +++ b/src/lang/norwegian_bokmal.txt @@ -12,8 +12,6 @@ ##case small -# $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. # 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. @@ -239,6 +237,8 @@ STR_TOOLTIP_FILTER_CRITERIA :{BLACK}Velg fil STR_BUTTON_SORT_BY :{BLACK}Sorter etter STR_BUTTON_LOCATION :{BLACK}Gå til STR_BUTTON_RENAME :{BLACK}Gi nytt navn +STR_BUTTON_CATCHMENT :{BLACK}Dekning +STR_TOOLTIP_CATCHMENT :{BLACK}Veksle mellom visning av dekningsområde STR_TOOLTIP_CLOSE_WINDOW :{BLACK}Lukk vindu STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Vindustittel - dra her for å flytte vindu @@ -267,6 +267,7 @@ STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT_TOOLTIP :{BLACK}Ved å a STR_BUTTON_DEFAULT :{BLACK}Standard STR_BUTTON_CANCEL :{BLACK}Avbryt STR_BUTTON_OK :{BLACK}OK +STR_WARNING_PASSWORD_SECURITY :{YELLOW}Advarsel: Server-administratorer kan lese tekst som blir skrevet her. # On screen keyboard window STR_OSK_KEYBOARD_LAYOUT :`1234567890-=\qwertyuiop[]asdfghjkl;' zxcvbnm,./ . @@ -340,6 +341,7 @@ STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN :{BLACK}Zoom inn STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT :{BLACK}Zoom ut STR_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Bygg jernbanespor STR_TOOLBAR_TOOLTIP_BUILD_ROADS :{BLACK}Bygg veier +STR_TOOLBAR_TOOLTIP_BUILD_TRAMWAYS :{BLACK}Bygg trikkespor STR_TOOLBAR_TOOLTIP_BUILD_SHIP_DOCKS :{BLACK}Bygg havner STR_TOOLBAR_TOOLTIP_BUILD_AIRPORTS :{BLACK}Bygg flyplasser STR_TOOLBAR_TOOLTIP_LANDSCAPING :{BLACK}Åpne landskapsverktøylinjen for å heve/senke land, plante trær, osv. @@ -360,6 +362,7 @@ STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION :{BLACK}Landskap STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Bygenerering STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Industrigenerering STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Veibygging +STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Bygg trikkespor STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Plant trær. Shift slår av/på kostnadsestimat STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Plasser skilt STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Plasser objekt. Shift slår av/på kostnadsestimat @@ -477,9 +480,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Vis/skjul konsoll STR_ABOUT_MENU_AI_DEBUG :AI/Spillskript-feilsøking STR_ABOUT_MENU_SCREENSHOT :Skjermbilde -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Fullt forstørret skjermbilde -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Normalt forstørret skjermbilde -STR_ABOUT_MENU_GIANT_SCREENSHOT :Skjermbilde av hele kartet STR_ABOUT_MENU_SHOW_FRAMERATE :Vis bildehastighet STR_ABOUT_MENU_ABOUT_OPENTTD :Om 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Spriteforskyver @@ -650,9 +650,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Egendefinert 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Musikkvolum STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Lydeffektvolum -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}MIN -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}MAKS -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -838,7 +835,7 @@ STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_COAL :{BIG_FONT}{BLAC STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_OIL :{BIG_FONT}{BLACK}Nye oljereserver funnet i {INDUSTRY}!{}En dobling i produksjonen ventes! STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM :{BIG_FONT}{BLACK}Forbedring i gårdbruksmetoder på {INDUSTRY} forventes å doble produksjonen! STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_SMOOTH :{BIG_FONT}{BLACK}Produksjonen av {STRING} ved {INDUSTRY} øker med {COMMA}{NBSP}%! -STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL :{BIG_FONT}{BLACK}{INDUSTRY} sin produksjon har sunket med 50{NBSP}% +STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL :{BIG_FONT}{BLACK}Produksjonen ved {INDUSTRY} har sunket med 50{NBSP}% STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM :{BIG_FONT}{BLACK}Insektinvasjon gjør stor skade på {INDUSTRY}!{}Produksjonen synker med 50{NBSP}% STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_SMOOTH :{BIG_FONT}{BLACK}Produksjonen av {STRING} ved {INDUSTRY} synker med {COMMA}{NBSP}%! @@ -869,6 +866,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}Ny{G "" "" tt} {STRING} er nå tilgjengelig! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} godtar ikke lenger {STRING} STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} godtar ikke lenger {STRING} eller {STRING} STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} godtar nå {STRING} @@ -935,6 +933,9 @@ STR_GAME_OPTIONS_CURRENCY_GEL :Georgisk lari ( STR_GAME_OPTIONS_CURRENCY_IRR :Iransk rial (IRR) STR_GAME_OPTIONS_CURRENCY_RUB :Ny russisk rubel (RUB) STR_GAME_OPTIONS_CURRENCY_MXN :Meksikansk peso (MXN) +STR_GAME_OPTIONS_CURRENCY_NTD :Ny Taiwan Dollar (NTD) +STR_GAME_OPTIONS_CURRENCY_CNY :Chinese Renminbi (CNY) +STR_GAME_OPTIONS_CURRENCY_HKD :Hong Kong Dollar (HKD) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Kjøretøy @@ -1186,6 +1187,8 @@ STR_CONFIG_SETTING_AUTOSLOPE :Tillat endring STR_CONFIG_SETTING_AUTOSLOPE_HELPTEXT :Tillat endring av landskapet under bygninger og spor uten å fjerne dem STR_CONFIG_SETTING_CATCHMENT :Mer realistisk størrelse på oppfangingsområder: {STRING} STR_CONFIG_SETTING_CATCHMENT_HELPTEXT :Ha oppsamlingsområder i forskjellige størrelser for forskjellige typer stasjoner og lufthavner +STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES :Firmaets stasjoner kan betjene industrier med tilknyttede nøytrale stasjoner: {STRING} +STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES_HELPTEXT :Hvis aktivert, vil industrier med egne stasjoner (slik som oljerigger) også kunne betjenes av firma-stasjoner bygget i nærheten. Hvis deaktivert, vil disse industriene bare kunne betjenes av sine egne stasjoner. Nærliggende firma-stasjoner vil ikke kunne betjene dem, heller ikke vil den egne stasjonen betjene noe annet enn den tilhørende industrien. STR_CONFIG_SETTING_EXTRADYNAMITE :Tillat fjerning av flere veier, broer osv. eid av byene: {STRING} STR_CONFIG_SETTING_EXTRADYNAMITE_HELPTEXT :Gjør det enklere å fjerne infrastruktur og bygninger som tilhører byer STR_CONFIG_SETTING_TRAIN_LENGTH :Maksimal toglengde: {STRING} @@ -1202,8 +1205,8 @@ STR_CONFIG_SETTING_TRAIN_SLOPE_STEEPNESS_HELPTEXT :Brattheten av e STR_CONFIG_SETTING_PERCENTAGE :{COMMA} % STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS :Skråningens bratthet for veikjøretøy: {STRING} STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS_HELPTEXT :Brattheten av et skrått kartelement for et veikjøretøy. Høyere verdier gjør det vanskeligere å kjøre opp bakken -STR_CONFIG_SETTING_FORBID_90_DEG :Forby tog og skip å gjøre 90° svinger: {STRING} -STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :90-graders svinger oppstår når et horisontalt spor etterfølges av et vertikalt spor på tilstøtende kartelement, som dermed fører til at toget må snu 90 grader når det krysser kartelementet, istedenfor de vanlige 45 grader for andre spor-kombinasjoner. Dette gjelder også for båters svingradius +STR_CONFIG_SETTING_FORBID_90_DEG :Forby tog å gjøre 90° svinger: {STRING} +STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :90-graders svinger oppstår når et horisontalt spor etterfølges av et vertikalt spor på tilstøtende kartelement, som medfører at toget må svinge 90 grader når det krysser kartelementet, i stedet for de vanlige 45 grader for andre spor-kombinasjoner. STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS :Tillat sammenslåing av stasjoner som ikke ligger inntil hverandre: {STRING} STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS_HELPTEXT :Gjør det mulig å legge til deler til en stasjon uten at de er direkte ved siden av hverandre. Bruk Ctrl+klikk for å bygge slike stasjoner. STR_CONFIG_SETTING_INFLATION :Inflasjon: {STRING} @@ -1240,9 +1243,9 @@ STR_CONFIG_SETTING_STOP_LOCATION_FAR_END :bortenden STR_CONFIG_SETTING_AUTOSCROLL :Flytt på bildet hvis pilen er nær ytterkantene av skjermen: {STRING} STR_CONFIG_SETTING_AUTOSCROLL_HELPTEXT :Når aktivert, vil synsfeltet begynne å rulle når musen er nær kanten av vinduet STR_CONFIG_SETTING_AUTOSCROLL_DISABLED :Deaktivert -STR_CONFIG_SETTING_AUTOSCROLL_MAIN_VIEWPORT_FULLSCREEN :Hoved tillegsvindu, bare fullskjerm -STR_CONFIG_SETTING_AUTOSCROLL_MAIN_VIEWPORT :hoved tillegsvindu -STR_CONFIG_SETTING_AUTOSCROLL_EVERY_VIEWPORT :alle tillegsvindu +STR_CONFIG_SETTING_AUTOSCROLL_MAIN_VIEWPORT_FULLSCREEN :Hovedvindu, bare fullskjerm +STR_CONFIG_SETTING_AUTOSCROLL_MAIN_VIEWPORT :Hovedvindu +STR_CONFIG_SETTING_AUTOSCROLL_EVERY_VIEWPORT :alle tilleggsvindu STR_CONFIG_SETTING_BRIBE :Tillat bestikkelser av bystyret: {STRING} STR_CONFIG_SETTING_BRIBE_HELPTEXT :Tillat firmaer å prøve å bestikke de lokale myndighetene i byen. Hvis bestikkelsen blir oppdaget av en inspektør, vil selskapet ikke være i stand til å gjøre forretninger i byen de neste seks månedene STR_CONFIG_SETTING_BRIBE_HELPTEXT.small :firma @@ -1260,8 +1263,8 @@ STR_CONFIG_SETTING_PLANE_SPEED :Flyfart faktor: STR_CONFIG_SETTING_PLANE_SPEED_HELPTEXT :Still den relative hastigheten til fly sammenlignet med andre kjøretøy, for å redusere inntekter ved luftfrakt STR_CONFIG_SETTING_PLANE_SPEED_VALUE :1 / {COMMA} STR_CONFIG_SETTING_PLANE_CRASHES :Antall flystyrter: {STRING} -STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Bestem sjansen for en flykatastrofe -STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Ingen +STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Bestem sannsynligheten for flykrasj.{}* Store fly vil alltid kunne krasje når de lander på små flyplasser. +STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Ingen* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Redusert STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normalt STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Tillat stoppesteder med gjennomkjøring på by-eide veier: {STRING} @@ -1416,7 +1419,7 @@ STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_ALL_NON_CONSTRUCTION :Alt utenom kons STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_ALL_NON_LANDSCAPING :Alt utenom landskapsendringer STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_ALL_ACTIONS :Alle handlinger STR_CONFIG_SETTING_ADVANCED_VEHICLE_LISTS :Bruk grupper i kjøretøyliste: {STRING} -STR_CONFIG_SETTING_ADVANCED_VEHICLE_LISTS_HELPTEXT :Aktiver bruk av de avanserte kjøretøyslistene for guppering av kjøretøy +STR_CONFIG_SETTING_ADVANCED_VEHICLE_LISTS_HELPTEXT :Aktiver bruk av avanserte kjøretøylister for guppering av kjøretøy STR_CONFIG_SETTING_LOADING_INDICATORS :Bruk lastingsindikatorer: {STRING} STR_CONFIG_SETTING_LOADING_INDICATORS_HELPTEXT :Velg hvorvidt lasteindikatorer vises over kjøretøy som lastes eller losses STR_CONFIG_SETTING_TIMETABLE_IN_TICKS :Vis rutetabell i antall tikk i stedet for antall dager: {STRING} @@ -1467,7 +1470,7 @@ STR_CONFIG_SETTING_MAX_SHIPS_HELPTEXT :Maksimalt antal STR_CONFIG_SETTING_AI_BUILDS_TRAINS :Hindre datamaskinen i å bygge tog: {STRING} STR_CONFIG_SETTING_AI_BUILDS_TRAINS_HELPTEXT :Aktivering av denne innstillingen gjør bygging av tog umulig for en datamaskin-spiller -STR_CONFIG_SETTING_AI_BUILDS_ROAD_VEHICLES :Hindre datamaskinen i å bygge kjøretøy: {STRING} +STR_CONFIG_SETTING_AI_BUILDS_ROAD_VEHICLES :Hindre datamaskinen i å bygge veikjøretøy: {STRING} STR_CONFIG_SETTING_AI_BUILDS_ROAD_VEHICLES_HELPTEXT :Aktivering av denne innstillingen gjør bygging av veikjøretøy umulig for en datamaskin-spiller STR_CONFIG_SETTING_AI_BUILDS_AIRCRAFT :Hindre datamaskinen i å bygge luftfartøy: {STRING} STR_CONFIG_SETTING_AI_BUILDS_AIRCRAFT_HELPTEXT :Aktivering av denne innstillingen gjør bygging av fly umulig for en datamaskin-spiller @@ -1484,6 +1487,9 @@ STR_CONFIG_SETTING_AI_IN_MULTIPLAYER :Tillat AI-er i STR_CONFIG_SETTING_AI_IN_MULTIPLAYER_HELPTEXT :Tillat datamaskin-spillere å delta i flerspiller-spill STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES :#opcodes før skript er avbrutt: {STRING} STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES_HELPTEXT :Maksimalt antall beregningstrinn et skript kan ta i én omgang +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY :Maks minnebruk pr. script: {STRING} +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_HELPTEXT :Hvor mye minne ett enkelt script kan bruke før det blir stoppet av systemet. Denne verdien må kanskje økes for store kart. +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_VALUE :{COMMA} MiB STR_CONFIG_SETTING_SERVINT_ISPERCENT :Vedlikeholdsintervaller er i prosent: {STRING} STR_CONFIG_SETTING_SERVINT_ISPERCENT_HELPTEXT :Velge om vedlikehold av kjøretøyer utløses av tiden som er forløpt fra siste gjennomførte vedlikehold, eller av at pålitelighet dropper under en bestemt prosent av maksimal pålitelighet @@ -1586,6 +1592,10 @@ STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :Ved å aktivere STR_CONFIG_SETTING_TOWN_FOUNDING_FORBIDDEN :Forbudt STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED :Tillatt STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED_CUSTOM_LAYOUT :Tillatt, egendefinert oppsett av by +STR_CONFIG_SETTING_TOWN_CARGOGENMODE :varegenerering byer: {STRING} +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_HELPTEXT :Hvor mye varer som genereres av hus i byer, i forhold til byens folketall.{}Kvadratisk vekst: En by av dobbel størrelse genererer fire ganger så mange passasjerer.{}Lineær vekst: En by av dobbel størrelse genererer dobbelt så mange passasjerer. +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_ORIGINAL :Kvadratisk (original) +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_BITCOUNT :Lineær STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :Plassering av trær i spillet: {STRING} STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :Kontroll tilfeldige utseender til tre under spillet. Dette kan påvirke industrier som avhenger av trevekst, for eksempel trelast @@ -1713,7 +1723,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Gods-di STR_CONFIG_SETTING_AI :{ORANGE}Motstandere STR_CONFIG_SETTING_AI_NPC :{ORANGE}Datamaskinstyrte spillere -STR_CONFIG_SETTING_PATHFINDER_OPF :Original STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Anbefalt) @@ -1797,13 +1806,9 @@ STR_QUIT_NO :{BLACK}Nei # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -2142,7 +2147,7 @@ STR_NETWORK_CHAT_ALL :[Alle] {STRING} STR_NETWORK_CHAT_OSKTITLE :{BLACK}Skriv inn tekst for nettverkssamtale # Network messages -STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}Ingen nettverksadaptere funnet eller kompilert uten ENABLE_NETWORK +STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}Ingen nettverksadapter funnet STR_NETWORK_ERROR_NOSERVER :{WHITE}Kunne ikke finne noen nettverksspill STR_NETWORK_ERROR_NOCONNECTION :{WHITE}Tjeneren svarte ikke på forespørselen STR_NETWORK_ERROR_NEWGRF_MISMATCH :{WHITE}Kunne ikke koble til pga. ulike versjoner av NewGRF @@ -2434,6 +2439,11 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL :{BLACK}Bygg vei STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Bygg trikkesportunnel. Shift slår av/på kostnadsestimat STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Veksle mellom bygging/fjerning for veibygging STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Veksle mellom bygging/fjerning for trikkesporkonstruksjon +STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_ROAD :{BLACK}Konverter/oppgrader veitypen. Shift slår av/på kostnadsestimat +STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_TRAM :{BLACK}Konverter/oppgrader trikketypen. Shift slår av/på kostnadsestimat + +STR_ROAD_NAME_ROAD :Vei +STR_ROAD_NAME_TRAM :Trikkespor # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Garasjens retning @@ -2618,8 +2628,11 @@ STR_LAND_AREA_INFORMATION_NEWGRF_NAME :{BLACK}NewGRF: STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED :{BLACK}Godtatte varer: {LTBLUE} STR_LAND_AREA_INFORMATION_CARGO_EIGHTS :({COMMA}/8 {STRING}) STR_LANG_AREA_INFORMATION_RAIL_TYPE :{BLACK}Skinnetype: {LTBLUE}{STRING} +STR_LANG_AREA_INFORMATION_ROAD_TYPE :{BLACK}Veitype: {LTBLUE}{STRING} +STR_LANG_AREA_INFORMATION_TRAM_TYPE :{BLACK}Trikketype: {LTBLUE}{STRING} STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT :{BLACK}Fartsgrense for jernbanespor: {LTBLUE}{VELOCITY} STR_LANG_AREA_INFORMATION_ROAD_SPEED_LIMIT :{BLACK}Veiens fartsgrense: {LTBLUE}{VELOCITY} +STR_LANG_AREA_INFORMATION_TRAM_SPEED_LIMIT :{BLACK}Fartsgrense for trikk: {LTBLUE}{VELOCITY} # Description of land area of different tiles STR_LAI_CLEAR_DESCRIPTION_ROCKS :Steiner @@ -2729,6 +2742,7 @@ STR_FRAMERATE_SPEED_FACTOR :{BLACK}Gjeldend STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}Hvor raskt spillet kjører i forhold til forventet hastighet ved normal simulering. STR_FRAMERATE_CURRENT :{WHITE}Gjeldende STR_FRAMERATE_AVERAGE :{WHITE}Middels +STR_FRAMERATE_MEMORYUSE :{WHITE}Minne STR_FRAMERATE_DATA_POINTS :{BLACK}Data basert på {COMMA} målinger STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL} ms STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL} ms @@ -2736,6 +2750,9 @@ STR_FRAMERATE_MS_BAD :{RED}{DECIMAL} STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL} bilder/s STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL} Bilder/s STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL} frames/s +STR_FRAMERATE_BYTES_GOOD :{LTBLUE}{BYTES} +STR_FRAMERATE_BYTES_WARN :{YELLOW}{BYTES} +STR_FRAMERATE_BYTES_BAD :{RED}{BYTES} STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} ms STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} s ############ Leave those lines in this order!! @@ -3359,8 +3376,7 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Infrastr STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Jernbanebiter: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Signaler STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Veibiter: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Vei -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Trikkespor +STR_COMPANY_INFRASTRUCTURE_VIEW_TRAM_SECT :{GOLD}Trikkevogner: STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Vannruter: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Kanaler STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Stasjoner: @@ -3371,8 +3387,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Industrier STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Ingen - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% transportert) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% transportert) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Industrinavn - klikk på navn for å gå til industri. Ctrl+klikk åpner et nytt tilleggsvindu over industrien @@ -3440,6 +3454,8 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Ugrupperte kjø STR_GROUP_DEFAULT_SHIPS :Ugrupperte skip STR_GROUP_DEFAULT_AIRCRAFTS :Ugrupperte luftfartøy +STR_GROUP_COUNT_WITH_SUBGROUP :{TINY_FONT}{COMMA} (+{COMMA}) + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Grupper - Klikk på en gruppe for å se alle kjøretøy i gruppen. Dra og slipp grupper for å arrangere dem hierarkisk STR_GROUP_CREATE_TOOLTIP :{BLACK}Klikk for å opprette en gruppe STR_GROUP_DELETE_TOOLTIP :{BLACK}Fjern den valgte gruppen @@ -3466,12 +3482,18 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Nye tog/vogner STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Nye tog/vogner for monorail STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Nye tog/vogner for maglev -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Nye tog/vogner STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Nye kjøretøy +STR_BUY_VEHICLE_TRAM_VEHICLE_CAPTION :Nye trikkekjøretøy + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Nye tog/vogner +STR_BUY_VEHICLE_ROAD_VEHICLE_ALL_CAPTION :Nye veikjøretøy STR_BUY_VEHICLE_SHIP_CAPTION :Nye skip STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Nye luftfartøy +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Kostnad: {GOLD}{CURRENCY_LONG}{BLACK} Vekt: {GOLD}{WEIGHT_SHORT} +STR_PURCHASE_INFO_COST_REFIT_WEIGHT :{BLACK}Kostnad: {GOLD}{CURRENCY_LONG}{BLACK} (Ombyggingskostnad: {GOLD}{CURRENCY_LONG}{BLACK}) Vekt: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Hastighet: {GOLD}{VELOCITY}{BLACK} Kraft: {GOLD}{POWER} STR_PURCHASE_INFO_SPEED :{BLACK}Hastighet: {GOLD}{VELOCITY} STR_PURCHASE_INFO_SPEED_OCEAN :{BLACK}Hastighet på havet: {GOLD}{VELOCITY} @@ -3482,8 +3504,10 @@ STR_PURCHASE_INFO_REFITTABLE :(ombyggbart) STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Designet: {GOLD}{NUM}{BLACK} Levetid: {GOLD}{COMMA} år STR_PURCHASE_INFO_RELIABILITY :{BLACK}Maks pålitelighet: {GOLD}{COMMA}{NBSP}% STR_PURCHASE_INFO_COST :{BLACK}Kostnad: {GOLD}{CURRENCY_LONG} +STR_PURCHASE_INFO_COST_REFIT :{BLACK}Kostnad: {GOLD}{CURRENCY_LONG}{BLACK} (Ombyggingskostnad: {GOLD}{CURRENCY_LONG}{BLACK}) STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Vekt: {GOLD}{WEIGHT_SHORT} ({WEIGHT_SHORT}) STR_PURCHASE_INFO_COST_SPEED :{BLACK}Kostnad: {GOLD}{CURRENCY_LONG}{BLACK} Hastighet: {GOLD}{VELOCITY} +STR_PURCHASE_INFO_COST_REFIT_SPEED :{BLACK}Kostnad: {GOLD}{CURRENCY_LONG}{BLACK} (Ombyggingskostnad: {GOLD}{CURRENCY_LONG}{BLACK}) Hastighet: {GOLD}{VELOCITY} STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Kapasitet: {GOLD}{CARGO_LONG}, {CARGO_LONG} STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Lokomotivvogner: {GOLD}+{POWER}{BLACK} Vekt: {GOLD}+{WEIGHT_SHORT} STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Kan bygges om til: {GOLD}{STRING} @@ -3504,11 +3528,21 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Kjøp kj STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Kjøp skip STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Kjøp luftfartøy +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Kjøp og bygg om kjøretøy +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Kjøp og bygg om kjøretøy +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Kjøp og bygg om skip +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Kjøp og bygg om luftfartøy + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Kjøp det merkede tog/vogn. Shift+klikk viser estimert kostnad STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Kjøp det merkede kjøretøy. Shift+klikk viser estimert kostnad STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Kjøp det merkede skip. Shift+klikk viser estimert kostnad STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Kjøp det merkede luftfartøy. Shift+klikk viser estimert kostnad +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Kjøp og bygg om merket tog/vogn. Shift+klikk viser anslått kostnad uten å kjøpe. +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Kjøp og bygg om det merkede kjøretøyet. Shift+klikk viser anslått kostnad uten å kjøpe. +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Kjøp og bygg om det merkede skipet. Shift+klikk viser anslått kostnad uten å kjøpe. +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Kjøp og bygg om det merkede luftfartøyet. Shift+klikk viser anslått kostnad uten å kjøpe. + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Endre navn STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Endre navn STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Endre navn @@ -3616,14 +3650,19 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Du er n # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Melding fra kjøretøysprodusent -STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Vi har nettopp designet e{G n i t} ny{G "" "" tt} {STRING} - er du interessert i et års ekslusivt bruk av dette, slik at vi kan se hvordan det virker før det blir allment tilgjengelig? +STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Vi har nettopp designet e{G n i t} ny{G "" "" tt} {STRING} - er du interessert i ett års ekslusivt bruk av dette, slik at vi kan se hvordan det virker før det blir allment tilgjengelig? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :{G=neuter}lokomotiv -STR_ENGINE_PREVIEW_ROAD_VEHICLE :{G=neuter}kjøretøy -STR_ENGINE_PREVIEW_AIRCRAFT :{G=neuter}luftfartøy -STR_ENGINE_PREVIEW_SHIP :{G=neuter}skip +STR_ENGINE_PREVIEW_ELRAIL_LOCOMOTIVE :{G=neuter}elektrisk lokomotiv STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :{G=neuter}monorail-lokomotiv STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :{G=neuter}maglev-lokomotiv +STR_ENGINE_PREVIEW_ROAD_VEHICLE :{G=neuter}kjøretøy +STR_ENGINE_PREVIEW_TRAM_VEHICLE :trikkekjøretøy + +STR_ENGINE_PREVIEW_AIRCRAFT :{G=neuter}luftfartøy +STR_ENGINE_PREVIEW_SHIP :{G=neuter}skip + STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Kostnad: {CURRENCY_LONG} Vekt: {WEIGHT_SHORT}{}Hastighet: {VELOCITY} Kraft: {POWER}{}Driftskostnader: {CURRENCY_LONG}/år{}Kapasitet: {CARGO_LONG} STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Kostnad: {CURRENCY_LONG} Vekt: {WEIGHT_SHORT}{}Hastighet: {VELOCITY} Kraft: {POWER} Maks trekkraft: {6:FORCE}{}Vedlikehold: {4:CURRENCY_LONG}/år{}Kapasitet: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Kostnad: {CURRENCY_LONG} Maks hastighet: {VELOCITY}{}Kapasitet: {CARGO_LONG}{}Driftskostnader: {CURRENCY_LONG}/år @@ -3660,15 +3699,20 @@ STR_REPLACE_HELP_STOP_BUTTON :{BLACK}Klikk de STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK}Veksle mellom tog- og vognerstatningsvinduet STR_REPLACE_ENGINES :Lokomotiv STR_REPLACE_WAGONS :Vogner -STR_REPLACE_ALL_RAILTYPE :Status: Mangler +STR_REPLACE_ALL_RAILTYPE :Alle jernbanekjøretøy +STR_REPLACE_ALL_ROADTYPE :Alle veikjøretøy STR_REPLACE_HELP_RAILTYPE :{BLACK}Velg jernbanetypen du vil bytte ut lokomotiv på +STR_REPLACE_HELP_ROADTYPE :{BLACK}Velg veitypen du vil bytte ut kjøretøy på STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Viser hvilket lokomotiv som overtar for det valgte lokomotivet på venstresiden STR_REPLACE_RAIL_VEHICLES :Jernbanekjøretøy STR_REPLACE_ELRAIL_VEHICLES :Elektriske jernbanekjøretøy STR_REPLACE_MONORAIL_VEHICLES :Monorail-kjøretøy STR_REPLACE_MAGLEV_VEHICLES :Maglev-kjøretøy +STR_REPLACE_ROAD_VEHICLES :Veikjøretøy +STR_REPLACE_TRAM_VEHICLES :Trikkekjøretøy + STR_REPLACE_REMOVE_WAGON :{BLACK}Vognfjerning: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}La autoerstatningen beholde lengen på toget ved å fjerne vogner (fra første vogn), hvis utskiftningen gjør toget lengre. @@ -3752,11 +3796,11 @@ STR_VEHICLE_INFO_AGE_RUNNING_COST_YR :{BLACK}Alder: { STR_VEHICLE_INFO_AGE :{COMMA} år ({COMMA}) STR_VEHICLE_INFO_AGE_RED :{RED}{COMMA} år ({COMMA}) -STR_VEHICLE_INFO_MAX_SPEED :{BLACK}Maks hastighet: {LTBLUE}{VELOCITY} -STR_VEHICLE_INFO_MAX_SPEED_TYPE :{BLACK}Maks. hastighet: {LTBLUE}{VELOCITY} {BLACK}Flytype: {LTBLUE}{STRING} -STR_VEHICLE_INFO_MAX_SPEED_TYPE_RANGE :{BLACK}Maks. hastighet: {LTBLUE}{VELOCITY} {BLACK}Flytype: {LTBLUE}{STRING} {BLACK}Rekkevidde: {LTBLUE}{COMMA} ruter -STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Vekt: {LTBLUE}{WEIGHT_SHORT} {BLACK}Kraft: {LTBLUE}{POWER}{BLACK} Maks hastighet: {LTBLUE}{VELOCITY} -STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Vekt: {LTBLUE}{WEIGHT_SHORT} {BLACK}Kraft: {LTBLUE}{POWER}{BLACK} Maks hastighet: {LTBLUE}{VELOCITY} {BLACK}Maks trekkraft: {LTBLUE}{FORCE} +STR_VEHICLE_INFO_MAX_SPEED :{BLACK}Topphastighet: {LTBLUE}{VELOCITY} +STR_VEHICLE_INFO_MAX_SPEED_TYPE :{BLACK}Topphastighet: {LTBLUE}{VELOCITY} {BLACK}Flytype: {LTBLUE}{STRING} +STR_VEHICLE_INFO_MAX_SPEED_TYPE_RANGE :{BLACK}Topphastighet: {LTBLUE}{VELOCITY} {BLACK}Flytype: {LTBLUE}{STRING} {BLACK}Rekkevidde: {LTBLUE}{COMMA} ruter +STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Vekt: {LTBLUE}{WEIGHT_SHORT} {BLACK}Kraft: {LTBLUE}{POWER}{BLACK} Topphastighet: {LTBLUE}{VELOCITY} +STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Vekt: {LTBLUE}{WEIGHT_SHORT} {BLACK}Kraft: {LTBLUE}{POWER}{BLACK} Topphastighet: {LTBLUE}{VELOCITY} {BLACK}Maks trekkraft: {LTBLUE}{FORCE} STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Fortjeneste i år: {LTBLUE}{CURRENCY_LONG} (i fjor: {CURRENCY_LONG}) STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Pålitelighet: {LTBLUE}{COMMA}{NBSP}% {BLACK}Havarier siden siste vedlikehold: {LTBLUE}{COMMA} @@ -3883,7 +3927,7 @@ STR_ORDER_CONDITIONAL_VARIABLE_TOOLTIP :{BLACK}Kjøret # Conditional order variables, must follow order of OrderConditionVariable enum STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE :Lastprosent STR_ORDER_CONDITIONAL_RELIABILITY :Pålitelighet -STR_ORDER_CONDITIONAL_MAX_SPEED :Maks hastighet +STR_ORDER_CONDITIONAL_MAX_SPEED :Topphastighet STR_ORDER_CONDITIONAL_AGE :Alder (år) STR_ORDER_CONDITIONAL_REQUIRES_SERVICE :Trenger vedlikehold STR_ORDER_CONDITIONAL_UNCONDITIONALLY :Alltid @@ -4120,6 +4164,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Velg det STR_AI_LIST_CANCEL :{BLACK}Avbryt STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Ikke endre skriptet + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parametre STR_AI_SETTINGS_CAPTION_AI :AI @@ -4322,7 +4367,6 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... denn STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... veien vender i feil retning STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... gjennomkjøringsstopper kan ikke ha hjørner STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... gjennomkjøringsstopper kan ikke ha kryss -STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... veien er enveiskjørt eller blokkert # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Kan ikke fjerne del av stasjonen... @@ -4392,7 +4436,8 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Må fjer STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Ingen passende jernbanespor STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Må fjerne jernbanespor først STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Veien er enveiskjørt eller blokkert -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Denne jernbanetypen tillater ikke planoverganger +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Denne jernbanetypen tillater ikke planoverganger +STR_ERROR_CROSSING_DISALLOWED_ROAD :{WHITE}Denne veitypen tillater ikke planoverganger STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Kan ikke bygge signaler her... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Kan ikke bygge jernbanespor her... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Kan ikke fjerne jernbanespor herfra... @@ -4412,6 +4457,12 @@ STR_ERROR_CAN_T_REMOVE_ROAD_FROM :{WHITE}Kan ikke STR_ERROR_CAN_T_REMOVE_TRAMWAY_FROM :{WHITE}Kan ikke fjerne trikkespor herfra... STR_ERROR_THERE_IS_NO_ROAD :{WHITE}... det finnes ingen vei STR_ERROR_THERE_IS_NO_TRAMWAY :{WHITE}... det finnes ingen trikkespor +STR_ERROR_CAN_T_CONVERT_ROAD :{WHITE}Kan ikke konvertere veitype her... +STR_ERROR_CAN_T_CONVERT_TRAMWAY :{WHITE}Kan ikke konvertere trikketype her... +STR_ERROR_NO_SUITABLE_ROAD :{WHITE}Ingen passende vei +STR_ERROR_NO_SUITABLE_TRAMWAY :{WHITE}Ingen passende trikkespor +STR_ERROR_INCOMPATIBLE_ROAD :{WHITE}... inkompatibel vei +STR_ERROR_INCOMPATIBLE_TRAMWAY :{WHITE}... ingen passende trikkespor # Waterway construction errors STR_ERROR_CAN_T_BUILD_CANALS :{WHITE}Kan ikke bygge kanaler her... @@ -4464,6 +4515,7 @@ STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Kan ikke STR_ERROR_GROUP_CAN_T_DELETE :{WHITE}Kan ikke slette denne gruppen... STR_ERROR_GROUP_CAN_T_RENAME :{WHITE}Kan ikke gi nytt navn på denne gruppen... STR_ERROR_GROUP_CAN_T_SET_PARENT :{WHITE}Kan ikke sette foreldregruppe... +STR_ERROR_GROUP_CAN_T_SET_PARENT_RECURSION :{WHITE}... løkker i gruppehierarkiet er ikke tillatt STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}Kan ikke fjerne alle kjøretøy fra denne gruppen... STR_ERROR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}Kan ikke legge til kjøretøyet i denne gruppen... STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}Kan ikke legge til delte kjøretøyer i gruppen... diff --git a/src/lang/norwegian_nynorsk.txt b/src/lang/norwegian_nynorsk.txt index 937b4923e0..e52486b21f 100644 --- a/src/lang/norwegian_nynorsk.txt +++ b/src/lang/norwegian_nynorsk.txt @@ -12,8 +12,6 @@ ##case small -# $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. # 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. @@ -474,9 +472,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Syne/gøym konsoll STR_ABOUT_MENU_AI_DEBUG :AI- / Spelscriptfeilsøking STR_ABOUT_MENU_SCREENSHOT :Skjermdump -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Fullt forstørra skjermbilete -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Normalt skjermbilete -STR_ABOUT_MENU_GIANT_SCREENSHOT :Stort skjermfoto STR_ABOUT_MENU_ABOUT_OPENTTD :Om 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Spriteforskyver STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Syne/gøym markeringsramme @@ -646,9 +641,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Eigendefinert 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Musikkvolum STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Lydeffektvolum -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}MIN -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}MAKS. -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -860,6 +852,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}Ny {STRING}type er tilgjengeleg! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} godtek ikkje lenger {STRING} STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} godtek ikkje lenger {STRING} eller {STRING} STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} godtek no {STRING} @@ -1607,7 +1600,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Varefor STR_CONFIG_SETTING_AI :{ORANGE}Motstandarar STR_CONFIG_SETTING_AI_NPC :{ORANGE}Datamaskinspelarar -STR_CONFIG_SETTING_PATHFINDER_OPF :Original STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Anbefalt) @@ -1690,13 +1682,9 @@ STR_QUIT_NO :{BLACK}Nei # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -2324,6 +2312,7 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Bygg tri STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Byt mellom bygging/fjerning for vegbygging STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Byt mellom bygge/fjerne for trikkesporbygging + # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Garasjens retning STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}Vel retning på garasje @@ -3179,8 +3168,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Infrastr STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Togsporbitar: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Signal STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Vegstubbar: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Veg -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Trikkespor STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Vannruter: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Kanalar STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Stasjonar: @@ -3191,8 +3178,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Industriar STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Ingen - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}{NBSP}% transportert) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}{NBSP}%/{COMMA}{NBSP}% transportert) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Industrinamn - Klikk på namnet for å syne industrien i hovedvisninga. CTRL+klikk syner industrien i eit tilleggsvindauge @@ -3254,6 +3239,7 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :køyretøy utan STR_GROUP_DEFAULT_SHIPS :Ugrupperte skip STR_GROUP_DEFAULT_AIRCRAFTS :Luftfartøy utan gruppe + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Grupper - Klikk på ei gruppe for å få ei liste over alle køyretøya i den STR_GROUP_CREATE_TOOLTIP :{BLACK}Klikk for å lage ei gruppe STR_GROUP_DELETE_TOOLTIP :{BLACK}Slett den valde gruppa @@ -3275,10 +3261,13 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Nytt elektrisk STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Nye tog/vogner for monorail STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Nye tog/vogner for maglev -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Nye tog/vogner STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Nye køyretøy + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Nye tog/vogner STR_BUY_VEHICLE_SHIP_CAPTION :Nye skip STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Nytt luftfartøy +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Kostnad: {GOLD}{CURRENCY_LONG}{BLACK} Vekt: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Hastigheit: {GOLD}{VELOCITY}{BLACK} Kraft: {GOLD}{POWER} @@ -3311,11 +3300,13 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Kjøp k STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Bygg skip STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Bygg luftfartøy + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Bygg den valde farkosten. Skift-klikk viser prisoverslag utan å kjøpe. STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Bygg det valde køyretøyet. Skift-klikk viser prisoverslag utan å kjøpe. STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Bygg det valde skipet. Skift-klikk viser prisoverslag utan å kjøpe. STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Bygg det valde luftfartøyet. Skift-klikk viser prisoverslag utan å kjøpe. + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Gje nytt namn STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Endre namn STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Endre namn @@ -3424,13 +3415,16 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Du er i # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Melding frå køyretøysprodusent STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Me har nyleg designa eit nytt {STRING} - er du interessert i å teste denne farkosten i eit år, slik at me kan sjå korleis det verkar før me gjer han tilgjengeleg på markedet? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :lokomotiv -STR_ENGINE_PREVIEW_ROAD_VEHICLE :køyretøy -STR_ENGINE_PREVIEW_AIRCRAFT :luftfartøy -STR_ENGINE_PREVIEW_SHIP :skip STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :monorail-lokomotiv STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :maglev-lokomotiv +STR_ENGINE_PREVIEW_ROAD_VEHICLE :køyretøy + +STR_ENGINE_PREVIEW_AIRCRAFT :luftfartøy +STR_ENGINE_PREVIEW_SHIP :skip + STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Kostnad: {CURRENCY_LONG} Vekt: {WEIGHT_SHORT}{}Hastigheit: {VELOCITY} Kraft: {POWER}{}Driftskostnader: {CURRENCY_LONG}/år{}Kapasitet: {CARGO_LONG} STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Pris: {CURRENCY_LONG} Vekt: {WEIGHT_SHORT}{}Hastigheit: {VELOCITY} Kraft: {POWER} Maks. trekkraft: {6:FORCE}{}Driftskostnad: {4:CURRENCY_LONG}/yr{}Kapasitet: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Pris: {CURRENCY_LONG} Maks. hastigheit: {VELOCITY}{}Kapasitet: {CARGO_LONG}{}Driftskostnad: {CURRENCY_LONG}/år @@ -3471,6 +3465,7 @@ STR_REPLACE_ELRAIL_VEHICLES :Elektriske jern STR_REPLACE_MONORAIL_VEHICLES :Monorail-køyretøy STR_REPLACE_MAGLEV_VEHICLES :Maglev-køyretøy + STR_REPLACE_REMOVE_WAGON :{BLACK}Vognfjerning: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Lat den automatiske utskiftinga behalde lengda på toget ved å fjerne vogner (frå første vogn), dersom utskiftinga gjer toget lenger. @@ -3915,6 +3910,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Merk uth STR_AI_LIST_CANCEL :{BLACK}Avbryt STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Ikkje endre AI + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parameter STR_AI_SETTINGS_CAPTION_AI :AI @@ -4186,7 +4182,7 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Må fjer STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Upassande jernbanespor STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Må fjerne jernbanespor først STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Vegen er einvegskøyrd eller blokkert -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Overgang ikkje tillate for denne typen jernbane +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Overgang ikkje tillate for denne typen jernbane STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Kan ikkje byggje signaler her... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Kan ikkje byggje jernbanespor her... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Kan ikkje fjerne jernbanespor herfrå... diff --git a/src/lang/polish.txt b/src/lang/polish.txt index 7d61bb7a44..01b0e92c7a 100644 --- a/src/lang/polish.txt +++ b/src/lang/polish.txt @@ -12,8 +12,6 @@ ##case d c b n m w -# $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. # 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. @@ -616,6 +614,8 @@ STR_TOOLTIP_FILTER_CRITERIA :{BLACK}Wybierz STR_BUTTON_SORT_BY :{BLACK}Sortuj wg STR_BUTTON_LOCATION :{BLACK}Położenie STR_BUTTON_RENAME :{BLACK}Zmień nazwę +STR_BUTTON_CATCHMENT :{BLACK}Zasięg +STR_TOOLTIP_CATCHMENT :{BLACK}Przełącz wyświetlanie zasięgu STR_TOOLTIP_CLOSE_WINDOW :{BLACK}Zamknij okno STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Tytuł okna - przeciągnij, aby przesunąć okno @@ -644,6 +644,7 @@ STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT_TOOLTIP :{BLACK}Włącze STR_BUTTON_DEFAULT :{BLACK}Domyślna STR_BUTTON_CANCEL :{BLACK}Anuluj STR_BUTTON_OK :{BLACK}OK +STR_WARNING_PASSWORD_SECURITY :{YELLOW}Uwaga: Administratorzy serwera mogą być w stanie przeczytać każdy wpisany tutaj tekst. # On screen keyboard window STR_OSK_KEYBOARD_LAYOUT :`1234567890-=\qwertyuiop[]asdfghjkl;' zxcvbnm,./ . @@ -717,6 +718,7 @@ STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN :{BLACK}Przybli STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT :{BLACK}Oddalenie STR_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Budowa kolei STR_TOOLBAR_TOOLTIP_BUILD_ROADS :{BLACK}Budowa dróg +STR_TOOLBAR_TOOLTIP_BUILD_TRAMWAYS :{BLACK}Budowa tramwajów STR_TOOLBAR_TOOLTIP_BUILD_SHIP_DOCKS :{BLACK}Budowa portów STR_TOOLBAR_TOOLTIP_BUILD_AIRPORTS :{BLACK}Budowa lotnisk STR_TOOLBAR_TOOLTIP_LANDSCAPING :{BLACK}Zmiana terenu, podwyższanie/obniżanie lądu, sadzenie drzew, itp. @@ -737,6 +739,7 @@ STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION :{BLACK}Tworzeni STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Tworzenie miast 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_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 @@ -845,6 +848,7 @@ STR_TOOLBAR_SOUND_MUSIC :Dźwięk/muzyka ############ range for message menu starts STR_NEWS_MENU_LAST_MESSAGE_NEWS_REPORT :Ostatnia wiadomość/ogłoszenie STR_NEWS_MENU_MESSAGE_HISTORY_MENU :Poprzednie wiadomości +STR_NEWS_MENU_DELETE_ALL_MESSAGES :Usuń wszystkie wiadomości ############ range ends here ############ range for about menu starts @@ -853,9 +857,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Przełącz konsolę STR_ABOUT_MENU_AI_DEBUG :Debugowanie SI / Game Script STR_ABOUT_MENU_SCREENSHOT :Zrzut ekranu -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Zrzut ekranu z pełnym przybliżeniem -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Zrzut ekranu z przybliżeniem domyślnym -STR_ABOUT_MENU_GIANT_SCREENSHOT :Zrzut ekranu całej mapy STR_ABOUT_MENU_SHOW_FRAMERATE :Pokaż ilość klatek na sekundę STR_ABOUT_MENU_ABOUT_OPENTTD :Info o 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Wyrównywanie sprite'ów @@ -1026,9 +1027,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Własny 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Głośność muzyki STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Głośność efektów -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}MIN -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}MAX -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -1053,6 +1051,7 @@ STR_MUSIC_TOOLTIP_TOGGLE_PROGRAM_SHUFFLE :{BLACK}Losowe o STR_MUSIC_TOOLTIP_SHOW_MUSIC_TRACK_SELECTION :{BLACK}Pokaż okno wyboru ścieżek # Playlist window +STR_PLAYLIST_MUSIC_SELECTION_SETNAME :{WHITE}Program muzyczny - '{STRING}' STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTBLUE}{ZEROFILL_NUM} "{STRING}" STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Wykaz ścieżek STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Programuj - '{STRING}' @@ -1245,6 +1244,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}Dostępn{G y a e} now{G y a e} {STRING} - {ENGINE}! + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} nie akceptuje już {STRING.d} STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} nie akceptuje już {STRING.d} ani {STRING.d} STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} już akceptuje {STRING.b} @@ -1264,10 +1264,10 @@ STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION :{BIG_FONT}{BLAC # Extra view window STR_EXTRA_VIEW_PORT_TITLE :{WHITE}Podgląd {COMMA} -STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Kopiuj do podglądu -STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Kopiuj pozycję głównego okna do podglądu -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Wstaw z podglądu -STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Przesuń główne okno na pozycję podglądu +STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}Zmień podgląd +STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN_TT :{BLACK}Kopiuj pozycję widoku głównego do podglądu +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}Zmień widok główny +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW_TT :{BLACK}Kopiuj pozycję tego podglądu do widoku głównego # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}Opcje gry @@ -1311,6 +1311,9 @@ STR_GAME_OPTIONS_CURRENCY_GEL :Lari gruziński STR_GAME_OPTIONS_CURRENCY_IRR :Rial irański (IRR) STR_GAME_OPTIONS_CURRENCY_RUB :Nowy rubel rosyjski (RUB) STR_GAME_OPTIONS_CURRENCY_MXN :Peso meksykańskie (MXN) +STR_GAME_OPTIONS_CURRENCY_NTD :Nowy dolar tajwański (TWD) +STR_GAME_OPTIONS_CURRENCY_CNY :Juan chiński (CNY) +STR_GAME_OPTIONS_CURRENCY_HKD :Dolar hongkoński (HKD) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Pojazdy drogowe @@ -1373,8 +1376,12 @@ STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normalne STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Podwójny STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Poczwórny +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_4X_ZOOM :Poczwórny +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_BASE_GRF :{BLACK}Podstawowy zestaw grafik STR_GAME_OPTIONS_BASE_GRF_TOOLTIP :{BLACK}Wybierz podstawowy zestaw grafik do użycia @@ -1558,6 +1565,8 @@ STR_CONFIG_SETTING_AUTOSLOPE :Pozwól na zmia STR_CONFIG_SETTING_AUTOSLOPE_HELPTEXT :Pozwalaj na modyfikowanie terenu pod budynkami i torami bez usuwania ich STR_CONFIG_SETTING_CATCHMENT :Pozwól na bardziej realistyczny zasięg obejmowania: {STRING} STR_CONFIG_SETTING_CATCHMENT_HELPTEXT :Używaj różnych rozmiarów pokrywania obszaru dla różnych typów stacji i lotnisk +STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES :Stacje firmowe mogą obsługiwać przedsiębiorstwa z dołączonymi stacjami neutralnymi: {STRING} +STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES_HELPTEXT :Jeśli włączone, przedsiębiorstwa z dołączonymi stacjami (takie jak platformy wiertnicze) mogą być obsługiwane także przez stacje firmowe znajdujące się w pobliżu. Jeśli wyłączone, przedsiębiorstwa te mogą być obsługiwane wyłącznie przez dołączone do nich stacje. Żadne pobliskie stacje firmowe nie będą mogły ich obsługiwać, a ponadto dołączone stacje nie będą obsługiwały niczego innego poza ich przedsiębiorstwem STR_CONFIG_SETTING_EXTRADYNAMITE :Pozwól usuwać drogi, mosty, tunele, itp. należące do miasta: {STRING} STR_CONFIG_SETTING_EXTRADYNAMITE_HELPTEXT :Ułatwiaj usuwanie infrastruktury i budynków należących do miast STR_CONFIG_SETTING_TRAIN_LENGTH :Maksymalna długość pociągów: {STRING} @@ -1574,8 +1583,8 @@ STR_CONFIG_SETTING_TRAIN_SLOPE_STEEPNESS_HELPTEXT :Pochylenie pola STR_CONFIG_SETTING_PERCENTAGE :{COMMA}% STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS :Nachylenie stoków dla pojazdów drogowych: {STRING} STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS_HELPTEXT :Pochylenie pola stoku dla pojazdów drogowych. Wyższa wartość utrudnia podjazd pod górę -STR_CONFIG_SETTING_FORBID_90_DEG :Zabroń pociągom i statkom skręcać o 90 stopni: {STRING} -STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :90-stopniowy zakręt występuje wtedy, gdy bezpośrednio po poziomym odcinku toru występuje odcinek pionowy na sąsiadującym polu zmuszając pociąg do skrętu o 90 stopni pokonując krawędź pola zamiast normalnego, 45-stopniowego skrętu w innych kombinacjach torów. Dotyczy to również kąta skrętu dla statków +STR_CONFIG_SETTING_FORBID_90_DEG :Zabroń pociągom skręcać o 90 stopni: {STRING} +STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :90-stopniowy zakręt występuje wtedy, gdy bezpośrednio po poziomym odcinku toru występuje odcinek pionowy na sąsiadującym polu zmuszając pociąg do skrętu o 90 stopni pokonując krawędź pola zamiast normalnego, 45-stopniowego skrętu w innych kombinacjach torów. STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS :Pozwól na łączenie stacji nie sąsiadujących bezpośrednio: {STRING} STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS_HELPTEXT :Pozwalaj na dodawanie części stacji nie stykających się ze sobą. Naciśnij Ctrl przed postawieniem nowej części STR_CONFIG_SETTING_INFLATION :Inflacja: {STRING} @@ -1631,8 +1640,8 @@ STR_CONFIG_SETTING_PLANE_SPEED :Prędkość sam STR_CONFIG_SETTING_PLANE_SPEED_HELPTEXT :Ustaw zależną prędkość samolotów w porównaniu do innych typów pojazdów, aby zmniejszyć przychód generowany przez transport samolotami STR_CONFIG_SETTING_PLANE_SPEED_VALUE :1 / {COMMA} STR_CONFIG_SETTING_PLANE_CRASHES :Liczba katastrof lotniczych: {STRING} -STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Ustaw szanse na katastrofy lotnicze -STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Brak +STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Ustaw szanse losowych katastrof lotniczych.{}* Duże samoloty zawsze ryzykują katastrofą lądując na małych lotniskach +STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Brak* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Zredukowana STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normalna STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Pozwól na budowę przystanków przelotowych na drogach miejskich: {STRING} @@ -1691,7 +1700,7 @@ STR_CONFIG_SETTING_TERRAIN_TYPE_HELPTEXT :Określa ukszta STR_CONFIG_SETTING_INDUSTRY_DENSITY :Liczba przedsiębiorstw: {STRING} STR_CONFIG_SETTING_INDUSTRY_DENSITY_HELPTEXT :Określa liczbę przedsiębiorstw na początku i w trakcie gry STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE :Maksymalna odległość od krawędzi dla rafinerii: {STRING} -STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :Rafinerie są budowane tylko w pobliżu krawędzi map, to znaczy na wybrzeżach dla map wyspiarskich +STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :Rafinerie są budowane tylko w pobliżu krawędzi map, to znaczy na wybrzeżach dla map wyspiarskichOgraniczenie jak daleko od krawędzi mapy mogą być budowane rafinerie i platformy wiertnicze. Na mapach wyspiarskich zapewnia to, że znajdą się blisko wybrzeża. Na mapach większych niż 256 pól, wartość ta jest skalowana w górę. STR_CONFIG_SETTING_SNOWLINE_HEIGHT :Wysokość granicy wiecznych śniegów: {STRING} STR_CONFIG_SETTING_SNOWLINE_HEIGHT_HELPTEXT :Wysokość linii śniegu w klimacie arktycznym. Poziom pokrywy śnieżnej wpływa na rozmieszczenie przedsiębiorstw i na warunki rozwoju miast STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN :Gładkość terenu: {STRING} @@ -1729,6 +1738,7 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :Kolor terenu na STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :zielony STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :ciemnozielony STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :fioletowy +STR_CONFIG_SETTING_SCROLLMODE :Zachowanie przeciągania okna podglądu: {STRING} STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :Zachowanie podczas przeciągania mapy STR_CONFIG_SETTING_SCROLLMODE_DEFAULT :Przeciągnij okno podglądu prawym przyciskiem myszy, pozycja myszy zablokowana STR_CONFIG_SETTING_SCROLLMODE_RMB_LOCKED :Przeciągnij mapę prawym przyciskiem myszy, pozycja myszy zablokowana @@ -1854,6 +1864,9 @@ STR_CONFIG_SETTING_AI_IN_MULTIPLAYER :Pozwól na SI w 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_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. +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_VALUE :{COMMA} MiB STR_CONFIG_SETTING_SERVINT_ISPERCENT :Okres między serwisowaniami w procentach: {STRING} STR_CONFIG_SETTING_SERVINT_ISPERCENT_HELPTEXT :Wybierz, czy serwisowanie pojazdów odbywa się na podstawie czasu od ostatniego serwisu, czy sprawności malejącej o pewien procent maksymalnej sprawności @@ -1916,6 +1929,8 @@ STR_CONFIG_SETTING_SMOOTH_ECONOMY :Pozwól na łag STR_CONFIG_SETTING_SMOOTH_ECONOMY_HELPTEXT :Kiedy włączone, produkcja zakładów zmienia się częściej, ale mniejszymi krokami. To ustawienie zazwyczaj nie daje żadnego efektu, jeśli typy zakładów są pobierane z NewGRFów STR_CONFIG_SETTING_ALLOW_SHARES :Pozwól kupować udziały w innych firmach: {STRING} STR_CONFIG_SETTING_ALLOW_SHARES_HELPTEXT :Kiedy włączone, pozwala na kupowanie i sprzedawanie udziałów w firmie. Udziały będą dostępne tylko dla firm z odpowiednim stażem +STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES :Minimalny wiek firmy pozwalający na handel udziałami: {STRING} +STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES_HELPTEXT :Ustaw minimalny wiek firmy pozwalający innym kupować i sprzedawać jej akcje. STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE :Podział przychodów w przypadku przeładunków: {STRING} STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE_HELPTEXT :Manipulowanie zrównoważeniem podziałów w łańcuchu dowozowym: przy 0% przychód zostanie zaksięgowany na konto wyłącznie ostatniego pojazdu w łańcuchu, wyższa wartość zwiększa zrównoważenie podziału STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY :Podczas przeciągania ustaw semafor co: {STRING} @@ -1956,6 +1971,10 @@ STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :Aktywacja tej o STR_CONFIG_SETTING_TOWN_FOUNDING_FORBIDDEN :Zabronione STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED :Dozwolone STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED_CUSTOM_LAYOUT :Dozwolone, dowolny układ miasta +STR_CONFIG_SETTING_TOWN_CARGOGENMODE :Generowanie ładunku przez miasta: {STRING} +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_HELPTEXT :Ilość ładunku produkowana przez domy w mieście względem ogólnej populacji miasta.{}Wzrost kwadratowy: miasto o podwojonej wielkości generuje czterokrotnie więcej pasażerów.{}Wzrost liniowy: miasto o podwojonej wielkości generuje dwukrotnie więcej pasażerów. +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_ORIGINAL :Kwadratowy (originalny) +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_BITCOUNT :Liniowy STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :Rozmieszczenie drzew w grze: {STRING} STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :Losowe pojawianie się drzew podczas gry. Może mieć to wpływ na zakłady opierające się na wyrastaniu drzew, np. tartaki @@ -2083,7 +2102,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Dystryb STR_CONFIG_SETTING_AI :{ORANGE}Rywale STR_CONFIG_SETTING_AI_NPC :{ORANGE}Gracze komputerowi -STR_CONFIG_SETTING_PATHFINDER_OPF :Oryginalne STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Zalecane) @@ -2167,13 +2185,9 @@ STR_QUIT_NO :{BLACK}Nie # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -2462,6 +2476,7 @@ STR_NETWORK_CONNECTION_DISCONNECT :{BLACK}Rozłąc STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Serwer jest chroniony. Wprowadź hasło STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Firma jest chroniona. Wprowadź hasło +STR_NETWORK_COMPANY_LIST_CLIENT_LIST_CAPTION :{WHITE}Lista klientów # Network company list added strings STR_NETWORK_COMPANY_LIST_CLIENT_LIST :Lista klientów @@ -2510,7 +2525,7 @@ STR_NETWORK_CHAT_ALL :[Wszyscy] {STRI STR_NETWORK_CHAT_OSKTITLE :{BLACK}Wpisz tekst do chat'u # Network messages -STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}Brak interface'u sieciowego lub skompilowano bez opcji ENABLE_NETWORK +STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}Nie znaleziono urządzeń sieciowych STR_NETWORK_ERROR_NOSERVER :{WHITE}Nie można znaleźć żadnej gry w sieci STR_NETWORK_ERROR_NOCONNECTION :{WHITE}Serwer nie odpowiada STR_NETWORK_ERROR_NEWGRF_MISMATCH :{WHITE}Nie można było połączyć z powodu niezgodności NewGRF @@ -2677,6 +2692,7 @@ STR_LINKGRAPH_LEGEND_CAPTION :{BLACK}Legenda STR_LINKGRAPH_LEGEND_ALL :{BLACK}Wszystkie STR_LINKGRAPH_LEGEND_NONE :{BLACK}Żadne STR_LINKGRAPH_LEGEND_SELECT_COMPANIES :{BLACK}Wybierz firmy, które mają być wyświetlane +STR_LINKGRAPH_LEGEND_COMPANY_TOOLTIP :{BLACK}{STRING}{}{COMPANY} # Linkgraph legend window and linkgraph legend in smallmap STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLACK}nieużywany @@ -2761,7 +2777,7 @@ STR_BUILD_SIGNAL_ELECTRIC_COMBO_TOOLTIP :{BLACK}Sygnaliz STR_BUILD_SIGNAL_ELECTRIC_PBS_TOOLTIP :{BLACK}Sygnalizator trasy (elektryczny){}Sygnalizator trasy umożliwiający wejście więcej niż jednemu pociagowi do bloku sygnalizatorów, o ile pociąg może zarezerwować trasę do bezpiecznego punktu zatrzymania. Zwykłe sygnalizatory trasy mogą być mijane w przeciwnym kierunku STR_BUILD_SIGNAL_ELECTRIC_PBS_OWAY_TOOLTIP :{BLACK}Jednokierunkowy sygnalizator trasy (elektryczny){}Sygnalizator trasy umożliwiający wejście więcej niż jednemu pociagowi do bloku sygnalizatorów, o ile pociąg może zarezerwować trasę do bezpiecznego punktu zatrzymania. Sygnalizatory jednokierunkowe nie mogą być mijane w przeciwnym kierunku STR_BUILD_SIGNAL_CONVERT_TOOLTIP :{BLACK}Zamiana sygnałów{}Jeżeli włączone, kliknięcie na istniejący sygnał spowoduje zamianę go na wybrany typ i wariant. CTRL+klik przełącza istniejący wariant. Shift+klik pokazuje szacowany koszt zamiany -STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP :{BLACK}Gęstość sygnałów przy przeciąganiu +STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP :{BLACK}Odległość między sygnałami przy przeciąganiu STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_DECREASE_TOOLTIP :{BLACK}Zmniejsz odległość między sygnałami przy przeciąganiu STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Zwiększ odległość między sygnałami przy przeciąganiu @@ -2801,6 +2817,11 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL :{BLACK}Zbuduj t STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Zbuduj tunel tramwajowy. Shift przełącza pomiędzy trybem budowania a szacowaniem jego kosztów STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Przełącz buduj/usuń dla konstrukcji dróg STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Przełącz buduj/usuń dla konstrukcji tramwajowej +STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_ROAD :{BLACK}Zamiana typu dróg. Shift przełącza pomiędzy trybem budowania a szacowaniem jego kosztów +STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_TRAM :{BLACK}Zamiana typu torów tramwajowych. Shift przełącza pomiędzy trybem budowania a szacowaniem jego kosztów + +STR_ROAD_NAME_ROAD :Droga +STR_ROAD_NAME_TRAM :Tory tramwajowe # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Ukierunkowanie zajezdni samochodowej @@ -2970,7 +2991,7 @@ STR_LAND_AREA_INFORMATION_REVENUE_WHEN_CLEARED :{BLACK}Zysk gdy STR_LAND_AREA_INFORMATION_OWNER_N_A :Brak STR_LAND_AREA_INFORMATION_OWNER :{BLACK}Właściciel: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_ROAD_OWNER :{BLACK}Wlasciciel drogi: {LTBLUE}{STRING} -STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Wlasciciel linii tramwajowej: {LTBLUE}{STRING} +STR_LAND_AREA_INFORMATION_TRAM_OWNER :{BLACK}Właściciel linii tramwajowej: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_RAIL_OWNER :{BLACK}Wlaściciel linii kolejowej: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Lokalne władze: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Brak @@ -2985,8 +3006,11 @@ STR_LAND_AREA_INFORMATION_NEWGRF_NAME :{BLACK}NewGRF: STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED :{BLACK}Akceptowany ładunek: {LTBLUE} STR_LAND_AREA_INFORMATION_CARGO_EIGHTS :({COMMA}/8 {STRING}) STR_LANG_AREA_INFORMATION_RAIL_TYPE :{BLACK}Typ torów: {LTBLUE}{STRING} +STR_LANG_AREA_INFORMATION_ROAD_TYPE :{BLACK}Rodzaj drogi: {LTBLUE}{STRING} +STR_LANG_AREA_INFORMATION_TRAM_TYPE :{BLACK}Typ torów tramwajowych: {LTBLUE}{STRING} STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT :{BLACK}Limit prędkości linii kolejowej: {LTBLUE}{VELOCITY} STR_LANG_AREA_INFORMATION_ROAD_SPEED_LIMIT :{BLACK}Drogowe ograniczenie prędkości: {LTBLUE}{VELOCITY} +STR_LANG_AREA_INFORMATION_TRAM_SPEED_LIMIT :{BLACK}Limit prędkości tramwajów: {LTBLUE}{VELOCITY} # Description of land area of different tiles STR_LAI_CLEAR_DESCRIPTION_ROCKS :Skały @@ -3026,7 +3050,7 @@ STR_LAI_ROAD_DESCRIPTION_ROAD_WITH_STREETLIGHTS :Droga z oświet STR_LAI_ROAD_DESCRIPTION_TREE_LINED_ROAD :Droga z drzewami STR_LAI_ROAD_DESCRIPTION_ROAD_VEHICLE_DEPOT :Zajezdnia samochodowa STR_LAI_ROAD_DESCRIPTION_ROAD_RAIL_LEVEL_CROSSING :Przejazd kolejowy -STR_LAI_ROAD_DESCRIPTION_TRAMWAY :Szyny tramwajowe +STR_LAI_ROAD_DESCRIPTION_TRAMWAY :Tor tramwajowy # Houses come directly from their building names STR_LAI_TOWN_INDUSTRY_DESCRIPTION_UNDER_CONSTRUCTION :{STRING} (w budowie) @@ -3088,11 +3112,15 @@ STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD # Framerate display window STR_FRAMERATE_CAPTION :{WHITE}Ilość klatek na sekundę STR_FRAMERATE_CAPTION_SMALL :{STRING}{WHITE} ({DECIMAL}x) +STR_FRAMERATE_RATE_GAMELOOP :{BLACK}Tempo symulacji: {STRING} STR_FRAMERATE_RATE_GAMELOOP_TOOLTIP :{BLACK}Liczba ticków gry symulowanych na sekundę. +STR_FRAMERATE_RATE_BLITTER :{BLACK}Klatki na sekundę: {STRING} STR_FRAMERATE_RATE_BLITTER_TOOLTIP :{BLACK}Liczba renderowanych klatek wideo na sekundę. +STR_FRAMERATE_SPEED_FACTOR :{BLACK}Obecny współczynnik szybkości gry: {DECIMAL}x STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}Jak szybko gra obecnie działa, w porównaniu do oczekiwanej prędkości przy normalnym tempie symulacji. STR_FRAMERATE_CURRENT :{WHITE}Obecny STR_FRAMERATE_AVERAGE :{WHITE}Średnia +STR_FRAMERATE_MEMORYUSE :{WHITE}Pamięć STR_FRAMERATE_DATA_POINTS :{BLACK}Dane oparte na {COMMA} pomiarach STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL} ms STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL} ms @@ -3100,24 +3128,44 @@ STR_FRAMERATE_MS_BAD :{RED}{DECIMAL} STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL} klatek/sek. STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL} klatek/sek. STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL} klatek/sek. +STR_FRAMERATE_BYTES_GOOD :{LTBLUE}{BYTES} +STR_FRAMERATE_BYTES_WARN :{YELLOW}{BYTES} +STR_FRAMERATE_BYTES_BAD :{RED}{BYTES} STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} ms STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} sek. ############ Leave those lines in this order!! +STR_FRAMERATE_GAMELOOP :{BLACK}Pętla gry łącznie: STR_FRAMERATE_GL_ECONOMY :{BLACK} Obsługa ładunku: -STR_FRAMERATE_GL_LINKGRAPH :{WHITE} Opóźnienie wykresu połączeń: +STR_FRAMERATE_GL_TRAINS :{BLACK} Tyknięcia pociągów: +STR_FRAMERATE_GL_ROADVEHS :{BLACK} Tyknięcia pojazdów drogowych: +STR_FRAMERATE_GL_SHIPS :{BLACK} Tyknięcia statków: +STR_FRAMERATE_GL_AIRCRAFT :{BLACK} Tyknięcia samolotów: +STR_FRAMERATE_GL_LANDSCAPE :{BLACK} Tyknięcia świata: +STR_FRAMERATE_GL_LINKGRAPH :{BLACK} Opóźnienie wykresu połączeń: STR_FRAMERATE_DRAWING :{BLACK}Renderowanie grafiki: STR_FRAMERATE_DRAWING_VIEWPORTS :{BLACK} Okna podgląu świata: -STR_FRAMERATE_VIDEO :{WHITE}Wyjście video: -STR_FRAMERATE_SOUND :{WHITE}Miksowanie dźwięku: +STR_FRAMERATE_VIDEO :{BLACK}Wyjście video: +STR_FRAMERATE_SOUND :{BLACK}Miksowanie dźwięku: +STR_FRAMERATE_ALLSCRIPTS :{BLACK} GS/SI łącznie: +STR_FRAMERATE_GAMESCRIPT :{BLACK} Game script: +STR_FRAMERATE_AI :{BLACK} SI {NUM} {STRING} ############ End of leave-in-this-order ############ Leave those lines in this order!! STR_FRAMETIME_CAPTION_GAMELOOP :Pętla gry STR_FRAMETIME_CAPTION_GL_ECONOMY :Obsługa ładunku +STR_FRAMETIME_CAPTION_GL_TRAINS :Tyknięcia pociągów +STR_FRAMETIME_CAPTION_GL_ROADVEHS :Tyknięcia pojazdów drogowych +STR_FRAMETIME_CAPTION_GL_SHIPS :Tyknięcia statków +STR_FRAMETIME_CAPTION_GL_AIRCRAFT :Tyknęcia samolotów +STR_FRAMETIME_CAPTION_GL_LANDSCAPE :Tyknięcia świata STR_FRAMETIME_CAPTION_GL_LINKGRAPH :Opóźnienie wykresu połączeń STR_FRAMETIME_CAPTION_DRAWING :Renderowanie grafiki STR_FRAMETIME_CAPTION_DRAWING_VIEWPORTS :Renderowanie okna podgląu świata STR_FRAMETIME_CAPTION_VIDEO :Wyjście wideo STR_FRAMETIME_CAPTION_SOUND :Miksowanie dźwięku +STR_FRAMETIME_CAPTION_ALLSCRIPTS :Wszystkie skrypty GS/SI +STR_FRAMETIME_CAPTION_GAMESCRIPT :Game script +STR_FRAMETIME_CAPTION_AI :SI {NUM} {STRING} ############ End of leave-in-this-order @@ -3264,7 +3312,9 @@ STR_NEWGRF_SETTINGS_MIN_VERSION :{BLACK}Kompatyb STR_NEWGRF_SETTINGS_MD5SUM :{BLACK}Suma MD5: {SILVER}{STRING} STR_NEWGRF_SETTINGS_PALETTE :{BLACK}Paleta: {SILVER}{STRING} STR_NEWGRF_SETTINGS_PALETTE_DEFAULT :Domyslny (D) -STR_NEWGRF_SETTINGS_PALETTE_DEFAULT_32BPP :Domyślny (D) / 32 bpp +STR_NEWGRF_SETTINGS_PALETTE_DEFAULT_32BPP :Domyślna (D) / 32 bpp +STR_NEWGRF_SETTINGS_PALETTE_LEGACY :Dawna (W) +STR_NEWGRF_SETTINGS_PALETTE_LEGACY_32BPP :Dawna (W) / 32 bpp STR_NEWGRF_SETTINGS_PARAMETER :{BLACK}Parametry: {SILVER}{STRING} STR_NEWGRF_SETTINGS_PARAMETER_NONE :Żadne @@ -3347,6 +3397,8 @@ STR_NEWGRF_ERROR_READ_BOUNDS :Odczyt poza obs STR_NEWGRF_ERROR_GRM_FAILED :Potrzebne źródło GRF nie jest dostępne (sprite {3:NUM}) STR_NEWGRF_ERROR_FORCEFULLY_DISABLED :{1:STRING} został wyłączony przez {STRING} STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT :Niepoprawny/nieznany format układu sprite'u (sprite {3:NUM}) +STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG :Zbyt wiele elementów na liście wartości właściwości (sprite {3:NUM}, właściwość {4:HEX}) +STR_NEWGRF_ERROR_INDPROD_CALLBACK :Niewłaściwy wywołanie produkcji przedsiębiorstwa (sprite {3:NUM}, "{2:STRING}") # NewGRF related 'general' warnings STR_NEWGRF_POPUP_CAUTION_CAPTION :{WHITE}Uwaga! @@ -3378,6 +3430,7 @@ STR_NEWGRF_BUGGY :{WHITE}NewGRF ' STR_NEWGRF_BUGGY_ARTICULATED_CARGO :{WHITE}Informacje o ładunku/naprawie dla '{1:ENGINE}' różnią się od listy zakupu po zbudowaniu. Może to spowodować, że autoodnowienie/-zamiana nie wykona remontu poprawnie STR_NEWGRF_BUGGY_ENDLESS_PRODUCTION_CALLBACK :{WHITE}'{1:STRING}' spowodował nieskończoną pętlę w wywołaniu produkcji STR_NEWGRF_BUGGY_UNKNOWN_CALLBACK_RESULT :{WHITE}Wywołanie {1:HEX} zwróciło nieznany/błędny wynik {2:HEX} +STR_NEWGRF_BUGGY_INVALID_CARGO_PRODUCTION_CALLBACK :{WHITE}'{1:STRING}' zwrócił niewłaściwy typ ładunku w wywołaniu produkcji w {2:HEX} # 'User removed essential NewGRFs'-placeholders for stuff without specs STR_NEWGRF_INVALID_CARGO : @@ -3444,6 +3497,8 @@ STR_TOWN_VIEW_RENAME_TOWN_BUTTON :Zmień nazwę m # Town local authority window STR_LOCAL_AUTHORITY_CAPTION :{WHITE}Lokalne władze m. {TOWN} +STR_LOCAL_AUTHORITY_ZONE :{BLACK}Strefa +STR_LOCAL_AUTHORITY_ZONE_TOOLTIP :{BLACK}Pokaż strefę granic władz lokalnych STR_LOCAL_AUTHORITY_COMPANY_RATINGS :{BLACK}Ocena transportu firmy: STR_LOCAL_AUTHORITY_COMPANY_RATING :{YELLOW}{COMPANY} {COMPANY_NUM}: {ORANGE}{STRING} STR_LOCAL_AUTHORITY_ACTIONS_TITLE :{BLACK}Możliwe działania: @@ -3701,8 +3756,7 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Infrastr STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Elementy kolei: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Sygnalizatory STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Elementy dróg: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Droga -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Tramwaj +STR_COMPANY_INFRASTRUCTURE_VIEW_TRAM_SECT :{GOLD}Elementy torów tramwajowych: STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Pola wody: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Kanały STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Stacje: @@ -3713,9 +3767,12 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Przedsiębiorstwa STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Żaden - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} (przetransportowano {COMMA}%) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} (przetransportowano {COMMA}%/{COMMA}%) +STR_INDUSTRY_DIRECTORY_ITEM_INFO :{BLACK}{CARGO_LONG}{STRING}{YELLOW} ({COMMA}% przetransportowano){BLACK} STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} +STR_INDUSTRY_DIRECTORY_ITEM_PROD1 :{ORANGE}{INDUSTRY} {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PROD2 :{ORANGE}{INDUSTRY} {STRING}, {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PROD3 :{ORANGE}{INDUSTRY} {STRING}, {STRING}, {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PRODMORE :{ORANGE}{INDUSTRY} {STRING}, {STRING}, {STRING} i {NUM} więcej... STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Nazwy zakładów - kliknij na nazwie zakładu by wyśrodkować na nim widok. Ctrl+klik otwiera nowy podgląd na lokacji zakładu # Industry view @@ -3726,6 +3783,9 @@ STR_INDUSTRY_VIEW_LOCATION_TOOLTIP :{BLACK}Centruj STR_INDUSTRY_VIEW_PRODUCTION_LEVEL :{BLACK}Poziom produkcji: {YELLOW}{COMMA}% STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE :{YELLOW}Przedsiębiorstwo ogłosiło likwidację! +STR_INDUSTRY_VIEW_REQUIRES_N_CARGO :{BLACK}Potrzebuje: {YELLOW}{STRING}{STRING} +STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Wytwarza: {YELLOW}{STRING}{STRING} +STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{STRING} STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Potrzebuje: STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING} @@ -3779,6 +3839,8 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Pojazdy bez gru STR_GROUP_DEFAULT_SHIPS :Statki bez grupy STR_GROUP_DEFAULT_AIRCRAFTS :Samoloty bez grupy +STR_GROUP_COUNT_WITH_SUBGROUP :{TINY_FONT}{COMMA} (+{COMMA}) + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Grupy - kliknij na grupę, aby wyświetlić wszystkie pojazdy z grupy. Przeciągnij i upuść grupy, aby dostosować hierarchię. STR_GROUP_CREATE_TOOLTIP :{BLACK}Kliknij aby stworzyć grupę STR_GROUP_DELETE_TOOLTIP :{BLACK}Usuń zaznaczoną grupę @@ -3805,12 +3867,18 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Nowe elektryczn STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Nowe pociągi jednoszynowe STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Nowe pociągi Maglev -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Nowe Pojazdy Szynowe STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Nowy pojazd drogowy +STR_BUY_VEHICLE_TRAM_VEHICLE_CAPTION :Nowe pojazdy tramwajowe + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Nowe Pojazdy Szynowe +STR_BUY_VEHICLE_ROAD_VEHICLE_ALL_CAPTION :Nowe pojazdy drogowe STR_BUY_VEHICLE_SHIP_CAPTION :Nowe statki STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Nowy samolot +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Koszt: {GOLD}{CURRENCY_LONG}{BLACK} Masa: {GOLD}{WEIGHT_SHORT} +STR_PURCHASE_INFO_COST_REFIT_WEIGHT :{BLACK}Koszt: {GOLD}{CURRENCY_LONG}{BLACK} (Kosz przebudowy: {GOLD}{CURRENCY_LONG}{BLACK}) Masa: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Prędkość: {GOLD}{VELOCITY}{BLACK} Moc: {GOLD}{POWER} STR_PURCHASE_INFO_SPEED :{BLACK}Prędkość: {GOLD}{VELOCITY} STR_PURCHASE_INFO_SPEED_OCEAN :{BLACK}Prędkość na oceanie: {GOLD}{VELOCITY} @@ -3821,8 +3889,10 @@ STR_PURCHASE_INFO_REFITTABLE :(przebudowywaln STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Zaprojektowany: {GOLD}{NUM}{BLACK} Żywotność: {GOLD}{COMMA} lat STR_PURCHASE_INFO_RELIABILITY :{BLACK}Maksymalna niezawodność: {GOLD}{COMMA}% STR_PURCHASE_INFO_COST :{BLACK}Koszt: {GOLD}{CURRENCY_LONG} +STR_PURCHASE_INFO_COST_REFIT :{BLACK}Koszt: {GOLD}{CURRENCY_LONG}{BLACK} (Koszt przebudowy: {GOLD}{CURRENCY_LONG}{BLACK}) STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Masa: {GOLD}{WEIGHT_SHORT} ({WEIGHT_SHORT}) STR_PURCHASE_INFO_COST_SPEED :{BLACK}Koszt: {GOLD}{CURRENCY_LONG}{BLACK} Prędkość: {GOLD}{VELOCITY} +STR_PURCHASE_INFO_COST_REFIT_SPEED :{BLACK}Koszt: {GOLD}{CURRENCY_LONG}{BLACK} (Koszt przebudowy: {GOLD}{CURRENCY_LONG}{BLACK}) Prędkość: {GOLD}{VELOCITY} 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} @@ -3843,11 +3913,21 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Kup poja STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Kup statek STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Kup samolot +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Kup i przebuduj pojazd +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Kup i przebuduj pojazd +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Kup i przebuduj statek +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Kup i przebuduj samolot + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Kup zaznaczony pociąg. Shift+klik pokazuje szacunkowy koszt bez dokonania zakupu STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Kup zaznaczony pojazd drogowy. Shift+klik pokazuje szacunkowy koszt bez dokonania zakupu STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Kup zaznaczony statek. Shift+klik pokazuje szacunkowy koszt bez dokonania zakupu STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Kup zaznaczony samolot. Shift+klik pokazuje szacunkowy koszt bez dokonania zakupu +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Kup i przebuduj zaznaczony pociąg. Shift+klik pokazuje szacunkowy koszt bez dokonania zakupu +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Kup i przebuduj zaznaczony pojazd drogowy. Shift+klik pokazuje szacunkowy koszt bez dokonania zakupu +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Kup i przebuduj zaznaczony statek. Shift+klik pokazuje szacunkowy koszt bez dokonania zakupu +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Kup i przebuduj zaznaczony samolot. Shift+klik pokazuje szacunkowy koszt bez dokonania zakupu + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Zmień nazwę STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Zmień nazwę STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Zmień nazwę @@ -3956,19 +4036,24 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Sprzeda # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Wiadomość od producenta pojazdów STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Właśnie zaprojektowaliśmy now{G y ą e} {STRING.b} - czy jesteś zainteresowany w rocznej wyłączności na użycie tego pojazdu, żebyśmy mogli zobaczyć przed wypuszczeniem na rynek jak się sprawuje? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :{G=f}lokomotywa STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE.b :lokomotywę -STR_ENGINE_PREVIEW_ROAD_VEHICLE :{G=m}pojazd -STR_ENGINE_PREVIEW_ROAD_VEHICLE.b :pojazd -STR_ENGINE_PREVIEW_AIRCRAFT :{G=m}samolot -STR_ENGINE_PREVIEW_AIRCRAFT.b :samolot -STR_ENGINE_PREVIEW_SHIP :{G=m}statek -STR_ENGINE_PREVIEW_SHIP.b :statek +STR_ENGINE_PREVIEW_ELRAIL_LOCOMOTIVE :{G=f}lokomotywa elektryczna STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :{G=f}lokomotywa jednoszynowa STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE.b :lokomotywę jednoszynową STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :{G=f}lokomotywa Maglev STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE.b :lokomotywę Maglev +STR_ENGINE_PREVIEW_ROAD_VEHICLE :{G=m}pojazd +STR_ENGINE_PREVIEW_ROAD_VEHICLE.b :pojazd +STR_ENGINE_PREVIEW_TRAM_VEHICLE :pojazd tramwajowy + +STR_ENGINE_PREVIEW_AIRCRAFT :{G=m}samolot +STR_ENGINE_PREVIEW_AIRCRAFT.b :samolot +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_MAX_SPEED_CAP_RUNCOST :{BLACK}Koszt: {CURRENCY_LONG} Prędkość maksymalna: {VELOCITY}{}Ładowność: {CARGO_LONG}{}Koszt utrzymania: {CURRENCY_LONG}/rok @@ -4006,14 +4091,19 @@ STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK}Przejdź STR_REPLACE_ENGINES :Lokomotywy STR_REPLACE_WAGONS :Wagony STR_REPLACE_ALL_RAILTYPE :Wszystkie pojazdy szynowe +STR_REPLACE_ALL_ROADTYPE :Wszystkie pojazdy drogowe STR_REPLACE_HELP_RAILTYPE :{BLACK}Wybierz dla jakiego typu torów chcesz zastąpić lokomotywy +STR_REPLACE_HELP_ROADTYPE :{BLACK}Wybierz dla jakiego typu dróg chcesz zastąpić silniki STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Wyświetla typ pojazdu na jaki będzie zastąpiony pojazd zaznaczony po lewej stronie STR_REPLACE_RAIL_VEHICLES :Kolej STR_REPLACE_ELRAIL_VEHICLES :Kolej elektryczna STR_REPLACE_MONORAIL_VEHICLES :Kolej jednoszynowa STR_REPLACE_MAGLEV_VEHICLES :Kolej Maglev +STR_REPLACE_ROAD_VEHICLES :Pojazdy drogowe +STR_REPLACE_TRAM_VEHICLES :Pojazdy tramwajowe + STR_REPLACE_REMOVE_WAGON :{BLACK}Usunięcie wagonów: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Autowymiana zachowuje długość pociągu poprzez usuwanie wagonów (począwszy od początku), jeśli wymiana lokomotywy spowoduje wydłużenie pociągu @@ -4464,6 +4554,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Wybierz STR_AI_LIST_CANCEL :{BLACK}Anuluj STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Nie zmieniaj skryptu + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parametry STR_AI_SETTINGS_CAPTION_AI :SI @@ -4666,7 +4757,6 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... ta d STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... droga jest zorientowana w złym kierunku STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... przystanki przelotowe nie mogą mieć zakrętów STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... przystanki przelotowe nie mogą mieć skrzyżowań -STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... droga jest jednokierunkowa lub zablokowana # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Nie można usunąć części stacji... @@ -4736,7 +4826,8 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Należy STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Nieodpowiednie tory/brak torów STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Należy najpierw usunąć tory STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Droga jest jednokierunkowa lub zablokowana -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Przejazd kolejowy nie dozwolony dla tego typu torów +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Przejazd kolejowy nie dozwolony dla tego typu torów +STR_ERROR_CROSSING_DISALLOWED_ROAD :{WHITE}Przejazdy kolejowe nie są dozwolone dla tego typu drogi STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Nie można tutaj postawić sygnałów... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Nie można tutaj ułożyć torów... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Nie można stąd usunąć torów... @@ -4756,6 +4847,12 @@ STR_ERROR_CAN_T_REMOVE_ROAD_FROM :{WHITE}Nie moż STR_ERROR_CAN_T_REMOVE_TRAMWAY_FROM :{WHITE}Nie można usunąć torowiska z tego miejsca... STR_ERROR_THERE_IS_NO_ROAD :{WHITE}...brak drogi STR_ERROR_THERE_IS_NO_TRAMWAY :{WHITE}...brak torowiska tramwajowego +STR_ERROR_CAN_T_CONVERT_ROAD :{WHITE}Nie można zmienić typu drogi w tym miejscu... +STR_ERROR_CAN_T_CONVERT_TRAMWAY :{WHITE}Nie można zmienić typu torów tramwajowych w tym miejscu... +STR_ERROR_NO_SUITABLE_ROAD :{WHITE}Brak właściwej drogi +STR_ERROR_NO_SUITABLE_TRAMWAY :{WHITE}Brak właściwej linii tramwajowej +STR_ERROR_INCOMPATIBLE_ROAD :{WHITE}... niekompatybilna droga +STR_ERROR_INCOMPATIBLE_TRAMWAY :{WHITE}... niekompatybilne tory tramwajowe # Waterway construction errors STR_ERROR_CAN_T_BUILD_CANALS :{WHITE}Nie można tutaj zbudować kanału... @@ -4808,6 +4905,7 @@ STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Nie moż STR_ERROR_GROUP_CAN_T_DELETE :{WHITE}Nie można usunąć tej grupy... STR_ERROR_GROUP_CAN_T_RENAME :{WHITE}Nie można zmienić nazwy grupy... STR_ERROR_GROUP_CAN_T_SET_PARENT :{WHITE}Nie można ustawić grupy nadrzędnej... +STR_ERROR_GROUP_CAN_T_SET_PARENT_RECURSION :{WHITE}... pętle w hierarchii grupy są niedozwolone STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}Nie można usunąć wszystkich pojazdów z tej grupy... STR_ERROR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}Nie można dodać pojazdu do tej grupy... STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}Nie można dodać pojazdów współdzielących polecenia do grupy... @@ -5454,5 +5552,3 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) - -# Android strings diff --git a/src/lang/portuguese.txt b/src/lang/portuguese.txt index 91b0ff2f3f..ef6912f21a 100644 --- a/src/lang/portuguese.txt +++ b/src/lang/portuguese.txt @@ -11,8 +11,6 @@ ##gender n m f mp fp -# $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. # 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. @@ -52,13 +50,13 @@ STR_CARGO_PLURAL_RUBBER :Borracha STR_CARGO_PLURAL_SUGAR :Açúcar STR_CARGO_PLURAL_TOYS :Brinquedos STR_CARGO_PLURAL_CANDY :Doces -STR_CARGO_PLURAL_COLA :Cola +STR_CARGO_PLURAL_COLA :Bebida de cola STR_CARGO_PLURAL_COTTON_CANDY :Algodão Doce STR_CARGO_PLURAL_BUBBLES :Bolhas STR_CARGO_PLURAL_TOFFEE :Caramelo STR_CARGO_PLURAL_BATTERIES :Baterias STR_CARGO_PLURAL_PLASTIC :Plástico -STR_CARGO_PLURAL_FIZZY_DRINKS :Bebidas Gasosas +STR_CARGO_PLURAL_FIZZY_DRINKS :Refrigerantes # Singular cargo name STR_CARGO_SINGULAR_NOTHING : @@ -86,13 +84,13 @@ STR_CARGO_SINGULAR_RUBBER :Borracha STR_CARGO_SINGULAR_SUGAR :Açúcar STR_CARGO_SINGULAR_TOY :Brinquedos STR_CARGO_SINGULAR_CANDY :Doces -STR_CARGO_SINGULAR_COLA :Cola +STR_CARGO_SINGULAR_COLA :Bebida de cola STR_CARGO_SINGULAR_COTTON_CANDY :Algodão Doce STR_CARGO_SINGULAR_BUBBLE :Bolhas STR_CARGO_SINGULAR_TOFFEE :Caramelo STR_CARGO_SINGULAR_BATTERY :Baterias STR_CARGO_SINGULAR_PLASTIC :Plástico -STR_CARGO_SINGULAR_FIZZY_DRINK :Bebidas Gasosas +STR_CARGO_SINGULAR_FIZZY_DRINK :Refrigerantes # Quantity of cargo STR_QUANTITY_NOTHING : @@ -120,13 +118,13 @@ STR_QUANTITY_RUBBER :{VOLUME_LONG} d STR_QUANTITY_SUGAR :{WEIGHT_LONG} de açúcar STR_QUANTITY_TOYS :{COMMA} brinquedo{P "" s} STR_QUANTITY_SWEETS :{COMMA} saco{P "" s} de doces -STR_QUANTITY_COLA :{VOLUME_LONG} de cola +STR_QUANTITY_COLA :{VOLUME_LONG} de bebida de cola STR_QUANTITY_CANDYFLOSS :{WEIGHT_LONG} de algodão doce STR_QUANTITY_BUBBLES :{COMMA} bolha{P "" s} STR_QUANTITY_TOFFEE :{WEIGHT_LONG} de caramelo STR_QUANTITY_BATTERIES :{COMMA} pilha{P "" s} STR_QUANTITY_PLASTIC :{VOLUME_LONG} de plástico -STR_QUANTITY_FIZZY_DRINKS :{COMMA} bebida{P "" s} gasosa{P "" s} +STR_QUANTITY_FIZZY_DRINKS :{COMMA} refrigerante{P "" s} STR_QUANTITY_N_A :N/D # Two letter abbreviation of cargo name @@ -161,7 +159,7 @@ STR_ABBREV_BUBBLES :{TINY_FONT}BO STR_ABBREV_TOFFEE :{TINY_FONT}CM STR_ABBREV_BATTERIES :{TINY_FONT}BA STR_ABBREV_PLASTIC :{TINY_FONT}PL -STR_ABBREV_FIZZY_DRINKS :{TINY_FONT}BG +STR_ABBREV_FIZZY_DRINKS :{TINY_FONT}RF STR_ABBREV_NONE :{TINY_FONT}NÃO STR_ABBREV_ALL :{TINY_FONT}TUDO @@ -174,14 +172,14 @@ STR_ITEMS :{COMMA} item{P STR_CRATES :{COMMA} caixa{P "" s} # Colours, do not shuffle -STR_COLOUR_DARK_BLUE :Azul Escuro -STR_COLOUR_PALE_GREEN :Verde Claro +STR_COLOUR_DARK_BLUE :Azul escuro +STR_COLOUR_PALE_GREEN :Verde claro STR_COLOUR_PINK :Rosa STR_COLOUR_YELLOW :Amarelo STR_COLOUR_RED :Vermelho -STR_COLOUR_LIGHT_BLUE :Azul Claro +STR_COLOUR_LIGHT_BLUE :Azul claro STR_COLOUR_GREEN :Verde -STR_COLOUR_DARK_GREEN :Verde Escuro +STR_COLOUR_DARK_GREEN :Verde escuro STR_COLOUR_BLUE :Azul STR_COLOUR_CREAM :Creme STR_COLOUR_MAUVE :Malva @@ -238,6 +236,7 @@ STR_TOOLTIP_FILTER_CRITERIA :{BLACK}Seleccio STR_BUTTON_SORT_BY :{BLACK}Ordenar por STR_BUTTON_LOCATION :{BLACK}Localização STR_BUTTON_RENAME :{BLACK}Renomear +STR_BUTTON_CATCHMENT :{BLACK}Cobertura STR_TOOLTIP_CLOSE_WINDOW :{BLACK}Fechar janela STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Título da janela - arraste isto para mover a janela @@ -333,13 +332,14 @@ STR_TOOLBAR_TOOLTIP_DISPLAY_COMPANY_LEAGUE :{BLACK}Mostrar STR_TOOLBAR_TOOLTIP_FUND_CONSTRUCTION_OF_NEW :{BLACK}Financiar a construção de uma nova indústria STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_TRAINS :{BLACK}Mostrar lista de comboios da empresa. Ctrl+Clique alterna entre abrir a lista de grupos/veículos STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_ROAD_VEHICLES :{BLACK}Mostrar lista de veículos rodoviários da empresa. Ctrl+Clique alterna entre abrir a lista de grupos/veículos -STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_SHIPS :{BLACK}Mostrar lista de barcos da empresa. Ctrl+Clique alterna entre abrir a lista de grupos/veículos +STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_SHIPS :{BLACK}Mostrar lista de navios da empresa. Ctrl+Clique alterna entre abrir a lista de grupos/veículos STR_TOOLBAR_TOOLTIP_DISPLAY_LIST_OF_COMPANY_AIRCRAFT :{BLACK}Mostrar lista de aeronaves da empresa. Ctrl+Clique alterna entre abrir a lista de grupos/veículos STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN :{BLACK}Ampliar STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT :{BLACK}Reduzir STR_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Construir caminhos-de-ferro STR_TOOLBAR_TOOLTIP_BUILD_ROADS :{BLACK}Construir estradas -STR_TOOLBAR_TOOLTIP_BUILD_SHIP_DOCKS :{BLACK}Construir docas para barcos +STR_TOOLBAR_TOOLTIP_BUILD_TRAMWAYS :{BLACK}Construir carris para elétricos +STR_TOOLBAR_TOOLTIP_BUILD_SHIP_DOCKS :{BLACK}Construir docas para navios STR_TOOLBAR_TOOLTIP_BUILD_AIRPORTS :{BLACK}Construir aeroportos STR_TOOLBAR_TOOLTIP_LANDSCAPING :{BLACK}Abra a barra de modelação ambiental para elevar ou baixar terreno, plantar árvores, etc. STR_TOOLBAR_TOOLTIP_SHOW_SOUND_MUSIC_WINDOW :{BLACK}Mostrar janela som/música @@ -359,6 +359,7 @@ STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION :{BLACK}Gerar te STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Gerar localidades 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_PLACE_SIGN :{BLACK}Colocar sinais STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Colocar objecto. Shift alterna contruir/mostrar custo estimado @@ -435,8 +436,8 @@ STR_INDUSTRY_MENU_FUND_NEW_INDUSTRY :Financiar nova ############ range ends here ############ range for railway construction menu starts -STR_RAIL_MENU_RAILROAD_CONSTRUCTION :Construir caminhos-de-ferro -STR_RAIL_MENU_ELRAIL_CONSTRUCTION :Construir caminhos-de-ferro electrificados +STR_RAIL_MENU_RAILROAD_CONSTRUCTION :Construção de caminhos-de-ferro +STR_RAIL_MENU_ELRAIL_CONSTRUCTION :Construção de caminhos-de-ferro eletrificados STR_RAIL_MENU_MONORAIL_CONSTRUCTION :Construir monocarril STR_RAIL_MENU_MAGLEV_CONSTRUCTION :Construir Maglev ############ range ends here @@ -447,11 +448,11 @@ STR_ROAD_MENU_TRAM_CONSTRUCTION :Construção de ############ range ends here ############ range for waterways construction menu starts -STR_WATERWAYS_MENU_WATERWAYS_CONSTRUCTION :Construção de canais +STR_WATERWAYS_MENU_WATERWAYS_CONSTRUCTION :Construção de hidrovia ############ range ends here ############ range for airport construction menu starts -STR_AIRCRAFT_MENU_AIRPORT_CONSTRUCTION :Construir aeroporto +STR_AIRCRAFT_MENU_AIRPORT_CONSTRUCTION :Construção de aeroportos ############ range ends here ############ range for landscaping menu starts @@ -473,17 +474,14 @@ STR_NEWS_MENU_DELETE_ALL_MESSAGES :Apagar todas as ############ range for about menu starts STR_ABOUT_MENU_LAND_BLOCK_INFO :Informações do terreno STR_ABOUT_MENU_SEPARATOR : -STR_ABOUT_MENU_TOGGLE_CONSOLE :Mostrar/ocultar consola -STR_ABOUT_MENU_AI_DEBUG :Depuração da IA/Scripts de Jogo +STR_ABOUT_MENU_TOGGLE_CONSOLE :Mostrar/Ocultar consola +STR_ABOUT_MENU_AI_DEBUG :Depuração da IA/Scripts de jogo STR_ABOUT_MENU_SCREENSHOT :Captura de ecrã -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Captura com resolução máxima -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Captura com resolução normal -STR_ABOUT_MENU_GIANT_SCREENSHOT :Captura de mapa -STR_ABOUT_MENU_SHOW_FRAMERATE :Mostrar taxa de fotograma +STR_ABOUT_MENU_SHOW_FRAMERATE :Mostrar taxa de fotogramas STR_ABOUT_MENU_ABOUT_OPENTTD :Sobre o 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Alinhador de gráficos STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Alternar as caixas envolventes -STR_ABOUT_MENU_TOGGLE_DIRTY_BLOCKS :Ligar/Desligar coloração de blocos sujos +STR_ABOUT_MENU_TOGGLE_DIRTY_BLOCKS :Ativar coloração de blocos sujos ############ range ends here ############ range for ordinal numbers used for the place in the highscore window @@ -628,7 +626,7 @@ STR_PERFORMANCE_DETAIL_MONEY :{BLACK}Dinheiro STR_PERFORMANCE_DETAIL_LOAN :{BLACK}Empréstimo: STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Total: ############ End of order list -STR_PERFORMANCE_DETAIL_VEHICLES_TOOLTIP :{BLACK}Número de veículos que lucraram no último ano. Isto inclui veículos rodoviários, comboios, barcos e aeronaves. +STR_PERFORMANCE_DETAIL_VEHICLES_TOOLTIP :{BLACK}Número de veículos que produziram lucro no último ano. Inclui veículos rodoviários, comboios, navios e aeronaves. STR_PERFORMANCE_DETAIL_STATIONS_TOOLTIP :{BLACK}Número de estações recentemente reparadas. Estações ferroviárias, paragens de autocarro, aeroportos são contabilizadas separadamente, mesmo se estiverem ligadas como uma só. STR_PERFORMANCE_DETAIL_MIN_PROFIT_TOOLTIP :{BLACK}O lucro do veículo com o rendimento menor (só são considerados veículos com mais de 2 anos) STR_PERFORMANCE_DETAIL_MIN_INCOME_TOOLTIP :{BLACK}Dinheiro conseguido no mês com os lucros mais baixos dos últimos 12 trimestres @@ -649,9 +647,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Personaliz. 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Volume da Música STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Volume dos efeitos -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}MIN -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}MAX -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -731,7 +726,7 @@ STR_SMALLMAP_LEGENDA_BUILDINGS_INDUSTRIES :{TINY_FONT}{BLA STR_SMALLMAP_LEGENDA_VEHICLES :{TINY_FONT}{BLACK}Veículos STR_SMALLMAP_LEGENDA_TRAINS :{TINY_FONT}{BLACK}Comboios STR_SMALLMAP_LEGENDA_ROAD_VEHICLES :{TINY_FONT}{BLACK}Veículos Rodoviários -STR_SMALLMAP_LEGENDA_SHIPS :{TINY_FONT}{BLACK}Barcos +STR_SMALLMAP_LEGENDA_SHIPS :{TINY_FONT}{BLACK}Navios STR_SMALLMAP_LEGENDA_AIRCRAFT :{TINY_FONT}{BLACK}Aeronaves STR_SMALLMAP_LEGENDA_TRANSPORT_ROUTES :{TINY_FONT}{BLACK}Rotas de Transporte STR_SMALLMAP_LEGENDA_FOREST :{TINY_FONT}{BLACK}Floresta @@ -790,7 +785,7 @@ STR_NEWS_FIRST_BUS_ARRIVAL :{BIG_FONT}{BLAC STR_NEWS_FIRST_TRUCK_ARRIVAL :{BIG_FONT}{BLACK}Cidadãos celebram . . .{}Primeiro camião chega a {STATION}! STR_NEWS_FIRST_PASSENGER_TRAM_ARRIVAL :{BIG_FONT}{BLACK}Cidadãos celebram . . .{}Primeiro eléctrico de passageiros chega a {STATION}! STR_NEWS_FIRST_CARGO_TRAM_ARRIVAL :{BIG_FONT}{BLACK}Cidadãos celebram . . .{}Primeiro eléctrico de mercadorias chega a {STATION}! -STR_NEWS_FIRST_SHIP_ARRIVAL :{BIG_FONT}{BLACK}Cidadãos celebram . . .{}Primeiro barco chega a {STATION}! +STR_NEWS_FIRST_SHIP_ARRIVAL :{BIG_FONT}{BLACK}Cidadãos celebram . . .{}Primeiro navio chega a {STATION}! STR_NEWS_FIRST_AIRCRAFT_ARRIVAL :{BIG_FONT}{BLACK}Cidadãos celebram . . .{}Primeira aeronave chega a {STATION}! STR_NEWS_TRAIN_CRASH :{BIG_FONT}{BLACK}Acidente de Comboios!{}{COMMA} mortem numa explosão após a colisão! @@ -868,6 +863,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}Novo modelo de {STRING} agora disponível! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} não aceita mais {STRING} STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} não aceita mais {STRING} ou {STRING} STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} agora aceita {STRING} @@ -934,6 +930,9 @@ STR_GAME_OPTIONS_CURRENCY_GEL :Lari Georgiano STR_GAME_OPTIONS_CURRENCY_IRR :Rial Iraniano (IRR) STR_GAME_OPTIONS_CURRENCY_RUB :Novo Rublo Russo (RUB) STR_GAME_OPTIONS_CURRENCY_MXN :Peso Mexicano (MXN) +STR_GAME_OPTIONS_CURRENCY_NTD :Novo dólar taiwanês (NTD) +STR_GAME_OPTIONS_CURRENCY_CNY :Renminbi chinês (CNY) +STR_GAME_OPTIONS_CURRENCY_HKD :Dólar de Hong Kong (HKD) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Veículos rodoviários @@ -1121,7 +1120,7 @@ STR_CONFIG_SETTING_TYPE_COMPANY_INGAME :Configurações STR_CONFIG_SETTING_RESTRICT_CATEGORY :{BLACK}Categoria: STR_CONFIG_SETTING_RESTRICT_TYPE :{BLACK}Tipo: STR_CONFIG_SETTING_RESTRICT_DROPDOWN_HELPTEXT :{BLACK}Restringe a lista abaixo para mostrar apenas opções modificadas -STR_CONFIG_SETTING_RESTRICT_BASIC :Opções Básicas (mostra apenas definições importantes) +STR_CONFIG_SETTING_RESTRICT_BASIC :Opções básicas (mostrar apenas definições importantes) STR_CONFIG_SETTING_RESTRICT_ADVANCED :Avançado (mostra grande parte das definições) STR_CONFIG_SETTING_RESTRICT_ALL :Avançado (mostrar todas as definições, incluindo as estranhas) STR_CONFIG_SETTING_RESTRICT_CHANGED_AGAINST_DEFAULT :Opções com um valor diferente das de origem @@ -1185,6 +1184,8 @@ STR_CONFIG_SETTING_AUTOSLOPE :Permite altera STR_CONFIG_SETTING_AUTOSLOPE_HELPTEXT :Permite alteração de terra sob edifícios e vias sem os remover STR_CONFIG_SETTING_CATCHMENT :Dimensionamento mais realista de áreas de abrangência: {STRING} 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_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 STR_CONFIG_SETTING_TRAIN_LENGTH :Tamanho máximo de comboios: {STRING} @@ -1201,8 +1202,8 @@ STR_CONFIG_SETTING_TRAIN_SLOPE_STEEPNESS_HELPTEXT :Ângulo de incl STR_CONFIG_SETTING_PERCENTAGE :{COMMA}% STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS :Ângulo de inclínação para veículos rodoviários: {STRING} STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS_HELPTEXT :Declive de um quadrado inclinado para um veiculo de estrada. Valores mais altos tornam mais difícil de subir. -STR_CONFIG_SETTING_FORBID_90_DEG :Proibir comboios e barcos fazer curvas de 90º: {STRING} -STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :Curvas de 90 graus ocorrem quando uma pista horizontal é directamente seguida por outra vertical num quadrado adjacente, fazendo com que o combóio vire 90 graus quando atravessa a fronteira dos quadrados, ao invés dos habituais 45 graus para outras combinações de pistas. Também se aplica ao raio de curvatura dos navios +STR_CONFIG_SETTING_FORBID_90_DEG :Proibir comboios fazer curvas de 90º: {STRING} +STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :Curvas de 90 graus ocorrem quando uma pista horizontal é directamente seguida por outra vertical num quadrado adjacente, fazendo com que o combóio vire 90 graus quando atravessa a fronteira dos quadrados, ao invés dos habituais 45 graus para outras combinações de pistas. STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS :Permitir juntar estações não adjacentes: {STRING} STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS_HELPTEXT :Permite adicionar novas partes a uma estação sem tocar nas partes já existentes. Requer pressionar CTRL+click para adicionar as novas partes STR_CONFIG_SETTING_INFLATION :Inflação: {STRING} @@ -1230,7 +1231,7 @@ STR_CONFIG_SETTING_SIGNALSIDE_RIGHT :Na direita STR_CONFIG_SETTING_SHOWFINANCES :Mostrar janela das finanças no fim do ano: {STRING} STR_CONFIG_SETTING_SHOWFINANCES_HELPTEXT :Se ativado, os pops up de finanças ao final de cada ano permitem fácil inspeção do estado financeiro da empresa STR_CONFIG_SETTING_NONSTOP_BY_DEFAULT :Novas ordens são 'sem parar' por predefinição: {STRING} -STR_CONFIG_SETTING_NONSTOP_BY_DEFAULT_HELPTEXT :Normalmente, um veículo parará em cada estação por que passe. Ao ligar esta configuração, passará sem parar por todas as estações parando apenas no destino final. Nota que isto só tem efeito para novas rotas. No entanto rotas existentes podem ser alteradas explicitamente para funcionarem assim também. +STR_CONFIG_SETTING_NONSTOP_BY_DEFAULT_HELPTEXT :Normalmente, um veículo para em cada estação por onde passa. Ao ativar esta configuração, um veículo irá passar por todas as estações no seu percurso, parando apenas no destino final. Esta opção só tem efeito para novas rotas, mas as rotas existentes podem ser alteradas para funcionarem de forma igual. STR_CONFIG_SETTING_STOP_LOCATION :Ordens novas do comboio param {STRING} da plataforma STR_CONFIG_SETTING_STOP_LOCATION_HELPTEXT :Local onde um combóio parará na plataforma por omissão. A opção 'extremo mais próximo' significa perto do ponto de entrada, 'meio' significa no meio da plataforma e 'extremo mais distante' significa o mais distante possível do ponto de entrada. Esta opção apenas afecta o valor por omissão para novas encomendas. Encomendas individuais podem utilizar qualquer uma das opções independentemente desta STR_CONFIG_SETTING_STOP_LOCATION_NEAR_END :no extremo perto @@ -1258,8 +1259,8 @@ STR_CONFIG_SETTING_PLANE_SPEED :Fator de veloci 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 STR_CONFIG_SETTING_PLANE_SPEED_VALUE :1 / {COMMA} STR_CONFIG_SETTING_PLANE_CRASHES :Número de acidentes de aeronaves: {STRING} -STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Indicar a hipótese da ocorrência de um acidente aéreo -STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Nenhum +STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Indicar a hipótese da ocorrência de um acidente aéreo.{}* As aeronaves maiores tem um risco acrescido a despenhar quando aterram em aeroportos pequenos +STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Nenhum* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Reduzido STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Normal STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Permite estações de passagem em estradas das localidades: {STRING} @@ -1336,8 +1337,8 @@ STR_CONFIG_SETTING_TREE_PLACER_HELPTEXT :Escolhe a distr STR_CONFIG_SETTING_TREE_PLACER_NONE :Nenhum STR_CONFIG_SETTING_TREE_PLACER_ORIGINAL :Original STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Melhorada -STR_CONFIG_SETTING_ROAD_SIDE :Veículo rodoviários: {STRING} -STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Escolhe o lado de condução +STR_CONFIG_SETTING_ROAD_SIDE :Veículos rodoviários: {STRING} +STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Escolher o lado de condução STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Rotação mapa de alt.: {STRING} STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Sentido anti-horário STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_CLOCKWISE :Sentido horário @@ -1381,7 +1382,7 @@ STR_CONFIG_SETTING_SCROLLWHEEL_OFF :Desligado STR_CONFIG_SETTING_SCROLLWHEEL_MULTIPLIER :Velocidade da roda do rato no mapa: {STRING} STR_CONFIG_SETTING_SCROLLWHEEL_MULTIPLIER_HELPTEXT :Controlo de sensibilidade da roda de rolagem do rato STR_CONFIG_SETTING_OSK_ACTIVATION :Teclado no ecrã: {STRING} -STR_CONFIG_SETTING_OSK_ACTIVATION_HELPTEXT :Seleccione o método de abertura do teclado no ecran para escrita de texto em caixas usando apenas o rato. Esta opção é pensada para equipamentos pequenos sem teclado físico. +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. STR_CONFIG_SETTING_OSK_ACTIVATION_DISABLED :Desactivado STR_CONFIG_SETTING_OSK_ACTIVATION_DOUBLE_CLICK :Duplo clique STR_CONFIG_SETTING_OSK_ACTIVATION_SINGLE_CLICK_FOCUS :Clique simples (quando em foco) @@ -1460,7 +1461,7 @@ STR_CONFIG_SETTING_MAX_ROAD_VEHICLES :Máximo de veí STR_CONFIG_SETTING_MAX_ROAD_VEHICLES_HELPTEXT :Número máximo de veículos de estrada que uma companhia pode ter STR_CONFIG_SETTING_MAX_AIRCRAFT :Máximo de aeronaves por empresa: {STRING} STR_CONFIG_SETTING_MAX_AIRCRAFT_HELPTEXT :Número máximo de aeronaves que uma companhia pode ter -STR_CONFIG_SETTING_MAX_SHIPS :Máximo de barcos por empresa: {STRING} +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} @@ -1469,7 +1470,7 @@ STR_CONFIG_SETTING_AI_BUILDS_ROAD_VEHICLES :Desactivar veí 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_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_SHIPS :Desactivar barcos para o computador: {STRING} +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_PROFILE :Perfil de preferências por omissão: {STRING} @@ -1482,6 +1483,7 @@ STR_CONFIG_SETTING_AI_IN_MULTIPLAYER :Permite IAs em STR_CONFIG_SETTING_AI_IN_MULTIPLAYER_HELPTEXT :Permite a jogadores controlados pelo computador a participação em jogos multi-jogador STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES :#opcodes antes de os scripts serem suspensos: {STRING} STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES_HELPTEXT :Número máximo de passos computacionais que um script pode executar num turno +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_HELPTEXT :Definir o volume máximo de memória que pode ser utilizada por um script antes de este ser terminado. Para mapas maiores é possível que este parâmetro tenha de ser aumentado. 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 @@ -1496,8 +1498,8 @@ STR_CONFIG_SETTING_SERVINT_AIRCRAFT_HELPTEXT :Definir o inter STR_CONFIG_SETTING_SERVINT_SHIPS :Intervalo de serviço para navios por omissão: {STRING} STR_CONFIG_SETTING_SERVINT_SHIPS_HELPTEXT :Definir o intervalo de manutenção por omissão para novos navios, se não for configurado um intervalo de manutenção explícito para o veículo STR_CONFIG_SETTING_NOSERVICE :Não fazer manutenção quando não há avarias: {STRING} -STR_CONFIG_SETTING_NOSERVICE_HELPTEXT :Quando activo, os veículos não farão manutenção se não puderem avariar -STR_CONFIG_SETTING_WAGONSPEEDLIMITS :Activar limites de velocidade para vagões: {STRING} +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_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 @@ -1544,6 +1546,7 @@ STR_CONFIG_SETTING_SMOOTH_ECONOMY :Activar economi STR_CONFIG_SETTING_SMOOTH_ECONOMY_HELPTEXT :Quando activa, a produção de indústrias muda frequentemente, em pequenos incrementos. Esta preferência não costuma ter efeito, se os tipos de indústria forem provenientes de um NewGRF 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_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. STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE :Percentagem do lucro do serviço a pagar em trajectos de um transporte que alimenta outro transporte: {STRING} STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE_HELPTEXT :Percentagem da receita dada a trajectos intermédios em sistemas em que um transporte alimenta outro, dando maior controlo sobre a receita STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY :Ao arrastar, colocar sinais a cada: {STRING} @@ -1558,12 +1561,12 @@ STR_CONFIG_SETTING_ENABLE_SIGNAL_GUI_HELPTEXT :Mostrar uma jan STR_CONFIG_SETTING_DEFAULT_SIGNAL_TYPE :Tipo de farol padrão para construir: {STRING} STR_CONFIG_SETTING_DEFAULT_SIGNAL_TYPE_HELPTEXT :Tipo de sinal a usar por omissão STR_CONFIG_SETTING_DEFAULT_SIGNAL_NORMAL :Sinais de bloqueio -STR_CONFIG_SETTING_DEFAULT_SIGNAL_PBS :Sinais de rota +STR_CONFIG_SETTING_DEFAULT_SIGNAL_PBS :Sinais de trajeto STR_CONFIG_SETTING_DEFAULT_SIGNAL_PBSOWAY :Sinais de sentido único STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES :Trocar tipos de faróis: {STRING} STR_CONFIG_SETTING_CYCLE_SIGNAL_TYPES_HELPTEXT :Mostrar uma janela para escolher o tipo de sinais a construir, em vez de escolher a rotação de sinais com +clique em sinais -STR_CONFIG_SETTING_CYCLE_SIGNAL_NORMAL :Apenas sinais de bloqueio -STR_CONFIG_SETTING_CYCLE_SIGNAL_PBS :Apenas sinais de rota +STR_CONFIG_SETTING_CYCLE_SIGNAL_NORMAL :Apenas sinais de bloco +STR_CONFIG_SETTING_CYCLE_SIGNAL_PBS :Apenas sinais de trajeto STR_CONFIG_SETTING_CYCLE_SIGNAL_ALL :Todos STR_CONFIG_SETTING_TOWN_LAYOUT :Disposição de estradas para novas localidades: {STRING} @@ -1584,6 +1587,10 @@ STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :Activar esta pr STR_CONFIG_SETTING_TOWN_FOUNDING_FORBIDDEN :Proibido STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED :Permitido STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED_CUSTOM_LAYOUT :Permitido, estrutura personalizada da localidade +STR_CONFIG_SETTING_TOWN_CARGOGENMODE :Geração de carga citadina: {STRING} +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_HELPTEXT :Quantidade de carga produzida por casas em localidades, relativa à população total da mesma.{}Crescimento quadrático: Uma localidade do dobro do tamanho gera 4x mais passageiros.{}Crescimento linear: Uma localidade do dobro do tamanho gera 2x a quantidade de passageiros. +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_ORIGINAL :Quadrático (original) +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_BITCOUNT :Linear STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :Criação de árvores no decorrer do jogo: {STRING} STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :Controlar o aparecimento aleatório de árvores durante o jogo. Isto poderá afectar indústrias que dependem do crescimento de árvores, como as madeireiras @@ -1711,7 +1718,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Distrib STR_CONFIG_SETTING_AI :{ORANGE}Oponentes STR_CONFIG_SETTING_AI_NPC :{ORANGE}Jogadores Computador -STR_CONFIG_SETTING_PATHFINDER_OPF :Original STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Recomendado) @@ -1719,10 +1725,10 @@ STR_CONFIG_SETTING_PATHFINDER_FOR_TRAINS :Sistema de enca STR_CONFIG_SETTING_PATHFINDER_FOR_TRAINS_HELPTEXT :Sistema de encaminhar comboios STR_CONFIG_SETTING_PATHFINDER_FOR_ROAD_VEHICLES :Sistema de encaminhar veículos rodoviários: {STRING} STR_CONFIG_SETTING_PATHFINDER_FOR_ROAD_VEHICLES_HELPTEXT :Sistema de encaminhar veículos rodoviários -STR_CONFIG_SETTING_PATHFINDER_FOR_SHIPS :Sistema de encaminhar barcos: {STRING} -STR_CONFIG_SETTING_PATHFINDER_FOR_SHIPS_HELPTEXT :Sistema de encaminhar barcos +STR_CONFIG_SETTING_PATHFINDER_FOR_SHIPS :Sistema de encaminhar navios: {STRING} +STR_CONFIG_SETTING_PATHFINDER_FOR_SHIPS_HELPTEXT :Sistema de encaminhar navios STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Inversão automática nos sinais: {STRING} -STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Permitir que os comboios invertam o sentido de marcha nos sinais caso estejam à espera muito tempo +STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Permitir que os comboios invertam o sentido de marcha nos sinais, caso estejam à espera muito tempo STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Alterar valor @@ -1749,32 +1755,32 @@ STR_CONFIG_ERROR_SPRITECACHE_TOO_BIG :{WHITE}Falha a # Intro window STR_INTRO_CAPTION :{WHITE}OpenTTD {REV} -STR_INTRO_NEW_GAME :{BLACK}Novo Jogo -STR_INTRO_LOAD_GAME :{BLACK}Abrir Jogo -STR_INTRO_PLAY_SCENARIO :{BLACK}Jogar Cenário +STR_INTRO_NEW_GAME :{BLACK}Novo jogo +STR_INTRO_LOAD_GAME :{BLACK}Carregar jogo +STR_INTRO_PLAY_SCENARIO :{BLACK}Jogar cenário STR_INTRO_PLAY_HEIGHTMAP :{BLACK}Jogar mapa de alturas -STR_INTRO_SCENARIO_EDITOR :{BLACK}Editor de Cenário +STR_INTRO_SCENARIO_EDITOR :{BLACK}Editor de cenário STR_INTRO_MULTIPLAYER :{BLACK}Multi-jogador -STR_INTRO_GAME_OPTIONS :{BLACK}Opções do Jogo -STR_INTRO_HIGHSCORE :{BLACK}Tabela de Classificações +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_ONLINE_CONTENT :{BLACK}Verificar Conteúdo Online -STR_INTRO_SCRIPT_SETTINGS :{BLACK}Definições de IA / Script de Jogo +STR_INTRO_ONLINE_CONTENT :{BLACK}Verificar conteúdo online +STR_INTRO_SCRIPT_SETTINGS :{BLACK}Definições de IA/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 -STR_INTRO_TOOLTIP_LOAD_GAME :{BLACK}Carregar um jogo gravado -STR_INTRO_TOOLTIP_PLAY_HEIGHTMAP :{BLACK}Iniciar novo jogo, usando um mapa de alturas como paisagem +STR_INTRO_TOOLTIP_LOAD_GAME :{BLACK}Carregar um jogo guardado +STR_INTRO_TOOLTIP_PLAY_HEIGHTMAP :{BLACK}Iniciar novo jogo, usando um mapa de alturas como terreno STR_INTRO_TOOLTIP_PLAY_SCENARIO :{BLACK}Iniciar um novo jogo, utilizando um cenário personalizado guardado no disco STR_INTRO_TOOLTIP_SCENARIO_EDITOR :{BLACK}Criar um cenário de jogo personalizado STR_INTRO_TOOLTIP_MULTIPLAYER :{BLACK}Começar um jogo multi-jogador -STR_INTRO_TOOLTIP_TEMPERATE :{BLACK}Seleccionar cenário do estilo 'temperado' -STR_INTRO_TOOLTIP_SUB_ARCTIC_LANDSCAPE :{BLACK}Seleccionar cenário do estilo 'subárctico' -STR_INTRO_TOOLTIP_SUB_TROPICAL_LANDSCAPE :{BLACK}Seleccionar cenário do estilo 'subtropical' -STR_INTRO_TOOLTIP_TOYLAND_LANDSCAPE :{BLACK}Seleccionar cenário do estilo 'terra dos brinquedos' +STR_INTRO_TOOLTIP_TEMPERATE :{BLACK}Selecionar terreno do estilo "temperado" +STR_INTRO_TOOLTIP_SUB_ARCTIC_LANDSCAPE :{BLACK}Selecionar terreno do estilo "subárctico" +STR_INTRO_TOOLTIP_SUB_TROPICAL_LANDSCAPE :{BLACK}Selecionar terreno do estilo "subtropical" +STR_INTRO_TOOLTIP_TOYLAND_LANDSCAPE :{BLACK}Selecionar terreno do estilo "terra dos brinquedos" STR_INTRO_TOOLTIP_GAME_OPTIONS :{BLACK}Mostrar opções de jogo STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Mostrar tabela de classificações @@ -1795,13 +1801,9 @@ STR_QUIT_NO :{BLACK}Não # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -1818,13 +1820,13 @@ STR_CHEAT_MONEY :{LTBLUE}Aumenta STR_CHEAT_CHANGE_COMPANY :{LTBLUE}Jogando como empresa: {ORANGE}{COMMA} STR_CHEAT_EXTRA_DYNAMITE :{LTBLUE}Bulldozer mágico (destrói indústrias, objectos amovíveis etc.): {ORANGE}{STRING} STR_CHEAT_CROSSINGTUNNELS :{LTBLUE}Os túneis poderão cruzar-se: {ORANGE}{STRING} -STR_CHEAT_NO_JETCRASH :{LTBLUE}Aviões a jacto não irão ter acidentes (frequentes) em aeroportos pequenos: {ORANGE}{STRING} +STR_CHEAT_NO_JETCRASH :{LTBLUE}Aviões a jato não irão ter acidentes (frequentes) em aeroportos pequenos: {ORANGE}{STRING} STR_CHEAT_EDIT_MAX_HL :{LTBLUE}Editar altura máxima do mapa: {ORANGE}{NUM} STR_CHEAT_EDIT_MAX_HL_QUERY_CAPT :{WHITE}Editar altura máxima de montanhas no mapa 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_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Terreno terra dos brinquedos 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} @@ -1835,7 +1837,7 @@ STR_LIVERY_CAPTION :{WHITE}{COMPANY STR_LIVERY_GENERAL_TOOLTIP :{BLACK}Exibir esquema de cores geral STR_LIVERY_TRAIN_TOOLTIP :{BLACK}Exibir esquemas de cores dos comboios STR_LIVERY_ROAD_VEHICLE_TOOLTIP :{BLACK}Exibir esquemas de cores dos veículos rodoviários -STR_LIVERY_SHIP_TOOLTIP :{BLACK}Exibir esquemas de cores dos barcos +STR_LIVERY_SHIP_TOOLTIP :{BLACK}Exibir esquemas de cores dos navios STR_LIVERY_AIRCRAFT_TOOLTIP :{BLACK}Exibir esquema de cores da aeronave STR_LIVERY_PRIMARY_TOOLTIP :{BLACK}Seleccione a cor primária para o veículo seleccionado. Ctrl+Clique vai usar esta cor para todos os esquemas STR_LIVERY_SECONDARY_TOOLTIP :{BLACK}Seleccione a cor secundária para o esquema seleccionado. Ctrl+Click afetará esta escolha para todos os esquemas @@ -1857,12 +1859,12 @@ STR_LIVERY_PASSENGER_WAGON_MAGLEV :Carruagem de Pa STR_LIVERY_FREIGHT_WAGON :Vagão de Carga STR_LIVERY_BUS :Autocarro STR_LIVERY_TRUCK :Veículo de Mercadorias -STR_LIVERY_PASSENGER_SHIP :Barco de Passageiros -STR_LIVERY_FREIGHT_SHIP :Barco Cargueiro +STR_LIVERY_PASSENGER_SHIP :Navio de passageiros +STR_LIVERY_FREIGHT_SHIP :Navio cargueiro STR_LIVERY_HELICOPTER :Helicóptero STR_LIVERY_SMALL_PLANE :Avião de Pequenas Dimensões STR_LIVERY_LARGE_PLANE :Avião de Grandes Dimensões -STR_LIVERY_PASSENGER_TRAM :Eléctrico de Passageiros +STR_LIVERY_PASSENGER_TRAM :Elétrico de passageiros STR_LIVERY_FREIGHT_TRAM :Eléctrico de Mercadorias # Face selection window @@ -2139,7 +2141,7 @@ STR_NETWORK_CHAT_ALL :[Todos] {STRING STR_NETWORK_CHAT_OSKTITLE :{BLACK}Introduza a mensagem para os outros jogadores # Network messages -STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}Não foram encontradas interfaces de rede ou o jogo foi compilado sem ENABLE_NETWORK +STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}Não foram encontradas interfaces de rede STR_NETWORK_ERROR_NOSERVER :{WHITE}Não foram encontrados jogos de rede STR_NETWORK_ERROR_NOCONNECTION :{WHITE}O servidor não respondeu ao pedido STR_NETWORK_ERROR_NEWGRF_MISMATCH :{WHITE}Impossível ligar devido a incompatibilidade de NewGRF @@ -2261,7 +2263,7 @@ STR_CONTENT_NO_ZLIB_SUB :{WHITE}... não STR_CONTENT_TYPE_BASE_GRAPHICS :Gráficos base STR_CONTENT_TYPE_NEWGRF :NewGRF STR_CONTENT_TYPE_AI :IA -STR_CONTENT_TYPE_AI_LIBRARY :Livraria IA +STR_CONTENT_TYPE_AI_LIBRARY :Biblioteca IA STR_CONTENT_TYPE_SCENARIO :Cenário STR_CONTENT_TYPE_HEIGHTMAP :Mapa de alturas STR_CONTENT_TYPE_BASE_SOUNDS :Sons base @@ -2289,7 +2291,7 @@ STR_MISSING_GRAPHICS_YES_DOWNLOAD :{BLACK}Sim, obt STR_MISSING_GRAPHICS_NO_QUIT :{BLACK}Não, sair do OpenTTD # Transparency settings window -STR_TRANSPARENCY_CAPTION :{WHITE}Opções de Transparência +STR_TRANSPARENCY_CAPTION :{WHITE}Opções de transparência STR_TRANSPARENT_SIGNS_TOOLTIP :{BLACK}Comutar transparência para sinais. Ctrl+Clique para bloquear. STR_TRANSPARENT_TREES_TOOLTIP :{BLACK}Comutar transparência das árvores. Ctrl+Clique para bloquear. STR_TRANSPARENT_HOUSES_TOOLTIP :{BLACK}Comutar transparência das casas. Ctrl+Clique para bloquear. @@ -2330,34 +2332,34 @@ STR_JOIN_WAYPOINT_CAPTION :{WHITE}Juntar p STR_JOIN_WAYPOINT_CREATE_SPLITTED_WAYPOINT :{YELLOW}Construir um ponto de controlo separado # Rail construction toolbar -STR_RAIL_TOOLBAR_RAILROAD_CONSTRUCTION_CAPTION :Construir caminhos-de-ferro -STR_RAIL_TOOLBAR_ELRAIL_CONSTRUCTION_CAPTION :Construir caminhos-de-ferro electrificados +STR_RAIL_TOOLBAR_RAILROAD_CONSTRUCTION_CAPTION :Construção de caminhos-de-ferro +STR_RAIL_TOOLBAR_ELRAIL_CONSTRUCTION_CAPTION :Construção de caminhos-de-ferro eletrificados STR_RAIL_TOOLBAR_MONORAIL_CONSTRUCTION_CAPTION :Construir monocarril STR_RAIL_TOOLBAR_MAGLEV_CONSTRUCTION_CAPTION :Construir Maglev STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Construir linha férrea. Ctrl alterna a construção/remoção de linha férrea. Shift alterna contruir/mostrar custo estimado STR_RAIL_TOOLBAR_TOOLTIP_BUILD_AUTORAIL :{BLACK}Construir caminhos-de-ferro usando o modo automático. Ctrl alterna a construção/remoção de caminhos-de-ferro. Shift alterna contruir/mostrar custo estimado STR_RAIL_TOOLBAR_TOOLTIP_BUILD_TRAIN_DEPOT_FOR_BUILDING :{BLACK}Construir depósito ferroviário (para compra e manutenção de comboios). Shift alterna contruir/mostrar custo estimado -STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL_TO_WAYPOINT :{BLACK}Converter linha em ponto de controlo. Ctrl permite juntar pontos de controlo. Shift alterna contruir/mostrar custo estimado +STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL_TO_WAYPOINT :{BLACK}Converter linha em ponto de controlo. Ctrl permite juntar pontos de controlo. Shift alterna construir/mostrar custo estimado STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_STATION :{BLACK}Construir estação ferroviária. Ctrl permite juntar estações. Shift alterna contruir/mostrar custo estimado -STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_SIGNALS :{BLACK}Construir sinais ferroviários. Ctrl alterna entre sinais clássicos/luminosos{}Arrastar constrói sinais ao longo de uma linha recta de carris. Ctrl constrói sinais até a próxima junção ou sinal{}Ctrl+Clique alterna entre abrir a janela de selecção de sinais. Shift alterna contruir/mostrar custo estimado +STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_SIGNALS :{BLACK}Construir sinais ferroviários. Ctrl alterna entre semáforos/sinais elétricos{}Arrastar constrói sinais ao longo de uma linha reta de carris. Ctrl constrói sinais até a próxima junção ou sinal{}Ctrl+Clique alterna entre abrir a janela de seleção de sinais. Shift alterna construir/mostrar custo estimado STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_BRIDGE :{BLACK}Construir ponte ferroviária. Shift alterna contruir/mostrar custo estimado STR_RAIL_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TUNNEL :{BLACK}Construir túnel ferroviário. Shift alterna contruir/mostrar custo estimado STR_RAIL_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR :{BLACK}Alternar entre construir/remover linha férrea, sinais, pontos de passagem e estações. Fixar o Ctrl também remove a linha férrea de pontos de passagem e estações -STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL :{BLACK}Converter/Atualizar tipo de linha. Shift alterna contruir/mostrar custo estimado +STR_RAIL_TOOLBAR_TOOLTIP_CONVERT_RAIL :{BLACK}Converter/Atualizar tipo de linha. Shift alterna construir/mostrar custo estimado STR_RAIL_NAME_RAILROAD :Caminhos-de-ferro -STR_RAIL_NAME_ELRAIL :Caminhos-de-ferro elétricos +STR_RAIL_NAME_ELRAIL :Caminhos-de-ferro elétrificados STR_RAIL_NAME_MONORAIL :Monocarril STR_RAIL_NAME_MAGLEV :Maglev # Rail depot construction window -STR_BUILD_DEPOT_TRAIN_ORIENTATION_CAPTION :{WHITE}Orientação do Depósito +STR_BUILD_DEPOT_TRAIN_ORIENTATION_CAPTION :{WHITE}Orientação do depósito STR_BUILD_DEPOT_TRAIN_ORIENTATION_TOOLTIP :{BLACK}Seleccionar a orientação do depósito # Rail waypoint construction window STR_WAYPOINT_CAPTION :{WHITE}Ponto de controlo -STR_WAYPOINT_GRAPHICS_TOOLTIP :{BLACK}Seleccione um tipo de ponto de controlo +STR_WAYPOINT_GRAPHICS_TOOLTIP :{BLACK}Selecione um tipo de ponto de controlo # Rail station construction window STR_STATION_BUILD_RAIL_CAPTION :{WHITE}Selecção de Estação @@ -2378,18 +2380,18 @@ STR_STATION_CLASS_WAYP :Pontos de passa # Signal window STR_BUILD_SIGNAL_CAPTION :{WHITE}Selecção de Sinal -STR_BUILD_SIGNAL_SEMAPHORE_NORM_TOOLTIP :{BLACK}Sinal Normal (semáforo){}Este é o tipo mais básico de sinal, que só permite um comboio dentro da mesma linha ferroviária ao mesmo tempo. -STR_BUILD_SIGNAL_SEMAPHORE_ENTRY_TOOLTIP :{BLACK}Sinal de Entrada (semáforo){}Verde enquanto existir um ou mais sinais de saída verdes no seguimento da linha. Caso contrário, ficará vermelho -STR_BUILD_SIGNAL_SEMAPHORE_EXIT_TOOLTIP :{BLACK}Sinal de Saída (semáforo){}Funciona da mesma forma que o sinal normal mas é necessário para conseguir a cor correcta nos pré-sinais de entrada e combinado. -STR_BUILD_SIGNAL_SEMAPHORE_COMBO_TOOLTIP :{BLACK}Sinal Combinado (semáforo){}O sinal combinado funciona como um sinal de entrada e de saída. Este permite construir grandes "árvores" de pré-sinais. -STR_BUILD_SIGNAL_SEMAPHORE_PBS_TOOLTIP :{BLACK}Sinal (semáforo){}Os sinais permitem que vários comboios utilizem a mesma linha desde que consigam chegar aos seus destinos em segurança. Sinais normais podem ser passados no sentido contrário. -STR_BUILD_SIGNAL_SEMAPHORE_PBS_OWAY_TOOLTIP :{BLACK}Sinal de sentido único (semáforo){}Os sinais permitem que vários comboios utilizem a mesma linha desde que consigam chegar aos seus destinos em segurança. Os comboios não podem passar no sentido oposto dos sinais. -STR_BUILD_SIGNAL_ELECTRIC_NORM_TOOLTIP :{BLACK}Sinal Normal(eléctrico){}Este é o tipo mais básico de sinal, que só permite um comboio dentro da mesma linha ferroviária ao mesmo tempo. -STR_BUILD_SIGNAL_ELECTRIC_ENTRY_TOOLTIP :{BLACK}Sinal de Entrada (eléctrico){}Verde enquanto existir um ou mais sinais de saída verdes no seguimento da linha. De outro modo ficará vermelho. -STR_BUILD_SIGNAL_ELECTRIC_EXIT_TOOLTIP :{BLACK}Sinal de Saída (eléctrico){}Funciona da mesma forma que o sinal normal mas é necessário para conseguir a cor correcta nos pré-sinais de entrada e combinado. -STR_BUILD_SIGNAL_ELECTRIC_COMBO_TOOLTIP :{BLACK}Sinal Combinado (eléctrico){}O sinal combinado funciona simplesmente como um sinal de entrada e de saída. Este permite construir grandes "árvores" de pré-sinais -STR_BUILD_SIGNAL_ELECTRIC_PBS_TOOLTIP :{BLACK}Sinal (eléctrico){}Os sinais permitem que vários comboios entrem na mesma linha ao mesmo tempo, desde que consigam chegar ao seu destino em segurança. Sinais padrão podem ser passados no sentido contrário. -STR_BUILD_SIGNAL_ELECTRIC_PBS_OWAY_TOOLTIP :{BLACK}Sinal de sentido único (eléctrico){}Um sinal de trajecto permite que mais de um comboio passe ao mesmo tempo um sinal se, o comboio conseguir reservar um caminho para onde posteriormente possa parar sem prejudicar o seguinte. Sinais de um único sentido não podem ser passados no sentido contrário. +STR_BUILD_SIGNAL_SEMAPHORE_NORM_TOOLTIP :{BLACK}Sinal de bloco (semáforo){}Este é o tipo mais básico de sinal. Permite apenas a passagem de um comboio dentro de um bloco de linha ao mesmo tempo. +STR_BUILD_SIGNAL_SEMAPHORE_ENTRY_TOOLTIP :{BLACK}Sinal de entrada (semáforo){}Apresenta-se verde enquanto existir um ou mais sinais de saída verdes no seguimento da linha. Caso contrário, ficará vermelho. +STR_BUILD_SIGNAL_SEMAPHORE_EXIT_TOOLTIP :{BLACK}Sinal de saída (semáforo){}Funciona da mesma forma que o sinal de bloco, mas é necessário para ativar a cor correta nos pré-sinais de entrada e combinado. +STR_BUILD_SIGNAL_SEMAPHORE_COMBO_TOOLTIP :{BLACK}Sinal combinado (semáforo){}O sinal combinado funciona simultaneamente como um sinal de entrada e de saída. Isto permite a construção de ramificações complexas de pré-sinais. +STR_BUILD_SIGNAL_SEMAPHORE_PBS_TOOLTIP :{BLACK}Sinal de trajeto (semáforo){}Permite que vários comboios passem simultaneamente um bloco de linha, desde que consigam reservar um caminho seguro sem prejudicar o veículo seguinte. Os sinais de trajeto padrão podem ser cruzados no sentido contrário. +STR_BUILD_SIGNAL_SEMAPHORE_PBS_OWAY_TOOLTIP :{BLACK}Sinal de sentido único (semáforo){}Funciona de maneira similar a um sinal de trajeto, mas não pode ser cruzado no sentido contrário. +STR_BUILD_SIGNAL_ELECTRIC_NORM_TOOLTIP :{BLACK}Sinal Normal(eléctrico){}Este é o tipo mais básico de sinal. Permite apenas a passagem de um comboio de cada vez dentro da mesma divisão de linha. +STR_BUILD_SIGNAL_ELECTRIC_ENTRY_TOOLTIP :{BLACK}Sinal de entrada (eléctrico){}Apresenta-se verde enquanto existir um ou mais sinais de saída verdes no seguimento da linha. De outro modo ficará vermelho. +STR_BUILD_SIGNAL_ELECTRIC_EXIT_TOOLTIP :{BLACK}Sinal de saída (eléctrico){}Funciona da mesma forma que o sinal normal, mas é necessário para ativar a cor correta nos pré-sinais de entrada e combinado. +STR_BUILD_SIGNAL_ELECTRIC_COMBO_TOOLTIP :{BLACK}Sinal combinado (eléctrico){}O sinal combinado funciona simultaneamente como um sinal de entrada e de saída. Isto permite construir ramificações complexas de pré-sinais. +STR_BUILD_SIGNAL_ELECTRIC_PBS_TOOLTIP :{BLACK}Sinal de trajeto (elétrico){}Permite que vários comboios passem simultaneamente um bloco de linha, desde que consigam reservar um caminho seguro sem prejudicar o veículo seguinte. Os sinais de trajeto padrão podem ser cruzados no sentido contrário. +STR_BUILD_SIGNAL_ELECTRIC_PBS_OWAY_TOOLTIP :{BLACK}Sinal de sentido único (eléctrico){}Um sinal de trajeto que permite que mais de um comboio passe simultaneamente uma divisão de linha, desde que consiga reservar um caminho para onde possa parar posteriormente sem prejudicar o seguinte. Os sinais de sentido único não podem ser cruzados no sentido contrário. STR_BUILD_SIGNAL_CONVERT_TOOLTIP :{BLACK}Conversão de Sinal{}Quando seleccionado, ao fazer clique num sinal existente este será convertido no tipo e variante de sinal seleccionado, Ctrl+clique irá comutar a variante existente. Shift+Clique mostra estimativa do custo de conversão STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP :{BLACK}Distância de arrasto de sinais STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_DECREASE_TOOLTIP :{BLACK}Reduzir distância de arrasto de sinais @@ -2412,8 +2414,8 @@ STR_BRIDGE_TUBULAR_SILICON :Tubular, Silíc # Road construction toolbar -STR_ROAD_TOOLBAR_ROAD_CONSTRUCTION_CAPTION :{WHITE}Construir Estradas -STR_ROAD_TOOLBAR_TRAM_CONSTRUCTION_CAPTION :{WHITE}Construção de Eléctricos +STR_ROAD_TOOLBAR_ROAD_CONSTRUCTION_CAPTION :{WHITE}Construção de estradas +STR_ROAD_TOOLBAR_TRAM_CONSTRUCTION_CAPTION :{WHITE}Construção de eléctricos STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_SECTION :{BLACK}Construir estradas. Ctrl alterna a construção/remoção de estradas STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION :{BLACK}Construir secção de carris para eléctricos. Ctrl alterna a construção/remoção de carris para eléctricos. Shift alterna contruir/mostrar custo estimado STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOROAD :{BLACK}Construir estradas usando o modo automático. Ctrl alterna a construção/remoção de estradas. Shift alterna contruir/mostrar custo estimado @@ -2431,9 +2433,14 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL :{BLACK}Construi STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Construir túnel para eléctricos. Shift alterna contruir/mostrar custo estimado STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Alternar entre construir/remover estradas STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Alternar construir/remover linhas de eléctricos e sinais +STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_ROAD :{BLACK}Converter/Atualizar tipo de estrada. Shift alterna construir/mostrar custo estimado +STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_TRAM :{BLACK}Converter/Atualizar tipo de carril para eléctricos. Shift alterna construir/mostrar custo estimado + +STR_ROAD_NAME_ROAD :Estrada +STR_ROAD_NAME_TRAM :Carris para elétricos # Road depot construction window -STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Orientação do Depósito +STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Orientação do depósito STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}Seleccionar a orientação do depósito STR_BUILD_DEPOT_TRAM_ORIENTATION_CAPTION :{WHITE}Orientação do depósito para eléctricos STR_BUILD_DEPOT_TRAM_ORIENTATION_SELECT_TOOLTIP :{BLACK}Escolher a orientação do depósito de eléctricos @@ -2449,14 +2456,14 @@ STR_STATION_BUILD_CARGO_TRAM_ORIENTATION :{WHITE}Orienta STR_STATION_BUILD_CARGO_TRAM_ORIENTATION_TOOLTIP :{BLACK}Seleccionar orientação da estação de eléctricos # Waterways toolbar (last two for SE only) -STR_WATERWAYS_TOOLBAR_CAPTION :{WHITE}Construção de Canais +STR_WATERWAYS_TOOLBAR_CAPTION :{WHITE}Construção de hidrovia STR_WATERWAYS_TOOLBAR_CAPTION_SE :{WHITE}Canais STR_WATERWAYS_TOOLBAR_BUILD_CANALS_TOOLTIP :{BLACK}Construir canais. Shift alterna construção/estimativa de custos STR_WATERWAYS_TOOLBAR_BUILD_LOCKS_TOOLTIP :{BLACK}Construir diques. Shift alterna contruir/mostrar custo estimado -STR_WATERWAYS_TOOLBAR_BUILD_DEPOT_TOOLTIP :{BLACK}Construir depósito naval (para compra e manutenção de barcos). Shift alterna contruir/mostrar custo estimado +STR_WATERWAYS_TOOLBAR_BUILD_DEPOT_TOOLTIP :{BLACK}Construir depósito naval (para compra e manutenção de navio). Shift alterna contruir/mostrar custo estimado STR_WATERWAYS_TOOLBAR_BUILD_DOCK_TOOLTIP :{BLACK}Construir doca naval. Ctrl permite juntar estações. Shift alterna contruir/mostar custo estimado -STR_WATERWAYS_TOOLBAR_BUOY_TOOLTIP :{BLACK}Bóia de posição, que pode ser usada para marcar pontos de rota adicionais. Shift alterna contrução/mostra de custos estimados -STR_WATERWAYS_TOOLBAR_BUILD_AQUEDUCT_TOOLTIP :{BLACK}Construir aqueduto. Shift alterna contruir/mostar custo estimado +STR_WATERWAYS_TOOLBAR_BUOY_TOOLTIP :{BLACK}Esta bóia de posição pode ser usada para marcar pontos de rota adicionais. Shift alterna construção/mostra de custos estimados +STR_WATERWAYS_TOOLBAR_BUILD_AQUEDUCT_TOOLTIP :{BLACK}Construir aqueduto. Shift alterna contruir/mostrar custo estimado STR_WATERWAYS_TOOLBAR_CREATE_LAKE_TOOLTIP :{BLACK}Definir área de água.{}Construir um canal, a não ser que a tecla Ctrl esteja pressionada a nível do mar, nesse caso inundará as zonas circundantes STR_WATERWAYS_TOOLBAR_CREATE_RIVER_TOOLTIP :{BLACK}Colocar rios @@ -2496,10 +2503,10 @@ STR_STATION_BUILD_NOISE :{BLACK}Ruído g # Landscaping toolbar STR_LANDSCAPING_TOOLBAR :{WHITE}Terreno -STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Baixa um canto da terra. Arrastando abaixa o primeiro canto selecionado e os níveis a área selecionada para a altura do canto novo. Ctrl selecciona a área na diagonal. Shift alterna construção/estimativa de custos -STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK}Elevar um canto da terra. Arrastando eleva o primeiro canto selecionado e os níveis a área selecionada para a altura do canto novo. Ctrl selecciona a área na diagonal. Shift alterna construção/estimativa de custos -STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Nívelar uma área de terra até a altura do primeiro canto selecionado. Ctrl selecciona a área na diagonal. Shift alterna construção/estimativa de custos -STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Comprar terreno para uso futuro. Shift alterna construir/mostrar custo estimado +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. # Object construction window STR_OBJECT_BUILD_CAPTION :{WHITE}Selecção de Objecto @@ -2515,8 +2522,8 @@ 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 contruir/mostrar custo estimado -STR_TREES_RANDOM_TREES_BUTTON :{BLACK}Plantar Aleatoriamente +STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Colocar árvores de tipo aleatório. 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 # Land generation window (SE) @@ -2534,7 +2541,6 @@ STR_QUERY_RESET_LANDSCAPE_CAPTION :{WHITE}Repor Te STR_RESET_LANDSCAPE_CONFIRMATION_TEXT :{WHITE}Tem a certeza que quer apagar todas as propriedades das empresas? # Town generation window (SE) - STR_FOUND_TOWN_CAPTION :{WHITE}Gerar Localidades STR_FOUND_TOWN_NEW_TOWN_BUTTON :{BLACK}Nova Localidade STR_FOUND_TOWN_NEW_TOWN_TOOLTIP :{BLACK}Fundar nova localidade. Shift+Clique mostra apenas o custo estimado @@ -2542,6 +2548,7 @@ 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_NAME_TITLE :{YELLOW}Nome da localidade: STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Introduza o nome da localidade STR_FOUND_TOWN_NAME_EDITOR_HELP :{BLACK}Clique para introduzir o nome da localidade @@ -2606,8 +2613,8 @@ STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY :{BLACK}Autorida STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE :Nenhum STR_LAND_AREA_INFORMATION_LANDINFO_COORDS :{BLACK}Coordenadas: {LTBLUE}{NUM} x {NUM} x {NUM} ({STRING}) STR_LAND_AREA_INFORMATION_BUILD_DATE :{BLACK}Construído: {LTBLUE}{DATE_LONG} -STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Tipo de Estação: {LTBLUE}{STRING} -STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Tipo de Estação: {LTBLUE}{STRING} +STR_LAND_AREA_INFORMATION_STATION_CLASS :{BLACK}Tipo de estação: {LTBLUE}{STRING} +STR_LAND_AREA_INFORMATION_STATION_TYPE :{BLACK}Tipo de estação: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_AIRPORT_CLASS :{BLACK}Tipo de aeroporto: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_AIRPORT_NAME :{BLACK}Nome do aeroporto: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_AIRPORTTILE_NAME :{BLACK}Nome do quadrado do aeroporto: {LTBLUE}{STRING} @@ -2615,14 +2622,17 @@ STR_LAND_AREA_INFORMATION_NEWGRF_NAME :{BLACK}NewGRF: STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED :{BLACK}Carga aceite: {LTBLUE} STR_LAND_AREA_INFORMATION_CARGO_EIGHTS :({COMMA}/8 {STRING}) STR_LANG_AREA_INFORMATION_RAIL_TYPE :{BLACK}Tipo de carril: {LTBLUE}{STRING} +STR_LANG_AREA_INFORMATION_ROAD_TYPE :{BLACK}Tipo de estrada: {LTBLUE}{STRING} +STR_LANG_AREA_INFORMATION_TRAM_TYPE :{BLACK}Tipo de elétrico: {LTBLUE}{STRING} STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT :{BLACK}Limite de velocidade da linha: {LTBLUE}{VELOCITY} STR_LANG_AREA_INFORMATION_ROAD_SPEED_LIMIT :{BLACK}Limite de velocidade da estrada: {LTBLUE}{VELOCITY} +STR_LANG_AREA_INFORMATION_TRAM_SPEED_LIMIT :{BLACK}Limite de velocidade para elétricos: {LTBLUE}{VELOCITY} # Description of land area of different tiles STR_LAI_CLEAR_DESCRIPTION_ROCKS :Rochas -STR_LAI_CLEAR_DESCRIPTION_ROUGH_LAND :Terreno Irregular -STR_LAI_CLEAR_DESCRIPTION_BARE_LAND :Terreno Deserto -STR_LAI_CLEAR_DESCRIPTION_GRASS :Terreno de Prados +STR_LAI_CLEAR_DESCRIPTION_ROUGH_LAND :Terreno irregular +STR_LAI_CLEAR_DESCRIPTION_BARE_LAND :Terreno deserto +STR_LAI_CLEAR_DESCRIPTION_GRASS :Prados STR_LAI_CLEAR_DESCRIPTION_FIELDS :Campos STR_LAI_CLEAR_DESCRIPTION_SNOW_COVERED_LAND :Neve STR_LAI_CLEAR_DESCRIPTION_DESERT :Deserto @@ -2662,7 +2672,7 @@ STR_LAI_ROAD_DESCRIPTION_TRAMWAY :Linha de eléct STR_LAI_TOWN_INDUSTRY_DESCRIPTION_UNDER_CONSTRUCTION :{STRING} (em construção) STR_LAI_TREE_NAME_TREES :Árvores -STR_LAI_TREE_NAME_RAINFOREST :Floresta Tropical +STR_LAI_TREE_NAME_RAINFOREST :Floresta tropical STR_LAI_TREE_NAME_CACTUS_PLANTS :Cactos STR_LAI_STATION_DESCRIPTION_RAILROAD_STATION :Estação ferroviária @@ -2726,6 +2736,7 @@ STR_FRAMERATE_SPEED_FACTOR :{BLACK}Factor d STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}Quão rápido o jogo está a ser executado, comparado com a velocidade esperada na taxa de simulação normal. STR_FRAMERATE_CURRENT :{WHITE}Actual STR_FRAMERATE_AVERAGE :{WHITE}Média +STR_FRAMERATE_MEMORYUSE :{WHITE}Memória STR_FRAMERATE_DATA_POINTS :{BLACK}Dados baseados em {COMMA} medições STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL} ms STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL} ms @@ -2733,6 +2744,7 @@ STR_FRAMERATE_MS_BAD :{RED}{DECIMAL} STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL} fotograma/s STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL} fotograma/s STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL} fotograma/s +STR_FRAMERATE_BYTES_GOOD :{LTBLUE}{BYTES} STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} ms STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} s ############ Leave those lines in this order!! @@ -2757,7 +2769,7 @@ STR_FRAMETIME_CAPTION_GAMELOOP :Loop de jogo STR_FRAMETIME_CAPTION_GL_ECONOMY :Movimentação de carga STR_FRAMETIME_CAPTION_GL_TRAINS :Quantidade de atraso no percurso do Comboio STR_FRAMETIME_CAPTION_GL_ROADVEHS :Quantidade de atraso no percurso do veículo rodoviário -STR_FRAMETIME_CAPTION_GL_SHIPS :Quantidade de atraso no percurso do barco +STR_FRAMETIME_CAPTION_GL_SHIPS :Quantidade de atraso no percurso do navio STR_FRAMETIME_CAPTION_GL_AIRCRAFT :Quantidade de atraso no percurso de Aeronave STR_FRAMETIME_CAPTION_GL_LANDSCAPE :Quantidade de Atraso no Percurso Mundial STR_FRAMETIME_CAPTION_GL_LINKGRAPH :Atraso no gráfico de ligação @@ -3246,7 +3258,7 @@ STR_CARGO_RATING_MEDIOCRE :Medíocre STR_CARGO_RATING_GOOD :Bom STR_CARGO_RATING_VERY_GOOD :Muito Bom STR_CARGO_RATING_EXCELLENT :Excelente -STR_CARGO_RATING_OUTSTANDING :Proeminente +STR_CARGO_RATING_OUTSTANDING :Excecional ############ range for rating ends STR_STATION_VIEW_CENTER_TOOLTIP :{BLACK}Centrar visualização na localização da estação. Ctrl+Clique abre um novo visualizador na localização da estação @@ -3255,7 +3267,7 @@ STR_STATION_VIEW_RENAME_TOOLTIP :{BLACK}Alterar STR_STATION_VIEW_SCHEDULED_TRAINS_TOOLTIP :{BLACK}Mostrar todos os comboios que têm esta estação nas ordens de serviço STR_STATION_VIEW_SCHEDULED_ROAD_VEHICLES_TOOLTIP :{BLACK}Mostrar todos os veículos rodoviários que têm esta estação nas ordens de serviço STR_STATION_VIEW_SCHEDULED_AIRCRAFT_TOOLTIP :{BLACK}Mostrar todas as aeronaves que têm esta estação nas ordens de serviço -STR_STATION_VIEW_SCHEDULED_SHIPS_TOOLTIP :{BLACK}Mostrar todos os barcos que têm esta estação nas ordens de serviço +STR_STATION_VIEW_SCHEDULED_SHIPS_TOOLTIP :{BLACK}Mostrar todos os navios que têm esta estação nas ordens de serviço STR_STATION_VIEW_RENAME_STATION_CAPTION :Alterar nome de estação/local de carga @@ -3280,18 +3292,18 @@ STR_FINANCES_SECTION_NEW_VEHICLES :{GOLD}Novos Ve STR_FINANCES_SECTION_TRAIN_RUNNING_COSTS :{GOLD}Circulação de Comboios STR_FINANCES_SECTION_ROAD_VEHICLE_RUNNING_COSTS :{GOLD}Circulação de Veículos STR_FINANCES_SECTION_AIRCRAFT_RUNNING_COSTS :{GOLD}Circulação de Aeronaves -STR_FINANCES_SECTION_SHIP_RUNNING_COSTS :{GOLD}Circulação de Barcos +STR_FINANCES_SECTION_SHIP_RUNNING_COSTS :{GOLD}Circulação de navios STR_FINANCES_SECTION_PROPERTY_MAINTENANCE :{GOLD}Manutenção de Propriedades STR_FINANCES_SECTION_TRAIN_INCOME :{GOLD}Lucros dos Comboios -STR_FINANCES_SECTION_ROAD_VEHICLE_INCOME :{GOLD}Lucros dos V. Rodoviários +STR_FINANCES_SECTION_ROAD_VEHICLE_INCOME :{GOLD}Lucros dos veículos rodoviários STR_FINANCES_SECTION_AIRCRAFT_INCOME :{GOLD}Lucros das Aeronaves -STR_FINANCES_SECTION_SHIP_INCOME :{GOLD}Lucros dos Barcos +STR_FINANCES_SECTION_SHIP_INCOME :{GOLD}Lucros dos navios STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}Juros do Empréstimo STR_FINANCES_SECTION_OTHER :{GOLD}Outros STR_FINANCES_NEGATIVE_INCOME :{BLACK}-{CURRENCY_LONG} STR_FINANCES_POSITIVE_INCOME :{BLACK}+{CURRENCY_LONG} STR_FINANCES_TOTAL_CAPTION :{WHITE}Total: -STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Balanço Bancário +STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Balanço bancário STR_FINANCES_LOAN_TITLE :{WHITE}Empréstimo STR_FINANCES_MAX_LOAN :{WHITE}Empréstimo Máximo: {BLACK}{CURRENCY_LONG} STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG} @@ -3311,7 +3323,7 @@ STR_COMPANY_VIEW_VEHICLES_TITLE :{GOLD}Veículos STR_COMPANY_VIEW_TRAINS :{WHITE}{COMMA} comboio{P "" s} STR_COMPANY_VIEW_ROAD_VEHICLES :{WHITE}{COMMA} veículo{P "" s} rodoviário{P "" s} STR_COMPANY_VIEW_AIRCRAFT :{WHITE}{COMMA} aeronave{P "" s} -STR_COMPANY_VIEW_SHIPS :{WHITE}{COMMA} barco{P "" s} +STR_COMPANY_VIEW_SHIPS :{WHITE}{COMMA} navio{P "" s} STR_COMPANY_VIEW_VEHICLES_NONE :{WHITE}Nenhum STR_COMPANY_VIEW_COMPANY_VALUE :{GOLD}Valor da empresa: {WHITE}{CURRENCY_LONG} STR_COMPANY_VIEW_SHARES_OWNED_BY :{WHITE}({COMMA}% propriedade de {COMPANY}) @@ -3332,7 +3344,7 @@ STR_COMPANY_VIEW_RELOCATE_COMPANY_HEADQUARTERS :{BLACK}Reconstr STR_COMPANY_VIEW_INFRASTRUCTURE_BUTTON :{BLACK}Detalhes STR_COMPANY_VIEW_INFRASTRUCTURE_TOOLTIP :{BLACK}Ver contagens de infraestrutura detalhadas -STR_COMPANY_VIEW_NEW_FACE_BUTTON :{BLACK}Nova Cara +STR_COMPANY_VIEW_NEW_FACE_BUTTON :{BLACK}Nova cara STR_COMPANY_VIEW_NEW_FACE_TOOLTIP :{BLACK}Seleccione uma nova cara para o presidente STR_COMPANY_VIEW_COLOUR_SCHEME_BUTTON :{BLACK}Cores STR_COMPANY_VIEW_COLOUR_SCHEME_TOOLTIP :{BLACK}Alterar cores dos veículos @@ -3342,9 +3354,9 @@ STR_COMPANY_VIEW_PRESIDENT_NAME_BUTTON :{BLACK}Nome do STR_COMPANY_VIEW_PRESIDENT_NAME_TOOLTIP :{BLACK}Alterar nome do presidente STR_COMPANY_VIEW_BUY_SHARE_BUTTON :{BLACK}Comprar 25% das acções -STR_COMPANY_VIEW_SELL_SHARE_BUTTON :{BLACK}Vender 25% das acções +STR_COMPANY_VIEW_SELL_SHARE_BUTTON :{BLACK}Vender 25% das ações STR_COMPANY_VIEW_BUY_SHARE_TOOLTIP :{BLACK}Comprar 25% das acções nesta empresa. Shift+Clique mostra valor estimado sem comprar nenhuma acção -STR_COMPANY_VIEW_SELL_SHARE_TOOLTIP :{BLACK}Vender 25% das acções nesta empresa. Shift+Clique mostra valor estimado sem vender nenhuma acção +STR_COMPANY_VIEW_SELL_SHARE_TOOLTIP :{BLACK}Vender 25% das ações nesta empresa. Shift+Clique mostra valor estimado sem vender nenhuma ação STR_COMPANY_VIEW_COMPANY_NAME_QUERY_CAPTION :Nome da Empresa STR_COMPANY_VIEW_PRESIDENT_S_NAME_QUERY_CAPTION :Nome do Presidente @@ -3356,8 +3368,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Infraest STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Secções de caminho-de-ferro: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Sinais STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Secções de estrada: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Estrada -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Via para elétricos STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Blocos de água: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Canais STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Estações: @@ -3368,8 +3378,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Indústrias STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Nenhuma - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% transportado) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% transportado) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Nomes de indústrias - clique no nome para centrar-se na indústria. Ctrl+Clique abre um novo visualizador na localização da indústria @@ -3395,19 +3403,19 @@ STR_CONFIG_GAME_PRODUCTION_LEVEL :{WHITE}Mudar o # Vehicle lists STR_VEHICLE_LIST_TRAIN_CAPTION :{WHITE}{STRING} - {COMMA} Comboio{P "" s} STR_VEHICLE_LIST_ROAD_VEHICLE_CAPTION :{WHITE}{STRING} - {COMMA} Veículo{P "" s} Rodoviário{P "" s} -STR_VEHICLE_LIST_SHIP_CAPTION :{WHITE}{STRING} - {COMMA} Barco{P "" s} +STR_VEHICLE_LIST_SHIP_CAPTION :{WHITE}{STRING} - {COMMA} Navio{P "" s} STR_VEHICLE_LIST_AIRCRAFT_CAPTION :{WHITE}{STRING} - {COMMA} Aeronave{P "" s} STR_VEHICLE_LIST_TRAIN_LIST_TOOLTIP :{BLACK}Comboios - clique num comboio para informações STR_VEHICLE_LIST_ROAD_VEHICLE_TOOLTIP :{BLACK}Veículos rodoviários - clique num veículo para informações -STR_VEHICLE_LIST_SHIP_TOOLTIP :{BLACK}Barcos - clique num barco para informações +STR_VEHICLE_LIST_SHIP_TOOLTIP :{BLACK}Navios - clique num navio para informações STR_VEHICLE_LIST_AIRCRAFT_TOOLTIP :{BLACK}Aeronaves - clique numa aeronave para informações STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Lucro deste ano: {CURRENCY_LONG} (último ano: {CURRENCY_LONG}) STR_VEHICLE_LIST_AVAILABLE_TRAINS :Comboios Disponíveis STR_VEHICLE_LIST_AVAILABLE_ROAD_VEHICLES :Veículos Disponíveis -STR_VEHICLE_LIST_AVAILABLE_SHIPS :Barcos Disponíveis +STR_VEHICLE_LIST_AVAILABLE_SHIPS :Navios disponíveis STR_VEHICLE_LIST_AVAILABLE_AIRCRAFT :Aeronaves Disponíveis STR_VEHICLE_LIST_AVAILABLE_ENGINES_TOOLTIP :{BLACK}Ver lista de modelos disponíveis de locomotivas para este tipo de veículo. @@ -3429,14 +3437,16 @@ STR_VEHICLE_LIST_SHARED_ORDERS_LIST_CAPTION :{WHITE}Ordens p # Group window STR_GROUP_ALL_TRAINS :Todos os Comboios STR_GROUP_ALL_ROAD_VEHICLES :Todos os veículos rodoviários -STR_GROUP_ALL_SHIPS :Todos os barcos +STR_GROUP_ALL_SHIPS :Todos os navios STR_GROUP_ALL_AIRCRAFTS :Todas as aeronaves STR_GROUP_DEFAULT_TRAINS :Comboios sem grupo STR_GROUP_DEFAULT_ROAD_VEHICLES :Veículos rodoviários sem grupo -STR_GROUP_DEFAULT_SHIPS :Barcos sem grupo +STR_GROUP_DEFAULT_SHIPS :Navios sem grupo STR_GROUP_DEFAULT_AIRCRAFTS :Aeronaves sem grupo +STR_GROUP_COUNT_WITH_SUBGROUP :{TINY_FONT}{COMMA} (+{COMMA}) + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Grupos - clique num grupo para listar todos os veículos contidos STR_GROUP_CREATE_TOOLTIP :{BLACK}Clique para criar um grupo STR_GROUP_DELETE_TOOLTIP :{BLACK}Remover o grupo seleccionado @@ -3463,12 +3473,18 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Novos Veículos STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Novos Veículos Monocarril STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Novos Veículos Maglev +STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Novos veículos rodoviários +STR_BUY_VEHICLE_TRAM_VEHICLE_CAPTION :Novos elétricos + +############ range for vehicle availability starts STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Novos Veículos Ferroviários -STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Novos Veículos Rodoviários -STR_BUY_VEHICLE_SHIP_CAPTION :Novos Barcos -STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Nova Aeronave +STR_BUY_VEHICLE_ROAD_VEHICLE_ALL_CAPTION :Novos veículos rodoviários +STR_BUY_VEHICLE_SHIP_CAPTION :Novos navios +STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Nova aeronave +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Custo: {GOLD}{CURRENCY_LONG}{BLACK} Peso: {GOLD}{WEIGHT_SHORT} +STR_PURCHASE_INFO_COST_REFIT_WEIGHT :{BLACK}Custo: {GOLD}{CURRENCY_LONG}{BLACK} (Custo da conversão: {GOLD}{CURRENCY_LONG}{BLACK}) Peso: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Velocidade: {GOLD}{VELOCITY}{BLACK} Potência: {GOLD}{POWER} STR_PURCHASE_INFO_SPEED :{BLACK}Velocidade: {GOLD}{VELOCITY} STR_PURCHASE_INFO_SPEED_OCEAN :{BLACK}Velocidade no oceano: {GOLD}{VELOCITY} @@ -3479,8 +3495,10 @@ STR_PURCHASE_INFO_REFITTABLE :(adaptável) STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Concebido: {GOLD}{NUM}{BLACK} Vida útil: {GOLD}{COMMA} ano{P "" s} STR_PURCHASE_INFO_RELIABILITY :{BLACK}Fiabilidade máxima: {GOLD}{COMMA}% STR_PURCHASE_INFO_COST :{BLACK}Custo: {GOLD}{CURRENCY_LONG} +STR_PURCHASE_INFO_COST_REFIT :{BLACK}Custo: {GOLD}{CURRENCY_LONG}{BLACK} (Custo da adaptação: {GOLD}{CURRENCY_LONG}{BLACK}) STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Peso: {GOLD}{WEIGHT_SHORT} ({WEIGHT_SHORT}) STR_PURCHASE_INFO_COST_SPEED :{BLACK}Custo: {GOLD}{CURRENCY_LONG}{BLACK} Velocidade: {GOLD}{VELOCITY} +STR_PURCHASE_INFO_COST_REFIT_SPEED :{BLACK}Custo: {GOLD}{CURRENCY_LONG}{BLACK} (Custo de conversão: {GOLD}{CURRENCY_LONG}{BLACK}) Velocidade: {GOLD}{VELOCITY} STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Capacidade: {GOLD}{CARGO_LONG}, {CARGO_LONG} STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Vagões Motorizados: {GOLD}+{POWER}{BLACK} Peso: {GOLD}+{WEIGHT_SHORT} STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Reconvertível para: {GOLD}{STRING} @@ -3496,16 +3514,26 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Lista de STR_BUY_VEHICLE_SHIP_LIST_TOOLTIP :{BLACK}Lista de selecção de barcos. Clique num navio para informações. Ctrl+Clique para alternar/ocultar o tipo de barco STR_BUY_VEHICLE_AIRCRAFT_LIST_TOOLTIP :{BLACK}Lista de aeronaves - clique na aeronave para informações -STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_BUTTON :{BLACK}Comprar Veículo -STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Comprar Veículo -STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Comprar Barco -STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Comprar Aeronave +STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_BUTTON :{BLACK}Comprar veículo +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Comprar veículo +STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Comprar navio +STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Comprar aeronave + +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Comprar e reconverter veiculo +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Comprar e Reconverter Veículo +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Comprar e converter navio +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Comprar e adaptar carga da aeronave STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Comprar o veículo ferroviário seleccionado. Shift+Clique mostra estimativa de custo, sem comprar -STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Comprar o veículo rodoviário seleccionado. Shift+Clique mostra estimativa de custo, sem comprar -STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Comprar barco seleccionado. Shift+Clique mostra estimativa de custo, sem comprar +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Comprar o veículo rodoviário selecionado. Shift+Clique mostra estimativa de custo, sem comprar +STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Comprar navio selecionado. Shift+Clique mostra estimativa de custo, sem comprar STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Comprar aeronave seleccionada. Shift+Clique mostra estimativa de custo, sem comprar +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Comprar e converter veículo ferroviário seleccionado. Shift+Clique mostra estimativa de custo, sem comprar +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_TOOLTIP :Comprar e converter veículo rodoviário seleccionado. Shift+Clique mostra estimativa de custo, sem comprar +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Comprar e converter navio seleccionado. Shift+Clique mostra estimativa de custo, sem comprar +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Comprar e converter aeronave seleccionada. Shift+Clique mostra estimativa de custo, sem comprar + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Renomear STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Renomear STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Renomear @@ -3513,7 +3541,7 @@ STR_BUY_VEHICLE_AIRCRAFT_RENAME_BUTTON :{BLACK}Renomear STR_BUY_VEHICLE_TRAIN_RENAME_TOOLTIP :{BLACK}Renomear tipo de veículo ferroviário STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_TOOLTIP :{BLACK}Renomear tipo de veículo rodoviário -STR_BUY_VEHICLE_SHIP_RENAME_TOOLTIP :{BLACK}Renomear tipo de barco +STR_BUY_VEHICLE_SHIP_RENAME_TOOLTIP :{BLACK}Renomear tipo de navio STR_BUY_VEHICLE_AIRCRAFT_RENAME_TOOLTIP :{BLACK}Renomear tipo de aeronave STR_BUY_VEHICLE_TRAIN_HIDE_TOGGLE_BUTTON :{BLACK}Esconder @@ -3528,12 +3556,12 @@ STR_BUY_VEHICLE_AIRCRAFT_SHOW_TOGGLE_BUTTON :{BLACK}Mostrar STR_BUY_VEHICLE_TRAIN_HIDE_SHOW_TOGGLE_TOOLTIP :{BLACK}Alternar mostrar/ocultar o tipo de veículo ferroviário STR_BUY_VEHICLE_ROAD_VEHICLE_HIDE_SHOW_TOGGLE_TOOLTIP :{BLACK}Alternar mostrar/ocultar o tipo de veículo rodoviário -STR_BUY_VEHICLE_SHIP_HIDE_SHOW_TOGGLE_TOOLTIP :{BLACK}Define mostrar/esconder tipo de barco +STR_BUY_VEHICLE_SHIP_HIDE_SHOW_TOGGLE_TOOLTIP :{BLACK}Definir mostrar/esconder tipo de navio STR_BUY_VEHICLE_AIRCRAFT_HIDE_SHOW_TOGGLE_TOOLTIP :{BLACK}Define mostrar/esconder tipo de aeronave STR_QUERY_RENAME_TRAIN_TYPE_CAPTION :{WHITE}Renomear tipo de veículo ferroviário STR_QUERY_RENAME_ROAD_VEHICLE_TYPE_CAPTION :{WHITE}Renomear tipo de veículo rodoviário -STR_QUERY_RENAME_SHIP_TYPE_CAPTION :{WHITE}Renomear tipo de barco +STR_QUERY_RENAME_SHIP_TYPE_CAPTION :{WHITE}Renomear tipo de navio STR_QUERY_RENAME_AIRCRAFT_TYPE_CAPTION :{WHITE}Renomear tipo de aeronave # Depot window @@ -3549,44 +3577,44 @@ STR_DEPOT_VEHICLE_TOOLTIP_CARGO :{}{CARGO_LONG} STR_DEPOT_TRAIN_LIST_TOOLTIP :{BLACK}Comboios - arraste o veículo com o botão esquerdo do rato para adicionar/remover do comboio, clique com o botão direito do rato para informações. Fixe o Ctrl para fazer com que as duas funções se apliquem à seguinte cadeia STR_DEPOT_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Veículos - faça clique direito num veículo para informações -STR_DEPOT_SHIP_LIST_TOOLTIP :{BLACK}Barcos - faça clique direito num barco para informações +STR_DEPOT_SHIP_LIST_TOOLTIP :{BLACK}Navios - faça clique direito num navio para informações STR_DEPOT_AIRCRAFT_LIST_TOOLTIP :{BLACK}Aeronave - faça clique direito na aeronave para informações STR_DEPOT_TRAIN_SELL_TOOLTIP :{BLACK}Arraste o veículo ferroviário para aqui para o vender STR_DEPOT_ROAD_VEHICLE_SELL_TOOLTIP :{BLACK}Arraste o veículo rodoviário para aqui para o vender -STR_DEPOT_SHIP_SELL_TOOLTIP :{BLACK}Arraste o barco para aqui para o vender +STR_DEPOT_SHIP_SELL_TOOLTIP :{BLACK}Arraste o navio para aqui para o vender STR_DEPOT_AIRCRAFT_SELL_TOOLTIP :{BLACK}Arraste a aeronave para aqui para a vender STR_DEPOT_DRAG_WHOLE_TRAIN_TO_SELL_TOOLTIP :{BLACK}Arrastar locomotiva para aqui para vender todo o comboio STR_DEPOT_SELL_ALL_BUTTON_TRAIN_TOOLTIP :{BLACK}Vender todos os comboios no depósito STR_DEPOT_SELL_ALL_BUTTON_ROAD_VEHICLE_TOOLTIP :{BLACK}Vender todos os veículos no depósito -STR_DEPOT_SELL_ALL_BUTTON_SHIP_TOOLTIP :{BLACK}Vender todos os barcos no depósito +STR_DEPOT_SELL_ALL_BUTTON_SHIP_TOOLTIP :{BLACK}Vender todos os navios no depósito STR_DEPOT_SELL_ALL_BUTTON_AIRCRAFT_TOOLTIP :{BLACK}Vender todas as aeronaves no hangar STR_DEPOT_AUTOREPLACE_TRAIN_TOOLTIP :{BLACK}Autosubstituir todos os comboios no depósito STR_DEPOT_AUTOREPLACE_ROAD_VEHICLE_TOOLTIP :{BLACK}Autosubstituir todos os veículos rodoviários no depósito -STR_DEPOT_AUTOREPLACE_SHIP_TOOLTIP :{BLACK}Autosubstituir todos os barcos no depósito +STR_DEPOT_AUTOREPLACE_SHIP_TOOLTIP :{BLACK}Autosubstituir todos os navios no depósito STR_DEPOT_AUTOREPLACE_AIRCRAFT_TOOLTIP :{BLACK}Autosubstituir todas as aeronaves no hangar STR_DEPOT_TRAIN_NEW_VEHICLES_BUTTON :{BLACK}Novos Veículos STR_DEPOT_ROAD_VEHICLE_NEW_VEHICLES_BUTTON :{BLACK}Novos Veículos -STR_DEPOT_SHIP_NEW_VEHICLES_BUTTON :{BLACK}Novos Barcos +STR_DEPOT_SHIP_NEW_VEHICLES_BUTTON :{BLACK}Novos navios STR_DEPOT_AIRCRAFT_NEW_VEHICLES_BUTTON :{BLACK}Nova Aeronave STR_DEPOT_TRAIN_NEW_VEHICLES_TOOLTIP :{BLACK}Comprar novo veículo ferroviário STR_DEPOT_ROAD_VEHICLE_NEW_VEHICLES_TOOLTIP :{BLACK}Comprar novo veículo rodoviário -STR_DEPOT_SHIP_NEW_VEHICLES_TOOLTIP :{BLACK}Comprar novo barco +STR_DEPOT_SHIP_NEW_VEHICLES_TOOLTIP :{BLACK}Comprar novo navio STR_DEPOT_AIRCRAFT_NEW_VEHICLES_TOOLTIP :{BLACK}Comprar nova aeronave STR_DEPOT_CLONE_TRAIN :{BLACK}Clonar Comboio STR_DEPOT_CLONE_ROAD_VEHICLE :{BLACK}Clonar Veículo -STR_DEPOT_CLONE_SHIP :{BLACK}Clonar Barco +STR_DEPOT_CLONE_SHIP :{BLACK}Clonar navio STR_DEPOT_CLONE_AIRCRAFT :{BLACK}Clonar Aeronave STR_DEPOT_CLONE_TRAIN_DEPOT_INFO :{BLACK}Esta acção comprará uma cópia de um comboio, incluindo todas as carruagens. Clique neste botão e, de seguida, num comboio que se encontre dentro ou fora do depósito. Ctrl+Clique irá partilhar as ordens. Shift+Clique mostra estimativa de custo, sem comprar STR_DEPOT_CLONE_ROAD_VEHICLE_DEPOT_INFO :{BLACK}Esta acção comprará uma cópia de um veículo rodoviário. Clique neste botão e, de seguida, num veículo que se encontre dentro ou fora de um depósito. Ctrl+Clique irá partilhar as ordens. Shift+Clique mostra estimativa de custo, sem comprar -STR_DEPOT_CLONE_SHIP_DEPOT_INFO :{BLACK}Esta acção comprará uma cópia de um barco. Clique neste botão e, de seguida, num barco que se encontre dentro ou fora do depósito. Ctrl+Clique irá partilhar as ordens. Shift+Clique mostra estimativa de custo, sem comprar +STR_DEPOT_CLONE_SHIP_DEPOT_INFO :{BLACK}Esta acção comprará uma cópia de um navio. Clique neste botão e, de seguida, num navio que se encontre dentro ou fora do depósito. Ctrl+Clique irá partilhar as ordens. Shift+Clique mostra estimativa de custo, sem comprar STR_DEPOT_CLONE_AIRCRAFT_INFO_HANGAR_WINDOW :{BLACK}Esta acção comprará uma cópia de uma aeronave. Clique neste botão e, de seguida, numa aeronave que se encontre dentro ou fora do hangar. Ctrl+Clique ira partilhar as ordens. Shift+Clique mostra estimativa de custo, sem comprar STR_DEPOT_TRAIN_LOCATION_TOOLTIP :{BLACK}Centrar visualização na localização de um depósito ferroviário. Ctrl+Clique abre um novo visualizador na localização do depósito ferroviário @@ -3596,17 +3624,17 @@ STR_DEPOT_AIRCRAFT_LOCATION_TOOLTIP :{BLACK}Centrar STR_DEPOT_VEHICLE_ORDER_LIST_TRAIN_TOOLTIP :{BLACK}Obter uma lista de todos os comboios em cujas ordens conste este depósito STR_DEPOT_VEHICLE_ORDER_LIST_ROAD_VEHICLE_TOOLTIP :{BLACK}Obter uma lista de todos os veículos em cujas ordens conste este depósito -STR_DEPOT_VEHICLE_ORDER_LIST_SHIP_TOOLTIP :{BLACK}Obter uma lista de todos os barcos em cujas ordens conste este depósito +STR_DEPOT_VEHICLE_ORDER_LIST_SHIP_TOOLTIP :{BLACK}Obter uma lista de todos os navios em cujas ordens conste este depósito STR_DEPOT_VEHICLE_ORDER_LIST_AIRCRAFT_TOOLTIP :{BLACK}Obter uma lista de todas as aeronaves em cujas ordens conste um hangar deste aeroporto -STR_DEPOT_MASS_STOP_DEPOT_TRAIN_TOOLTIP :{BLACK}Pressione botão esquerdo do rato para imobilizar todos os comboios no depósito -STR_DEPOT_MASS_STOP_DEPOT_ROAD_VEHICLE_TOOLTIP :{BLACK}Pressione botão esquerdo do rato para imobilizar todos os veículos no depósito -STR_DEPOT_MASS_STOP_DEPOT_SHIP_TOOLTIP :{BLACK}Pressione botão esquerdo do rato para imobilizar todos os barcos no depósito +STR_DEPOT_MASS_STOP_DEPOT_TRAIN_TOOLTIP :{BLACK}Pressione o botão esquerdo do rato para imobilizar todos os comboios no depósito +STR_DEPOT_MASS_STOP_DEPOT_ROAD_VEHICLE_TOOLTIP :{BLACK}Pressione o botão esquerdo do rato para imobilizar todos os veículos no depósito +STR_DEPOT_MASS_STOP_DEPOT_SHIP_TOOLTIP :{BLACK}Pressione o botão esquerdo do rato para imobilizar todos os navios no depósito STR_DEPOT_MASS_STOP_HANGAR_TOOLTIP :{BLACK}Pressione botão esquerdo do rato para imobilizar todas as aeronaves no hangar STR_DEPOT_MASS_START_DEPOT_TRAIN_TOOLTIP :{BLACK}Pressione botão esquerdo do rato para iniciar todos os comboios no depósito STR_DEPOT_MASS_START_DEPOT_ROAD_VEHICLE_TOOLTIP :{BLACK}Pressione botão esquerdo do rato para iniciar todos os veículos rodoviários no depósito -STR_DEPOT_MASS_START_DEPOT_SHIP_TOOLTIP :{BLACK}Pressione botão esquerdo do rato para iniciar todos os barcos no depósito +STR_DEPOT_MASS_START_DEPOT_SHIP_TOOLTIP :{BLACK}Pressione o botão esquerdo do rato para iniciar todos os navios no depósito STR_DEPOT_MASS_START_HANGAR_TOOLTIP :{BLACK}Pressione botão esquerdo do rato para iniciar todas as aeronaves no hangar STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Está prestes a vender todos os veículos no depósito. Tem a certeza? @@ -3614,13 +3642,18 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Está p # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Mensagem de um fabricante de veículos STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Projectámos um novo modelo de {STRING} - gostaria de ter um ano de exclusividade de uso deste veículo, de modo a que possamos avaliar o seu desempenho antes de o disponibilizar globalmente? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :locomotiva ferroviária -STR_ENGINE_PREVIEW_ROAD_VEHICLE :veículo rodoviário -STR_ENGINE_PREVIEW_AIRCRAFT :aeronave -STR_ENGINE_PREVIEW_SHIP :barco +STR_ENGINE_PREVIEW_ELRAIL_LOCOMOTIVE :locomotiva de caminhos-de-ferro electrificados STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :locomotiva monocarril STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :locomotiva maglev +STR_ENGINE_PREVIEW_ROAD_VEHICLE :veículo rodoviário +STR_ENGINE_PREVIEW_TRAM_VEHICLE :elétrico + +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_MAX_SPEED_CAP_RUNCOST :{BLACK}Custo: {CURRENCY_LONG} Velocidade Máx.: {VELOCITY}{}Capacidade: {CARGO_LONG}{}Custo de Circulação: {CURRENCY_LONG}/ano @@ -3633,7 +3666,7 @@ STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_RANGE_CAP_RUNCOST :{BLACK}Custo: { STR_REPLACE_VEHICLES_WHITE :{WHITE}Substituir {STRING} - {STRING} STR_REPLACE_VEHICLE_TRAIN :Comboio STR_REPLACE_VEHICLE_ROAD_VEHICLE :Veículo rodoviário -STR_REPLACE_VEHICLE_SHIP :Barco +STR_REPLACE_VEHICLE_SHIP :Navio STR_REPLACE_VEHICLE_AIRCRAFT :Aeronave STR_REPLACE_VEHICLE_VEHICLES_IN_USE :{YELLOW}Veículos em utilização @@ -3658,14 +3691,19 @@ STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK}Alternar STR_REPLACE_ENGINES :Locomotivas STR_REPLACE_WAGONS :Vagões STR_REPLACE_ALL_RAILTYPE :Todos os veículos ferroviários +STR_REPLACE_ALL_ROADTYPE :Todos os veículos rodoviários -STR_REPLACE_HELP_RAILTYPE :{BLACK}Seleccione o tipo de carril para o qual deseja efectuar a substituição dos motores +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_REPLACE_INFO_TAB :{BLACK}Exibe o tipo de motor que substituirá o que está seleccionado à esquerda, se algum STR_REPLACE_RAIL_VEHICLES :Comboios STR_REPLACE_ELRAIL_VEHICLES :Comboios eléctricos STR_REPLACE_MONORAIL_VEHICLES :Monocarris STR_REPLACE_MAGLEV_VEHICLES :Maglevs +STR_REPLACE_ROAD_VEHICLES :Veículos rodoviários +STR_REPLACE_TRAM_VEHICLES :Elétricos + STR_REPLACE_REMOVE_WAGON :{BLACK}Remover vagões: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Forçar a substituição automática a manter o comprimento do comboio, removendo vagões (do início), nas situações em que a substituição da locomotiva pode resultar num comboio mais comprido. @@ -3674,42 +3712,42 @@ STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE STR_VEHICLE_VIEW_TRAIN_LOCATION_TOOLTIP :{BLACK}Centrar visualização na localização do comboio. Ctrl+Clique segue o comboio na visualização STR_VEHICLE_VIEW_ROAD_VEHICLE_LOCATION_TOOLTIP :{BLACK}Centrar visualização na localização do veículo. Ctrl+Clique segue o veículo na visualização -STR_VEHICLE_VIEW_SHIP_LOCATION_TOOLTIP :{BLACK}Centrar visualização na localização do barco. Ctrl+Clique segue o barco na visualização +STR_VEHICLE_VIEW_SHIP_LOCATION_TOOLTIP :{BLACK}Centrar visualização na localização do navio. Ctrl+Clique segue o navio na visualização STR_VEHICLE_VIEW_AIRCRAFT_LOCATION_TOOLTIP :{BLACK}Centrar visualização na localização da aeronave. Ctrl+Clique segue a aeronave na visualização STR_VEHICLE_VIEW_TRAIN_SEND_TO_DEPOT_TOOLTIP :{BLACK}Mandar comboio para o depósito STR_VEHICLE_VIEW_ROAD_VEHICLE_SEND_TO_DEPOT_TOOLTIP :{BLACK}Mandar veículo para o depósito -STR_VEHICLE_VIEW_SHIP_SEND_TO_DEPOT_TOOLTIP :{BLACK}Mandar barco para o depósito +STR_VEHICLE_VIEW_SHIP_SEND_TO_DEPOT_TOOLTIP :{BLACK}Mandar navio para o depósito STR_VEHICLE_VIEW_AIRCRAFT_SEND_TO_DEPOT_TOOLTIP :{BLACK}Mandar aeronave para o hangar -STR_VEHICLE_VIEW_CLONE_TRAIN_INFO :{BLACK}Esta acção comprará uma cópia do comboio, incluindo as carruagens. Ctrl+Clique irá partilhar as ordens.Shift+Clique Shift + Clique mostra estimativa de custo, sem comprar -STR_VEHICLE_VIEW_CLONE_ROAD_VEHICLE_INFO :{BLACK}Esta acção comprará uma cópia do veículo. Ctrl+Clique para partilhar as ordens.Shift+Clique mostra estimativa de custo, sem comprar -STR_VEHICLE_VIEW_CLONE_SHIP_INFO :{BLACK}Esta acção comprará uma cópia do barco. Ctrl+Clique para partilhar as ordens. Shift+Clique mostra estimativa de custo, sem comprar -STR_VEHICLE_VIEW_CLONE_AIRCRAFT_INFO :{BLACK}Esta acção comprará uma cópia da aeronave. Ctrl+Clique para partilhar as ordens.Shift+Clique mostra estimativa de custo, sem comprar +STR_VEHICLE_VIEW_CLONE_TRAIN_INFO :{BLACK}Esta ação comprará uma cópia do comboio, incluindo as carruagens. Ctrl+Clique irá partilhar as ordens. Shift + Clique mostra estimativa de custo, sem comprar +STR_VEHICLE_VIEW_CLONE_ROAD_VEHICLE_INFO :{BLACK}Esta ação comprará uma cópia do veículo. Ctrl+Clique para partilhar as ordens. Shift+Clique mostra estimativa de custo, sem comprar +STR_VEHICLE_VIEW_CLONE_SHIP_INFO :{BLACK}Esta ação comprará uma cópia do navio. Ctrl+Clique para partilhar as ordens. Shift+Clique mostra estimativa de custo, sem comprar +STR_VEHICLE_VIEW_CLONE_AIRCRAFT_INFO :{BLACK}Esta ação comprará uma cópia da aeronave. Ctrl+Clique para partilhar as ordens.Shift+Clique mostra estimativa de custo, sem comprar STR_VEHICLE_VIEW_TRAIN_IGNORE_SIGNAL_TOOLTIP :{BLACK}Forçar comboio a prosseguir sem esperar pelo sinal -STR_VEHICLE_VIEW_TRAIN_REFIT_TOOLTIP :{BLACK}Converter comboio para um tipo de carga diferente -STR_VEHICLE_VIEW_ROAD_VEHICLE_REFIT_TOOLTIP :{BLACK}Reconverter veículo para transportar outro tipo de carga -STR_VEHICLE_VIEW_SHIP_REFIT_TOOLTIP :{BLACK}Adaptar barco para um tipo de carga diferente -STR_VEHICLE_VIEW_AIRCRAFT_REFIT_TOOLTIP :{BLACK}Adaptar aeronave para um tipo de carga diferente +STR_VEHICLE_VIEW_TRAIN_REFIT_TOOLTIP :{BLACK}Converter comboio para transportar outro tipo de carga +STR_VEHICLE_VIEW_ROAD_VEHICLE_REFIT_TOOLTIP :{BLACK}Converter veículo para transportar outro tipo de carga +STR_VEHICLE_VIEW_SHIP_REFIT_TOOLTIP :{BLACK}Converter navio para transportar outro tipo de carga +STR_VEHICLE_VIEW_AIRCRAFT_REFIT_TOOLTIP :{BLACK}Converter aeronave para transportar outro tipo de carga STR_VEHICLE_VIEW_TRAIN_REVERSE_TOOLTIP :{BLACK}Inverter direcção do comboio STR_VEHICLE_VIEW_ROAD_VEHICLE_REVERSE_TOOLTIP :{BLACK}Forçar veículo a dar a volta STR_VEHICLE_VIEW_TRAIN_ORDERS_TOOLTIP :{BLACK}Mostrar ordens do comboio. Ctrl+Clique para mostrar o horário do comboio STR_VEHICLE_VIEW_ROAD_VEHICLE_ORDERS_TOOLTIP :{BLACK}Mostrar ordens do veículo. Ctrl+Clique para mostrar o horário do veículo -STR_VEHICLE_VIEW_SHIP_ORDERS_TOOLTIP :{BLACK}Mostrar ordens do barco. Ctrl+Clique para mostrar o horário do barco +STR_VEHICLE_VIEW_SHIP_ORDERS_TOOLTIP :{BLACK}Mostrar ordens do navio. Ctrl+Clique para mostrar o horário do navio STR_VEHICLE_VIEW_AIRCRAFT_ORDERS_TOOLTIP :{BLACK}Mostrar ordens da aeronave. Ctrl+Clique para mostrar o horário da aeronave STR_VEHICLE_VIEW_TRAIN_SHOW_DETAILS_TOOLTIP :{BLACK}Mostrar detalhes do comboio STR_VEHICLE_VIEW_ROAD_VEHICLE_SHOW_DETAILS_TOOLTIP :{BLACK}Mostrar detalhes do veículo rodoviário -STR_VEHICLE_VIEW_SHIP_SHOW_DETAILS_TOOLTIP :{BLACK}Mostrar detalhes do barco +STR_VEHICLE_VIEW_SHIP_SHOW_DETAILS_TOOLTIP :{BLACK}Mostrar detalhes do navio STR_VEHICLE_VIEW_AIRCRAFT_SHOW_DETAILS_TOOLTIP :{BLACK}Mostrar detalhes da aeronave STR_VEHICLE_VIEW_TRAIN_STATE_START_STOP_TOOLTIP :{BLACK}Tarefa actual do comboio - clique aqui para iniciar/parar comboio. Ctrl+Clique para deslocar-se ao destino STR_VEHICLE_VIEW_ROAD_VEHICLE_STATE_START_STOP_TOOLTIP :{BLACK}Tarefa actual do veículo - clique aqui para iniciar/parar veículo. Ctrl+Clique para deslocar-se ao destino -STR_VEHICLE_VIEW_SHIP_STATE_START_STOP_TOOLTIP :{BLACK}Tarefa actual do barco - clique aqui para iniciar/parar barco. Ctrl+Clique para deslocar-se ao destino +STR_VEHICLE_VIEW_SHIP_STATE_START_STOP_TOOLTIP :{BLACK}Tarefa atual do navio - clique aqui para iniciar/parar navio. Ctrl+Clique para deslocar-se ao destino STR_VEHICLE_VIEW_AIRCRAFT_STATE_START_STOP_TOOLTIP :{BLACK}Tarefa actual da aeronave - clique aqui para iniciar/parar a aeronave. Ctrl+Clique para deslocar-se ao destino # Messages in the start stop button in the vehicle view @@ -3727,7 +3765,7 @@ STR_VEHICLE_STATUS_HEADING_FOR_STATION_VEL :{LTBLUE}Dirige- STR_VEHICLE_STATUS_NO_ORDERS_VEL :{LTBLUE}Sem ordens, {VELOCITY} STR_VEHICLE_STATUS_HEADING_FOR_WAYPOINT_VEL :{LTBLUE}Dirige-se a {WAYPOINT}, {VELOCITY} STR_VEHICLE_STATUS_HEADING_FOR_DEPOT_VEL :{ORANGE}Dirige-se para {DEPOT}, {VELOCITY} -STR_VEHICLE_STATUS_HEADING_FOR_DEPOT_SERVICE_VEL :{LTBLUE}Efectuar manutenção em {DEPOT}, {VELOCITY} +STR_VEHICLE_STATUS_HEADING_FOR_DEPOT_SERVICE_VEL :{LTBLUE}Efetuar manutenção em {DEPOT}, {VELOCITY} # Vehicle stopped/started animations STR_VEHICLE_COMMAND_STOPPED_SMALL :{TINY_FONT}{RED}Parou @@ -3741,7 +3779,7 @@ STR_VEHICLE_NAME_BUTTON :{BLACK}Nome STR_VEHICLE_DETAILS_TRAIN_RENAME :{BLACK}Renomear comboio STR_VEHICLE_DETAILS_ROAD_VEHICLE_RENAME :{BLACK}Renomear veículo rodoviário -STR_VEHICLE_DETAILS_SHIP_RENAME :{BLACK}Renomear barco +STR_VEHICLE_DETAILS_SHIP_RENAME :{BLACK}Renomear navio STR_VEHICLE_DETAILS_AIRCRAFT_RENAME :{BLACK}Renomear aeronave STR_VEHICLE_INFO_AGE_RUNNING_COST_YR :{BLACK}Idade: {LTBLUE}{STRING}{BLACK} Custo de circulação: {LTBLUE}{CURRENCY_LONG}/ano @@ -3778,7 +3816,7 @@ STR_VEHICLE_DETAILS_PERCENT :Percentagem STR_QUERY_RENAME_TRAIN_CAPTION :{WHITE}Renomear comboio STR_QUERY_RENAME_ROAD_VEHICLE_CAPTION :{WHITE}Renomear veículo rodoviário -STR_QUERY_RENAME_SHIP_CAPTION :{WHITE}Renomear barco +STR_QUERY_RENAME_SHIP_CAPTION :{WHITE}Renomear navio STR_QUERY_RENAME_AIRCRAFT_CAPTION :{WHITE}Renomear aeronave # Extra buttons for train details windows @@ -3814,18 +3852,18 @@ STR_REFIT_NEW_CAPACITY_INCOME_FROM_AIRCRAFT_REFIT :{BLACK}Nova cap STR_REFIT_SELECT_VEHICLES_TOOLTIP :{BLACK}Selecionar os veículos a readaptar. Arrastando com o rato permite selecionar vários veículos. Clicando sobre um espaço vazio irá selecionar todo o veículo. Ctrl+Clique irá selecionar um veículo e composição STR_REFIT_TRAIN_LIST_TOOLTIP :{BLACK}Seleccionar tipo de carga do comboio -STR_REFIT_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Seleccione o tipo de carga para o veículo -STR_REFIT_SHIP_LIST_TOOLTIP :{BLACK}Seleccionar tipo de carga do barco +STR_REFIT_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Selecione o tipo de carga para o veículo +STR_REFIT_SHIP_LIST_TOOLTIP :{BLACK}Selecionar tipo de carga do navio STR_REFIT_AIRCRAFT_LIST_TOOLTIP :{BLACK}Seleccionar tipo de carga da aeronave STR_REFIT_TRAIN_REFIT_BUTTON :{BLACK}Converter comboio STR_REFIT_ROAD_VEHICLE_REFIT_BUTTON :{BLACK}Reconverter veículo -STR_REFIT_SHIP_REFIT_BUTTON :{BLACK}Adaptar barco +STR_REFIT_SHIP_REFIT_BUTTON :{BLACK}Adaptar navio STR_REFIT_AIRCRAFT_REFIT_BUTTON :{BLACK}Adaptar aeronave STR_REFIT_TRAIN_REFIT_TOOLTIP :{BLACK}Converter comboio para transportar a carga seleccionada STR_REFIT_ROAD_VEHICLE_REFIT_TOOLTIP :{BLACK}Reconverter veículo para transportar o tipo de carga seleccionado -STR_REFIT_SHIP_REFIT_TOOLTIP :{BLACK}Adaptar barco para transportar a carga seleccionada +STR_REFIT_SHIP_REFIT_TOOLTIP :{BLACK}Adaptar navio para transportar a carga selecionada STR_REFIT_AIRCRAFT_REFIT_TOOLTIP :{BLACK}Converter aeronave para transportar a carga seleccionada # Order view @@ -3982,7 +4020,7 @@ STR_ORDER_CONDITIONAL_UNCONDITIONAL :Saltar para ord STR_ORDER_CONDITIONAL_NUM :Saltar para ordem {COMMA} quando {STRING} {STRING} {COMMA} STR_ORDER_CONDITIONAL_TRUE_FALSE :Saltar para ordem {COMMA} quando {STRING} {STRING} -STR_INVALID_ORDER :{RED} (Ordem Inválida) +STR_INVALID_ORDER :{RED} (Ordem inválida) # Time table window STR_TIMETABLE_TITLE :{WHITE}{VEHICLE} (Horário) @@ -4024,10 +4062,10 @@ STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Muda o e STR_TIMETABLE_CLEAR_TIME :{BLACK}Apagar Tempo STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Apagar o tempo que dura a ordem seleccionada -STR_TIMETABLE_CHANGE_SPEED :{BLACK}Alterar Limite de Velocidade +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_CLEAR_SPEED :{BLACK}Apagar Limite de Velocidade +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_RESET_LATENESS :{BLACK}Apagar Contador Atraso @@ -4054,14 +4092,14 @@ STR_DATE_YEAR_TOOLTIP :{BLACK}Seleccio # AI debug window -STR_AI_DEBUG :{WHITE}Depuração de IA/Script de Jogo +STR_AI_DEBUG :{WHITE}Depuração de IA/Script de jogo STR_AI_DEBUG_NAME_AND_VERSION :{BLACK}{STRING} (v{NUM}) STR_AI_DEBUG_NAME_TOOLTIP :{BLACK}Nome do script STR_AI_DEBUG_SETTINGS :{BLACK}Definições STR_AI_DEBUG_SETTINGS_TOOLTIP :{BLACK}Alterar as definições do script STR_AI_DEBUG_RELOAD :{BLACK}Recarregar IA STR_AI_DEBUG_RELOAD_TOOLTIP :{BLACK}Termina a IA, recarrega o script e reinicia a IA -STR_AI_DEBUG_BREAK_STR_ON_OFF_TOOLTIP :{BLACK}Activar/desactivar paragem quando o registo da IA for igual à string de paragem +STR_AI_DEBUG_BREAK_STR_ON_OFF_TOOLTIP :{BLACK}Ativar/Desativar paragem quando o registo da IA for igual à string de paragem STR_AI_DEBUG_BREAK_ON_LABEL :{BLACK}Parar em: STR_AI_DEBUG_BREAK_STR_OSKTITLE :{BLACK}Parar em STR_AI_DEBUG_BREAK_STR_TOOLTIP :{BLACK}Quando a mensagem do registo da IA for igual a esta string, o jogo é posto em pausa @@ -4070,33 +4108,33 @@ STR_AI_DEBUG_MATCH_CASE_TOOLTIP :{BLACK}Alternar STR_AI_DEBUG_CONTINUE :{BLACK}Continuar STR_AI_DEBUG_CONTINUE_TOOLTIP :{BLACK}Sair da pausa e continuar a IA STR_AI_DEBUG_SELECT_AI_TOOLTIP :{BLACK}Ver saída de depuração desta IA -STR_AI_GAME_SCRIPT :{BLACK}Script de Jogo -STR_AI_GAME_SCRIPT_TOOLTIP :{BLACK}Verifique o registo do Script de Jogo +STR_AI_GAME_SCRIPT :{BLACK}Script de jogo +STR_AI_GAME_SCRIPT_TOOLTIP :{BLACK}Verifique o registo do Script de jogo STR_ERROR_AI_NO_AI_FOUND :Não foi encontrada IA adequada para carregar.{}Esta IA é um pacote vazio e não fará nada.{}Pode descarregar várias IA através do sistema 'Conteúdo Online' STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Houve um erro num script. Por favor reporte isto ao autor do script com uma imagem da janela Depuramento de IA/Scripts de Jogo. -STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}A janela Depuração da IA/Scripts de Jogo está disponível apenas para o servidor +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_GAMELIST_TOOLTIP :{BLACK}O Script de Jogo que será carregado no próximo jogo +STR_AI_CONFIG_CAPTION :{WHITE}Configuração IA/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_RANDOM_AI :IA aleatória STR_AI_CONFIG_NONE :(nenhum) -STR_AI_CONFIG_MOVE_UP :{BLACK}Mover para Cima +STR_AI_CONFIG_MOVE_UP :{BLACK}Mover para cima STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Move a IA seleccionada para cima -STR_AI_CONFIG_MOVE_DOWN :{BLACK}Mover para Baixo +STR_AI_CONFIG_MOVE_DOWN :{BLACK}Mover para baixo 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 :{SILVER}Script de jogo 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_GAMESCRIPT :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 @@ -4104,7 +4142,7 @@ STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}Configur # Available AIs window STR_AI_LIST_CAPTION :{WHITE}Disponível {STRING} STR_AI_LIST_CAPTION_AI :IAs -STR_AI_LIST_CAPTION_GAMESCRIPT :Scripts de Jogo +STR_AI_LIST_CAPTION_GAMESCRIPT :Scripts de jogo STR_AI_LIST_TOOLTIP :{BLACK}Clique para seleccionar um script STR_AI_LIST_AUTHOR :{LTBLUE}Autor: {ORANGE}{STRING} @@ -4116,10 +4154,11 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Seleccio STR_AI_LIST_CANCEL :{BLACK}Cancelar STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Não mudar o script + # AI 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} @@ -4165,9 +4204,9 @@ STR_MESSAGE_ESTIMATED_INCOME :{WHITE}Lucro Es STR_ERROR_SAVE_STILL_IN_PROGRESS :{WHITE}Gravação ainda em curso,{}por favor aguarde! STR_ERROR_AUTOSAVE_FAILED :{WHITE}Falha ao guardar automaticamente STR_ERROR_UNABLE_TO_READ_DRIVE :{BLACK}Não é possível ler unidade -STR_ERROR_GAME_SAVE_FAILED :{WHITE}Falha ao Guardar Jogo{}{STRING} +STR_ERROR_GAME_SAVE_FAILED :{WHITE}Falha ao guardar jogo{}{STRING} STR_ERROR_UNABLE_TO_DELETE_FILE :{WHITE}Não é possível eliminar ficheiro -STR_ERROR_GAME_LOAD_FAILED :{WHITE}Falha ao Abrir Jogo{}{STRING} +STR_ERROR_GAME_LOAD_FAILED :{WHITE}Falha ao abrir jogo{}{STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR :Erro interno: {STRING} STR_GAME_SAVELOAD_ERROR_BROKEN_SAVEGAME :Ficheiro corrompido - {STRING} STR_GAME_SAVELOAD_ERROR_TOO_NEW_SAVEGAME :Jogo gravado numa versão mais recente do jogo @@ -4175,7 +4214,7 @@ STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE :Impossível ler STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE :Impossível escrever ficheiro STR_GAME_SAVELOAD_ERROR_DATA_INTEGRITY_CHECK_FAILED :Falha ao verificar integridade de dados STR_GAME_SAVELOAD_NOT_AVAILABLE : -STR_WARNING_LOADGAME_REMOVED_TRAMS :{WHITE}O jogo foi salvo numa versão sem suporte a eléctricos. Todos os eléctricos foram removidos. +STR_WARNING_LOADGAME_REMOVED_TRAMS :{WHITE}O jogo foi salvo numa versão sem suporte para eléctricos. Todos os elétricos foram removidos. # Map generation messages STR_ERROR_COULD_NOT_CREATE_TOWN :{WHITE}Geração de mapa abortada...{}... não há locais apropriados para localidades @@ -4318,7 +4357,6 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... esta STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... estrada orientada na direcção incorrecta STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... estações de passagem não podem ter curvas STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... estações de passagem não podem ter cruzamentos -STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... estrada de sentido único ou bloqueada # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Não é possível remover parte da estação... @@ -4388,7 +4426,8 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Deverá STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Tipo de linha não apropriado STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Deverá remover a linha férrea primeiro STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Estrada de sentido único ou bloqueada -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Passagens de nível não são permitidas para este tipo de linha +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Passagens de nível não são permitidas para este tipo de linha +STR_ERROR_CROSSING_DISALLOWED_ROAD :{WHITE}Passagens de nível não são permitidas para este tipo de estrada STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Não é possível construir sinais aqui... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Não é possível construir linha férrea aqui... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Não é possível remover linha férrea daqui... @@ -4408,6 +4447,10 @@ STR_ERROR_CAN_T_REMOVE_ROAD_FROM :{WHITE}Não é STR_ERROR_CAN_T_REMOVE_TRAMWAY_FROM :{WHITE}Não é possível remover carris para eléctricos deste local... STR_ERROR_THERE_IS_NO_ROAD :{WHITE}... não há estrada STR_ERROR_THERE_IS_NO_TRAMWAY :{WHITE}... não há carris para eléctricos +STR_ERROR_CAN_T_CONVERT_ROAD :{WHITE}Não é possível converter aqui o tipo de estrada... +STR_ERROR_CAN_T_CONVERT_TRAMWAY :{WHITE}Não é possível converter aqui o tipo de carril para eléctricos... +STR_ERROR_INCOMPATIBLE_ROAD :{WHITE}... estrada não-compatível +STR_ERROR_INCOMPATIBLE_TRAMWAY :Cisterna de bebida de cola # Waterway construction errors STR_ERROR_CAN_T_BUILD_CANALS :{WHITE}Não é possível construir canais aqui... @@ -4460,6 +4503,7 @@ STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Impossí STR_ERROR_GROUP_CAN_T_DELETE :{WHITE}Impossível remover este grupo... STR_ERROR_GROUP_CAN_T_RENAME :{WHITE}Impossível renomear o grupo... STR_ERROR_GROUP_CAN_T_SET_PARENT :{WHITE}Não é possível definir grupo parente... +STR_ERROR_GROUP_CAN_T_SET_PARENT_RECURSION :{WHITE}... não são permitidos ciclos na hierarquia de grupos STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}Não é possível remover todos os veículos deste grupo... STR_ERROR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}Impossível adicionar o veículo a este grupo... STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}Impossível adicionar veículos com ordens partilhadas ao grupo... @@ -4467,47 +4511,47 @@ STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}Impossí # Generic vehicle errors STR_ERROR_TRAIN_IN_THE_WAY :{WHITE}Comboio no caminho STR_ERROR_ROAD_VEHICLE_IN_THE_WAY :{WHITE}Veículo rodoviário no caminho -STR_ERROR_SHIP_IN_THE_WAY :{WHITE}Barco no caminho +STR_ERROR_SHIP_IN_THE_WAY :{WHITE}Navio no caminho STR_ERROR_AIRCRAFT_IN_THE_WAY :{WHITE}Aeronave no caminho STR_ERROR_CAN_T_REFIT_TRAIN :{WHITE}Não é possível converter comboio... STR_ERROR_CAN_T_REFIT_ROAD_VEHICLE :{WHITE}Não é possível reconverter veículo -STR_ERROR_CAN_T_REFIT_SHIP :{WHITE}Não é possível adaptar barco... +STR_ERROR_CAN_T_REFIT_SHIP :{WHITE}Não é possível adaptar navio... STR_ERROR_CAN_T_REFIT_AIRCRAFT :{WHITE}Não é possível converter aeronave... STR_ERROR_CAN_T_RENAME_TRAIN :{WHITE}Não é possível renomear comboio... STR_ERROR_CAN_T_RENAME_ROAD_VEHICLE :{WHITE}Não é possível renomear veículo rodoviário... -STR_ERROR_CAN_T_RENAME_SHIP :{WHITE}Não é possível renomear barco... +STR_ERROR_CAN_T_RENAME_SHIP :{WHITE}Não é possível renomear navio... STR_ERROR_CAN_T_RENAME_AIRCRAFT :{WHITE}Não é possível renomear aeronave... STR_ERROR_CAN_T_STOP_START_TRAIN :{WHITE}Não é possível iniciar/parar comboio... STR_ERROR_CAN_T_STOP_START_ROAD_VEHICLE :{WHITE}Não é possível iniciar/parar veículo rodoviário... -STR_ERROR_CAN_T_STOP_START_SHIP :{WHITE}Não é possível iniciar/parar barco... +STR_ERROR_CAN_T_STOP_START_SHIP :{WHITE}Não é possível iniciar/parar navio... STR_ERROR_CAN_T_STOP_START_AIRCRAFT :{WHITE}Não é possível iniciar/parar aeronave... STR_ERROR_CAN_T_SEND_TRAIN_TO_DEPOT :{WHITE}Não é possível mandar o comboio para o depósito... STR_ERROR_CAN_T_SEND_ROAD_VEHICLE_TO_DEPOT :{WHITE}Não é possível mandar o veículo para o depósito... -STR_ERROR_CAN_T_SEND_SHIP_TO_DEPOT :{WHITE}Não é possível mandar barco para o depósito... +STR_ERROR_CAN_T_SEND_SHIP_TO_DEPOT :{WHITE}Não é possível mandar navio para o depósito... STR_ERROR_CAN_T_SEND_AIRCRAFT_TO_HANGAR :{WHITE}Não é possível mandar aeronave para o hangar... STR_ERROR_CAN_T_BUY_TRAIN :{WHITE}Não é possível comprar veículo ferroviário... STR_ERROR_CAN_T_BUY_ROAD_VEHICLE :{WHITE}Não é possível comprar veículo rodoviário... -STR_ERROR_CAN_T_BUY_SHIP :{WHITE}Não é possível comprar barco... +STR_ERROR_CAN_T_BUY_SHIP :{WHITE}Não é possível comprar navio... STR_ERROR_CAN_T_BUY_AIRCRAFT :{WHITE}Não é possível comprar aeronave... STR_ERROR_CAN_T_RENAME_TRAIN_TYPE :{WHITE}Não é possível renomear tipo de veículo ferroviário... STR_ERROR_CAN_T_RENAME_ROAD_VEHICLE_TYPE :{WHITE}Não é possível renomear tipo de veículo rodoviário... -STR_ERROR_CAN_T_RENAME_SHIP_TYPE :{WHITE}Não é possível renomear tipo de barco... +STR_ERROR_CAN_T_RENAME_SHIP_TYPE :{WHITE}Não é possível renomear tipo de navio... STR_ERROR_CAN_T_RENAME_AIRCRAFT_TYPE :{WHITE}Não é possível renomear tipo de aeronave... STR_ERROR_CAN_T_SELL_TRAIN :{WHITE}Não é possível vender veículo ferroviário... STR_ERROR_CAN_T_SELL_ROAD_VEHICLE :{WHITE}Não é possível vender veículo rodoviário... -STR_ERROR_CAN_T_SELL_SHIP :{WHITE}Não é possível vender barco... +STR_ERROR_CAN_T_SELL_SHIP :{WHITE}Não é possível vender navio... STR_ERROR_CAN_T_SELL_AIRCRAFT :{WHITE}Não é possível vender aeronave... STR_ERROR_RAIL_VEHICLE_NOT_AVAILABLE :{WHITE}Veículo não está disponível STR_ERROR_ROAD_VEHICLE_NOT_AVAILABLE :{WHITE}Veículo não está disponível -STR_ERROR_SHIP_NOT_AVAILABLE :{WHITE}Barco não está disponível +STR_ERROR_SHIP_NOT_AVAILABLE :{WHITE}Navio não está disponível STR_ERROR_AIRCRAFT_NOT_AVAILABLE :{WHITE}Aeronave não está disponível STR_ERROR_TOO_MANY_VEHICLES_IN_GAME :{WHITE}Existem demasiados veículos em jogo @@ -4570,8 +4614,8 @@ STR_BASESOUNDS_DOS_DESCRIPTION :Sons originais STR_BASESOUNDS_WIN_DESCRIPTION :Sons originais da edição Windows de Transport Tycoon Deluxe. STR_BASESOUNDS_NONE_DESCRIPTION :Um conjunto de sons vazio. STR_BASEMUSIC_WIN_DESCRIPTION :Música original da edição Windows de Transport Tycoon Deluxe. -STR_BASEMUSIC_DOS_DESCRIPTION :Música original da edição DOS do Transport Tycoon Deluxe. -STR_BASEMUSIC_TTO_DESCRIPTION :Música original da edição DOS do Transport Tycoon (Original/Editor de Mundo) +STR_BASEMUSIC_DOS_DESCRIPTION :Música original da edição DOS de Transport Tycoon Deluxe. +STR_BASEMUSIC_TTO_DESCRIPTION :Música original da edição DOS de Transport Tycoon (Original/Editor de Mundo) STR_BASEMUSIC_NONE_DESCRIPTION :Um conjunto de música vazio. ##id 0x2000 @@ -4641,11 +4685,11 @@ STR_INDUSTRY_NAME_LUMBER_MILL :{G=f}Serração STR_INDUSTRY_NAME_COTTON_CANDY_FOREST :{G=f}Floresta de Algodão Doce STR_INDUSTRY_NAME_CANDY_FACTORY :{G=f}Fábrica de Doces STR_INDUSTRY_NAME_BATTERY_FARM :{G=m}Campo de Baterias -STR_INDUSTRY_NAME_COLA_WELLS :{G=mp}Poços de Cola +STR_INDUSTRY_NAME_COLA_WELLS :{G=mp}Poços de bebida de cola STR_INDUSTRY_NAME_TOY_SHOP :{G=f}Loja de Brinquedos STR_INDUSTRY_NAME_TOY_FACTORY :{G=f}Fábrica de Brinquedos STR_INDUSTRY_NAME_PLASTIC_FOUNTAINS :{G=fp}Fontes de Plástico -STR_INDUSTRY_NAME_FIZZY_DRINK_FACTORY :{G=f}Fábrica de Bebidas Gasosas +STR_INDUSTRY_NAME_FIZZY_DRINK_FACTORY :{G=f}Fábrica de refrigerantes STR_INDUSTRY_NAME_BUBBLE_GENERATOR :{G=m}Produtor de Bolhas STR_INDUSTRY_NAME_TOFFEE_QUARRY :{G=f}Exploração de Caramelo STR_INDUSTRY_NAME_SUGAR_MINE :{G=f}Mina de Açúcar @@ -4657,7 +4701,7 @@ STR_SV_EMPTY : STR_SV_UNNAMED :Sem nome STR_SV_TRAIN_NAME :Comboio {COMMA} STR_SV_ROAD_VEHICLE_NAME :Veículo Rodoviário {COMMA} -STR_SV_SHIP_NAME :Barco {COMMA} +STR_SV_SHIP_NAME :Navio {COMMA} STR_SV_AIRCRAFT_NAME :Aeronave {COMMA} STR_SV_STNAME :{STRING} @@ -4719,33 +4763,33 @@ STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_SH_30_ELECTRIC :SH '30' (Eléct STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_SH_40_ELECTRIC :SH '40' (Eléctrico) STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_T_I_M_ELECTRIC :'T.I.M.' (Eléctrico) STR_VEHICLE_NAME_TRAIN_ENGINE_RAIL_ASIASTAR_ELECTRIC :'AsiaStar' (Eléctrico) -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_PASSENGER_CAR :Carruagem de Passageiros +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_PASSENGER_CAR :Carruagem de passageiros STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_MAIL_VAN :Vagão de Correio STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_COAL_CAR :Vagão de Carvão STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_OIL_TANKER :Cisterna de Petróleo STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_LIVESTOCK_VAN :Vagão de Gado STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_GOODS_VAN :Vagão de Bens STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_GRAIN_HOPPER :Vagão de Cereais -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_WOOD_TRUCK :Vagão de Madeira +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_WOOD_TRUCK :Vagão de madeira STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_IRON_ORE_HOPPER :Vagão de Minério de Ferro -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_STEEL_TRUCK :Vagão de Aço +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_STEEL_TRUCK :Vagão de aço STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_ARMORED_VAN :Vagão Blindado STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_FOOD_VAN :Vagão Alimentar STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_PAPER_TRUCK :Vagão de Papel STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_COPPER_ORE_HOPPER :Vagão de Minério de Cobre -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_WATER_TANKER :Cisterna de Água +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_WATER_TANKER :Cisterna de água STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_FRUIT_TRUCK :Vagão de Fruta -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_RUBBER_TRUCK :Vagão de Borracha -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_SUGAR_TRUCK :Vagão de Açúcar +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_RUBBER_TRUCK :Vagão de borracha +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_SUGAR_TRUCK :Vagão de açúcar STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_COTTON_CANDY_HOPPER :Vagão de Algodão Doce -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_TOFFEE_HOPPER :Vagão de Caramelo +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_TOFFEE_HOPPER :Vagão de caramelo STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_BUBBLE_VAN :Vagão de Bolhas -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_COLA_TANKER :Cisterna de Cola +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_COLA_TANKER :Cisterna de bebida de cola STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_CANDY_VAN :Vagão de Doces STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_TOY_VAN :Vagão de Brinquedos STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_BATTERY_TRUCK :Vagão de Baterias -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_FIZZY_DRINK_TRUCK :Vagão de Bebidas Gasosas -STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_PLASTIC_TRUCK :Vagão de Plástico +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_FIZZY_DRINK_TRUCK :Vagão de refrigerantes +STR_VEHICLE_NAME_TRAIN_WAGON_RAIL_PLASTIC_TRUCK :Vagão de plástico STR_VEHICLE_NAME_TRAIN_ENGINE_MONORAIL_X2001_ELECTRIC :'X2001' (Eléctrico) STR_VEHICLE_NAME_TRAIN_ENGINE_MONORAIL_MILLENNIUM_Z1_ELECTRIC :'Millennium Z1' (Eléctrico) STR_VEHICLE_NAME_TRAIN_ENGINE_MONORAIL_WIZZOWOW_Z99 :Wizzowow Z99 @@ -4770,11 +4814,11 @@ STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_SUGAR_TRUCK :Vagão de Açú STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_COTTON_CANDY_HOPPER :Vagão de Algodão Doce STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_TOFFEE_HOPPER :Vagão de Caramelo STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_BUBBLE_VAN :Vagão de Bolhas -STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_COLA_TANKER :Cisterna de Cola +STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_COLA_TANKER :Cisterna de beibda de cola STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_CANDY_VAN :Vagão de Doces STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_TOY_VAN :Vagão de Brinquedos STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_BATTERY_TRUCK :Vagão de Baterias -STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_FIZZY_DRINK_TRUCK :Vagão de Bebidas Gasosas +STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_FIZZY_DRINK_TRUCK :Vagão de refrigerantes STR_VEHICLE_NAME_TRAIN_WAGON_MONORAIL_PLASTIC_TRUCK :Vagão de Plástico STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_LEV1_LEVIATHAN_ELECTRIC :Lev1 'Leviathan' (Eléctrico) STR_VEHICLE_NAME_TRAIN_ENGINE_MAGLEV_LEV2_CYCLOPS_ELECTRIC :Lev2 'Cyclops' (Eléctrico) @@ -4802,11 +4846,11 @@ STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_SUGAR_TRUCK :Vagão de Açú STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_COTTON_CANDY_HOPPER :Vagão de Algodão Doce STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_TOFFEE_HOPPER :Vagão de Caramelo STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_BUBBLE_VAN :Vagão de Bolhas -STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_COLA_TANKER :Cisterna de Cola +STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_COLA_TANKER :Cisterna de bebida de cola STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_CANDY_VAN :Vagão de Doces STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_TOY_VAN :Vagão de Brinquedos STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_BATTERY_TRUCK :Vagão de Baterias -STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_FIZZY_DRINK_TRUCK :Vagão de Bebidas Gasosas +STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_FIZZY_DRINK_TRUCK :Vagão de refrigerantes STR_VEHICLE_NAME_TRAIN_WAGON_MAGLEV_PLASTIC_TRUCK :Vagão de Plástico STR_VEHICLE_NAME_ROAD_VEHICLE_MPS_REGAL_BUS :Autocarro MPS Regal STR_VEHICLE_NAME_ROAD_VEHICLE_HEREFORD_LEOPARD_BUS :Autocarro Hereford Leopard @@ -4869,9 +4913,9 @@ STR_VEHICLE_NAME_ROAD_VEHICLE_RMT_RUBBER_TRUCK :Camião de Borr STR_VEHICLE_NAME_ROAD_VEHICLE_MIGHTYMOVER_SUGAR_TRUCK :Camião de Açúcar MightyMover STR_VEHICLE_NAME_ROAD_VEHICLE_POWERNAUGHT_SUGAR_TRUCK :Camião de Açúcar Powernaught STR_VEHICLE_NAME_ROAD_VEHICLE_WIZZOWOW_SUGAR_TRUCK :Camião de Açúcar Wizzowow -STR_VEHICLE_NAME_ROAD_VEHICLE_MIGHTYMOVER_COLA_TRUCK :Camião de Cola MightyMover -STR_VEHICLE_NAME_ROAD_VEHICLE_POWERNAUGHT_COLA_TRUCK :Camião de Cola Powernaught -STR_VEHICLE_NAME_ROAD_VEHICLE_WIZZOWOW_COLA_TRUCK :Camião de Cola Wizzowow +STR_VEHICLE_NAME_ROAD_VEHICLE_MIGHTYMOVER_COLA_TRUCK :Camião de bebida de cola MightyMover +STR_VEHICLE_NAME_ROAD_VEHICLE_POWERNAUGHT_COLA_TRUCK :Camião de bebida de cola Powernaught +STR_VEHICLE_NAME_ROAD_VEHICLE_WIZZOWOW_COLA_TRUCK :Camião de bebida de cola Wizzowow STR_VEHICLE_NAME_ROAD_VEHICLE_MIGHTYMOVER_COTTON_CANDY :Camião de Algodão Doce MightyMover STR_VEHICLE_NAME_ROAD_VEHICLE_POWERNAUGHT_COTTON_CANDY :Camião de Algodão Doce Powernaught STR_VEHICLE_NAME_ROAD_VEHICLE_WIZZOWOW_COTTON_CANDY_TRUCK :Camião de Algodão Doce Wizzowow @@ -4887,9 +4931,9 @@ STR_VEHICLE_NAME_ROAD_VEHICLE_WIZZOWOW_CANDY_TRUCK :Camião de Doce STR_VEHICLE_NAME_ROAD_VEHICLE_MIGHTYMOVER_BATTERY_TRUCK :Camião de Baterias MightyMover STR_VEHICLE_NAME_ROAD_VEHICLE_POWERNAUGHT_BATTERY_TRUCK :Camião de Baterias Powernaught STR_VEHICLE_NAME_ROAD_VEHICLE_WIZZOWOW_BATTERY_TRUCK :Camião de Baterias Wizzowow -STR_VEHICLE_NAME_ROAD_VEHICLE_MIGHTYMOVER_FIZZY_DRINK :Camião de Bebidas Gasosas MightyMover -STR_VEHICLE_NAME_ROAD_VEHICLE_POWERNAUGHT_FIZZY_DRINK :Camião de Bebidas Gasosas Powernaught -STR_VEHICLE_NAME_ROAD_VEHICLE_WIZZOWOW_FIZZY_DRINK_TRUCK :Camião de Bebidas Gasosas Wizzowow +STR_VEHICLE_NAME_ROAD_VEHICLE_MIGHTYMOVER_FIZZY_DRINK :Camião de refrigerantes MightyMover +STR_VEHICLE_NAME_ROAD_VEHICLE_POWERNAUGHT_FIZZY_DRINK :Camião de refrigerantes Powernaught +STR_VEHICLE_NAME_ROAD_VEHICLE_WIZZOWOW_FIZZY_DRINK_TRUCK :Camião de refrigerantes Wizzowow STR_VEHICLE_NAME_ROAD_VEHICLE_MIGHTYMOVER_PLASTIC_TRUCK :Camião de Plástico MightyMover STR_VEHICLE_NAME_ROAD_VEHICLE_POWERNAUGHT_PLASTIC_TRUCK :Camião de Plástico Powernaught STR_VEHICLE_NAME_ROAD_VEHICLE_WIZZOWOW_PLASTIC_TRUCK :Camião de Plástico Wizzowow @@ -4898,15 +4942,15 @@ STR_VEHICLE_NAME_ROAD_VEHICLE_POWERNAUGHT_BUBBLE_TRUCK :Camião de Bolh STR_VEHICLE_NAME_ROAD_VEHICLE_WIZZOWOW_BUBBLE_TRUCK :Camião de Bolhas Wizzowow STR_VEHICLE_NAME_SHIP_MPS_OIL_TANKER :Cisterna de Petróleo MPS STR_VEHICLE_NAME_SHIP_CS_INC_OIL_TANKER :Cisterna de Petróleo CS-Inc. -STR_VEHICLE_NAME_SHIP_MPS_PASSENGER_FERRY :Barco de Passageiros MPS -STR_VEHICLE_NAME_SHIP_FFP_PASSENGER_FERRY :Barco de Passageiros FFP +STR_VEHICLE_NAME_SHIP_MPS_PASSENGER_FERRY :Navio de passageiros MPS +STR_VEHICLE_NAME_SHIP_FFP_PASSENGER_FERRY :Navio de passageiros FFP STR_VEHICLE_NAME_SHIP_BAKEWELL_300_HOVERCRAFT :Hovercraft Bakewell 300 -STR_VEHICLE_NAME_SHIP_CHUGGER_CHUG_PASSENGER :Barco de Passageiros Chugger-Chug -STR_VEHICLE_NAME_SHIP_SHIVERSHAKE_PASSENGER_FERRY :Barco de Passageiros Shivershake -STR_VEHICLE_NAME_SHIP_YATE_CARGO_SHIP :Barco de Mercadorias Yate -STR_VEHICLE_NAME_SHIP_BAKEWELL_CARGO_SHIP :Barco de Mercadorias Bakewell -STR_VEHICLE_NAME_SHIP_MIGHTYMOVER_CARGO_SHIP :Barco de Mercadorias MightyMover -STR_VEHICLE_NAME_SHIP_POWERNAUT_CARGO_SHIP :Barco de Mercadorias Powernaut +STR_VEHICLE_NAME_SHIP_CHUGGER_CHUG_PASSENGER :Navio de passageiros Chugger-Chug +STR_VEHICLE_NAME_SHIP_SHIVERSHAKE_PASSENGER_FERRY :Navio de passageiros Shivershake +STR_VEHICLE_NAME_SHIP_YATE_CARGO_SHIP :Navio de mercadorias Yate +STR_VEHICLE_NAME_SHIP_BAKEWELL_CARGO_SHIP :Navio de mercadorias Bakewell +STR_VEHICLE_NAME_SHIP_MIGHTYMOVER_CARGO_SHIP :Navio de carga MightyMover +STR_VEHICLE_NAME_SHIP_POWERNAUT_CARGO_SHIP :Navio de carga Powernaut STR_VEHICLE_NAME_AIRCRAFT_SAMPSON_U52 :Sampson U52 STR_VEHICLE_NAME_AIRCRAFT_COLEMAN_COUNT :Coleman Count STR_VEHICLE_NAME_AIRCRAFT_FFP_DART :FFP Dart @@ -5069,5 +5113,3 @@ STR_PLANE :{BLACK}{PLANE} STR_SHIP :{BLACK}{SHIP} STR_TOOLBAR_RAILTYPE_VELOCITY :{STRING} ({VELOCITY}) - -# Android strings diff --git a/src/lang/romanian.txt b/src/lang/romanian.txt index 0852d415e6..478b273082 100644 --- a/src/lang/romanian.txt +++ b/src/lang/romanian.txt @@ -10,8 +10,6 @@ ##grflangid 0x28 -# $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. # 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. @@ -472,9 +470,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Consolă pornit/oprit STR_ABOUT_MENU_AI_DEBUG :Depanare Inteligenţă Artificială / Script Joc STR_ABOUT_MENU_SCREENSHOT :Capturează ecranul -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Captură mărită -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Mărimea implicită a capturii -STR_ABOUT_MENU_GIANT_SCREENSHOT :Capturează toată harta STR_ABOUT_MENU_SHOW_FRAMERATE :Arată FPS STR_ABOUT_MENU_ABOUT_OPENTTD :Despre 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Aliniere imagini @@ -645,9 +640,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Personale 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Volumul muzicii STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Volumul efectelor sonore -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}MIN -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}MAX -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -860,6 +852,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}Un nou tip de {STRING} este acum disponibil! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} nu mai acceptă {STRING} STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} nu mai acceptă {STRING} sau {STRING} STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} acceptă acum {STRING} @@ -1665,7 +1658,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Distrib STR_CONFIG_SETTING_AI :{ORANGE}Concurenţi STR_CONFIG_SETTING_AI_NPC :{ORANGE}Jucători virtuali -STR_CONFIG_SETTING_PATHFINDER_OPF :Original STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Recomandat) @@ -1748,13 +1740,9 @@ STR_QUIT_NO :{BLACK}Nu # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -2383,6 +2371,7 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Construi STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Comutator pentru construcţie/înlăturare şosele STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Comută construcţie/înlăturare pentru şine de tramvai + # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Orientarea autobazei STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}Alege orientarea autobazei @@ -3244,8 +3233,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Infrastr STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Pătrățele de cale ferată: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Semnale STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Pătrățele cu drumuri: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Drumuri -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Tramvaie STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Suprafață apă: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Canale STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Stații: @@ -3256,8 +3243,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Industrii STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Nimic- -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% transportat) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% transportat) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Numele industriilor - clic pe nume pentru focalizarea pe industrie. Ctrl+Click deschide o fereastră cu locaţia industriei @@ -3319,6 +3304,7 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Vehicule rutier STR_GROUP_DEFAULT_SHIPS :Nave negrupate STR_GROUP_DEFAULT_AIRCRAFTS :Aeronave negrupate + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Grupuri - click pe un grup pentru lista completă a vehiculelor acestuia STR_GROUP_CREATE_TOOLTIP :{BLACK}Click pentru a creea un grup STR_GROUP_DELETE_TOOLTIP :{BLACK}Şterge grupul selectat @@ -3343,10 +3329,13 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Noi Vehicule El STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Noi vehicule monoşină STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Noi vehicule pe Pernă Magnetică -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Vehicule pe şine STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Autovehicule noi + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Vehicule pe şine STR_BUY_VEHICLE_SHIP_CAPTION :Nave noi STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Aeronavă nouă +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Cost: {GOLD}{CURRENCY_LONG}{BLACK} Greutate: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Viteză: {GOLD}{VELOCITY}{BLACK} Putere: {GOLD}{POWER} @@ -3379,11 +3368,13 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Cumpăr STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Cumpără navă STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Cumpără aeronavă + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Cumpără vehiculul feroviar selectat. Shift+Click arată costul estimat fără să cumpere vehiculul STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Cumpără autovehiculul selectat. Shift+Click arată costul estimat fără să cumpere autovehiculul STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Cumpără nava selectată. Shift+Click arată costul estimativ fără a efectua achiziţia STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Cumpără aeronava selectată. Shift+Click arată costul estimativ fără a efectua achiziţia + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Nume nou STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Nume nou STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Nume nou @@ -3492,13 +3483,16 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Eşti p # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Mesaj de la producătorul de vehicule STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Am creat un nou tip de {STRING}. Aţi fi interesaţi de folosirea exclusivă pentru un an a acestui vehicul, astfel ca noi să-i putem observa performanţele înaintea lansării oficiale? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :locomotivă -STR_ENGINE_PREVIEW_ROAD_VEHICLE :autovehicul -STR_ENGINE_PREVIEW_AIRCRAFT :aeronavă -STR_ENGINE_PREVIEW_SHIP :navă STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :locomotivă monoşină STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :locomotivă pernă magnetică +STR_ENGINE_PREVIEW_ROAD_VEHICLE :autovehicul + +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}{}Cost de rulare: {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}{}Cost rulaj: {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 @@ -3540,6 +3534,7 @@ STR_REPLACE_ELRAIL_VEHICLES :Vehicule Electr STR_REPLACE_MONORAIL_VEHICLES :Vehicule Monorail STR_REPLACE_MAGLEV_VEHICLES :Vehicule Pernă Magnetică + STR_REPLACE_REMOVE_WAGON :{BLACK}Retragere vagoane: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Fă optiunea de autoînlocuire să păstreze identică lungimea unui tren prin eliminarea vagoanelor (începând din faţă) dacă înlocuirea locomotivei ar face trenul mai lung @@ -3985,6 +3980,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Alege sc STR_AI_LIST_CANCEL :{BLACK}Anulează STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Nu schimba scriptul + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parametrii STR_AI_SETTINGS_CAPTION_AI :IA @@ -4255,7 +4251,7 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Trebuie STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Cale ferată nepotrivită STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Mai întâi trebuie înlăturată calea ferată STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Drum cu sens unic sau blocat -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Trecerea la nivel nu este permisă pentru acest tip de cale ferată +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Trecerea la nivel nu este permisă pentru acest tip de cale ferată STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Nu se pot plasa semafoare aici... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Nu se poate construi cale ferată aici... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Nu se poate înlătura calea ferată... diff --git a/src/lang/russian.txt b/src/lang/russian.txt index 65f0cf92c1..fdc010f792 100644 --- a/src/lang/russian.txt +++ b/src/lang/russian.txt @@ -12,8 +12,6 @@ ##case m f n p nom gen dat acc abl pre -# $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. # 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. @@ -363,6 +361,8 @@ STR_TOOLTIP_FILTER_CRITERIA :{BLACK}Выбе STR_BUTTON_SORT_BY :{BLACK}Сортировка STR_BUTTON_LOCATION :{BLACK}Обзор STR_BUTTON_RENAME :{BLACK}Переименовать +STR_BUTTON_CATCHMENT :{BLACK}Охват +STR_TOOLTIP_CATCHMENT :{BLACK}Переключить подсветку участков, находящихся в зонах обслуживания станциями игрока, а также не попадающих в эти зоны. STR_TOOLTIP_CLOSE_WINDOW :{BLACK}Закрыть окно STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Окна можно перетаскивать, схватив за заголовок @@ -391,6 +391,7 @@ STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT_TOOLTIP :{BLACK}Если STR_BUTTON_DEFAULT :{BLACK}По умолчанию STR_BUTTON_CANCEL :{BLACK}Отмена STR_BUTTON_OK :{BLACK}OK +STR_WARNING_PASSWORD_SECURITY :{YELLOW}Внимание: администраторы сервера могут увидеть ваш пароль. # On screen keyboard window STR_OSK_KEYBOARD_LAYOUT :`1234567890-=\qwertyuiop[]asdfghjkl;' zxcvbnm,./ . @@ -410,7 +411,7 @@ STR_SORT_BY_CAPTION_DATE :{BLACK}Дата STR_SORT_BY_NAME :Название STR_SORT_BY_PRODUCTION :Производительность STR_SORT_BY_TYPE :Тип -STR_SORT_BY_TRANSPORTED :Вывоз +STR_SORT_BY_TRANSPORTED :% перевезённого STR_SORT_BY_NUMBER :Номер STR_SORT_BY_PROFIT_LAST_YEAR :Прибыль в прошлом году STR_SORT_BY_PROFIT_THIS_YEAR :Прибыль в текущем году @@ -464,6 +465,7 @@ STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN :{BLACK}Приб STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT :{BLACK}Отдалить STR_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Строительство железных дорог STR_TOOLBAR_TOOLTIP_BUILD_ROADS :{BLACK}Строительство автомобильных дорог +STR_TOOLBAR_TOOLTIP_BUILD_TRAMWAYS :{BLACK}Строительство трамвайных путей STR_TOOLBAR_TOOLTIP_BUILD_SHIP_DOCKS :{BLACK}Строительство водных коммуникаций STR_TOOLBAR_TOOLTIP_BUILD_AIRPORTS :{BLACK}Строительство аэропортов STR_TOOLBAR_TOOLTIP_LANDSCAPING :{BLACK}Открыть панель ландшафта для изменения рельефа, посадки деревьев и т.д. @@ -484,6 +486,7 @@ STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION :{BLACK}Созд STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Создание городов STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Создание предприятий STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Строительство автомобильных дорог +STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Строительство трамвайных путей STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Посадить деревья. При нажатом Shift - оценка стоимости высадки. STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Поставить метку STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Разместить объект. При нажатом Shift - оценка стоимости строительства. @@ -601,9 +604,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Консоль STR_ABOUT_MENU_AI_DEBUG :Отладка ИИ / скриптов STR_ABOUT_MENU_SCREENSHOT :Снимок экрана -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Снимок экрана в макс. приближении -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Снимок экрана в обычном масштабе -STR_ABOUT_MENU_GIANT_SCREENSHOT :Снимок всей карты STR_ABOUT_MENU_SHOW_FRAMERATE :Информация о скорости игры STR_ABOUT_MENU_ABOUT_OPENTTD :Об игре STR_ABOUT_MENU_SPRITE_ALIGNER :Выравнивание спрайтов @@ -786,9 +786,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Пользоват. 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Громкость музыки STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Громкость звука -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}МИН -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}МАКС -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -1012,6 +1009,8 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}Начато серийное производство новой модели {STRING.gen}! - {ENGINE} +STR_NEWS_SHOW_VEHICLE_GROUP_TOOLTIP :{BLACK}Открыть окно групп транспорта и выбрать группу, к которой принадлежит это транспортное средство + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} больше не принимает {STRING.acc} STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} больше не принимает {STRING.acc} и {STRING.acc} STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} теперь принимает {STRING.acc} @@ -1078,6 +1077,9 @@ STR_GAME_OPTIONS_CURRENCY_GEL :Грузинс STR_GAME_OPTIONS_CURRENCY_IRR :Иранский риал (IRR) STR_GAME_OPTIONS_CURRENCY_RUB :Российский новый рубль (RUR) STR_GAME_OPTIONS_CURRENCY_MXN :Мексиканский песо (MXN) +STR_GAME_OPTIONS_CURRENCY_NTD :Новый тайваньский доллар (NTD) +STR_GAME_OPTIONS_CURRENCY_CNY :Китайский юань (CNY) +STR_GAME_OPTIONS_CURRENCY_HKD :Гонконгский доллар (HKD) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Движение автомобилей @@ -1336,6 +1338,8 @@ STR_CONFIG_SETTING_AUTOSLOPE :Разреши 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 :Упростить снос городских зданий и инфраструктуры STR_CONFIG_SETTING_TRAIN_LENGTH :Максимальная длина состава: {STRING} @@ -1352,8 +1356,8 @@ STR_CONFIG_SETTING_TRAIN_SLOPE_STEEPNESS_HELPTEXT :Настрой STR_CONFIG_SETTING_PERCENTAGE :{COMMA}% STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS :Крутизна склона для автотранспорта: {STRING} STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS_HELPTEXT :Настройка крутизны склона для автотранспорта. Высокие значения делают подъём более тяжёлым. -STR_CONFIG_SETTING_FORBID_90_DEG :Запретить 90-градусные повороты на ж/д и море: {STRING} -STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :Поворот на 90° происходит, когда к горизонтальному участку рельсов примыкает вертикальный. В остальных случаях поезда поворачивают на 45°. Запрет поворота на 90° относится также и к кораблям. +STR_CONFIG_SETTING_FORBID_90_DEG :Запретить 90-градусные повороты на ж/д: {STRING} +STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :Поворот на 90° происходит, когда к горизонтальному участку рельсов примыкает вертикальный. В остальных случаях поезда поворачивают на 45°. STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS :Разрешить объединение не примыкающих друг к другу станций: {STRING} STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS_HELPTEXT :Разрешить объединять несколько станций в одну, даже если они не примыкают друг к другу. Требуется нажать Ctrl+щелчок при расширении станции. STR_CONFIG_SETTING_INFLATION :Включить инфляцию: {STRING} @@ -1409,7 +1413,7 @@ STR_CONFIG_SETTING_PLANE_SPEED :Множите STR_CONFIG_SETTING_PLANE_SPEED_HELPTEXT :Ограничение скорости воздушных судов относительно другого транспорта для снижения сверхприбылей от использования самолётов STR_CONFIG_SETTING_PLANE_SPEED_VALUE :1 / {COMMA} STR_CONFIG_SETTING_PLANE_CRASHES :Вероятность падения самолётов: {STRING} -STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Настройка вероятности падения самолёта +STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Настройка вероятности падения самолёта.{}У крупных самолётов всегда есть риск крушения при посадке в маленьких аэропортах. STR_CONFIG_SETTING_PLANE_CRASHES_NONE :отсутствует STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :сниженная STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :обычная @@ -1457,6 +1461,8 @@ STR_CONFIG_SETTING_POPULATION_IN_LABEL :Показыв STR_CONFIG_SETTING_POPULATION_IN_LABEL_HELPTEXT :Показывать количество жителей городов в названиях STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS :Толщина линий графиков: {STRING} STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Толщина линий графиков. Тонкие линии более точны; толстые линии лучше видны и их цвета лучше различимы. +STR_CONFIG_SETTING_SHOW_NEWGRF_NAME :Показывать имя NewGRF в окне покупки транспорта: {STRING} +STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT :Показывать название модуля NewGRF, содержащего выбранную модель транспортного средства, в окне покупки транспорта. STR_CONFIG_SETTING_LANDSCAPE :Тип карты: {STRING} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :Выбор типа карты определяет основу игрового процесса, например, доступные типы транспорта и грузов, различные условия роста городов. Всё это также может быть изменено с помощью модулей NewGRF и игровых скриптов. @@ -1468,8 +1474,8 @@ STR_CONFIG_SETTING_TERRAIN_TYPE :Тип ланд STR_CONFIG_SETTING_TERRAIN_TYPE_HELPTEXT :(Только для TerraGenesis){}Холмистость ландшафта STR_CONFIG_SETTING_INDUSTRY_DENSITY :Количество предприятий: {STRING} STR_CONFIG_SETTING_INDUSTRY_DENSITY_HELPTEXT :Выберите, сколько предприятий создавать в начале и на каком уровне поддерживать их количество в процессе игры. -STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE :Максимальное расстояние от края карты до нефтезаводов: {STRING} -STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :Нефтеперерабатывающие заводы всегда строятся у краёв карты или на берегах островов, находящихся недалеко от края +STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE :Макс. расстояние от края карты до предприятий нефтяной индустрии: {STRING} +STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :Эта настройка ограничивает расстояние от края карты до нефтяных платформ и нефтеперерабатывающих заводов. Таким образом, на краях карты, оканчивающихся водой, они будут строиться у берега. На картах размером более 256 это значение будет соответственно увеличено. STR_CONFIG_SETTING_SNOWLINE_HEIGHT :Высота снеговой линии: {STRING} STR_CONFIG_SETTING_SNOWLINE_HEIGHT_HELPTEXT :Укажите, на какой высоте в субарктическом климате устанавливается снеговой покров. Наличие снега влияет на расстановку предприятий и на условия роста городов. STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN :Грубость ландшафта: {STRING} @@ -1574,8 +1580,8 @@ STR_CONFIG_SETTING_TIMETABLE_SHOW_ARRIVAL_DEPARTURE :Показыв STR_CONFIG_SETTING_TIMETABLE_SHOW_ARRIVAL_DEPARTURE_HELPTEXT :Показывать ожидаемое время прибытия и отправления в графиках движения STR_CONFIG_SETTING_QUICKGOTO :Быстрое создание заданий транспорта: {STRING} 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 :Тип ж/д путей по умолчанию (после старта/загрузки): {STRING} +STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_HELPTEXT :Тип железнодорожных путей, выбираемый по умолчанию после старта или загрузки игры.{}«Первые доступные» - самый старый тип рельсов.{}«Последние доступные» - самый новый тип.{}«Наиболее используемые» - тип рельсов, наиболее широко используемых в игре. STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_FIRST :первые доступные STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_LAST :последние доступные STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_MOST_USED :наиболее используемые @@ -1633,6 +1639,9 @@ STR_CONFIG_SETTING_AI_IN_MULTIPLAYER :Разреши STR_CONFIG_SETTING_AI_IN_MULTIPLAYER_HELPTEXT :Разрешить игрокам, управляемым компьютером, участвовать в сетевых играх STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES :Количество операций перед остановкой скрипта: {STRING} STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES_HELPTEXT :Максимальное количество операций, которое скрипт может выполнить за один цикл +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY :Макс. объём памяти для скрипта: {STRING} +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_HELPTEXT :Объём памяти, который может использовать скрипт. При превышении этого объёма скрипт будет принудительно завершён. Для больших карт это значение, возможно, потребуется увеличить. +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_VALUE :{COMMA} Мбайт STR_CONFIG_SETTING_SERVINT_ISPERCENT :Интервал обслуживания в процентах: {STRING} STR_CONFIG_SETTING_SERVINT_ISPERCENT_HELPTEXT :Выберите, должно ли техническое обслуживание транспорта выполняться через определённые промежутки времени, либо при снижении надёжности транспортного средства на определённый процент от максимума @@ -1691,10 +1700,16 @@ STR_CONFIG_SETTING_NEWS_MESSAGES_FULL :полност STR_CONFIG_SETTING_COLOURED_NEWS_YEAR :Цветные газеты появляются в {STRING} году STR_CONFIG_SETTING_COLOURED_NEWS_YEAR_HELPTEXT :Обычно в газетах печатают чёрно-белые изображения, а начиная с указанного года - цветные STR_CONFIG_SETTING_STARTING_YEAR :Год начала игры: {STRING} +STR_CONFIG_SETTING_ENDING_YEAR :Последний год игры: {STRING} +STR_CONFIG_SETTING_ENDING_YEAR_HELPTEXT :По прошествии указанного года рассчитывается рейтинг компании и выводится таблица рекордов. После этого игру можно продолжить.{}Если указанный год предшествует году начала игры, то таблица рекордов не отображается. +STR_CONFIG_SETTING_ENDING_YEAR_VALUE :{NUM} +STR_CONFIG_SETTING_ENDING_YEAR_ZERO :Никогда STR_CONFIG_SETTING_SMOOTH_ECONOMY :Включить плавную экономику (частые, небольшие изменения): {STRING} STR_CONFIG_SETTING_SMOOTH_ECONOMY_HELPTEXT :При включении производительность предприятий меняется чаще и более плавно. Эта настройка обычно не влияет на предприятия, внесённые в игру модулями NewGRF. STR_CONFIG_SETTING_ALLOW_SHARES :Разрешить торговлю акциями других компаний: {STRING} STR_CONFIG_SETTING_ALLOW_SHARES_HELPTEXT :Разрешает торговлю акциями транспортных компаний. Акции выпускаются компаниями через некоторое время после основания. +STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES :Мин. возраст компании для выпуска акций: {STRING} +STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES_HELPTEXT :Минимальный возраст, которого должна достичь компания для начала выпуска акций, которыми смогут торговать другие игроки. STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE :Процент дохода, начисляемый при частичной перевозке: {STRING} STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE_HELPTEXT :Процент прибыли, начисляемый транспорту за частичную перевозку груза. STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY :При перетаскивании ставить сигналы каждые: {STRING} @@ -1735,6 +1750,10 @@ STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :Включен STR_CONFIG_SETTING_TOWN_FOUNDING_FORBIDDEN :запрещено STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED :разрешено STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED_CUSTOM_LAYOUT :разрешено с выбором сети дорог +STR_CONFIG_SETTING_TOWN_CARGOGENMODE :Количество грузов и пассажиров в городах: {STRING} +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_HELPTEXT :Зависимость количества грузов и пассажиров от размера города.{}Линейная: в городе двукратного размера появляется в 2 раза больше пассажиров.{}Квадратичная: в городе двукратного размера появляется в 4 раза больше пассажиров. +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_ORIGINAL :квадратичная зависимость (оригинальная) +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_BITCOUNT :линейная зависимость STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :Размножение деревьев в игре: {STRING} STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :Настройка возможности самостоятельного размножения деревьев в игре. Это может влиять на работоспособность некоторых предприятий, например, лесопилок. @@ -1862,7 +1881,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Рас STR_CONFIG_SETTING_AI :{ORANGE}Конкуренты STR_CONFIG_SETTING_AI_NPC :{ORANGE}Искусственный интеллект -STR_CONFIG_SETTING_PATHFINDER_OPF :оригинальный STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Рекомендуется) @@ -1946,13 +1964,9 @@ STR_QUIT_NO :{BLACK}Нет # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -2290,7 +2304,7 @@ STR_NETWORK_CHAT_ALL :[Всем] {STR STR_NETWORK_CHAT_OSKTITLE :{BLACK}Введите текст для сетевого сообщения # Network messages -STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}Не найдены сетевые устройства или игра скомпилирована без поддержки сети +STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}Не найдены сетевые устройства STR_NETWORK_ERROR_NOSERVER :{WHITE}Не найдены сетевые игры STR_NETWORK_ERROR_NOCONNECTION :{WHITE}Сервер не ответил на запрос STR_NETWORK_ERROR_NEWGRF_MISMATCH :{WHITE}Невозможно присоединиться из-за несоответствия NewGRF @@ -2306,6 +2320,7 @@ STR_NETWORK_ERROR_WRONG_PASSWORD :{WHITE}Неве STR_NETWORK_ERROR_SERVER_FULL :{WHITE}Сервер переполнен STR_NETWORK_ERROR_SERVER_BANNED :{WHITE}Вас забанили на этом сервере 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_TIMEOUT_PASSWORD :{WHITE}Вы не успели ввести пароль @@ -2365,6 +2380,7 @@ STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} п STR_NETWORK_MESSAGE_GAVE_MONEY_AWAY :*** Вы передали {1:STRING} {2:CURRENCY_LONG} STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}Сервер закрыл сессию STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}Сервер перезапускается...{}Пожалуйста, подождите... +STR_NETWORK_MESSAGE_KICKED :*** {STRING} был исключён из игры. Причина: ({STRING}) # Content downloading window STR_CONTENT_TITLE :{WHITE}Загрузка контента @@ -2606,6 +2622,11 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL :{BLACK}Стро STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Строительство трамвайных туннелей. При нажатом Shift - оценка стоимости строительства. STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Строительство/удаление автомобильных дорог и станций STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Строительство/удаление трамвайных путей и станций +STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_ROAD :{BLACK}Реконструкция/изменение типа дорожного полотна. С нажатым Shift - оценка стоимости строительства. +STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_TRAM :{BLACK}Реконструкция трамвайных путей. С нажатым Shift - оценка стоимости строительства. + +STR_ROAD_NAME_ROAD :Автомобильная дорога +STR_ROAD_NAME_TRAM :Трамвайные пути # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Направление гаража @@ -2794,8 +2815,11 @@ STR_LAND_AREA_INFORMATION_NEWGRF_NAME :{BLACK}NewGRF: STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED :{BLACK}Принимает: {LTBLUE} STR_LAND_AREA_INFORMATION_CARGO_EIGHTS :({COMMA}/8 {STRING}) STR_LANG_AREA_INFORMATION_RAIL_TYPE :{BLACK}Тип ж/д полотна: {LTBLUE}{STRING} +STR_LANG_AREA_INFORMATION_ROAD_TYPE :{BLACK}Тип дорожного полотна: {LTBLUE}{STRING} +STR_LANG_AREA_INFORMATION_TRAM_TYPE :{BLACK}Тип трамвайных путей: {LTBLUE}{STRING} STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT :{BLACK}Макс. скорость ж/д: {LTBLUE}{VELOCITY} STR_LANG_AREA_INFORMATION_ROAD_SPEED_LIMIT :{BLACK}Макс. скорость авто: {LTBLUE}{VELOCITY} +STR_LANG_AREA_INFORMATION_TRAM_SPEED_LIMIT :{BLACK}Ограничение скорости трамваев: {LTBLUE}{VELOCITY} # Description of land area of different tiles STR_LAI_CLEAR_DESCRIPTION_ROCKS :Камни @@ -2830,9 +2854,9 @@ STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBO_NOENTRYSIGNALS :Ж/д путь STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PBS_NOENTRYSIGNALS :Ж/д путь с маршрутным и односторонним маршрутным сигналами STR_LAI_RAIL_DESCRIPTION_TRAIN_DEPOT :Ж/д депо -STR_LAI_ROAD_DESCRIPTION_ROAD :Дорога -STR_LAI_ROAD_DESCRIPTION_ROAD_WITH_STREETLIGHTS :Дорога с уличным освещением -STR_LAI_ROAD_DESCRIPTION_TREE_LINED_ROAD :Дорога с озеленением +STR_LAI_ROAD_DESCRIPTION_ROAD :Автодорога +STR_LAI_ROAD_DESCRIPTION_ROAD_WITH_STREETLIGHTS :Освещённая автодорога +STR_LAI_ROAD_DESCRIPTION_TREE_LINED_ROAD :Автодорога с озеленением STR_LAI_ROAD_DESCRIPTION_ROAD_VEHICLE_DEPOT :Гараж STR_LAI_ROAD_DESCRIPTION_ROAD_RAIL_LEVEL_CROSSING :Железнодорожный переезд STR_LAI_ROAD_DESCRIPTION_TRAMWAY :Трамвайные пути @@ -2905,6 +2929,7 @@ STR_FRAMERATE_SPEED_FACTOR :{BLACK}Теку STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}Фактическая скорость игры STR_FRAMERATE_CURRENT :{WHITE}Сейчас STR_FRAMERATE_AVERAGE :{WHITE}В среднем +STR_FRAMERATE_MEMORYUSE :{WHITE}Объём памяти STR_FRAMERATE_DATA_POINTS :{BLACK}Данные по {COMMA} измерени{P ю ям ям} STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL} мс STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL} мс @@ -2912,6 +2937,9 @@ STR_FRAMERATE_MS_BAD :{RED}{DECIMAL} STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL} кадр{P "" а ов}/с STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL} кадр{P "" а ов}/с STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL} кадр{P "" а ов}/с +STR_FRAMERATE_BYTES_GOOD :{LTBLUE}{BYTES} +STR_FRAMERATE_BYTES_WARN :{YELLOW}{BYTES} +STR_FRAMERATE_BYTES_BAD :{RED}{BYTES} STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} мс STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} с ############ Leave those lines in this order!! @@ -3278,6 +3306,8 @@ STR_TOWN_VIEW_RENAME_TOWN_BUTTON :Переиме # Town local authority window STR_LOCAL_AUTHORITY_CAPTION :{WHITE}Администрация г.{NBSP}{TOWN} +STR_LOCAL_AUTHORITY_ZONE :{BLACK}Граница +STR_LOCAL_AUTHORITY_ZONE_TOOLTIP :{BLACK}Показать область, находящуюся под управлением местной администрации. STR_LOCAL_AUTHORITY_COMPANY_RATINGS :{BLACK}Рейтинг транспортных компаний STR_LOCAL_AUTHORITY_COMPANY_RATING :{YELLOW}{COMPANY} {COMPANY_NUM}: {ORANGE}{STRING} STR_LOCAL_AUTHORITY_ACTIONS_TITLE :{BLACK}Доступные действия: @@ -3301,7 +3331,7 @@ STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{YELLOW}Про 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_BRIBE :{YELLOW}Дать взятку городской администрации для повышения рейтинга. Существует риск санкций, если факт подкупа раскроется.{}Цена: {CURRENCY_LONG} # Goal window STR_GOALS_CAPTION :{WHITE}Задачи компании «{COMPANY}» @@ -3535,8 +3565,7 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Инфр STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Ж/д участки: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Сигналы STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Дорожные участки: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Автодороги -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Трамвайные пути +STR_COMPANY_INFRASTRUCTURE_VIEW_TRAM_SECT :{GOLD}Трамвайные участки: STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Водные участки: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Каналы STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Станции: @@ -3547,10 +3576,17 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Предприятия STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Нет - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% перевезено) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% перевезено) +STR_INDUSTRY_DIRECTORY_ITEM_INFO :{BLACK}{CARGO_LONG}{STRING}{YELLOW} ({COMMA}% перевезено){BLACK} STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} +STR_INDUSTRY_DIRECTORY_ITEM_PROD1 :{ORANGE}{INDUSTRY} {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PROD2 :{ORANGE}{INDUSTRY} {STRING}, {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PROD3 :{ORANGE}{INDUSTRY} {STRING}, {STRING}, {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PRODMORE :{ORANGE}{INDUSTRY} {STRING}, {STRING}, {STRING} и ещё {NUM}... STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Список предприятий - щелчок по названию показывает предприятие в основном окне. Ctrl+щелчок показывает в дополнительном окне. +STR_INDUSTRY_DIRECTORY_ACCEPTED_CARGO_FILTER :{BLACK}Принимаемый груз: {SILVER}{STRING} +STR_INDUSTRY_DIRECTORY_PRODUCED_CARGO_FILTER :{BLACK}Производимый груз: {SILVER}{STRING} +STR_INDUSTRY_DIRECTORY_FILTER_ALL_TYPES :Любой +STR_INDUSTRY_DIRECTORY_FILTER_NONE :Отсутствует # Industry view STR_INDUSTRY_VIEW_CAPTION :{WHITE}{INDUSTRY} @@ -3616,6 +3652,8 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Без груп STR_GROUP_DEFAULT_SHIPS :Без группы STR_GROUP_DEFAULT_AIRCRAFTS :Без группы +STR_GROUP_COUNT_WITH_SUBGROUP :{TINY_FONT}{COMMA} (+{COMMA}) + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Щёлкните по имени группы для отображения списка транспорта. Можно создавать вложенные группы с помощью перетаскивания. STR_GROUP_CREATE_TOOLTIP :{BLACK}Создать группу STR_GROUP_DELETE_TOOLTIP :{BLACK}Удалить выбранную группу @@ -3642,12 +3680,18 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Новый эл STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Новый монорельсовый поезд STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Новый магниторельсовый поезд -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Новый поезд STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Новый автомобиль +STR_BUY_VEHICLE_TRAM_VEHICLE_CAPTION :Новые трамваи + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Новый поезд +STR_BUY_VEHICLE_ROAD_VEHICLE_ALL_CAPTION :Новый дорожный транспорт STR_BUY_VEHICLE_SHIP_CAPTION :Новый корабль -STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Новый авиатранспорт +STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Новое воздушное судно +############ range for vehicle availability ends 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} @@ -3658,8 +3702,10 @@ STR_PURCHASE_INFO_REFITTABLE :(переоб.) STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Разработан в {GOLD}{NUM} г.{BLACK} Срок службы: {GOLD}{COMMA} {P год года лет} STR_PURCHASE_INFO_RELIABILITY :{BLACK}Макс. надёжность: {GOLD}{COMMA}% STR_PURCHASE_INFO_COST :{BLACK}Цена: {GOLD}{CURRENCY_LONG} +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} @@ -3680,11 +3726,21 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Купи STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Купить STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Купить +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Купить и переоборудовать +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Купить и переоборудовать +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Купить и переоборудовать +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Купить и переоборудовать + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Приобрести выбранный локомотив/вагон. Shift+щелчок покажет ориентировочную стоимость покупки. STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Приобрести выбранный автомобиль. Shift+щелчок покажет ориентировочную стоимость покупки. STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Приобрести выбранное судно. Shift+щелчок покажет ориентировочную стоимость покупки. STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Приобрести выбранное воздушное судно. Shift+щелчок покажет ориентировочную стоимость покупки. +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Приобрести и переоборудовать выбранный локомотив/вагон. Shift+щелчок покажет ориентировочную стоимость покупки. +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Приобрести и переоборудовать выбранный автомобиль. Shift+щелчок покажет ориентировочную стоимость покупки. +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Приобрести и переоборудовать выбранное судно. Shift+щелчок покажет ориентировочную стоимость покупки. +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Приобрести и переоборудовать выбранное воздушное судно. Shift+щелчок покажет ориентировочную стоимость покупки. + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Переименовать STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Переименовать STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Переименовать @@ -3793,19 +3849,26 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Вес # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Сообщение от производителя транспорта STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Мы создали новую модель {STRING.gen}. Заинтересованы ли вы в его годовом эксклюзивном использовании для проверки перед запуском в серийное производство? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :ж/д локомотив STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE.gen :ж/д локомотива -STR_ENGINE_PREVIEW_ROAD_VEHICLE :автомобиль -STR_ENGINE_PREVIEW_ROAD_VEHICLE.gen :автомобиля -STR_ENGINE_PREVIEW_AIRCRAFT :воздушное судно -STR_ENGINE_PREVIEW_AIRCRAFT.gen :воздушного судна -STR_ENGINE_PREVIEW_SHIP :корабль -STR_ENGINE_PREVIEW_SHIP.gen :корабля +STR_ENGINE_PREVIEW_ELRAIL_LOCOMOTIVE :электровоз +STR_ENGINE_PREVIEW_ELRAIL_LOCOMOTIVE.gen :электровоза STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :монорельсовый локомотив STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE.gen :монорельсового локомотива STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :магниторельсовый локомотив STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE.gen :магниторельсового локомотива +STR_ENGINE_PREVIEW_ROAD_VEHICLE :автомобиль +STR_ENGINE_PREVIEW_ROAD_VEHICLE.gen :автомобиля +STR_ENGINE_PREVIEW_TRAM_VEHICLE :трамвай +STR_ENGINE_PREVIEW_TRAM_VEHICLE.gen :трамвая + +STR_ENGINE_PREVIEW_AIRCRAFT :воздушное судно +STR_ENGINE_PREVIEW_AIRCRAFT.gen :воздушного судна +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_MAX_SPEED_CAP_RUNCOST :{BLACK}Цена: {CURRENCY_LONG} Макс. скорость: {VELOCITY}{}Ёмкость: {CARGO_LONG}{}Стоимость обслуж.: {CURRENCY_LONG}/год @@ -3830,8 +3893,8 @@ STR_REPLACE_VEHICLE_VEHICLES_IN_USE_TOOLTIP :{BLACK}Здес STR_REPLACE_VEHICLE_AVAILABLE_VEHICLES :{YELLOW}Доступные ТС STR_REPLACE_VEHICLE_AVAILABLE_VEHICLES_TOOLTIP :{BLACK}Здесь перечислены модели транспортных средств, доступные для замены -STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Выбор типа транспорта для замены -STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Выбор типа транспорта, на который следует заменить +STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}Выбор заменяемой модели транспортного средства +STR_REPLACE_HELP_RIGHT_ARRAY :{BLACK}Выбор заменяющей модели транспортного средства STR_REPLACE_VEHICLES_START :{BLACK}Начать замену STR_REPLACE_VEHICLES_NOW :Начать замену всех ТС @@ -3847,14 +3910,19 @@ STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK}Пере STR_REPLACE_ENGINES :Локомотивы STR_REPLACE_WAGONS :Вагоны STR_REPLACE_ALL_RAILTYPE :Весь ж/д транспорт +STR_REPLACE_ALL_ROADTYPE :Весь дорожный транспорт STR_REPLACE_HELP_RAILTYPE :{BLACK}Тип ж/д транспорта, подлежащего замене +STR_REPLACE_HELP_ROADTYPE :{BLACK}Выбор вида транспорта для замены STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Транспорт, на который происходит замена STR_REPLACE_RAIL_VEHICLES :Поезда STR_REPLACE_ELRAIL_VEHICLES :Электропоезда STR_REPLACE_MONORAIL_VEHICLES :Монорельсовые STR_REPLACE_MAGLEV_VEHICLES :Магнитные +STR_REPLACE_ROAD_VEHICLES :Автотранспорт +STR_REPLACE_TRAM_VEHICLES :Трамваи + STR_REPLACE_REMOVE_WAGON :{BLACK}Удаление вагонов: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Разрешить при автозамене сохранять длину поездов путём удаления вагонов (начиная с головы поезда), если при автозамене локомотива увеличится длина поезда. @@ -4305,6 +4373,14 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Выбр STR_AI_LIST_CANCEL :{BLACK}Отмена STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Не менять скрипт +STR_SCREENSHOT_CAPTION :{WHITE}Снимок экрана +STR_SCREENSHOT_SCREENSHOT :{BLACK}Обычный снимок +STR_SCREENSHOT_ZOOMIN_SCREENSHOT :{BLACK}Видимая область в максимальном приближении +STR_SCREENSHOT_DEFAULTZOOM_SCREENSHOT :{BLACK}Видимая область в обычном масштабе +STR_SCREENSHOT_WORLD_SCREENSHOT :{BLACK}Снимок всей карты +STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Снимок карты высот +STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Снимок миникарты + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}Параметры {STRING} STR_AI_SETTINGS_CAPTION_AI :ИИ @@ -4388,10 +4464,10 @@ STR_WARNING_FALLBACK_SOUNDSET :{WHITE}Теку # Screenshot related messages STR_WARNING_SCREENSHOT_SIZE_CAPTION :{WHITE}Огромный снимок экрана -STR_WARNING_SCREENSHOT_SIZE_MESSAGE :{YELLOW}Снимок экрана будет иметь размер {COMMA} х {COMMA} пикселей. Его создание займёт некоторое время. Продолжить? +STR_WARNING_SCREENSHOT_SIZE_MESSAGE :{YELLOW}Снимок экрана будет иметь размер {COMMA}{NBSP}х{NBSP}{COMMA}{NBSP}пиксел{P ь я ей}. Его создание займёт некоторое время. Продолжить? STR_MESSAGE_SCREENSHOT_SUCCESSFULLY :{WHITE}Снимок экрана сохранён под именем «{STRING}» -STR_ERROR_SCREENSHOT_FAILED :{WHITE}Не удалось сохранить снимок экрана +STR_ERROR_SCREENSHOT_FAILED :{WHITE}Не удалось сделать снимок экрана # Error message titles STR_ERROR_MESSAGE_CAPTION :{YELLOW}Сообщение @@ -4507,7 +4583,6 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... эт STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... неверное направление дороги STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... на проходных остановках нельзя делать повороты STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... на проходных остановках нельзя делать перекрёстки -STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... дорога односторонняя или заблокирована # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Невозможно удалить часть станции... @@ -4577,7 +4652,8 @@ 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 :{WHITE}Через этот вид рельсов запрещено строить переезды +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Через этот вид рельсов запрещено строить переезды +STR_ERROR_CROSSING_DISALLOWED_ROAD :{WHITE}Пересечение дорог такого типа недопустимо STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Здесь невозможно поставить сигнал... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Здесь невозможно проложить рельсы... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Не удалось удалить рельсы... @@ -4597,6 +4673,12 @@ STR_ERROR_CAN_T_REMOVE_ROAD_FROM :{WHITE}Не у STR_ERROR_CAN_T_REMOVE_TRAMWAY_FROM :{WHITE}Не удалось удалить трамвайные пути... STR_ERROR_THERE_IS_NO_ROAD :{WHITE}... здесь нет дороги STR_ERROR_THERE_IS_NO_TRAMWAY :{WHITE}... здесь нет трамвайных путей +STR_ERROR_CAN_T_CONVERT_ROAD :{WHITE}Здесь невозможно изменить тип дорожного полотна... +STR_ERROR_CAN_T_CONVERT_TRAMWAY :{WHITE}Невозможно сменить тип трамвайных рельсов... +STR_ERROR_NO_SUITABLE_ROAD :{WHITE}Нет подходящего дорожного полотна +STR_ERROR_NO_SUITABLE_TRAMWAY :{WHITE}Нет подходящих трамвайных путей +STR_ERROR_INCOMPATIBLE_ROAD :{WHITE}... несовместимый тип дороги +STR_ERROR_INCOMPATIBLE_TRAMWAY :{WHITE}... несовместимый тип трамвайных путей # Waterway construction errors STR_ERROR_CAN_T_BUILD_CANALS :{WHITE}Здесь невозможно построить канал... @@ -4649,6 +4731,7 @@ STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Нево STR_ERROR_GROUP_CAN_T_DELETE :{WHITE}Невозможно удалить группу... STR_ERROR_GROUP_CAN_T_RENAME :{WHITE}Невозможно переименовать группу... STR_ERROR_GROUP_CAN_T_SET_PARENT :{WHITE}Невозможно установить корректное вложение групп... +STR_ERROR_GROUP_CAN_T_SET_PARENT_RECURSION :{WHITE}... кольцевые зависимости в иерархии групп недопустимы STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}Невозможно удалить весь транспорт из группы... STR_ERROR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}Невозможно добавить транспорт в группу... STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}Невозможно добавить транспорт с общим маршрутом в группу... diff --git a/src/lang/serbian.txt b/src/lang/serbian.txt index be40e5b828..c63fc7d089 100644 --- a/src/lang/serbian.txt +++ b/src/lang/serbian.txt @@ -12,8 +12,6 @@ ##case nom big gen dat aku vok lok ins -# $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. # 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. @@ -660,9 +658,6 @@ 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 partije STR_ABOUT_MENU_SCREENSHOT :Sačuvaj sliku -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Čuva sliku skroz približenog terena -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Podrazumevani nivo zuma za sliku ekrana -STR_ABOUT_MENU_GIANT_SCREENSHOT :Sačuvaj sliku celog terena STR_ABOUT_MENU_ABOUT_OPENTTD :O OpenTTD-u STR_ABOUT_MENU_SPRITE_ALIGNER :Poravnjavanje sprajta STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Uključi/isključi granične linije @@ -832,9 +827,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Lični raspored 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Jačina muzike STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Jačina ambijenta -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}Tiho -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}Glasno -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -1057,6 +1049,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}Nov{G "" a o} {STRING} od sada u prodaji! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} više ne prihvata {STRING} STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} više ne prihvata ni {STRING} ni {STRING} STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} od sada prihvata {STRING.aku} @@ -1891,7 +1884,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Distrib STR_CONFIG_SETTING_AI :{ORANGE}Suparnici STR_CONFIG_SETTING_AI_NPC :{ORANGE}Računar -STR_CONFIG_SETTING_PATHFINDER_OPF :Originalno STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Preporučuje se) @@ -1974,13 +1966,9 @@ STR_QUIT_NO :{BLACK}Ne # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -2609,6 +2597,7 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Izgradnj STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Uključi građenje/rušenje drumskih puteva STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Uključi građenje/rušenje tramvajskih građevina + # 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 @@ -3471,8 +3460,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Infrastr STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Delova pruge: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Signalizacija STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Delova druma: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Drum -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Tramvajska pruga STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Pločica sa vodom: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Kanali STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Stanice: @@ -3483,8 +3470,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Fabrike STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Nema - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% prevezeno) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% prevezeno) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} 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 @@ -3549,6 +3534,7 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Negrupisana dru STR_GROUP_DEFAULT_SHIPS :Negrupisani brodovi STR_GROUP_DEFAULT_AIRCRAFTS :Negrupisane letilice + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Grupe - klikom na grupu se prikazuje spisak vozila u grupi. Hijerarhija grupa se uređuje metodom "prevuci i pusti" STR_GROUP_CREATE_TOOLTIP :{BLACK}Klikom se pravi nova grupa STR_GROUP_DELETE_TOOLTIP :{BLACK}Briše se označena grupa @@ -3574,10 +3560,13 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Nova Železnič STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Nova Jednošinska Vozila STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Nova Maglev Vozila -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Šinska Vozila STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Nova Drumska Vozila + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Šinska Vozila STR_BUY_VEHICLE_SHIP_CAPTION :Novi Brodovi STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Nove Letilice +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Cena: {GOLD}{CURRENCY_LONG}{BLACK} Težina: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Brzina: {GOLD}{VELOCITY}{BLACK} Snaga: {GOLD}{POWER} @@ -3611,11 +3600,13 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Kupi Voz 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_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_RENAME_BUTTON :{BLACK}Preimenuj STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Promena naziva STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Preimenuj @@ -3724,19 +3715,22 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Upravo # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Poruka od proizvođača vozila STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Upravo smo završili projektovanje nov{G og e og} {STRING.aku} - da li ste zainteresovani za jednogodišnja eksluzivna prava upotrebe ovog vozila, kako bi smo proverili radne osobine pre puštanja u masovnu proizvodnju? + 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_ROAD_VEHICLE :{G=srednji}drumsko vozilo -STR_ENGINE_PREVIEW_ROAD_VEHICLE.aku :drumskog vozila -STR_ENGINE_PREVIEW_AIRCRAFT :{G=ženski}letilica -STR_ENGINE_PREVIEW_AIRCRAFT.aku :letilice -STR_ENGINE_PREVIEW_SHIP :{G=muški}brod -STR_ENGINE_PREVIEW_SHIP.aku :broda 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_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_AIRCRAFT :{G=ženski}letilica +STR_ENGINE_PREVIEW_AIRCRAFT.aku :letilice +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. @@ -3792,6 +3786,7 @@ STR_REPLACE_ELRAIL_VEHICLES :Elektrošinska STR_REPLACE_MONORAIL_VEHICLES :Jednošinska Vozila STR_REPLACE_MAGLEV_VEHICLES :Magnetnošinska Vozila + STR_REPLACE_REMOVE_WAGON :{BLACK}Ukanjanje vagona: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Ukoliko bi se zamenom kompozicija produžila, automatska obnova će ukloniti vagone (sa početka) kako bi se zadržala dužina kompozicije @@ -4241,6 +4236,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Izabira STR_AI_LIST_CANCEL :{BLACK}Otkaži STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Ne menja skriptu + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parametri STR_AI_SETTINGS_CAPTION_AI :VI @@ -4443,7 +4439,6 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... ova STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... ulica je okrenuta u drugom pravcu STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... stajalište ne može biti na krivini STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... stajalište ne može biti na raskrsnici -STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... put je jednosmeran ili blokiran. # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Deo stanice se ne može ukloniti... @@ -4513,7 +4508,7 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Neophodn STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Nedostaje odgovarajuća železnička pruga STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Potrebno je prvo ukloniti železničku prugu STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Put je jednosmeran ili je blokiran -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Putni prelaz nije dozvoljen za ovu vrstu pruge +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Putni prelaz nije dozvoljen za ovu vrstu pruge STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Izgradnja signalizacije ovde nije moguća... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Izgradnja železničke pruge ovde nije moguća... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Nemoguće je ukloniti železničku prugu odatle... diff --git a/src/lang/simplified_chinese.txt b/src/lang/simplified_chinese.txt index 0aaf8f824a..6a0f4f0790 100644 --- a/src/lang/simplified_chinese.txt +++ b/src/lang/simplified_chinese.txt @@ -10,8 +10,6 @@ ##grflangid 0x56 -# $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. # 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. @@ -189,6 +187,8 @@ STR_COLOUR_ORANGE :橘黄色 STR_COLOUR_BROWN :棕 色 STR_COLOUR_GREY :浅灰色 STR_COLOUR_WHITE :白 色 +STR_COLOUR_RANDOM :随机 +STR_COLOUR_DEFAULT :默认 # Units used in OpenTTD STR_UNITS_VELOCITY_IMPERIAL :{COMMA}{NBSP}英里/小时 @@ -235,6 +235,8 @@ STR_TOOLTIP_FILTER_CRITERIA :{BLACK}选择 STR_BUTTON_SORT_BY :{BLACK}排序 STR_BUTTON_LOCATION :{BLACK}定位 STR_BUTTON_RENAME :{BLACK}重命名 +STR_BUTTON_CATCHMENT :{BLACK}覆盖范围 +STR_TOOLTIP_CATCHMENT :{BLACK}显示覆盖范围 STR_TOOLTIP_CLOSE_WINDOW :{BLACK}关闭窗口 STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}窗口标题 - 拖动这里可以移动该窗口 @@ -263,6 +265,7 @@ STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT_TOOLTIP :{BLACK}如启 STR_BUTTON_DEFAULT :{BLACK}默认 STR_BUTTON_CANCEL :{BLACK}取消 STR_BUTTON_OK :{BLACK}确定 +STR_WARNING_PASSWORD_SECURITY :{YELLOW}注意:服务器管理员可以看到你所输入的文字 # On screen keyboard window STR_OSK_KEYBOARD_LAYOUT :`1234567890-=\qwertyuiop[]asdfghjkl;' zxcvbnm,./ . @@ -336,6 +339,7 @@ STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN :{BLACK}放大 STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT :{BLACK}缩小视图 STR_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}显示铁路建设工具 STR_TOOLBAR_TOOLTIP_BUILD_ROADS :{BLACK}显示公路建设工具 +STR_TOOLBAR_TOOLTIP_BUILD_TRAMWAYS :{BLACK}建造电车道 STR_TOOLBAR_TOOLTIP_BUILD_SHIP_DOCKS :{BLACK}显示水运建设工具 STR_TOOLBAR_TOOLTIP_BUILD_AIRPORTS :{BLACK}显示机场建设工具 STR_TOOLBAR_TOOLTIP_LANDSCAPING :{BLACK}打开景观美化工具栏{}以修改地形、设置地貌等 @@ -356,6 +360,7 @@ STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION :{BLACK}生成 STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}生成城镇 STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}生成工业 STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}公路建设 +STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}电车道建设 STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}植树。Shift显示预计花费。 STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}放置标志 STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}放置物体,按住Shift键操作显示预计费用 @@ -464,6 +469,7 @@ STR_TOOLBAR_SOUND_MUSIC :声音/音乐 ############ range for message menu starts STR_NEWS_MENU_LAST_MESSAGE_NEWS_REPORT :最新消息/新闻 STR_NEWS_MENU_MESSAGE_HISTORY_MENU :消息历史 +STR_NEWS_MENU_DELETE_ALL_MESSAGES :删除全部消息 ############ range ends here ############ range for about menu starts @@ -472,9 +478,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :切换到控制台模式 STR_ABOUT_MENU_AI_DEBUG :AI /游戏脚本调试 STR_ABOUT_MENU_SCREENSHOT :屏幕截图 -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :高清截图 -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :默认缩放模式下的屏幕截图 -STR_ABOUT_MENU_GIANT_SCREENSHOT :全地图截图 STR_ABOUT_MENU_SHOW_FRAMERATE :显示帧率 STR_ABOUT_MENU_ABOUT_OPENTTD :关于 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Sprite 对齐 @@ -645,9 +648,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}自定义2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}音乐音量 STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}音效音量 -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}MIN -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}MAX -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -863,6 +863,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}新 {STRING} 上市了! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} 将不再接受 {STRING} STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} 将不再接受 {STRING} 和 {STRING} STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} 开始接受 {STRING} @@ -927,6 +928,10 @@ STR_GAME_OPTIONS_CURRENCY_ZAR :南非兰特( STR_GAME_OPTIONS_CURRENCY_CUSTOM :自定义… STR_GAME_OPTIONS_CURRENCY_GEL :格鲁吉亚拉里(GEL) STR_GAME_OPTIONS_CURRENCY_IRR :伊朗里亚尔(IRR) +STR_GAME_OPTIONS_CURRENCY_RUB :新俄罗斯卢布 (RUB) +STR_GAME_OPTIONS_CURRENCY_MXN :墨西哥比索 (MXN) +STR_GAME_OPTIONS_CURRENCY_NTD :新台币 (NTD) +STR_GAME_OPTIONS_CURRENCY_CNY :中国人民币 (CNY) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}汽车行驶 @@ -989,7 +994,10 @@ 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_DROPDOWN_TOOLTIP :{BLACK}选择此字体大小 +STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :两倍大小 +STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :四倍大小 STR_GAME_OPTIONS_BASE_GRF :{BLACK}基础图形组 STR_GAME_OPTIONS_BASE_GRF_TOOLTIP :{BLACK}选择要使用的基础图形组 @@ -1173,6 +1181,7 @@ STR_CONFIG_SETTING_AUTOSLOPE :允许在建筑 STR_CONFIG_SETTING_AUTOSLOPE_HELPTEXT :允许在建筑和轨道下方改变地形而不需要拆除他们 STR_CONFIG_SETTING_CATCHMENT :允许更真实的客源范围:{STRING} STR_CONFIG_SETTING_CATCHMENT_HELPTEXT :启用时不同类型的车站和机场有不同的客源范围 +STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES_HELPTEXT :启用后,自带车站的工业设施(如钻井平台)也可以被临近的公司私有车站服务。禁用后,这些工业设施只能被它们自带的车站服务。任何临近的公司车站将不能服务它们,工业设施自有车站也不会提供除本工业设施的产品以外的其他产品 STR_CONFIG_SETTING_EXTRADYNAMITE :允许拆除更多的由城镇所有的公路、桥梁、隧道等:{STRING} STR_CONFIG_SETTING_EXTRADYNAMITE_HELPTEXT :启用时更容易拆除城市自有的设施和建筑 STR_CONFIG_SETTING_TRAIN_LENGTH :火车的最大长度:{STRING} @@ -1190,7 +1199,7 @@ STR_CONFIG_SETTING_PERCENTAGE :{COMMA}% STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS :斜坡对汽车速度影响率: {STRING} STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS_HELPTEXT :每一格斜坡对汽车速度的影响率,数值越大,汽车越难爬上斜坡 STR_CONFIG_SETTING_FORBID_90_DEG :禁止列车和轮船 90 度转弯:{STRING} -STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :当水平方向轨道与垂直方向轨道交叉时,没有采用45度的轨道组合连接,而是采用轨道90度直接连接时,列车通过时需要90度转弯,当本设置”打开“时,将禁止火车90度转弯,本设置同样影响船只转弯时的航线。 +STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :当水平方向轨道与垂直方向轨道交叉时,没有采用45度的轨道组合连接,而是采用轨道90度直接连接时,列车通过时需要90度转弯,当本设置”打开“时,将禁止火车90度转弯。 STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS :允许非毗邻站台合并:{STRING} STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS_HELPTEXT :“打开”时允许为已经存在的车站添加不相邻的站台,建造新的部分时需要按住Ctrl键 STR_CONFIG_SETTING_INFLATION :通货膨胀:{STRING} @@ -1258,6 +1267,8 @@ 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 :初创公司颜色:{STRING} +STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR_HELPTEXT :选定公司的初始配色方案 STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS :总允许建设小型机场: {STRING} STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS_HELPTEXT :“打开”此选项,每种类型机场出现后一直是可用的 @@ -1296,7 +1307,7 @@ STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :图表中曲线 STR_CONFIG_SETTING_LANDSCAPE :景观: {STRING} STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :此设置决定基本的游戏场景、有什么货物可供运输,以及城镇发展的所需条件。然而,NewGRF 及游戏脚本可以比此设置更加细致地设置游戏场景 STR_CONFIG_SETTING_LAND_GENERATOR :生成地形:{STRING} -STR_CONFIG_SETTING_LAND_GENERATOR_HELPTEXT :使用原始算法时,系统会依赖基础图形组去生成固定的地形。新算法则是一个建基于 Perlin 噪声原理的地形生成程序,并支援较为细致的地形设置 +STR_CONFIG_SETTING_LAND_GENERATOR_HELPTEXT :使用原始算法时,系统会依赖基础图形组去生成固定的地形。新算法 TerraGenesis 是一个基于 Perlin 噪声的地形生成程序,支持较为细致的地形设置 STR_CONFIG_SETTING_LAND_GENERATOR_ORIGINAL :原始算法 STR_CONFIG_SETTING_LAND_GENERATOR_TERRA_GENESIS :新算法 STR_CONFIG_SETTING_TERRAIN_TYPE :地貌类型: {STRING} @@ -1342,7 +1353,9 @@ STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_HELPTEXT :设置缩略地 STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_GREEN :绿色 STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_DARK_GREEN :深绿色 STR_CONFIG_SETTING_SMALLMAP_LAND_COLOUR_VIOLET :紫色 -STR_CONFIG_SETTING_SCROLLMODE_DEFAULT :鼠标右键移动地图,鼠标指针不跟随移动 +STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT :滚动地图的行为 +STR_CONFIG_SETTING_SCROLLMODE_DEFAULT :鼠标右键移动视角,鼠标指针不跟随移动 +STR_CONFIG_SETTING_SCROLLMODE_RMB_LOCKED :鼠标右键移动地图,鼠标指针不跟随移动 STR_CONFIG_SETTING_SCROLLMODE_RMB :鼠标右键移动地图 STR_CONFIG_SETTING_SCROLLMODE_LMB :鼠标左键移动地图 STR_CONFIG_SETTING_SMOOTH_SCROLLING :平滑视角滚动: {STRING} @@ -1465,6 +1478,9 @@ STR_CONFIG_SETTING_AI_IN_MULTIPLAYER :联机游戏时 STR_CONFIG_SETTING_AI_IN_MULTIPLAYER_HELPTEXT :“打开”时联机游戏允许电脑玩家 STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES :可允许的最大的代码量(如超过则会令脚本被禁用):{STRING} STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES_HELPTEXT :脚本在一个回合中可进行计算步数的最大值 +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY :每个脚本的内存上限: {STRING} +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_HELPTEXT :单个脚本强制终止前可占用的最大内存量。对于大地图可能需要增加。 +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_VALUE :{COMMA} MiB STR_CONFIG_SETTING_SERVINT_ISPERCENT :保养周期(百分数): {STRING} STR_CONFIG_SETTING_SERVINT_ISPERCENT_HELPTEXT :选择触发车辆保养的条件,距离上一次保养的时间或者与最高可靠性的百分比 @@ -1567,6 +1583,9 @@ STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :“打开”本 STR_CONFIG_SETTING_TOWN_FOUNDING_FORBIDDEN :禁止 STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED :允许 STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED_CUSTOM_LAYOUT :允许,自定义城镇布局 +STR_CONFIG_SETTING_TOWN_CARGOGENMODE :城镇货物生成:{STRING} +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_ORIGINAL :四倍(原版) +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_BITCOUNT :线性 STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :树木自动生长: {STRING} STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :控制游戏中数目的随机生长,这将影响依赖树木的工业,比如木材厂 @@ -1694,7 +1713,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}货物 STR_CONFIG_SETTING_AI :{ORANGE}竞争 STR_CONFIG_SETTING_AI_NPC :{ORANGE}电脑玩家 -STR_CONFIG_SETTING_PATHFINDER_OPF :原始的 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(推荐) @@ -1767,6 +1785,7 @@ STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}连接 STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}查看AI和脚本设定 STR_INTRO_TOOLTIP_QUIT :{BLACK}退出 'OpenTTD' +STR_INTRO_BASESET :{BLACK}当前选定的基础图形组缺少 {NUM} 个子画面。请检查基础图形组有无更新。 STR_INTRO_TRANSLATION :{BLACK}中文语言版本缺失了 {NUM} 条翻译。 请注册成为翻译人员,以帮助OpenTTD发展。{}详见readme.txt。 # Quit window @@ -1777,13 +1796,9 @@ STR_QUIT_NO :{BLACK}否 # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -1812,6 +1827,7 @@ STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}改变 STR_CHEAT_SETUP_PROD :{LTBLUE}开启可调整产量模式:{ORANGE}{STRING} # Livery window +STR_LIVERY_CAPTION :{WHITE}{COMPANY} 的色彩方案 STR_LIVERY_GENERAL_TOOLTIP :{BLACK}显示总体配色方案 STR_LIVERY_TRAIN_TOOLTIP :{BLACK}显示列车配色方案 @@ -2071,6 +2087,7 @@ STR_NETWORK_CONNECTION_DISCONNECT :{BLACK}断开 STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}服务器需要密码: STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}公司需要密码: +STR_NETWORK_COMPANY_LIST_CLIENT_LIST_CAPTION :{WHITE}客户端列表 # Network company list added strings STR_NETWORK_COMPANY_LIST_CLIENT_LIST :客户端列表 @@ -2286,6 +2303,7 @@ STR_LINKGRAPH_LEGEND_CAPTION :{BLACK}客货 STR_LINKGRAPH_LEGEND_ALL :{BLACK}全部 STR_LINKGRAPH_LEGEND_NONE :{BLACK}无 STR_LINKGRAPH_LEGEND_SELECT_COMPANIES :{BLACK}选择要查看的公司 +STR_LINKGRAPH_LEGEND_COMPANY_TOOLTIP :{BLACK}{STRING}{}{COMPANY} # Linkgraph legend window and linkgraph legend in smallmap STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLACK}空跑 @@ -2410,6 +2428,11 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL :{BLACK}建设 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_TOOLBAR_TOOLTIP_CONVERT_ROAD :{BLACK}转换/升级 公路类型。按住 Shift 键显示预计费用。 +STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_TRAM :转换/升级 电车道类型。按住 Shift 键显示预计费用。 + +STR_ROAD_NAME_ROAD :路 +STR_ROAD_NAME_TRAM :电车轨道 # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}汽车车库的方向…… @@ -2594,8 +2617,10 @@ STR_LAND_AREA_INFORMATION_NEWGRF_NAME :{BLACK}NewGRF: STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED :{BLACK}接受货物:{LTBLUE} STR_LAND_AREA_INFORMATION_CARGO_EIGHTS :({COMMA}/8 {STRING}) STR_LANG_AREA_INFORMATION_RAIL_TYPE :{BLACK}铁轨类型: {LTBLUE}{STRING} +STR_LANG_AREA_INFORMATION_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 :岩石 @@ -2697,20 +2722,40 @@ STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD # Framerate display window STR_FRAMERATE_CAPTION :{WHITE}帧率 STR_FRAMERATE_CAPTION_SMALL :{STRING}{WHITE} ({DECIMAL}x) +STR_FRAMERATE_RATE_GAMELOOP :{BLACK}模拟速率: {STRING} STR_FRAMERATE_RATE_BLITTER :{BLACK}帧率:{STRING} STR_FRAMERATE_RATE_BLITTER_TOOLTIP :{BLACK}每秒渲染更新的图像帧。 STR_FRAMERATE_SPEED_FACTOR :{BLACK}当前游戏速度:{DECIMAL}x +STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}当前游戏运行速度,与正常速度之比率 +STR_FRAMERATE_CURRENT :{WHITE}当前 STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL} ms STR_FRAMERATE_MS_BAD :{RED}{DECIMAL} ms STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL} fps STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL} fps STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL} fps +STR_FRAMERATE_BYTES_GOOD :{LTBLUE}{BYTES} +STR_FRAMERATE_BYTES_WARN :{YELLOW}{BYTES} +STR_FRAMERATE_BYTES_BAD :{RED}{BYTES} STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} ms ############ Leave those lines in this order!! +STR_FRAMERATE_GL_ROADVEHS :{BLACK} 道路车辆耗时: +STR_FRAMERATE_GL_SHIPS :{BLACK} 船只耗时: +STR_FRAMERATE_GL_AIRCRAFT :{BLACK} 飞机耗时: STR_FRAMERATE_VIDEO :{BLACK}视频输出: STR_FRAMERATE_SOUND :{BLACK}混响: +STR_FRAMERATE_ALLSCRIPTS :{BLACK} GS/AI 总计: +STR_FRAMERATE_GAMESCRIPT :{BLACK} 游戏脚本: +STR_FRAMERATE_AI :{BLACK} AI {NUM} {STRING} ############ End of leave-in-this-order ############ Leave those lines in this order!! +STR_FRAMETIME_CAPTION_GL_ECONOMY :货物处理 +STR_FRAMETIME_CAPTION_GL_ROADVEHS :道路车辆耗时 +STR_FRAMETIME_CAPTION_GL_AIRCRAFT :飞机耗时 +STR_FRAMETIME_CAPTION_GL_LANDSCAPE :世界耗时 +STR_FRAMETIME_CAPTION_DRAWING :图形渲染 +STR_FRAMETIME_CAPTION_DRAWING_VIEWPORTS :世界视点渲染 +STR_FRAMETIME_CAPTION_SOUND :混响 +STR_FRAMETIME_CAPTION_AI :AI {NUM} {STRING} ############ End of leave-in-this-order @@ -2737,6 +2782,8 @@ 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_OVERWRITE_WARNING :{YELLOW}你确定要覆盖已有文件吗? STR_SAVELOAD_OSKTITLE :{BLACK}为存档命名 @@ -2854,7 +2901,10 @@ STR_NEWGRF_SETTINGS_VERSION :{BLACK}版本: STR_NEWGRF_SETTINGS_MIN_VERSION :{BLACK}最低兼容版本: {SILVER}{NUM} STR_NEWGRF_SETTINGS_MD5SUM :{BLACK}MD5 码:{SILVER}{STRING} STR_NEWGRF_SETTINGS_PALETTE :{BLACK}调色板: {SILVER}{STRING} +STR_NEWGRF_SETTINGS_PALETTE_DEFAULT :默认 (D) +STR_NEWGRF_SETTINGS_PALETTE_LEGACY :传统 (W) STR_NEWGRF_SETTINGS_PARAMETER :{BLACK}参数:{SILVER}{STRING} +STR_NEWGRF_SETTINGS_PARAMETER_NONE :无 STR_NEWGRF_SETTINGS_NO_INFO :{BLACK}没有可用的信息 STR_NEWGRF_SETTINGS_NOT_FOUND :{RED}没有找到对应的文件 @@ -2960,12 +3010,13 @@ STR_NEWGRF_BROKEN :{WHITE}NewGRF ' STR_NEWGRF_BROKEN_POWERED_WAGON :{WHITE}{1:ENGINE}机车车厢的状态没在车库内发生变动 STR_NEWGRF_BROKEN_VEHICLE_LENGTH :{WHITE}当车辆不在车库中时,这将改变 '{1:ENGINE}' 的车辆长度. STR_NEWGRF_BROKEN_CAPACITY :{WHITE}它会在 '{1:ENGINE}' 在机厂外或不在接受改装时改変其运载能力 -STR_BROKEN_VEHICLE_LENGTH :{WHITE}列车 '{VEHICLE}' 属于 '{COMPANY}' 使长度无效化了. 这可能是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}' 后,将造成货物/运费的参数与购买列表不符,这将有可能造成自动更新/购买不成功。 STR_NEWGRF_BUGGY_ENDLESS_PRODUCTION_CALLBACK :{WHITE}'{1:STRING}' 产生了一个死循环 STR_NEWGRF_BUGGY_UNKNOWN_CALLBACK_RESULT :{WHITE}回调函数 {1:HEX} 返回了一个未知/错误的结果 {2:HEX} +STR_NEWGRF_BUGGY_INVALID_CARGO_PRODUCTION_CALLBACK :{WHITE}'{1:STRING}' 返回了错误的货物类型。位于产品回调函数 {2:HEX} 处 # 'User removed essential NewGRFs'-placeholders for stuff without specs STR_NEWGRF_INVALID_CARGO : @@ -2999,6 +3050,7 @@ STR_EDIT_SIGN_SIGN_OSKTITLE :{BLACK}为标 STR_TOWN_DIRECTORY_CAPTION :{WHITE}城镇 STR_TOWN_DIRECTORY_NONE :{ORANGE}- 没有 - STR_TOWN_DIRECTORY_TOWN :{ORANGE}{TOWN}{BLACK} ({COMMA}) +STR_TOWN_DIRECTORY_CITY :{ORANGE}{TOWN}{YELLOW} (都市){BLACK} ({COMMA}) STR_TOWN_DIRECTORY_LIST_TOOLTIP :{BLACK} 城镇名称 点击名称可以将屏幕中心{}移动到城镇所在的位置. 单击的同时按住Ctrl会在新视点中显示城镇位置 STR_TOWN_POPULATION :{BLACK}所有城镇人口总数:{COMMA} @@ -3006,6 +3058,7 @@ STR_TOWN_POPULATION :{BLACK}所有 STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (都市) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}人口:{ORANGE}{COMMA}{BLACK} 房屋:{ORANGE}{COMMA} +STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX :{BLACK}{CARGO_LIST} 上月:{ORANGE}{COMMA}{BLACK} 最大:{ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}城镇发展所必需的货物: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{RED} 需要: {ORANGE}{STRING} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} 冬季的需求 @@ -3030,6 +3083,7 @@ STR_TOWN_VIEW_RENAME_TOWN_BUTTON :重命名城镇 # Town local authority window STR_LOCAL_AUTHORITY_CAPTION :{WHITE}{TOWN} 地方政府 +STR_LOCAL_AUTHORITY_ZONE :{BLACK}城区 STR_LOCAL_AUTHORITY_COMPANY_RATINGS :{BLACK}对运输公司评价: STR_LOCAL_AUTHORITY_COMPANY_RATING :{YELLOW}{COMPANY} {COMPANY_NUM}: {ORANGE}{STRING} STR_LOCAL_AUTHORITY_ACTIONS_TITLE :{BLACK}可执行的操作: @@ -3058,7 +3112,8 @@ STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}贿赂 # Goal window STR_GOALS_CAPTION :{WHITE}{COMPANY} 目标 STR_GOALS_SPECTATOR_CAPTION :{WHITE}全球目标: -STR_GOALS_GLOBAL_TITLE :{BLACK}全球目标: +STR_GOALS_SPECTATOR :全局目标 +STR_GOALS_GLOBAL_TITLE :{BLACK}全局目标: STR_GOALS_TEXT :{ORANGE}{STRING} STR_GOALS_NONE :{ORANGE}- 无目标 - STR_GOALS_SPECTATOR_NONE :{ORANGE}- 不适用 - @@ -3106,6 +3161,7 @@ STR_SUBSIDIES_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER :{BLACK}点击 # Story book window STR_STORY_BOOK_CAPTION :{WHITE}{COMPANY}的历史纪录 STR_STORY_BOOK_SPECTATOR_CAPTION :{WHITE}全域历史纪录 +STR_STORY_BOOK_SPECTATOR :全域历史纪录 STR_STORY_BOOK_TITLE :{YELLOW}{STRING} STR_STORY_BOOK_GENERIC_PAGE_ITEM :第{NUM}页 STR_STORY_BOOK_SEL_PAGE_TOOLTIP :{BLACK}从下拉选单中选择想要查看的页面. @@ -3285,8 +3341,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}{COMPANY STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}铁路: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}信号灯 STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}道路: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}普通道路 -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}电车线路 STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}水运: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}运河 STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}站台: @@ -3297,8 +3351,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}每年{C # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}工业设施 STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- 没有 - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% 已运输) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% 已运输) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}工业设施{}点击可以将屏幕中心移动到其所在位置. 单击的同时按住Ctrl会在新视点中显示工业位置 @@ -3310,6 +3362,7 @@ STR_INDUSTRY_VIEW_LOCATION_TOOLTIP :{BLACK}将屏 STR_INDUSTRY_VIEW_PRODUCTION_LEVEL :{BLACK}生产程度: {YELLOW}{COMMA}% STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE :{YELLOW}此工业已经宣布即刻停业倒闭! +STR_INDUSTRY_VIEW_REQUIRES_N_CARGO :{BLACK}需要: {YELLOW}{STRING}{STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING} STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} 等待中{STRING} @@ -3362,6 +3415,7 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :未分组汽车 STR_GROUP_DEFAULT_SHIPS :未分组船只 STR_GROUP_DEFAULT_AIRCRAFTS :未分组飞机 + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}组 - 点击一个组别以显示所有隶属此组的车辆。拖曳组别标签以重新排列组别的次序和层级。 STR_GROUP_CREATE_TOOLTIP :{BLACK}创建分组 STR_GROUP_DELETE_TOOLTIP :{BLACK}删除分组 @@ -3387,12 +3441,17 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :购买电气化 STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :购买单轨列车 STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :购买磁悬浮列车 -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :新列车 STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :购买汽车 +STR_BUY_VEHICLE_TRAM_VEHICLE_CAPTION :新电车 + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :新列车 STR_BUY_VEHICLE_SHIP_CAPTION :购买船只 STR_BUY_VEHICLE_AIRCRAFT_CAPTION :购买飞机 +############ range for vehicle availability ends 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} @@ -3409,6 +3468,7 @@ STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}运载 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_ALL_BUT :除了 {CARGO_LIST} STR_PURCHASE_INFO_MAX_TE :{BLACK}最大牵引力:{GOLD}{FORCE} STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}航行距离: {GOLD}{COMMA} 格 @@ -3424,11 +3484,15 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}购买 STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}购买船只 STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}购买飞机 +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_BUTTON :{BLACK}购买并改装 +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_BUTTON :{BLACK}购买并改装飞机 + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}购买选定的列车,按住 Shift 键单击可以显示所需资金 STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}购买选定的汽车,按住 Shift 键单击可以显示所需资金 STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}购买选定的船只,按住 Shift 键单击可以显示所需资金 STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}购买选定的飞机,按住 Shift 键单击可以显示所需资金 + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}重命名 STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}重命名 STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}重命名 @@ -3537,13 +3601,16 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}你将 # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}来自供货商的消息 STR_ENGINE_PREVIEW_MESSAGE :{GOLD}我们新近设计了一款{STRING}{}您愿意在产品正式上市前试用一年吗? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :火车机车 -STR_ENGINE_PREVIEW_ROAD_VEHICLE :汽车 -STR_ENGINE_PREVIEW_AIRCRAFT :飞机 -STR_ENGINE_PREVIEW_SHIP :船只 STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :单轨机车 STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :磁悬浮机车 +STR_ENGINE_PREVIEW_ROAD_VEHICLE :汽车 + +STR_ENGINE_PREVIEW_AIRCRAFT :飞机 +STR_ENGINE_PREVIEW_SHIP :船只 + STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}售价:{CURRENCY_LONG} 重量:{WEIGHT_SHORT}{}速度:{VELOCITY} 功率:{POWER}{}运行费用:{CURRENCY_LONG}/年{}运载能力: {CARGO_LONG} STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}售价:{CURRENCY_LONG} 重量:{WEIGHT_SHORT}{}速度:{VELOCITY} 功率:{POWER} 最大牵引力:{6:FORCE}{}运行费用{4:CURRENCY_LONG}/年{}运载能力:{5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}售价:{CURRENCY_LONG} 最大速度:{VELOCITY}{}运载能力:{CARGO_LONG}{}运行成本:{CURRENCY_LONG} /年 @@ -3581,14 +3648,17 @@ STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK}可以 STR_REPLACE_ENGINES :机车 STR_REPLACE_WAGONS :挂车 STR_REPLACE_ALL_RAILTYPE :所有铁路车辆 +STR_REPLACE_ALL_ROADTYPE :所有道路载具 STR_REPLACE_HELP_RAILTYPE :{BLACK}选择要更新的车辆对应的铁路类型 +STR_REPLACE_HELP_ROADTYPE :{BLACK}选择要更新的车辆对应的道路类型 STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}显示用来替换左侧被选定车辆的新车辆 STR_REPLACE_RAIL_VEHICLES :普通列车 STR_REPLACE_ELRAIL_VEHICLES :电力机车 STR_REPLACE_MONORAIL_VEHICLES :单轨列车 STR_REPLACE_MAGLEV_VEHICLES :磁悬浮列车 + STR_REPLACE_REMOVE_WAGON :{BLACK}清理挂车:{ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}当车辆升级可能造成列车变长时{}自动从最前面的挂车去掉若干节以保证列车长度不变 @@ -3674,6 +3744,7 @@ STR_VEHICLE_INFO_AGE_RED :{RED}{COMMA} STR_VEHICLE_INFO_MAX_SPEED :{BLACK}最大速度:{LTBLUE}{VELOCITY} STR_VEHICLE_INFO_MAX_SPEED_TYPE :{BLACK}最高速度: {LTBLUE}{VELOCITY} {BLACK}飞机种类: {LTBLUE}{STRING} +STR_VEHICLE_INFO_MAX_SPEED_TYPE_RANGE :{BLACK}最大速度: {LTBLUE}{VELOCITY} {BLACK}飞机类型: {LTBLUE}{STRING} {BLACK}续航里程: {LTBLUE}{COMMA} 格 STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}重量:{LTBLUE}{WEIGHT_SHORT} {BLACK}功率:{LTBLUE}{POWER}{BLACK} 最大速度:{LTBLUE}{VELOCITY} STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}重量:{LTBLUE}{WEIGHT_SHORT} {BLACK}功率:{LTBLUE}{POWER}{BLACK} 最大速度:{LTBLUE}{VELOCITY} {BLACK}最大牵引力:{LTBLUE}{FORCE} @@ -3807,6 +3878,7 @@ STR_ORDER_CONDITIONAL_AGE :寿命(年) STR_ORDER_CONDITIONAL_REQUIRES_SERVICE :需要维修 STR_ORDER_CONDITIONAL_UNCONDITIONALLY :总是 STR_ORDER_CONDITIONAL_REMAINING_LIFETIME :剩余寿命年限 (年) +STR_ORDER_CONDITIONAL_MAX_RELIABILITY :最大可靠度 STR_ORDER_CONDITIONAL_COMPARATOR_TOOLTIP :{BLACK}如何比较车辆数据值与所给数据 STR_ORDER_CONDITIONAL_COMPARATOR_EQUALS :等于 @@ -4037,6 +4109,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}选择 STR_AI_LIST_CANCEL :{BLACK}取消 STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}不修改本 AI + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} 参数 STR_AI_SETTINGS_CAPTION_AI :AI @@ -4308,7 +4381,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 :{WHITE}该轨道类型不允许建设平交道 +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}该轨道类型不允许建设平交道 STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}不能在这里设置信号灯…… STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}不能在这里铺设轨道…… STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}不能从这里拆除轨道…… @@ -4328,6 +4401,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_ROAD :{WHITE}无法转换道路类型 +STR_ERROR_NO_SUITABLE_ROAD :{WHITE}没有合适的道路 # Waterway construction errors STR_ERROR_CAN_T_BUILD_CANALS :{WHITE}不能在这里兴建运河…… diff --git a/src/lang/slovak.txt b/src/lang/slovak.txt index 6135aa084c..53765f31fd 100644 --- a/src/lang/slovak.txt +++ b/src/lang/slovak.txt @@ -12,8 +12,6 @@ ##case g -# $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. # 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. @@ -536,9 +534,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Zobraziť / skryť konzolu STR_ABOUT_MENU_AI_DEBUG :Umelá inteligencia / Ladenie skriptov STR_ABOUT_MENU_SCREENSHOT :Snímka -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Plne priblížená snímka -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Snímka s predvoleným priblížením -STR_ABOUT_MENU_GIANT_SCREENSHOT :Veľká snímka celej mapy STR_ABOUT_MENU_ABOUT_OPENTTD :O hre 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Sprite zarovnávač STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Prepnúť okrajové boxy @@ -708,9 +703,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Vlastné 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Hlasitosť hudby STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Hlasitosť zvuk. efektov -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}MIN -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}MAX -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -926,6 +918,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}Nov{G "ý" "á" "é"} {STRING} dostupn{G "ý" "á" "é"}! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} už neprijíma {STRING} STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} už neprijíma {STRING} alebo {STRING} STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} teraz prijíma {STRING} @@ -1752,7 +1745,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Distrib STR_CONFIG_SETTING_AI :{ORANGE}Konkurenti STR_CONFIG_SETTING_AI_NPC :{ORANGE}Počítačový hráči -STR_CONFIG_SETTING_PATHFINDER_OPF :Pôvodný STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(odporučený) @@ -1835,13 +1827,9 @@ STR_QUIT_NO :{BLACK}Nie # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -2469,6 +2457,7 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Postavi STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Prepnúť stavbu/odstraňovanie cesty STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Prepnúť stavbu/odstraňovanie električkovej dráhy + # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Orientacia garaze STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}Zvoľte orientáciu garáže @@ -3328,8 +3317,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Infrašt STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Políčka železnice: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Semafóry STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Políčka cesty: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Cesta -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Električka STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Vodné políčka: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Kanále STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Stanice: @@ -3340,8 +3327,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Priemysel STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Nič - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% prepraven{P é é ých}) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% prepraven{P é é ých}) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Názvy priemyslu - klikni na meno pre vycentrovanie priemyslu na stred obrazovky @@ -3403,6 +3388,7 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Nezaradené voz STR_GROUP_DEFAULT_SHIPS :Nezaradené lode STR_GROUP_DEFAULT_AIRCRAFTS :Nezaradené lietadlá + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Skupiny - klikni na skupinu pre zobrazenie všetkých vozidiel skupiny. Ťahaj a Pusti pre usporiadanie hierarchiu v skupine STR_GROUP_CREATE_TOOLTIP :{BLACK}Klikni pre vytvorenie skupiny STR_GROUP_DELETE_TOOLTIP :{BLACK}Zrušiť vybranú skupinu @@ -3424,10 +3410,13 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Nové elektrick STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Nové jednokoľajové vlaky STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Nové magnetické vlaky -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Železnicne vozidlá STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Nové automobily + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Železnicne vozidlá STR_BUY_VEHICLE_SHIP_CAPTION :Nové lode STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Nove Lietadlo +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Cena: {GOLD}{CURRENCY_LONG}{BLACK} Hmotnosť: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Rýchlosť: {GOLD}{VELOCITY}{BLACK} Výkon: {GOLD}{POWER} @@ -3460,11 +3449,13 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Kúpiť STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Kúpiť loď STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Kúpiť lietadlo + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Kúpiť vybraný vlak. Shift+klik zobrazí predpokladanú cenu bez nákupu. STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Kúpiť vybrané vozidlo. Shift+klik zobrazí predpokladanú cenu bez nákupu STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Kúpiť vybranú loď. Shift+klik zobrazí predpokladanú cenu bez nákupu STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Kúpiť vybrané lietadlo. Shift+klik zobrazí predpokladanú cenu bez nákupu + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Premenovať STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Premenovať STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Premenovať @@ -3573,13 +3564,16 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Chystá # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Správa od výrobcu dopravných prostriedkov STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Práve sme navrhli nov{G "ý" "ú" "é"} {STRING} - máte záujem o právo exkluzívneho používania na 1 rok? Chceme otestovať vlastnosti tohto modelu pred jeho uvedením na trh. + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :{G=z}železničná lokomotíva -STR_ENGINE_PREVIEW_ROAD_VEHICLE :{G=m}automobil -STR_ENGINE_PREVIEW_AIRCRAFT :{G=s}lietadlo -STR_ENGINE_PREVIEW_SHIP :{G=z}loď STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :{G=z}jednokoľajová lokomotíva STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :{G=z}magnetická lokomotíva +STR_ENGINE_PREVIEW_ROAD_VEHICLE :{G=m}automobil + +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_MAX_SPEED_CAP_RUNCOST :{BLACK}Cena: {CURRENCY_LONG} Max. Rýchlosť: {VELOCITY}{}Kapacita: {CARGO_LONG}{}Prevádzkové náklady: {CURRENCY_LONG}/rok @@ -3620,6 +3614,7 @@ STR_REPLACE_ELRAIL_VEHICLES :Elektrické lok STR_REPLACE_MONORAIL_VEHICLES :Lokomotíva pre jednokoľajku STR_REPLACE_MAGLEV_VEHICLES :Lokomotíva pre magnetickú dráhu + STR_REPLACE_REMOVE_WAGON :{BLACK}Odstránenie vagónu: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Zachovanie pôvodnej dĺžky vlaku, odstránením vagónov (odpredu), keď by funkcia automatickej zmeny rušňa vlak predĺžila @@ -4067,6 +4062,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Vybrať STR_AI_LIST_CANCEL :{BLACK}Zrušiť STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Nemeniť skript + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parametre STR_AI_SETTINGS_CAPTION_AI :Imelá inteligencia @@ -4338,7 +4334,7 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Najprv j STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Žiadne použiteľné železničné koľaje STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Musíš najskôr odstrániť železničné koľaje STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Cesta je jednosmerná alebo blokovaná. -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Nie sú povolené priecestia pre tento typ železníc +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Nie sú povolené priecestia pre tento typ železníc STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Nemôžeš tu stavať návestidlá... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Nemôžeš tu stavať železničné koľaje... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Nemôžeš tu odstrániť železničné koľaje... diff --git a/src/lang/slovenian.txt b/src/lang/slovenian.txt index bb4f651db5..bf86b47715 100644 --- a/src/lang/slovenian.txt +++ b/src/lang/slovenian.txt @@ -11,8 +11,6 @@ ##case r d t -# $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. # 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. @@ -625,9 +623,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Vklopi/Izklopi konzolo STR_ABOUT_MENU_AI_DEBUG :Razhročevanje UI / skript STR_ABOUT_MENU_SCREENSHOT :Zajemi sliko -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Zajemi približano sliko -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Zajem slike pri privzeti povečavi -STR_ABOUT_MENU_GIANT_SCREENSHOT :Zajemi celostno sliko STR_ABOUT_MENU_ABOUT_OPENTTD :O 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Uravnavanje sličice STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Vklop/izklop okvirjev @@ -797,9 +792,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Po meri 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Glasnost glasbe STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Glasnost zvokov -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}MIN -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}MAX -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -963,6 +955,7 @@ STR_NEWS_MERGER_TAKEOVER_TITLE :{BIG_FONT}{BLAC STR_PRESIDENT_NAME_MANAGER :{BLACK}{PRESIDENT_NAME}{}(Direktor) STR_NEWS_NEW_TOWN :{BLACK}{BIG_FONT}{STRING} sponzorirana gradnja novega mesta {TOWN}! +STR_NEWS_NEW_TOWN_UNSPONSORED :{BLACK}{BIG_FONT}Novo mesto z imenom {TOWN} je bilo zgrajeno! STR_NEWS_INDUSTRY_CONSTRUCTION :{BIG_FONT}{BLACK}Na novo se gradi {STRING} blizu mesta {TOWN}! STR_NEWS_INDUSTRY_PLANTED :{BIG_FONT}{BLACK}Postavlja se {STRING} blizu mesta {TOWN}! @@ -1011,6 +1004,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}Novo! {STRING} sedaj na razpolago! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} ne sprejema več {STRING.r} STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} ne sprejema več {STRING.r} ali {STRING.r} STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} sedaj sprejema {STRING.t} @@ -1838,7 +1832,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Razpore STR_CONFIG_SETTING_AI :{ORANGE}Tekmeci STR_CONFIG_SETTING_AI_NPC :{ORANGE}Računalniški igralci -STR_CONFIG_SETTING_PATHFINDER_OPF :Original STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Priporočeno) @@ -1921,13 +1914,9 @@ STR_QUIT_NO :{BLACK}Ne # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -1956,6 +1945,7 @@ STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Spremeni STR_CHEAT_SETUP_PROD :{LTBLUE}Omogoči spreminjanje proizvodnih vrednosti: {ORANGE}{STRING} # Livery window +STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Barvna shema STR_LIVERY_GENERAL_TOOLTIP :{BLACK}Prikaz glavnih barvnih shem STR_LIVERY_TRAIN_TOOLTIP :{BLACK}Prikaz barvnih shem vlakov @@ -2555,6 +2545,7 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Zgradi p STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Preklopi gradnja/rušenje cestnih konstrukcij STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Preklop gradi/odstrani za tramvaj progo + # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Smer garaže STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}Izberi smer garaže @@ -3414,8 +3405,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Infrastr STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Kosi tirov: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Signali STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Odseki cest: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Cesta -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Tramvaj STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Polja vode: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Kanali STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Postaje: @@ -3426,8 +3415,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Industrije STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Brez - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% prepeljano) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% prepeljano) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Imena industrij - klikni na ime za pogled na industrijo. Ctrl+Klik odpre nov pogled na lokaciji industrije @@ -3489,6 +3476,7 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Cestna vozila b STR_GROUP_DEFAULT_SHIPS :Ladje brez skupine STR_GROUP_DEFAULT_AIRCRAFTS :Letala brez skupine + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Skupine - Klikni na skupino za seznam vseh vozil v skupini STR_GROUP_CREATE_TOOLTIP :{BLACK}Klikni za ustvarit skupino STR_GROUP_DELETE_TOOLTIP :{BLACK}Izbriši izbrano skupino @@ -3510,10 +3498,13 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Nova električn STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Nova enotirna vozila STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Nova magnetna vozila -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Nova tirna vozila STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Nova cestna vozila + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Nova tirna vozila STR_BUY_VEHICLE_SHIP_CAPTION :Nove ladje STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Nova letala +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Cena: {GOLD}{CURRENCY_LONG}{BLACK} Teža: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Hitrost: {GOLD}{VELOCITY}{BLACK} Moč: {GOLD}{POWER} @@ -3546,11 +3537,13 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Kupi voz STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Kupi ladjo STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Kupi letalo + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Kupi izbrano železniško vozilo. Shift+Klik prikaže predviden strošek brez nakupa STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Kupi izbrano cestno vozilo. Shift+Klik prikaže predviden strošek brez nakupa STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Kupi izbrano ladjo. Shift+Klik prikaže predviden strošek brez nakupa STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Kupi izbrano letalo. Shift+Klik prikaže predviden strošek brez nakupa + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Preimenuj STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Preimenuj STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Preimenuj @@ -3659,13 +3652,16 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Priprav # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Sporočilo od proizvajalca vozila STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Na novo smo izdelali {STRING} - ali te zanima enoletna izključna pravica do{}uporabe tega vozila, preden ga ponudimo{}na trgu? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :železniška lokomotiva -STR_ENGINE_PREVIEW_ROAD_VEHICLE :cestno vozilo -STR_ENGINE_PREVIEW_AIRCRAFT :letalo -STR_ENGINE_PREVIEW_SHIP :ladja STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :enotirna lokomotiva STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :magnetna lokomotiva +STR_ENGINE_PREVIEW_ROAD_VEHICLE :cestno vozilo + +STR_ENGINE_PREVIEW_AIRCRAFT :letalo +STR_ENGINE_PREVIEW_SHIP :ladja + STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Cena: {CURRENCY_LONG} Teža: {WEIGHT_SHORT}{}Hitrost: {VELOCITY} Moč: {POWER}{}Cena delovanja: {CURRENCY_LONG}/leto{}Zmogljivost: {CARGO_LONG} STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Cena: {CURRENCY_LONG} Teža: {WEIGHT_SHORT}{}Hitrost: {VELOCITY} Moč: {POWER} Max. T.E.: {6:FORCE}{}Stroški: {4:CURRENCY_LONG}/yr{}Zmogljivost: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Cena: {CURRENCY_LONG} Max. hitrost: {VELOCITY}{}Zmogljivost: {CARGO_LONG}{}Cena delovanja: {CURRENCY_LONG}/leto @@ -3707,6 +3703,7 @@ STR_REPLACE_ELRAIL_VEHICLES :Električna tir STR_REPLACE_MONORAIL_VEHICLES :Enotirna vozila STR_REPLACE_MAGLEV_VEHICLES :Magnetna tirna vozila + STR_REPLACE_REMOVE_WAGON :{BLACK}Odstranitev vagonov: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Dovoli samozamenjavi, da z odstranitvijo vagonov, začenši na začetku, ohrani isto dolžino vlaka, če bi ga menjava lokomotive podaljšala @@ -3924,6 +3921,7 @@ STR_ORDER_CONDITIONAL_AGE :Starost (leta) STR_ORDER_CONDITIONAL_REQUIRES_SERVICE :Potrebuje servis STR_ORDER_CONDITIONAL_UNCONDITIONALLY :Vedno STR_ORDER_CONDITIONAL_REMAINING_LIFETIME :Preostala življenjska doba (let) +STR_ORDER_CONDITIONAL_MAX_RELIABILITY :Največja zanesljivost STR_ORDER_CONDITIONAL_COMPARATOR_TOOLTIP :{BLACK}Kako primerjati podatke vozila na podano vrednost STR_ORDER_CONDITIONAL_COMPARATOR_EQUALS :je enaka @@ -4154,6 +4152,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Izberi o STR_AI_LIST_CANCEL :{BLACK}Prekliči STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Ne spremeni skripte + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parametri STR_AI_SETTINGS_CAPTION_AI :UI @@ -4425,7 +4424,7 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Najprej STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Ni primernih tračnic STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Najprej moraš odstraniti tračnice STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Cesta je enosmerna ali blokirana -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Istonivojna križišča niso dovoljena za ta tip železnice +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Istonivojna križišča niso dovoljena za ta tip železnice STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Tukaj ni mogoče zgraditi signalov... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Tukaj ni mogoče zgraditi železniških tirov... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Tukaj ni mogoče odstraniti železniških tirov... @@ -4607,6 +4606,7 @@ STR_BASESOUNDS_DOS_DESCRIPTION :Originalni zvok STR_BASESOUNDS_WIN_DESCRIPTION :Originalni zvoki Transport Tycoon Deluxe različice oken(windows). STR_BASESOUNDS_NONE_DESCRIPTION :Zvočni paket brez zvoka. STR_BASEMUSIC_WIN_DESCRIPTION :Originalna glasba Transport Tycoon Deluxe različice oken(windows). +STR_BASEMUSIC_DOS_DESCRIPTION :Originalna glasba Transport Tycoon Deluxe DOS različice STR_BASEMUSIC_NONE_DESCRIPTION :Glasbeni paket z vključeno glasbo. ##id 0x2000 diff --git a/src/lang/spanish.txt b/src/lang/spanish.txt index a2ad54b6af..517dfe5b1e 100644 --- a/src/lang/spanish.txt +++ b/src/lang/spanish.txt @@ -11,8 +11,6 @@ ##gender m f -# $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. # 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. @@ -191,6 +189,7 @@ STR_COLOUR_BROWN :Marrón STR_COLOUR_GREY :Gris STR_COLOUR_WHITE :Blanco STR_COLOUR_RANDOM :Aleatorio +STR_COLOUR_DEFAULT :Por Defecto # Units used in OpenTTD STR_UNITS_VELOCITY_IMPERIAL :{COMMA}{NBSP}mph @@ -237,6 +236,8 @@ STR_TOOLTIP_FILTER_CRITERIA :{BLACK}Seleccio STR_BUTTON_SORT_BY :{BLACK}Ordenar por STR_BUTTON_LOCATION :{BLACK}Sitio STR_BUTTON_RENAME :{BLACK}Renombrar +STR_BUTTON_CATCHMENT :{BLACK}Cobertura +STR_TOOLTIP_CATCHMENT :{BLACK}Mostrar u ocultar área de cobertura STR_TOOLTIP_CLOSE_WINDOW :{BLACK}Cerrar ventana STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Título de la ventana - arrastre para moverla @@ -265,6 +266,7 @@ STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT_TOOLTIP :{BLACK}Al activ STR_BUTTON_DEFAULT :{BLACK}Por defecto STR_BUTTON_CANCEL :{BLACK}Cancelar STR_BUTTON_OK :{BLACK}OK +STR_WARNING_PASSWORD_SECURITY :{YELLOW}Advertencia: Los administradores del servidor podrían ser capaz de leer cualquier texto introducido aquí. # On screen keyboard window STR_OSK_KEYBOARD_LAYOUT :º1234567890'¡\qwertyuiop`+asdfghjklñ´ç @@ -3054,6 +3116,7 @@ STR_TOWN_VIEW_RENAME_TOWN_BUTTON :Renombrar Munic # Town local authority window STR_LOCAL_AUTHORITY_CAPTION :{WHITE}{TOWN} autoridad local +STR_LOCAL_AUTHORITY_ZONE :{BLACK}Zona STR_LOCAL_AUTHORITY_COMPANY_RATINGS :{BLACK}Calificación de empresas de transporte: STR_LOCAL_AUTHORITY_COMPANY_RATING :{YELLOW}{COMPANY} {COMPANY_NUM}: {ORANGE}{STRING} STR_LOCAL_AUTHORITY_ACTIONS_TITLE :{BLACK}Acciones disponibles: @@ -3082,6 +3145,7 @@ STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}Soborna # Goal window STR_GOALS_CAPTION :{WHITE}Metas de {COMPANY} STR_GOALS_SPECTATOR_CAPTION :{WHITE}Metas Globales +STR_GOALS_SPECTATOR :Metas Globales STR_GOALS_GLOBAL_TITLE :{BLACK}Metas globales: STR_GOALS_TEXT :{ORANGE}{STRING} STR_GOALS_NONE :{ORANGE}- Ninguna - @@ -3130,6 +3194,7 @@ STR_SUBSIDIES_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Click so # Story book window STR_STORY_BOOK_CAPTION :{WHITE}Historial de {COMPANY} STR_STORY_BOOK_SPECTATOR_CAPTION :{WHITE}Historial Global +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}Permite saltar a una página específica al seleccionarla en esta lista desplegable @@ -3309,8 +3374,7 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Infraest STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Trozos de ferrocarril: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Señales STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Trozos de carretera: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Carretera -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Tranvía +STR_COMPANY_INFRASTRUCTURE_VIEW_TRAM_SECT :{GOLD}Piezas de tranvía: STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Casillas de agua: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Canales STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Estaciones: @@ -3321,8 +3385,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Industrias STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Ninguna - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% transportado) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% transportado) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Nombre de industrias - Click sobre un nombre para centrar la vista principal en la industria. Ctrl+Click abre un punto de vista en dicha posición @@ -3336,6 +3398,7 @@ STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE :{YELLOW}La indu STR_INDUSTRY_VIEW_REQUIRES_N_CARGO :{BLACK}Requiere: {YELLOW}{STRING}{STRING} STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Produce: {YELLOW}{STRING}{STRING} +STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{STRING} STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Necesita: STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING} @@ -3389,10 +3452,13 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Vehículos de c STR_GROUP_DEFAULT_SHIPS :Barcos sin agrupar STR_GROUP_DEFAULT_AIRCRAFTS :Aeronaves sin agrupar +STR_GROUP_COUNT_WITH_SUBGROUP :{TINY_FONT}{COMMA} (+{COMMA}) + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Grupos - Click en un grupo para ver la lista de sus vehículos. Es posible arrastrar grupos para modificar su jerarquía. STR_GROUP_CREATE_TOOLTIP :{BLACK}Click para crear un grupo STR_GROUP_DELETE_TOOLTIP :{BLACK}Borrar el grupo seleccionado STR_GROUP_RENAME_TOOLTIP :{BLACK}Renombrar el grupo seleccionado +STR_GROUP_LIVERY_TOOLTIP :{BLACK}Cambiar el color del grupo seleccionado STR_GROUP_REPLACE_PROTECTION_TOOLTIP :{BLACK}Click para proteger este grupo del auto reemplazado global STR_QUERY_GROUP_DELETE_CAPTION :{WHITE}Borrar Grupo @@ -3414,12 +3480,18 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Nuevos Vehícul STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Nuevos Vehículos de Monorraíl STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Nuevos Vehículos Maglev -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Nuevos Vehículos de Ferrocarril STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Nuevos Vehículos de Carretera +STR_BUY_VEHICLE_TRAM_VEHICLE_CAPTION :Vehículos de Tranvía Nuevos + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Nuevos Vehículos de Ferrocarril +STR_BUY_VEHICLE_ROAD_VEHICLE_ALL_CAPTION :Vehículos de Carretera Nuevos STR_BUY_VEHICLE_SHIP_CAPTION :Nuevos Barcos STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Nueva Aeronave +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Coste: {GOLD}{CURRENCY_LONG}{BLACK} Peso: {GOLD}{WEIGHT_SHORT} +STR_PURCHASE_INFO_COST_REFIT_WEIGHT :{BLACK}Precio: {GOLD}{CURRENCY_LONG}{BLACK} (Costo de Reforma: {GOLD}{CURRENCY_LONG}{BLACK}) Peso: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Velocidad: {GOLD}{VELOCITY}{BLACK} Potencia: {GOLD}{POWER} STR_PURCHASE_INFO_SPEED :{BLACK}Velocidad: {GOLD}{VELOCITY} STR_PURCHASE_INFO_SPEED_OCEAN :{BLACK}Velocidad en el océano: {GOLD}{VELOCITY} @@ -3430,12 +3502,15 @@ STR_PURCHASE_INFO_REFITTABLE :(reformable) STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Diseñado: {GOLD}{NUM}{BLACK} Vida: {GOLD}{COMMA} año{P "" s} STR_PURCHASE_INFO_RELIABILITY :{BLACK}Fiabilidad máxima: {GOLD}{COMMA}% STR_PURCHASE_INFO_COST :{BLACK}Coste: {GOLD}{CURRENCY_LONG} +STR_PURCHASE_INFO_COST_REFIT :{BLACK}Precio: {GOLD}{CURRENCY_LONG}{BLACK} (Costo de Reforma: {GOLD}{CURRENCY_LONG}{BLACK}) STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Peso: {GOLD}{WEIGHT_SHORT} ({WEIGHT_SHORT}) STR_PURCHASE_INFO_COST_SPEED :{BLACK}Coste: {GOLD}{CURRENCY_LONG}{BLACK} Velocidad: {GOLD}{VELOCITY} +STR_PURCHASE_INFO_COST_REFIT_SPEED :{BLACK}Precio: {GOLD}{CURRENCY_LONG}{BLACK} (Costo de Reforma: {GOLD}{CURRENCY_LONG}{BLACK}) Velocidad: {GOLD}{VELOCITY} STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Capacidad: {GOLD}{CARGO_LONG}, {CARGO_LONG} STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Vagones con motor: {GOLD}+{POWER}{BLACK} Peso: {GOLD}+{WEIGHT_SHORT} STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Reformable a: {GOLD}{STRING} STR_PURCHASE_INFO_ALL_TYPES :Todos los tipos de carga +STR_PURCHASE_INFO_NONE :Sin carga STR_PURCHASE_INFO_ALL_BUT :Todo excepto {CARGO_LIST} STR_PURCHASE_INFO_MAX_TE :{BLACK}F.T máxima: {GOLD}{FORCE} STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Alcance: {GOLD}{COMMA} casillas @@ -3451,11 +3526,21 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Comprar STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Comprar barco STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Comprar aeronave +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Comprar y Reformar Vehículo +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Comprar y Reformar Vehículo +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Comprar y Reformar Barco +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Comprar y Reformar Aeronave + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Compra el vehículo de ferrocarril resaltado. Shift+Click muestra una estimación del precio sin realizar la compra STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Comprar el vehículo de carretera resaltado. Shift+Click muestra una estimación del precio sin realizar la compra STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Comprar el barco resaltado. Shift+Click muestra una estimación del precio sin realizar la compra STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Comprar la aeronave resaltada. Shift+Click muestra una estimación del precio sin realizar la compra +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Comprar y reformar el vehículo de ferrocarril resaltado. Shift+Click muestra una estimación del precio sin realizar la compra +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Comprar y reformar el vehículo resaltado. Shift+Click muestra una estimación del precio sin realizar la compra +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Comprar y reformar el barco resaltado. Shift+Click muestra una estimación del precio sin realizar la compra +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}}Comprar y reformar la aeronave resaltada. Shift+Click muestra una estimación del precio sin realizar la compra + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Renombrar STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Renombrar STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Renombrar @@ -3564,13 +3649,18 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Está a # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Mensaje del fabricante de vehículos STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Hemos diseñado un{G "" a} nuev{G o a} {STRING} - ¿estaría interesado en el uso exclusivo por un año de este vehículo, para que podamos comprobar cómo rinde antes de que esté universalmente disponible? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :{G=f}locomotora -STR_ENGINE_PREVIEW_ROAD_VEHICLE :{G=m}vehículo de carretera -STR_ENGINE_PREVIEW_AIRCRAFT :{G=f}aeronave -STR_ENGINE_PREVIEW_SHIP :{G=m}barco +STR_ENGINE_PREVIEW_ELRAIL_LOCOMOTIVE :Locomotora de ferrocarril eléctrico STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :{G=f}locomotora de monorraíl STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :{G=f}locomotora maglev +STR_ENGINE_PREVIEW_ROAD_VEHICLE :{G=m}vehículo de carretera +STR_ENGINE_PREVIEW_TRAM_VEHICLE :vehículo de tranvía + +STR_ENGINE_PREVIEW_AIRCRAFT :{G=f}aeronave +STR_ENGINE_PREVIEW_SHIP :{G=m}barco + STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Coste: {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}Coste: {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_MAX_SPEED_CAP_RUNCOST :{BLACK}Coste: {CURRENCY_LONG} Velocidad Máx.: {VELOCITY}{}Capacidad: {CARGO_LONG}{}Coste Mantenimiento: {CURRENCY_LONG}/año @@ -3608,14 +3698,19 @@ STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK}Cambia e STR_REPLACE_ENGINES :Locomotoras STR_REPLACE_WAGONS :Vagones STR_REPLACE_ALL_RAILTYPE :Todos los vehículos ferroviarios +STR_REPLACE_ALL_ROADTYPE :Todos los vehículos de carretera STR_REPLACE_HELP_RAILTYPE :{BLACK}Seleccione tipo de ferrocarril para el que desea reemplazar locomotoras +STR_REPLACE_HELP_ROADTYPE :{BLACK}Selecciona el tipo de carretera para el que se desea reemplazar vehículos STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Muestra con qué vehículo está siendo reemplazado el vehículo de la izquierda STR_REPLACE_RAIL_VEHICLES :Vehículos de Ferrocarril STR_REPLACE_ELRAIL_VEHICLES :Vehículos de Ferrocarril Eléctrico STR_REPLACE_MONORAIL_VEHICLES :Vehículos de Monorraíl STR_REPLACE_MAGLEV_VEHICLES :Vehículos Maglev +STR_REPLACE_ROAD_VEHICLES :Vehículos Terrestres +STR_REPLACE_TRAM_VEHICLES :Vehículos de Tranvía + STR_REPLACE_REMOVE_WAGON :{BLACK}Retirar vagón: {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 @@ -4066,6 +4161,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Seleccio STR_AI_LIST_CANCEL :{BLACK}Cancelar STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}No cambiar de script + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}Parámetros {STRING} STR_AI_SETTINGS_CAPTION_AI :IA @@ -4268,7 +4364,6 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... esta STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... carretera en la dirección incorrecta STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... las estaciones de autobús de paso no pueden tener esquinas STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... las estaciones de autobús de paso no pueden tener intersecciones -STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... carretera de un solo sentido o bloqueada # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}No se puede retirar parte de la estación... @@ -4338,7 +4433,8 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Primero STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Tramo de ferrocarril no apropiado STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Primero se debe retirar tramo de ferrocarril STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Carretera de un solo sentido o bloqueada -STR_ERROR_CROSSING_DISALLOWED :{WHITE}No se permiten pasos a nivel para este tipo de ferrocarril +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}No se permiten pasos a nivel para este tipo de ferrocarril +STR_ERROR_CROSSING_DISALLOWED_ROAD :{WHITE}No se permiten pasos a nivel para este tipo de carretera STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}No se pueden construir señales aquí... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}No se pueden construir ferrocarriles aquí... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}No se pueden retirar ferrocarriles aquí... @@ -4358,6 +4454,12 @@ STR_ERROR_CAN_T_REMOVE_ROAD_FROM :{WHITE}No se pu STR_ERROR_CAN_T_REMOVE_TRAMWAY_FROM :{WHITE}No se puede retirar tranvía de aquí... STR_ERROR_THERE_IS_NO_ROAD :{WHITE}... no hay carretera STR_ERROR_THERE_IS_NO_TRAMWAY :{WHITE}... no hay tranvía +STR_ERROR_CAN_T_CONVERT_ROAD :{WHITE}No es posible transformar esta carretera... +STR_ERROR_CAN_T_CONVERT_TRAMWAY :{WHITE}No se puede convertir el tipo de tranvía aquí... +STR_ERROR_NO_SUITABLE_ROAD :{WHITE}No hay carretera adecuada +STR_ERROR_NO_SUITABLE_TRAMWAY :{WHITE}No hay un tranvía adecuado +STR_ERROR_INCOMPATIBLE_ROAD :{WHITE}... carretera incompatible +STR_ERROR_INCOMPATIBLE_TRAMWAY :{WHITE}... tranvía incompatible # Waterway construction errors STR_ERROR_CAN_T_BUILD_CANALS :{WHITE}No pueden construirse canales aquí... @@ -4410,6 +4512,7 @@ STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}No se pu STR_ERROR_GROUP_CAN_T_DELETE :{WHITE}No se puede borrar grupo... STR_ERROR_GROUP_CAN_T_RENAME :{WHITE}No se puede renombrar grupo... STR_ERROR_GROUP_CAN_T_SET_PARENT :{WHITE}No se puede establecer la jerarquía de grupos... +STR_ERROR_GROUP_CAN_T_SET_PARENT_RECURSION :{WHITE}... No se permiten bucles en la jerarquía del grupo STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}No se pueden quitar todos los vehículos de este grupo... STR_ERROR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}No se puede añadir el vehículo a este grupo... STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}No se pueden añadir vehículos compartidos al grupo... diff --git a/src/lang/spanish_MX.txt b/src/lang/spanish_MX.txt index e39254134e..ce99c9ca49 100644 --- a/src/lang/spanish_MX.txt +++ b/src/lang/spanish_MX.txt @@ -11,8 +11,6 @@ ##gender m f -# $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. # 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. @@ -238,13 +236,15 @@ STR_TOOLTIP_FILTER_CRITERIA :{BLACK}Elegir c STR_BUTTON_SORT_BY :{BLACK}Ordenar por STR_BUTTON_LOCATION :{BLACK}Ubicación STR_BUTTON_RENAME :{BLACK}Cambiar nombre +STR_BUTTON_CATCHMENT :{BLACK}Cobertura +STR_TOOLTIP_CATCHMENT :{BLACK}Mostrar u ocultar área de cobertura STR_TOOLTIP_CLOSE_WINDOW :{BLACK}Cerrar ventana STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Título de la ventana (arrastrar para mover) STR_TOOLTIP_SHADE :{BLACK}Ocultar ventana (mostrar solo título) STR_TOOLTIP_DEBUG :{BLACK}Mostrar información de depuración de NewGRF -STR_TOOLTIP_DEFSIZE :{BLACK}Cambiar al tamaño predeterminado de la ventana. Ctrl+Clic guarda el tamaño actual como nuevo tamaño predeterminado -STR_TOOLTIP_STICKY :{BLACK}Excluir esta ventana de la función 'Cerrar todas las ventanas' (tecla Supr). Ctrl+Clic guarda esta preferencia como opción predeterminada +STR_TOOLTIP_DEFSIZE :{BLACK}Cambiar al tamaño por defecto de la ventana. Ctrl+Clic guarda el tamaño actual como nuevo tamaño por defecto +STR_TOOLTIP_STICKY :{BLACK}Excluir esta ventana de la función de la tecla "Cerrar todas las ventanas". Ctrl+Clic guarda esta preferencia como opción por defecto STR_TOOLTIP_RESIZE :{BLACK}Arrastrar para cambiar el tamaño de esta ventana STR_TOOLTIP_TOGGLE_LARGE_SMALL_WINDOW :{BLACK}Cambiar entre tamaño de ventana grande o pequeño STR_TOOLTIP_VSCROLL_BAR_SCROLLS_LIST :{BLACK}Barra de desplazamiento (mueve la lista arriba o abajo) @@ -263,9 +263,10 @@ STR_SHOW_HIDDEN_ENGINES_VEHICLE_SHIP_TOOLTIP :{BLACK}Activar STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT_TOOLTIP :{BLACK}Activar para mostrar también las aeronaves ocultas # Query window -STR_BUTTON_DEFAULT :{BLACK}Predeterminado +STR_BUTTON_DEFAULT :{BLACK}Por defecto STR_BUTTON_CANCEL :{BLACK}Cancelar STR_BUTTON_OK :{BLACK}Aceptar +STR_WARNING_PASSWORD_SECURITY :{YELLOW}Advertencia: los administradores del servidor tienen acceso al texto escrito aquí # On screen keyboard window STR_OSK_KEYBOARD_LAYOUT :|1234567890'¿\qwertyuiop´+asdfghjklñ{} @@ -3112,6 +3143,7 @@ STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW} Muta d # Goal window STR_GOALS_CAPTION :{WHITE}{COMPANY} Mål STR_GOALS_SPECTATOR_CAPTION :{WHITE}Globala mål +STR_GOALS_SPECTATOR :Globala mål STR_GOALS_GLOBAL_TITLE :{BLACK}Globala mål: STR_GOALS_TEXT :{ORANGE}{STRING} STR_GOALS_NONE :{ORANGE}- Inga - @@ -3160,6 +3192,7 @@ STR_SUBSIDIES_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Klicka f # Story book window STR_STORY_BOOK_CAPTION :{WHITE}{COMPANY} berättelsebok STR_STORY_BOOK_SPECTATOR_CAPTION :{WHITE}Global berättelsebok +STR_STORY_BOOK_SPECTATOR :Global berättelsebok STR_STORY_BOOK_TITLE :{YELLOW}{STRING} STR_STORY_BOOK_GENERIC_PAGE_ITEM :Sida {NUM} STR_STORY_BOOK_SEL_PAGE_TOOLTIP :{BLACK}Hoppa till valfri sida genom att välja sidan i denna lista @@ -3339,8 +3372,7 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Infrastr STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Järnvägsbitar: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Signaler STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Vägbitar: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Väg -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Spårväg +STR_COMPANY_INFRASTRUCTURE_VIEW_TRAM_SECT :{GOLD}Spårvagnsdelar: STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Vattenrutor: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Kanaler STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Stationer: @@ -3351,8 +3383,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Industrier STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Inga - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% transporterat) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% transporterat) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Industrinamn - klicka på namnet för att centrera huvudvyn över industrin. Ctrl+klick öppnar en ny vy över industrins läge @@ -3420,6 +3450,8 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Ogrupperade vä STR_GROUP_DEFAULT_SHIPS :Ogrupperade skepp STR_GROUP_DEFAULT_AIRCRAFTS :Ogrupperade flygmaskiner +STR_GROUP_COUNT_WITH_SUBGROUP :{TINY_FONT}{COMMA} (+{COMMA}) + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Grupper - klicka på en grupp för att lista alla fordon i gruppen. Dra och släpp grupper för att ordna hierarkin. STR_GROUP_CREATE_TOOLTIP :{BLACK}Klicka för att skapa en grupp STR_GROUP_DELETE_TOOLTIP :{BLACK}Ta bort vald grupp @@ -3446,12 +3478,18 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Nya elektriska STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Nytt monorailfordon STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Nytt maglevfordon -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Nya rälsfordon STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Nytt Vägfordon +STR_BUY_VEHICLE_TRAM_VEHICLE_CAPTION :Nya spårvägsfordon + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Nya rälsfordon +STR_BUY_VEHICLE_ROAD_VEHICLE_ALL_CAPTION :Nya vägfordon STR_BUY_VEHICLE_SHIP_CAPTION :Nytt skepp STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Nytt flygplan +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Kostnad: {GOLD}{CURRENCY_LONG}{BLACK} Vikt: {GOLD}{WEIGHT_SHORT} +STR_PURCHASE_INFO_COST_REFIT_WEIGHT :{BLACK}Kostnad: {GOLD}{CURRENCY_LONG}{BLACK} (Kostnad för anpassning: {GOLD}{CURRENCY_LONG}{BLACK}) Vikt: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Hastighet: {GOLD}{VELOCITY}{BLACK} Kraft: {GOLD}{POWER} STR_PURCHASE_INFO_SPEED :{BLACK}Hastighet: {GOLD}{VELOCITY} STR_PURCHASE_INFO_SPEED_OCEAN :{BLACK}Hastighet i hav: {GOLD}{VELOCITY} @@ -3462,8 +3500,10 @@ STR_PURCHASE_INFO_REFITTABLE :(anpassningsbar STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Designår: {GOLD}{NUM}{BLACK} Livslängd: {GOLD}{COMMA} år STR_PURCHASE_INFO_RELIABILITY :{BLACK}Max. tillförlitlighet: {GOLD}{COMMA} % STR_PURCHASE_INFO_COST :{BLACK}Kostnad: {GOLD}{CURRENCY_LONG} +STR_PURCHASE_INFO_COST_REFIT :{BLACK}Kostnad: {GOLD}{CURRENCY_LONG}{BLACK} (Anpassningskostnad: {GOLD}{CURRENCY_LONG}{BLACK}) STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Vikt: {GOLD}{WEIGHT_SHORT} ({WEIGHT_SHORT}) STR_PURCHASE_INFO_COST_SPEED :{BLACK}Kostnad: {GOLD}{CURRENCY_LONG}{BLACK} Hastighet: {GOLD}{VELOCITY} +STR_PURCHASE_INFO_COST_REFIT_SPEED :{BLACK}Kostnad: {GOLD}{CURRENCY_LONG}{BLACK} (Kostnad för anpassning: {GOLD}{CURRENCY_LONG}{BLACK}) Hastighet: {GOLD}{VELOCITY} STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Kapacitet: {GOLD}{CARGO_LONG}, {CARGO_LONG} STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Motoriserade vagnar: {GOLD}+{POWER}{BLACK} Vikt: {GOLD}+{WEIGHT_SHORT} STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Anpassningsbar till: {GOLD}{STRING} @@ -3484,11 +3524,21 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Köp for STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Köp skepp STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Köp flygplan +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Köp och anpassa fordon +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Köp och anpassa fordon +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Köp och anpassa skepp +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Köp och anpassa flygplan + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Köp markerad tågvagn. Shift+klick visar kostnad utan att köpa STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Köp markerat vägfordon. Shift+klick visar kostnad utan att köpa STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Köp markerat skepp. Shift+klick visar kostnad utan att köpa STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Köp markerat flygplan. Shift+klick visar kostnad utan att köpa +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Köp och anpassa markerat tåg. Shift+klick visar kostnad utan att köpa +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Köp och anpassa markerat vägfordon. Shift+klick visar kostnad utan att köpa +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Köp och anpassa markerat skepp. Shift+klick visar kostnad utan att köpa +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Köp och anpassa markerat flygplan. Shift+klick visar kostnad utan att köpa + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Byt namn på STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Byt namn på STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Byt namn på @@ -3597,13 +3647,18 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Du är # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Meddelande från fordonstillverkare STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Vi har just designat ett nytt {STRING} - är du intresserad av ett års exklusiv användning av detta fordon, så vi kan se hur det presterar innan vi gör det allmänt tillgängligt? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :järnvägslok -STR_ENGINE_PREVIEW_ROAD_VEHICLE :vägfordon -STR_ENGINE_PREVIEW_AIRCRAFT :flygplan -STR_ENGINE_PREVIEW_SHIP :skepp +STR_ENGINE_PREVIEW_ELRAIL_LOCOMOTIVE :elektrifierat järnvägslok STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :monorail-lok STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :maglev-lok +STR_ENGINE_PREVIEW_ROAD_VEHICLE :vägfordon +STR_ENGINE_PREVIEW_TRAM_VEHICLE :spårvägsfordon + +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}{}Löpande kostnad: {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}{}Löpande kostnad: {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}{}Körkostnad: {CURRENCY_LONG}/år @@ -3641,14 +3696,19 @@ STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK}Växla m STR_REPLACE_ENGINES :Lok STR_REPLACE_WAGONS :Vagnar STR_REPLACE_ALL_RAILTYPE :Alla järnvägsfordon +STR_REPLACE_ALL_ROADTYPE :Alla vägfordon STR_REPLACE_HELP_RAILTYPE :{BLACK}Välj vilken järnvägstyp du vill byta ut lok för +STR_REPLACE_HELP_ROADTYPE :{BLACK}Välj vilken vägtyp du vill byta ut motorer för STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Visa vilket fordon det vänstra fordonet byts ut till, om något STR_REPLACE_RAIL_VEHICLES :Järnvägsfordon STR_REPLACE_ELRAIL_VEHICLES :Elektriska järnvägsfordon STR_REPLACE_MONORAIL_VEHICLES :Monorail-fordon STR_REPLACE_MAGLEV_VEHICLES :Maglevfordon +STR_REPLACE_ROAD_VEHICLES :Vägfordon +STR_REPLACE_TRAM_VEHICLES :Spårvägsfordon + STR_REPLACE_REMOVE_WAGON :{BLACK}Vagnborttagning: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Gör så att automatiskt utbyte behåller ett tågs längd genom att ta bort vagnar (med början längst fram) om utbytandet av loket skulle göra tåget längre @@ -3790,7 +3850,7 @@ STR_VEHICLE_DETAILS_TRAIN_ARTICULATED_RV_CAPACITY :{BLACK}Kapacite # Vehicle refit STR_REFIT_CAPTION :{WHITE}{VEHICLE} (Anpassa) STR_REFIT_TITLE :{GOLD}Välj godstyp att frakta: -STR_REFIT_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Ny kapacitet: {GOLD}{CARGO_LONG}{}{BLACK}Anpassningens kostnad: {RED}{CURRENCY_LONG} +STR_REFIT_NEW_CAPACITY_COST_OF_REFIT :{BLACK}Ny kapacitet: {GOLD}{CARGO_LONG}{}{BLACK}Kostnad för anpassning: {RED}{CURRENCY_LONG} STR_REFIT_NEW_CAPACITY_INCOME_FROM_REFIT :{BLACK}Ny kapacitet: {GOLD}{CARGO_LONG}{}{BLACK}Inkomstens vinst: {GREEN}{CURRENCY_LONG} STR_REFIT_NEW_CAPACITY_COST_OF_AIRCRAFT_REFIT :{BLACK}Ny kapacitet: {GOLD}{CARGO_LONG}, {GOLD}{CARGO_LONG}{}{BLACK}Kostnad för anpassning: {RED}{CURRENCY_LONG} STR_REFIT_NEW_CAPACITY_INCOME_FROM_AIRCRAFT_REFIT :{BLACK}Ny kapacitet: {GOLD}{CARGO_LONG}. {GOLD}{CARGO_LONG}{}{BLACK}Inkomstens vinst: {GREEN}{CURRENCY_LONG} @@ -4099,6 +4159,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Välj ma STR_AI_LIST_CANCEL :{BLACK}Avbryt STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Ändra inte datorspelare + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} parametrar STR_AI_SETTINGS_CAPTION_AI :Datorspelarens @@ -4301,7 +4362,6 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... dett STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... vägen pekar i fel riktning STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... genomfartshållplatser kan inte ha gatuhörn STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... genomfartshållplatser kan inte ha korsningar -STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... vägen är enkelriktad eller blockerad # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Kan ej ta bort del av station... @@ -4371,7 +4431,8 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Måste t STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Inget passande järnvägsspår STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Måste ta bort järnväg först STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Vägen är enkelriktad eller blockerad -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Plankorsningar är inte tillåtna för denna typ av spår +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Plankorsningar är inte tillåtna för denna typ av spår +STR_ERROR_CROSSING_DISALLOWED_ROAD :{WHITE}Plankorsningar är inte tillåtna för denna vägtyp STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Kan inte bygga signaler här... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Kan inte bygga järnvägsspår här... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Kan inte ta bort järnvägspår här... @@ -4391,6 +4452,12 @@ STR_ERROR_CAN_T_REMOVE_ROAD_FROM :{WHITE}Kan inte STR_ERROR_CAN_T_REMOVE_TRAMWAY_FROM :{WHITE}Kan inte ta bort spårvagnsrälsen härifrån... STR_ERROR_THERE_IS_NO_ROAD :{WHITE}... det finns ingen väg STR_ERROR_THERE_IS_NO_TRAMWAY :{WHITE}... det finns ingen spårvagnsräls +STR_ERROR_CAN_T_CONVERT_ROAD :{WHITE}Kan inte konvertera vägtyp här... +STR_ERROR_CAN_T_CONVERT_TRAMWAY :{WHITE}Kan inte konvertera spårvagnstyp här... +STR_ERROR_NO_SUITABLE_ROAD :{WHITE}Ingen lämplig väg +STR_ERROR_NO_SUITABLE_TRAMWAY :{WHITE}Ingen passande spårväg +STR_ERROR_INCOMPATIBLE_ROAD :{WHITE}... oförenlig väg +STR_ERROR_INCOMPATIBLE_TRAMWAY :{WHITE}... oförenlig spårväg # Waterway construction errors STR_ERROR_CAN_T_BUILD_CANALS :{WHITE}Kan inte bygga kanaler här... @@ -4443,6 +4510,7 @@ STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Kan inte STR_ERROR_GROUP_CAN_T_DELETE :{WHITE}Kan inte ta bort denna grupp... STR_ERROR_GROUP_CAN_T_RENAME :{WHITE}Kan inte döpa om grupp... STR_ERROR_GROUP_CAN_T_SET_PARENT :{WHITE}Kan inte ställa in föräldragrupp ... +STR_ERROR_GROUP_CAN_T_SET_PARENT_RECURSION :{WHITE}... loopar i grupphierarkin är inte tillåtna STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}Kan inte ta bort alla fordon i denna grupp... STR_ERROR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}Kan inte lägga till fordon i denna grupp... STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}Kan inte lägga till delade fordon i denna grupp... diff --git a/src/lang/tamil.txt b/src/lang/tamil.txt index b429be2b85..c996e397e2 100644 --- a/src/lang/tamil.txt +++ b/src/lang/tamil.txt @@ -10,8 +10,6 @@ ##grflangid 0x0a -# $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. # 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. @@ -189,6 +187,8 @@ STR_COLOUR_ORANGE :ஆரஞ்ச STR_COLOUR_BROWN :பழுப்பு STR_COLOUR_GREY :சாம்பல் STR_COLOUR_WHITE :வெள்ளை +STR_COLOUR_RANDOM :ஏதோவொரு +STR_COLOUR_DEFAULT :இயல்பிருப்பு # Units used in OpenTTD STR_UNITS_VELOCITY_IMPERIAL :{COMMA}{NBSP}mph @@ -435,7 +435,7 @@ STR_RAIL_MENU_MAGLEV_CONSTRUCTION :மேக்ல ############ range for road construction menu starts STR_ROAD_MENU_ROAD_CONSTRUCTION :சாலை கட்டுமானம் -STR_ROAD_MENU_TRAM_CONSTRUCTION :ட்ரேம்வே கட்டுமானம் +STR_ROAD_MENU_TRAM_CONSTRUCTION :அமிழ் தண்டூர்திப் பாதை கட்டுமானம் ############ range ends here ############ range for waterways construction menu starts @@ -459,6 +459,7 @@ STR_TOOLBAR_SOUND_MUSIC :ஒலி/இ ############ range for message menu starts STR_NEWS_MENU_LAST_MESSAGE_NEWS_REPORT :கடைசி செய்தி/செய்தி அறிவிக்கை STR_NEWS_MENU_MESSAGE_HISTORY_MENU :செய்தி வரலாறு +STR_NEWS_MENU_DELETE_ALL_MESSAGES :எல்லா செய்திகளையும் நீக்கு ############ range ends here ############ range for about menu starts @@ -467,9 +468,7 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :முனையத்தை மாற்று STR_ABOUT_MENU_AI_DEBUG :AI/வரிவடிவம் சரிபார் STR_ABOUT_MENU_SCREENSHOT :திரைபிடிப்பு -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :முழுமையாக பெரிதாக்கிய நிலையில் திரைப்பிடிப்பு செய் -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :பெரிதாக்கிய நிலையில் திரைப்பிடிப்பு செய் -STR_ABOUT_MENU_GIANT_SCREENSHOT :முழு வரைபடத்தையும் திரைபிடிப்பு செய் +STR_ABOUT_MENU_SHOW_FRAMERATE :பிரேம் வீதத்தைக் காட்டு STR_ABOUT_MENU_ABOUT_OPENTTD :'OpenTTD' பற்றி STR_ABOUT_MENU_SPRITE_ALIGNER :ஸ்ரைட்டு அலைனர் STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :எல்லைக் கட்டங்களை மாற்றவும் @@ -529,7 +528,7 @@ STR_DAY_NUMBER_31ST :31வது ############ range for days ends ############ range for months starts -STR_MONTH_ABBREV_JAN :ஜனவரி +STR_MONTH_ABBREV_JAN :சனவரி STR_MONTH_ABBREV_FEB :பெப் STR_MONTH_ABBREV_MAR :மார்ச் STR_MONTH_ABBREV_APR :ஏப்ரல் @@ -635,12 +634,10 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}பாடல்பட்டியல் 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}ஒலி அளவு STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}ஒலியமைப்புகளின் அளவு -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}குறைந்தபட்ச -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}அதிகபட்ச -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ +STR_MUSIC_TITLE_NOMUSIC :{TINY_FONT}{DKGREEN}இசை எதுவும் கிடைக்கவில்லை STR_MUSIC_TITLE_NAME :{TINY_FONT}{DKGREEN}"{STRING}" STR_MUSIC_TRACK :{TINY_FONT}{BLACK}இசைத்தடம் STR_MUSIC_XTITLE :{TINY_FONT}{BLACK}தலைப்பு @@ -664,6 +661,7 @@ STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTB STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}இசைத்தடம் வரிசை STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}பிரோகிராம் - '{STRING}' STR_PLAYLIST_CLEAR :{TINY_FONT}{BLACK}அழி +STR_PLAYLIST_CHANGE_SET :{BLACK} மாற்று STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK :{BLACK}தற்போதைய பிரோகிராமிலிருந்து இசைத்தடத்தினை நீக்க சொடுக்கவும் (பயனரால் மாற்றப்பட்ட1 அல்லது 2 மட்டும்) # Highscore window @@ -835,6 +833,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}புதிய {STRING} இப்போது கிடைக்கும்! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} இனிமேல் {STRING} ஏற்றுக்கொள்ளாது STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} இனிமேல் {STRING} அல்லது {STRING} ஏற்றுக்கொள்ளாது STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} இப்போது {STRING} ஏற்றுக்கொள்கிறது @@ -849,6 +848,7 @@ STR_NEWS_EXCLUSIVE_RIGHTS_DESCRIPTION :{BIG_FONT}{BLAC # Extra view window STR_EXTRA_VIEW_PORT_TITLE :{WHITE}பார்வைப் படம் {COMMA} STR_EXTRA_VIEW_MOVE_VIEW_TO_MAIN :{BLACK}பார்படத்திற்கு மாற்றவும் +STR_EXTRA_VIEW_MOVE_MAIN_TO_VIEW :{BLACK}பிரதான பார்வையை மாற்றவும் # Game options window STR_GAME_OPTIONS_CAPTION :{WHITE}ஆட்டத்தின் அமைப்புகள் @@ -888,6 +888,7 @@ STR_GAME_OPTIONS_CURRENCY_LTL :லிதுவ STR_GAME_OPTIONS_CURRENCY_KRW :தென்கொரிய வொன் (KRW) STR_GAME_OPTIONS_CURRENCY_ZAR :தென் ஆப்பிரிக்க ரான்ட் (ZAR) STR_GAME_OPTIONS_CURRENCY_CUSTOM :புதிதாக... +STR_GAME_OPTIONS_CURRENCY_RUB :புதிய ரஷ்ய ரூபிள் (RUB) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}சாலை வாகனங்கள் @@ -923,6 +924,7 @@ STR_GAME_OPTIONS_TOWN_NAME_CATALAN :கடலன் ############ end of townname region STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}தானாக சேமி +STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}தானியங்கி விளையாட்டு சேமிப்பு இடைவெளியைத் தேர்ந்தெடுக்கவும் ############ start of autosave dropdown STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_OFF :Off @@ -936,6 +938,7 @@ STR_GAME_OPTIONS_LANGUAGE :{BLACK}மொ STR_GAME_OPTIONS_LANGUAGE_TOOLTIP :{BLACK}பயன்படுத்தப்போகும் மொழியினை தேர்ந்தெடு STR_GAME_OPTIONS_FULLSCREEN :{BLACK}முழு படம் +STR_GAME_OPTIONS_FULLSCREEN_TOOLTIP :{BLACK}OpenTTD-ஐ முழுத்திரையில் விளையாட இந்த கட்டத்தினை சொடுக்கவும் STR_GAME_OPTIONS_RESOLUTION :{BLACK}திரையின் அளவு STR_GAME_OPTIONS_RESOLUTION_TOOLTIP :{BLACK}திரை அளவினைத் தேர்ந்தெடுக்கவும் @@ -946,7 +949,9 @@ 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_2X_ZOOM :இரண்டு மடங்கு STR_GAME_OPTIONS_BASE_GRF :{BLACK}அடிப்படை அசைவூட்டம் STR_GAME_OPTIONS_BASE_GRF_TOOLTIP :{BLACK}பயன்படுத்தப்போகும் அடிப்படை அசைவூட்டத்தினை தேர்ந்தெடுக்கவும் @@ -973,6 +978,7 @@ STR_CURRENCY_INCREASE_EXCHANGE_RATE_TOOLTIP :{BLACK}உங STR_CURRENCY_SET_EXCHANGE_RATE_TOOLTIP :{BLACK}உங்களது நாணயத்தின் நாணயமாற்று விகிதத்தை ஒரு பவுண்டாக (£) அமைக்கவும் STR_CURRENCY_SEPARATOR :{LTBLUE}பிரிப்பான்: {ORANGE}{STRING} +STR_CURRENCY_SET_CUSTOM_CURRENCY_SEPARATOR_TOOLTIP :{BLACK}உங்களது நாணயத்தின் பிரியியினை அமை STR_CURRENCY_PREFIX :{LTBLUE}முன் ஒட்டு: {ORANGE}{STRING} STR_CURRENCY_SET_CUSTOM_CURRENCY_PREFIX_TOOLTIP :{BLACK}உங்கள் நாணயத்தின் முன் ஒட்டத்தினை அமையுங்கள் @@ -1125,7 +1131,7 @@ STR_CONFIG_SETTING_ROAD_VEHICLE_ACCELERATION_MODEL :சாலை STR_CONFIG_SETTING_TRAIN_SLOPE_STEEPNESS :இரயில்களின் மலை ஏறுதல் வேகத்தடை: {STRING} STR_CONFIG_SETTING_PERCENTAGE :{COMMA}% STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS :சாலை வாகங்களின் மலையேறுதல் வேகத்தடை: {STRING} -STR_CONFIG_SETTING_FORBID_90_DEG :இரயில் மற்றும் கப்பல்களை 90° வளைவுகள் எடுப்பதை அனுமதிக்காதே: {STRING} +STR_CONFIG_SETTING_FORBID_90_DEG :இரயில்கள் 90° வளைவுளை எடுப்பதை அனுமதிக்காதே: {STRING} STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS :நேரடியாக இணைக்கப்படாத நிலையங்களை இணைக்க அனுமதி: {STRING} STR_CONFIG_SETTING_INFLATION :விலைவாசி ஏற்றம்: {STRING} STR_CONFIG_SETTING_INFLATION_HELPTEXT :பண வீக்கத்தினை செயல்படுத்து, இதனால் செலவுகள் வளர்ச்சி வரவுகளின் வளர்ச்சியைவிட அதிகமாகும் @@ -1168,10 +1174,11 @@ STR_CONFIG_SETTING_PLANE_SPEED :விமான STR_CONFIG_SETTING_PLANE_SPEED_VALUE :1 / {COMMA} STR_CONFIG_SETTING_PLANE_CRASHES :விமான விபத்துகளின் எண்ணிக்கை: {STRING} STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :விமான விபத்து நிகழ்வதற்கான வாய்ப்புகளை அமை -STR_CONFIG_SETTING_PLANE_CRASHES_NONE :ஒன்றுமில்லை +STR_CONFIG_SETTING_PLANE_CRASHES_NONE :ஒன்றுமில்லை* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :குறைக்கப்பட்ட STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :இயல்பான STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :வழிசெல்லக்கூடிய சாலை நிறுத்தங்களை நகராட்சியின் சாலைகளில் அமைக்க அனுமதி: {STRING} +STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD_HELPTEXT :நகரத்திற்குச் சொந்தமான சாலைகளில் டிரைவ்-த்ரோ சாலை நிறுத்தங்களை உருவாக்க அனுமதிக்கவும் STR_CONFIG_SETTING_DYNAMIC_ENGINES_EXISTING_VEHICLES :{WHITE}வாகனங்கள் இருக்கும் பொது இந்த அமைப்பினை மாற்ற இயலாது STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE :கட்டட பராமரிப்பு: {STRING} @@ -1205,7 +1212,7 @@ STR_CONFIG_SETTING_LAND_GENERATOR :நில உ STR_CONFIG_SETTING_LAND_GENERATOR_ORIGINAL :உண்மையான STR_CONFIG_SETTING_LAND_GENERATOR_TERRA_GENESIS :TerraGenesis STR_CONFIG_SETTING_INDUSTRY_DENSITY :தொழிற்சாலை அடர்த்தி: {STRING} -STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE :வரைபட எல்லையிலிருந்து எண்ணெய் சுத்திகரிப்பு நிலையங்கள் இருக்கக்கூடிய தூரம்: {STRING} +STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE :வரைபட எல்லையிலிருந்து எண்ணெய் தொழிற்சாலைகள் இருக்கக்கூடிய தூரம்: {STRING} STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :எண்ணெய் சுத்திகரிப்பு நிலையங்கள் வரைபடத்தின் எல்லைகளில் மட்டுமே கட்ட இயலும், அதாவது தீவு வரைபடங்களில் கடற்கரைகளில் கட்ட இயலும் STR_CONFIG_SETTING_SNOWLINE_HEIGHT :பனி-கோடின் உயரம்: {STRING} STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN :நிலப்பகுதியின் சமனில்லாத நிலை (TerraGenesis மட்டும்) : {STRING} @@ -1213,6 +1220,7 @@ 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 :மிகவும் கரடுமுரடான +STR_CONFIG_SETTING_RIVER_AMOUNT :ஆறுகளின் எண்ணிக்கை: {STRING} STR_CONFIG_SETTING_TREE_PLACER :மரங்கள் நடும் வகை: {STRING} STR_CONFIG_SETTING_TREE_PLACER_NONE :ஒன்றுமில்லை STR_CONFIG_SETTING_TREE_PLACER_ORIGINAL :உண்மையான @@ -1268,6 +1276,8 @@ STR_CONFIG_SETTING_COMMAND_PAUSE_LEVEL_ALL_NON_CONSTRUCTION :அனைத் 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_LOADING_INDICATORS_HELPTEXT :வாகனங்களை ஏற்றுவதற்கு அல்லது இறக்குவதற்கு மேலே ஏற்றுதல் குறிகாட்டிகள் காட்டப்படுகிறதா என்பதைத் தேர்ந்தெடுக்கவும் +STR_CONFIG_SETTING_TIMETABLE_IN_TICKS :கால அட்டவணையை நாட்களில் அல்லாமல் சொடுக்குகளில் காட்டு: {STRING} STR_CONFIG_SETTING_TIMETABLE_SHOW_ARRIVAL_DEPARTURE :கால அட்டவணைகளில் காலங்களைக் காட்டவும்: {STRING} STR_CONFIG_SETTING_QUICKGOTO :வாகன கட்டளைகளை விரிவாக உருவாக்கவும்: {STRING} STR_CONFIG_SETTING_DEFAULT_RAIL_TYPE_FIRST :முதலில் கிடைக்கும் @@ -1321,16 +1331,19 @@ STR_CONFIG_SETTING_SERVINT_VALUE :{COMMA}{NBSP} STR_CONFIG_SETTING_SERVINT_DISABLED :செயலிழக்க செய்யப்பட்டது STR_CONFIG_SETTING_SERVINT_ROAD_VEHICLES :சாலை வாகனங்களின் பழுதுபார்த்தல் இடைவேளி: {STRING} STR_CONFIG_SETTING_SERVINT_AIRCRAFT :விமாங்களின் பழுதுபார்த்தல் இடைவேளி: {STRING} +STR_CONFIG_SETTING_SERVINT_AIRCRAFT_HELPTEXT :புதிய விமானங்களுக்கான இயல்புநிலை சேவை இடைவெளியை அமைக்கவும், வாகனத்திற்கு வெளிப்படையான சேவை இடைவெளி எதுவும் அமைக்கப்படவில்லை என்றால் STR_CONFIG_SETTING_SERVINT_SHIPS :கப்பல்களின் பழுதுபார்த்தல் இடைவேளி: {STRING} STR_CONFIG_SETTING_NOSERVICE :பழுதுகள் இல்லையெனில் பழுதுபார்த்தலினை செயலிழக்கவும்: {STRING} STR_CONFIG_SETTING_WAGONSPEEDLIMITS :பெட்டி வேக கட்டுப்பாட்டினை செயல்படுத்தவும்: {STRING} 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} STR_CONFIG_SETTING_NEWS_ACCIDENTS_DISASTERS :விபத்துகள் / பேரழிவுகள்: {STRING} STR_CONFIG_SETTING_NEWS_ACCIDENTS_DISASTERS_HELPTEXT :விபத்துகள் அல்லது பேரழிவுகள் நிகழும்போது செய்தித்தாள் ஒன்றினைக் காட்டு STR_CONFIG_SETTING_NEWS_COMPANY_INFORMATION :நிறுவனத்தின் விவரம்: {STRING} +STR_CONFIG_SETTING_NEWS_COMPANY_INFORMATION_HELPTEXT :ஒரு புதிய நிறுவனம் தொடங்கும் போது அல்லது நிறுவனங்கள் திவாலாகும் அபாயத்தில் இருக்கும்போது ஒரு செய்தித்தாளைக் காண்பி STR_CONFIG_SETTING_NEWS_INDUSTRY_OPEN :தொழிற்சாலைகளின் திறப்பு: {STRING} STR_CONFIG_SETTING_NEWS_INDUSTRY_OPEN_HELPTEXT :தொழிற்சாலைகள் திறக்கப்படும்போது செய்தித்தாளினைக் காட்டு STR_CONFIG_SETTING_NEWS_INDUSTRY_CLOSE :தொழிற்சாலைகளின் மூடல்: {STRING} @@ -1355,6 +1368,7 @@ STR_CONFIG_SETTING_COLOURED_NEWS_YEAR :நிற ச STR_CONFIG_SETTING_STARTING_YEAR :தொடங்கும் வருடம்: {STRING} STR_CONFIG_SETTING_SMOOTH_ECONOMY :இயல்பான பொருளாதாரத்தினைச் செயல்படுத்தவும் (அதிகமான, சிறிய மாற்றங்கள்): {STRING} STR_CONFIG_SETTING_ALLOW_SHARES :மற்ற நிறுவனங்களின் பங்குகளை வாங்குவதை அனுமதிக்கவும்: {STRING} +STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES :பங்குகள் பரிமாற்றத்திற்கு தேவையான குறைந்தபட்ச நிறுவன வயது: {STRING} STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY :இழுத்தால், சிக்னல்களை இடவும், ஒவ்வொறு: {STRING} STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY_VALUE :{COMMA} கட்ட{P 0 "ம்" ங்கள்} STR_CONFIG_SETTING_DRAG_SIGNALS_FIXED_DISTANCE :இழுக்கும்போது, சிக்னல்களுக்கு இடையே சீரான இடைவேளியினை விடவும்: {STRING} @@ -1385,8 +1399,11 @@ STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :இந்த STR_CONFIG_SETTING_TOWN_FOUNDING_FORBIDDEN :இயலாது STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED :அனுமதிக்கப்படுகிறது STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED_CUSTOM_LAYOUT :அனுமதிக்கப்படுகிறது, ஆனால் மாற்றியமைக்கப்பட்ட நகர அமைப்பு +STR_CONFIG_SETTING_TOWN_CARGOGENMODE :நகரத்தின் சரக்கு உற்பத்தி: {STRING} +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_ORIGINAL :இருபடி (அசல்) STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :ஆட்டத்தின் போது மரங்களை நடுதல்: {STRING} +STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :விளையாட்டின் போது மரங்களின் சீரற்ற தோற்றத்தைக் கட்டுப்படுத்தவும். இது மர வளர்ச்சியை நம்பியுள்ள தொழில்களை பாதிக்கலாம், எடுத்துக்காட்டாக மரம் வெட்டுதல் ஆலைகள் STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_NONE :ஒன்றுமில்லை {RED}(மர மில்லை உடைக்கும்) STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_RAINFOREST :மழைக் காடுகளில் மட்டும் STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_ALL :எங்கும் @@ -1419,6 +1436,8 @@ STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER :தொடக் STR_CONFIG_SETTING_CITY_SIZE_MULTIPLIER_HELPTEXT :ஆட்டத்தின் தொடக்கத்தில் மாநகரங்களின் அளவு நகரங்களை ஒப்பிடுகையில் STR_CONFIG_SETTING_DISTRIBUTION_MANUAL :கைமுறை +STR_CONFIG_SETTING_DISTRIBUTION_ASYMMETRIC :சமச்சீர்மையிலா +STR_CONFIG_SETTING_DISTRIBUTION_SYMMETRIC :சமச்சீரான STR_CONFIG_SETTING_DISTRIBUTION_PAX :பயணிகள் பரிமாற்றம் வகை: {STRING} STR_CONFIG_SETTING_DISTRIBUTION_MAIL :அஞ்சல் பரிமாற்றம் வகை: {STRING} @@ -1454,10 +1473,13 @@ STR_CONFIG_SETTING_LOCALISATION_UNITS_HEIGHT_SI :SI (மீ) STR_CONFIG_SETTING_GRAPHICS :{ORANGE}அசைவூட்டம் STR_CONFIG_SETTING_SOUND :{ORANGE}ஒலிகள் STR_CONFIG_SETTING_INTERFACE :{ORANGE}Interface +STR_CONFIG_SETTING_INTERFACE_GENERAL :{ORANGE} பொதுவான STR_CONFIG_SETTING_INTERFACE_CONSTRUCTION :{ORANGE}கட்டுமானம் +STR_CONFIG_SETTING_ADVISORS :{ORANGE}செய்திகள் / அறிவுரைஞர்கள் STR_CONFIG_SETTING_COMPANY :{ORANGE}நிறுவனம் STR_CONFIG_SETTING_ACCOUNTING :{ORANGE}கணக்கியல் STR_CONFIG_SETTING_VEHICLES :{ORANGE}வாகனங்கள் +STR_CONFIG_SETTING_VEHICLES_PHYSICS :{ORANGE}இயற்பியல் STR_CONFIG_SETTING_VEHICLES_ROUTING :{ORANGE}வழி மாற்றல் STR_CONFIG_SETTING_LIMITATIONS :{ORANGE}எல்லைகள் STR_CONFIG_SETTING_ACCIDENTS :{ORANGE}பேரழிவுகள் / விபத்துகள் @@ -1468,7 +1490,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}சர STR_CONFIG_SETTING_AI :{ORANGE}போட்டியாளர்கள் STR_CONFIG_SETTING_AI_NPC :{ORANGE}கணினி வீரர்கள் -STR_CONFIG_SETTING_PATHFINDER_OPF :அசல் STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(பரிந்துரைக்கப்பட்டது) @@ -1488,6 +1509,7 @@ STR_CONFIG_ERROR_ARRAY :{WHITE}... '{ST STR_CONFIG_ERROR_INVALID_VALUE :{WHITE}... செல்லாத மதிப்பு '{STRING}' '{STRING}' இற்கு STR_CONFIG_ERROR_INVALID_GRF :{WHITE}... பயன்படுத்த இயலாத NewGRF இனை பயன்படுத்தவில்லை '{STRING}': {STRING} STR_CONFIG_ERROR_INVALID_GRF_NOT_FOUND :கிடைக்கவில்லை +STR_CONFIG_ERROR_INVALID_GRF_UNSAFE :நிலையான பயன்பாட்டிற்கு உகந்தது அல்ல STR_CONFIG_ERROR_INVALID_GRF_SYSTEM :கணினி NewGRF STR_CONFIG_ERROR_INVALID_GRF_INCOMPATIBLE :இந்த OpenTTD பதிப்புடன் பயன்படுத்த இயலாது STR_CONFIG_ERROR_INVALID_GRF_UNKNOWN :தெரியவில்லை @@ -1504,6 +1526,7 @@ STR_INTRO_LOAD_GAME :{BLACK}ஆட STR_INTRO_PLAY_SCENARIO :{BLACK}சித்திரக்காட்சியில் விளையாடு STR_INTRO_PLAY_HEIGHTMAP :{BLACK}உயர்படத்தில் விளையாடு STR_INTRO_SCENARIO_EDITOR :{BLACK}சித்திரக்காட்சி திருத்தி +STR_INTRO_MULTIPLAYER :{BLACK}பல்வீரர் STR_INTRO_GAME_OPTIONS :{BLACK}ஆட்டத்தின் அமைப்புகள் STR_INTRO_HIGHSCORE :{BLACK}புள்ளிகள் பட்டியல் @@ -1516,6 +1539,7 @@ STR_INTRO_QUIT :{BLACK}வெ STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}புதிய ஆட்டத்தினைத் தொடங்கும். Ctrl+Click அழுத்தினால் வரைபட அமைப்புவடிவாக்கம் தவிர்க்கப்படும் STR_INTRO_TOOLTIP_LOAD_GAME :{BLACK}பதிவு செய்யப்பட்ட விளையாட்டை ஏற்று STR_INTRO_TOOLTIP_PLAY_HEIGHTMAP :{BLACK}புதிய ஆட்டத்தினைத் தொடங்கு, உயர்படத்தினை நிலப்பரப்பிற்கு பயன்படுத்தி +STR_INTRO_TOOLTIP_MULTIPLAYER :{BLACK}புதிய பல்வீரர் ஆட்டத்தினைத் தொடங்கவும் STR_INTRO_TOOLTIP_SUB_ARCTIC_LANDSCAPE :{BLACK}'உபதுருவ' நிலப்பரப்புப் பாணியைத் தேர்ந்தெடுக்கவும் STR_INTRO_TOOLTIP_SUB_TROPICAL_LANDSCAPE :{BLACK}'மிதவெப்பமண்டல' நிலப்பரப்புப் பாணியைத் தேர்ந்தெடுக்கவும் @@ -1537,13 +1561,9 @@ STR_QUIT_NO :{BLACK}இல # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -1570,6 +1590,7 @@ STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}நட STR_CHEAT_SETUP_PROD :{LTBLUE}தயாரிப்பு மதிப்புகளை மாற்ற முடியும்: {ORANGE}{STRING} # Livery window +STR_LIVERY_CAPTION :{WHITE}{COMPANY} - நிற கோட்பாடு STR_LIVERY_GENERAL_TOOLTIP :{BLACK}பொதுவான நிற கோட்பாடுகளைக் காட்டவும் STR_LIVERY_TRAIN_TOOLTIP :{BLACK}இரயில் நிற கோட்பாடுகளைக் காட்டவும் @@ -1622,7 +1643,7 @@ STR_FACE_LOAD_TOOLTIP :{BLACK}பி STR_FACE_FACECODE :{BLACK}விளையாடுபவர் முக எண் STR_FACE_FACECODE_CAPTION :{WHITE}நிறுவனரின் முக எண்னை பார் அல்லது அமை STR_FACE_FACECODE_SET :{WHITE}புதிய முக எண் குறி அமைக்கப்பட்டது -STR_FACE_SAVE :{BLACK}சேமி\ +STR_FACE_SAVE :{BLACK}சேமி STR_FACE_SAVE_TOOLTIP :{BLACK}பிடித்த முகத்தினைப் பதிவுசெய் STR_FACE_EUROPEAN :{BLACK}ஐரோப்பிய STR_FACE_SELECT_EUROPEAN :{BLACK}ஐரோப்பிய முகங்களினைத் தேர்ந்தெடுக்கவும் @@ -1656,6 +1677,7 @@ STR_FACE_EARRING :கம்மல STR_FACE_TIE_EARRING_TOOLTIP :{BLACK}Tie அல்லது காதணியை மாற்றவும் # Network server list +STR_NETWORK_SERVER_LIST_CAPTION :{WHITE}பல்வீரர் STR_NETWORK_SERVER_LIST_ADVERTISED :{BLACK}விளம்பரப்படுத்தப்பட்ட STR_NETWORK_SERVER_LIST_ADVERTISED_NO :இல்லை STR_NETWORK_SERVER_LIST_ADVERTISED_YES :ஆம் @@ -1811,6 +1833,7 @@ STR_NETWORK_CONNECTION_DISCONNECT :{BLACK}இண STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}சர்வர் காக்கப்பட்டுள்ளது. கடவுச்சொல்லினை இடவும் STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}நிற்வனம் காக்கப்பட்டுள்ளது. கடவுச்சொல்லினை இடவும் +STR_NETWORK_COMPANY_LIST_CLIENT_LIST_CAPTION :{WHITE}விளையாடுவோர் பட்டியல் # Network company list added strings STR_NETWORK_COMPANY_LIST_CLIENT_LIST :விளையாடுவோர் பட்டியல் @@ -2006,6 +2029,7 @@ STR_TRANSPARENCY_CAPTION :{WHITE}ஒள STR_LINKGRAPH_LEGEND_ALL :{BLACK}அனைத்தும் STR_LINKGRAPH_LEGEND_NONE :{BLACK}ஒன்றுமில்லை STR_LINKGRAPH_LEGEND_SELECT_COMPANIES :{BLACK}கட்டப்பட வேண்டிய நிறுவனங்களைத் தேர்ந்தெடு +STR_LINKGRAPH_LEGEND_COMPANY_TOOLTIP :{BLACK}{STRING}{}{COMPANY} # Linkgraph legend window and linkgraph legend in smallmap STR_LINKGRAPH_LEGEND_UNUSED :{TINY_FONT}{BLACK}பயன்படுத்தப்படவில்லை @@ -2091,7 +2115,7 @@ STR_BRIDGE_TUBULAR_SILICON :குழாய # Road construction toolbar STR_ROAD_TOOLBAR_ROAD_CONSTRUCTION_CAPTION :{WHITE}சாலை கட்டுமானம் -STR_ROAD_TOOLBAR_TRAM_CONSTRUCTION_CAPTION :{WHITE}ட்ரேம்வே கட்டுமானம் +STR_ROAD_TOOLBAR_TRAM_CONSTRUCTION_CAPTION :{WHITE}அமிழ் தண்டூர்திப் பாதை கட்டுமானம் STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_SECTION :{BLACK}சாலையினை இடவும். Ctrl அழுத்தினால் சாலையினை நீக்கலாம்/கட்டலாம். Shift அழுத்தினால் கட்டுமான/செலவு மதிப்பீடு காட்டப்படும் STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION :{BLACK}ட்ராம்வே தடத்தினைக் கட்டவும். Ctrl அழுத்தினால் தடத்தினை நீக்கலாம்/கட்டலாம். Shift அழுத்தினால் கட்டுமான/செலவு மதிப்பீடு காட்டப்படும் STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_VEHICLE_DEPOT :{BLACK}சாலை வாகன பணிமனையினை கட்டவும் (வாகங்களை வாங்க மற்றும் பழுதுபார்க்க). Shift அழுத்தினால் கட்டுமான/செலவு மதிப்பீடு @@ -2108,6 +2132,7 @@ 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}ட்ராம்வே கட்டுமானம் செய்யவும்/நீக்கவும் + # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}சாலை வாகன பணிமனை திசையமைப்பு STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}சாலை வாகன பணிமனை திசையமைப்பினை தேர்ந்தெடுக்கவும் @@ -2162,6 +2187,7 @@ STR_AIRPORT_HELISTATION :வானூர STR_AIRPORT_CLASS_SMALL :சிறிய விமான நிலையங்கள் STR_AIRPORT_CLASS_LARGE :பெரிய விமான நிலையங்கள் +STR_AIRPORT_CLASS_HUB :விமான நடுவங்கள் STR_AIRPORT_CLASS_HELIPORTS :ஹெலிகாப்டர் நிலையங்கள் STR_STATION_BUILD_NOISE :{BLACK}ஒலி இரைச்சல்: {GOLD}{COMMA} @@ -2277,8 +2303,10 @@ STR_LAND_AREA_INFORMATION_AIRPORTTILE_NAME :{BLACK}வி STR_LAND_AREA_INFORMATION_NEWGRF_NAME :{BLACK}NewGRF: {LTBLUE}{STRING} STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED :{BLACK}ஏற்றுக்கொள்ளப்படும் சரக்குகள்: {LTBLUE} STR_LAND_AREA_INFORMATION_CARGO_EIGHTS :({COMMA}/8 {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 :கற்கள் @@ -2311,14 +2339,14 @@ STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_EXIT_NOENTRYSIGNALS :இரயில STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBO_PBSSIGNALS :இரயில்வே தடம் இணைந்த மற்றும் பாதை சிக்னல்களுடன் STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_COMBO_NOENTRYSIGNALS :இரயில்வே தடம் இணைந்த மற்றும் ஒருவழிப் பாதை சிக்னல்களுடன் STR_LAI_RAIL_DESCRIPTION_TRACK_WITH_PBS_NOENTRYSIGNALS :இரயில்வே தடம் பாதை மற்றும் ஒருவழிப் பாதை சிக்னல்களுடன் -STR_LAI_RAIL_DESCRIPTION_TRAIN_DEPOT :இரயில்வே இரயில் பணிமனை +STR_LAI_RAIL_DESCRIPTION_TRAIN_DEPOT :இரயில் பணிமனை STR_LAI_ROAD_DESCRIPTION_ROAD :சாலை STR_LAI_ROAD_DESCRIPTION_ROAD_WITH_STREETLIGHTS :தெரு விளக்குகளுடன் சாலை STR_LAI_ROAD_DESCRIPTION_TREE_LINED_ROAD :மரங்கள் நடுவே சாலை STR_LAI_ROAD_DESCRIPTION_ROAD_VEHICLE_DEPOT :சாலை வாகன பணிமனை STR_LAI_ROAD_DESCRIPTION_ROAD_RAIL_LEVEL_CROSSING :சாலை/இரயில் பாதை கடக்கும் இடம் -STR_LAI_ROAD_DESCRIPTION_TRAMWAY :ட்ரேம்வே +STR_LAI_ROAD_DESCRIPTION_TRAMWAY :தண்டூர்திப் பாதை # Houses come directly from their building names STR_LAI_TOWN_INDUSTRY_DESCRIPTION_UNDER_CONSTRUCTION :{STRING} (கட்டுமானம் நடக்கிறது) @@ -2378,9 +2406,25 @@ STR_ABOUT_VERSION :{BLACK}OpenTTD STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT} 2002-2019 OpenTTD குழுமம் # Framerate display window +STR_FRAMERATE_CAPTION :{WHITE}பிரேம் வீதம் +STR_FRAMERATE_AVERAGE :{WHITE}சராசரி +STR_FRAMERATE_MEMORYUSE :{WHITE}நினைவாற்றல் +STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL} ms +STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL} நுண்ணொடி +STR_FRAMERATE_BYTES_GOOD :{LTBLUE}{BYTES} +STR_FRAMERATE_BYTES_WARN :{YELLOW}{BYTES} +STR_FRAMERATE_BYTES_BAD :{RED}{BYTES} ############ Leave those lines in this order!! +STR_FRAMERATE_GL_LANDSCAPE :{BLACK} உலக சொடுக்குகள்: +STR_FRAMERATE_GL_LINKGRAPH :{BLACK} இணைப்பு வரைபட தாமதம்: +STR_FRAMERATE_SOUND :{BLACK}இசை இயக்கம்: +STR_FRAMERATE_ALLSCRIPTS :{BLACK} GS/AI மொத்தம்: ############ End of leave-in-this-order ############ Leave those lines in this order!! +STR_FRAMETIME_CAPTION_GL_ECONOMY :சரக்கு கையாளுதல் +STR_FRAMETIME_CAPTION_GL_ROADVEHS :சாலை வாகனத்தின் பயண நேரம் +STR_FRAMETIME_CAPTION_GAMESCRIPT :விளையாட்டின் ஸ்கிரிப்ட் +STR_FRAMETIME_CAPTION_AI :AI {NUM} {STRING} ############ End of leave-in-this-order @@ -2399,6 +2443,7 @@ STR_SAVELOAD_SAVE_BUTTON :{BLACK}சே STR_SAVELOAD_SAVE_TOOLTIP :{BLACK}தற்போதைய ஆட்டத்தினை பதிவு செய், தேர்ந்தெடுக்கப்பட்டப் பெயரில் STR_SAVELOAD_LOAD_BUTTON :{BLACK}ஏற்று STR_SAVELOAD_LOAD_TOOLTIP :{BLACK}தேர்ந்தெடுக்கப்பட்ட ஆட்டத்தினை ஏற்று +STR_SAVELOAD_LOAD_HEIGHTMAP_TOOLTIP :{BLACK} தேர்ந்தெடுக்கப்பட்டுள்ள உயர்படத்தினை ஏற்று STR_SAVELOAD_DETAIL_CAPTION :{BLACK}ஆட்டத்தின் விவரங்கள் STR_SAVELOAD_DETAIL_NOT_AVAILABLE :{BLACK}எந்த தகவலும் கிடைக்கவில்லை STR_SAVELOAD_DETAIL_COMPANY_INDEX :{SILVER}{COMMA}: {WHITE}{STRING} @@ -2425,6 +2470,7 @@ STR_MAPGEN_TERRAIN_TYPE :{BLACK}நி STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}கடல் மட்டம்: STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}ஆறுகள்: STR_MAPGEN_SMOOTHNESS :{BLACK}சமநிலை: +STR_MAPGEN_VARIETY :{BLACK}பலவகை பரவல்: STR_MAPGEN_GENERATE :{WHITE}உருவாக்கு # Strings for map borders at game generation @@ -2513,8 +2559,11 @@ STR_NEWGRF_SETTINGS_GRF_ID :{BLACK}GRF ID: STR_NEWGRF_SETTINGS_VERSION :{BLACK}பதிப்பு: {SILVER}{NUM} STR_NEWGRF_SETTINGS_MIN_VERSION :{BLACK}குறைந்த். பயன்படுத்தக்கூடிய பதிப்பு: {SILVER}{NUM} STR_NEWGRF_SETTINGS_MD5SUM :{BLACK}MD5sum: {SILVER}{STRING} -STR_NEWGRF_SETTINGS_PALETTE :{BLACK}Palette: {SILVER}{STRING} +STR_NEWGRF_SETTINGS_PALETTE :{BLACK}தட்டு: {SILVER}{STRING} +STR_NEWGRF_SETTINGS_PALETTE_DEFAULT_32BPP :முதன்மை / 32 bpp +STR_NEWGRF_SETTINGS_PALETTE_LEGACY :மரபுரிமை (W) STR_NEWGRF_SETTINGS_PARAMETER :{BLACK}குணாதிசயங்கள்: {SILVER}{STRING} +STR_NEWGRF_SETTINGS_PARAMETER_NONE :ஒன்றுமில்லை STR_NEWGRF_SETTINGS_NO_INFO :{BLACK}எந்தத் தகவலும் இல்லை STR_NEWGRF_SETTINGS_NOT_FOUND :{RED}பொருத்தமான கோப்பு கிடைக்கவில்லை @@ -2522,6 +2571,9 @@ STR_NEWGRF_SETTINGS_DISABLED :{RED}செய STR_NEWGRF_SETTINGS_INCOMPATIBLE :{RED}இந்த OpenTTD பதிப்புடன் பயன்படுத்த இயலாது # NewGRF save preset window +STR_SAVE_PRESET_CAPTION :{WHITE}Preset-ஐ பதிவுசெய் +STR_SAVE_PRESET_TITLE :{BLACK}Preset இற்கு ஒரு பெயரினை இடு +STR_SAVE_PRESET_SAVE :{BLACK}சேமி # NewGRF parameters window STR_NEWGRF_PARAMETERS_CAPTION :{WHITE}NewGRF குணாதிசயங்களை மாற்று @@ -2546,6 +2598,8 @@ STR_SPRITE_ALIGNER_CAPTION :{WHITE}ஸ் STR_SPRITE_ALIGNER_NEXT_BUTTON :{BLACK}அடுத்த ஸ்பிரைட்டு STR_SPRITE_ALIGNER_GOTO_BUTTON :{BLACK}ஸ்பிரைட்டுயிற்கு செல்லவும் STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}முந்தைய ஸ்பிரைட்டு +STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}முன்னிருந்தமாதிரி மாற்று +STR_SPRITE_ALIGNER_OFFSETS_REL :{BLACK}X ஒதுக்கம்: {NUM}, Y ஒதுக்கம்: {NUM} (சார்பு) STR_SPRITE_ALIGNER_PICKER_BUTTON :{BLACK}ஸ்பிரைட்டினைத் தேர்ந்தெடுக்கவும் STR_SPRITE_ALIGNER_GOTO_CAPTION :{WHITE}ஸ்பிரைட்டிற்கு செல்லவும் @@ -2628,6 +2682,7 @@ STR_TOWN_POPULATION :{BLACK}உல STR_TOWN_VIEW_TOWN_CAPTION :{WHITE}{TOWN} STR_TOWN_VIEW_CITY_CAPTION :{WHITE}{TOWN} (மாநகரம்) STR_TOWN_VIEW_POPULATION_HOUSES :{BLACK}மக்கள்தொகை: {ORANGE}{COMMA}{BLACK} வீடுகள்: {ORANGE}{COMMA} +STR_TOWN_VIEW_CARGO_LAST_MONTH_MAX :{BLACK}{CARGO_LIST} சென்ற மாதம்: {ORANGE}{COMMA}{BLACK} அதிகபட்சம்: {ORANGE}{COMMA} STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH :{BLACK}நகரத்தின் வளர்ச்சியிற்கு தேவையான சரக்குகள்: STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_GENERAL :{ORANGE}{STRING}{RED} தேவை STR_TOWN_VIEW_CARGO_FOR_TOWNGROWTH_REQUIRED_WINTER :{ORANGE}{STRING}{BLACK} குளிர்காலத்தில் தேவை @@ -2651,6 +2706,7 @@ STR_TOWN_VIEW_RENAME_TOWN_BUTTON :நகரத் # Town local authority window STR_LOCAL_AUTHORITY_CAPTION :{WHITE}{TOWN} நகராட்சி +STR_LOCAL_AUTHORITY_ZONE :{BLACK}மண்டலம் STR_LOCAL_AUTHORITY_COMPANY_RATINGS :{BLACK}போக்குவரத்து நிறுவன தரங்கள்: STR_LOCAL_AUTHORITY_COMPANY_RATING :{YELLOW}{COMPANY} {COMPANY_NUM}: {ORANGE}{STRING} STR_LOCAL_AUTHORITY_ACTIONS_TITLE :{BLACK}செயற்பாடுகள்: @@ -2885,8 +2941,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}{COMPANY STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}இரயில் பாகங்கள்: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}சிக்னல்கள் STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}சாலை பாகங்கள்: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}சாலை -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}ட்ராம்வே STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}தண்ணீர் வட்டங்கள்: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}கால்வாய்கள் STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}நிலையங்கள்: @@ -2897,8 +2951,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}தொழிற்சாலைகள் STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- ஒன்றுமில்லை - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% நகர்த்தப்பட்டது) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% நகர்த்தப்பட்டது) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} # Industry view @@ -2909,6 +2961,8 @@ STR_INDUSTRY_VIEW_PRODUCTION_LEVEL :{BLACK}தய STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE :{YELLOW}தொழிற்சாலை உடனடியாக மூடப்படும் என்று அறிவிக்கப்பட்டுள்ளது! +STR_INDUSTRY_VIEW_REQUIRES :{BLACK}வேண்டியவன: +STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} காத்துக்கொண்டிருக்கிறது{STRING} STR_CONFIG_GAME_PRODUCTION :{WHITE}தயாரிப்பினை மாற்றவும் (8 இன் பெருக்கங்கள், 2040 வரை) STR_CONFIG_GAME_PRODUCTION_LEVEL :{WHITE}தயாரிப்பு அளவினை மாற்றவும் (சதவிகிதம், 800% வரை) @@ -2957,6 +3011,7 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :குழுவ STR_GROUP_DEFAULT_SHIPS :குழுவில் இல்லாத கப்பல்கள் STR_GROUP_DEFAULT_AIRCRAFTS :குழுவில் இல்லாத விமானம் + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}குழுக்கள் - குழுவில் உள்ள அனைத்து வாகனங்களினை பார்க்க அக்குழுவினை சொடுக்கவும் STR_GROUP_CREATE_TOOLTIP :{BLACK}ஓர் குழுவினை உருவாக்க சொடுக்கவும் STR_GROUP_DELETE_TOOLTIP :{BLACK}தேர்ந்தெடுக்கப்பட்ட குழுவின் பெயரினை நீக்கவும் @@ -2968,6 +3023,7 @@ STR_GROUP_REMOVE_ALL_VEHICLES :அனைத் STR_GROUP_RENAME_CAPTION :{BLACK}குழுவின் பெயரினை மாற்றவும் +STR_GROUP_OCCUPANCY :தற்போதைய பயன்பாடு: # Build vehicle window STR_BUY_VEHICLE_TRAIN_RAIL_CAPTION :புது இரயில் வாகனங்கள் @@ -2975,10 +3031,14 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :புது STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :புது மோனோ இரயில் வாகனங்கள் STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :புதிய மேக்லெவ் வாகனங்கள் -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :புது இரயில் வாகனங்கள் STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :புது சாலை வாகனங்கள் +STR_BUY_VEHICLE_TRAM_VEHICLE_CAPTION :புதிய அமிழ் தண்டூர்தி வாகனங்கள் + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :புது இரயில் வாகனங்கள் STR_BUY_VEHICLE_SHIP_CAPTION :புது கப்பல்கள் STR_BUY_VEHICLE_AIRCRAFT_CAPTION :புது விமானம் +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}செலவு: {GOLD}{CURRENCY_LONG}{BLACK} எடை: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}வேகம்: {GOLD}{VELOCITY}{BLACK} திறன்: {GOLD}{POWER} @@ -3011,11 +3071,15 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}வா STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}கப்பலை வாங்கு STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}விமானத்தை வாங்கு +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_BUTTON :{BLACK}கப்பலை வாங்கி மாற்றியமை +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_BUTTON :{BLACK}விமானத்தை வாங்கி மாற்றியமை + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}காட்டப்படும் இரயில் வாகனத்தை வாங்கவும். Shift+Click செய்தால் வாங்கும்போது ஆகும் மதிப்பிடப்பட்டச் செலவுகளைக் காட்டு STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}காட்டப்படும் சாலை வாகனத்தை வாங்கவும். Shift+Click செய்தால் வாங்கும்போது ஆகும் மதிப்பிடப்பட்டச் செலவுகளைக் காட்டும் STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}காட்டப்படும் கப்பலை வாங்கவும். Shift+Click செய்தால் வாங்கும்போது ஆகும் மதிப்பிடப்பட்டச் செலவுகளைக் காட்டும் STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}காட்டப்படும் விமானத்தை வாங்கவும். Shift+Click செய்தால் வாங்கும்போது ஆகும் மதிப்பிடப்பட்டச் செலவுகளைக் காட்டும் + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}பெயரிடு STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}பெயரிடு STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}பெயரிடு @@ -3026,8 +3090,11 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_TOOLTIP :{BLACK}சா STR_BUY_VEHICLE_SHIP_RENAME_TOOLTIP :{BLACK}கப்பல் வகையின் பெயரினை மாற்றவும் STR_BUY_VEHICLE_AIRCRAFT_RENAME_TOOLTIP :{BLACK}விமான வகையின் பெயரினை மாற்றவும் +STR_BUY_VEHICLE_AIRCRAFT_HIDE_TOGGLE_BUTTON :{BLACK}மறை +STR_BUY_VEHICLE_ROAD_VEHICLE_SHOW_TOGGLE_BUTTON :{BLACK}காட்சி +STR_BUY_VEHICLE_SHIP_HIDE_SHOW_TOGGLE_TOOLTIP :{BLACK}கப்பல் வகையினை காட்டு/மறை STR_QUERY_RENAME_TRAIN_TYPE_CAPTION :{WHITE}இரயில் வாகன வகையின் பெயரினை மாற்றவும் STR_QUERY_RENAME_ROAD_VEHICLE_TYPE_CAPTION :{WHITE}சாலை வாகன வகையின் பெயரினை மாற்றவும் @@ -3102,16 +3169,22 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}நீ # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}வாகன உற்பத்தியாலரிடமிருந்து ஓர் தகவல் + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :இரயில்வே வாகனம் -STR_ENGINE_PREVIEW_ROAD_VEHICLE :சாலை வாகனம் -STR_ENGINE_PREVIEW_AIRCRAFT :விமானம் -STR_ENGINE_PREVIEW_SHIP :கப்பல் +STR_ENGINE_PREVIEW_ELRAIL_LOCOMOTIVE :மின்சார இரயில் STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :மோனோ இரயில் வாகனம் STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :மேக்லெவ் வாகனம் +STR_ENGINE_PREVIEW_ROAD_VEHICLE :சாலை வாகனம் + +STR_ENGINE_PREVIEW_AIRCRAFT :விமானம் +STR_ENGINE_PREVIEW_SHIP :கப்பல் + STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}செலவு: {CURRENCY_LONG} எடை: {WEIGHT_SHORT}{}வேகம்: {VELOCITY} திறன்: {POWER}{}ஓட்டுவதற்கான செலவு: {CURRENCY_LONG}/வரு{}கொள்ளளவு: {CARGO_LONG} STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}செலவு: {CURRENCY_LONG} எடை: {WEIGHT_SHORT}{}வேகம்: {VELOCITY} திறன்: {POWER} அதி. T.E.: {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_RUNCOST :{BLACK}செலவு: {CURRENCY_LONG} அதி. வேகம்: {VELOCITY}{}விமான வகை: {STRING}{}கொள்ளளவு: {CARGO_LONG}{}ஓட்டும் செலவு: {CURRENCY_LONG}/ஆண்டிற்கு +STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_RANGE_CAP_CAP_RUNCOST :{BLACK}செலவு: {CURRENCY_LONG} அதி. வேகம்: {VELOCITY}{}விமான வகை: {STRING} வீச்சு எல்லை: {COMMA} கட்டங்கள்{}கொள்ளளவு: {CARGO_LONG}, {CARGO_LONG}{}ஓட்டும் செலவு: {CURRENCY_LONG}/ஆண்டிற்கு # Autoreplace window STR_REPLACE_VEHICLES_WHITE :{WHITE}மாற்று {STRING} - {STRING} @@ -3120,6 +3193,7 @@ STR_REPLACE_VEHICLE_ROAD_VEHICLE :சாலை STR_REPLACE_VEHICLE_SHIP :கப்பல் STR_REPLACE_VEHICLE_AIRCRAFT :விமானம் +STR_REPLACE_VEHICLE_VEHICLES_IN_USE :{YELLOW}பயன்பாட்டிலுள்ள வாகனங்கள் STR_REPLACE_HELP_LEFT_ARRAY :{BLACK}மாற்றியமைக்க பொறி வகையினை தேர்ந்தெடுக்க @@ -3139,6 +3213,9 @@ STR_REPLACE_ELRAIL_VEHICLES :மின்ச STR_REPLACE_MONORAIL_VEHICLES :மோனோ இரயில் வாகனங்கள் STR_REPLACE_MAGLEV_VEHICLES :மேக்லெவ் வாகனங்கள் +STR_REPLACE_ROAD_VEHICLES :சாலை வாகனங்கள் +STR_REPLACE_TRAM_VEHICLES :அமிழ் தண்டூர்தி வாகனங்கள் + STR_REPLACE_REMOVE_WAGON :{BLACK}பெட்டி நீக்கம்: {ORANGE}{STRING} # Vehicle view @@ -3332,6 +3409,7 @@ STR_ORDER_DROP_SERVICE_DEPOT :தேவைப STR_ORDER_DROP_HALT_DEPOT :நிறுத்து STR_ORDER_SERVICE_TOOLTIP :{BLACK}பழுது சரிபார்த்தல் இல்லையெனில் இந்தக் கட்டளையினை தவிற்கவும் +STR_ORDER_CONDITIONAL_VARIABLE_TOOLTIP :{BLACK}அடிப்படை ஜம்பிங் செய்ய வாகனத் தரவு # Conditional order variables, must follow order of OrderConditionVariable enum STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE :சுமை அளவு @@ -3450,6 +3528,7 @@ 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_STAY_FOR_ESTIMATED :({STRING} வரை இரு, நேர அட்டவணை இடப்படாதது) STR_TIMETABLE_STAY_FOR :மற்றும் {STRING} இற்கு நிற்கவும் STR_TIMETABLE_AND_TRAVEL_FOR :மற்றும் {STRING} இற்கு பயணிக்கவும் STR_TIMETABLE_DAYS :{COMMA}{NBSP}நாள்{P "" "நாட்கள்"} @@ -3558,6 +3637,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}கு STR_AI_LIST_CANCEL :{BLACK}இரத்து செய் STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}வரிவடிவத்தினை மாற்றாதே + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} குணாதிசயங்கள் STR_AI_SETTINGS_CAPTION_AI :AI @@ -3824,7 +3904,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 :{WHITE}இந்த வகையிலான இரயில்களுக்கு இருப்புப்பாதை சந்திக் கடவுகள் கிடையாது +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}இந்த வகையிலான இரயில்களுக்கு இருப்புப்பாதை சந்திக் கடவுகள் கிடையாது STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}இங்கே சிக்னல்களை நிறுவ இயலாது... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}இங்கே இரயில்வே தடங்களை பதிய முடியாது... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}இங்கிருந்து இரயில்வே தடங்களை அகற்ற முடியாது... @@ -3844,6 +3924,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_INCOMPATIBLE_TRAMWAY :{WHITE}... இணக்கமற்ற தண்டூர்தி # Waterway construction errors STR_ERROR_CAN_T_BUILD_CANALS :{WHITE}இங்கே கால்வாய்களை கட்ட இயலாது... @@ -3895,6 +3976,7 @@ STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... இ STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}குழுவை உருவாக்க முடியாது... STR_ERROR_GROUP_CAN_T_DELETE :{WHITE}இந்தக் குழுவினை நீக்க முடியாது... STR_ERROR_GROUP_CAN_T_RENAME :{WHITE}குழுவின் பெயரினை மாற்ற இயலாது... +STR_ERROR_GROUP_CAN_T_SET_PARENT :{WHITE}பெற்றோர் குழுவை அமைக்க முடியாது ... STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}இந்தக் குழுவில் உள்ள அனைத்து வாகனங்களையும் நீக்க இயலாது... STR_ERROR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}வாகனத்தினை இந்தக் குழுவில் இணைக்க இயலாது... STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}பகிரப்பட்ட வாகனத்தினை இந்தக் குழுவில் இணைக்க இயலாது... @@ -4005,6 +4087,7 @@ STR_BASESOUNDS_DOS_DESCRIPTION :அசல் STR_BASESOUNDS_WIN_DESCRIPTION :அசல் டிரான்ஸ்ஃபோர்ட் டைகூன் டீலக்ஸ் விண்டோஸ் பதிப்பு ஒலிகள். STR_BASESOUNDS_NONE_DESCRIPTION :ஒலிகள் இல்லாத ஒலி தொகுப்பு. STR_BASEMUSIC_WIN_DESCRIPTION :அசல் டிரான்ஸ்ஃபோர்ட் டைகூன் டீலக்ஸ் விண்டோஸ் பதிப்பு இசை. +STR_BASEMUSIC_DOS_DESCRIPTION :அசல் டிரான்ஸ்ஃபோர்ட் டைகூன் டீலக்ஸ் DOS பதிப்பு இசை. STR_BASEMUSIC_NONE_DESCRIPTION :இசை இல்லாத இசைத்தொகுப்பு. ##id 0x2000 diff --git a/src/lang/thai.txt b/src/lang/thai.txt index fb8f1126ce..3034a26495 100644 --- a/src/lang/thai.txt +++ b/src/lang/thai.txt @@ -10,8 +10,6 @@ ##grflangid 0x42 -# $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. # 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. @@ -464,9 +462,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :เปิด/ปิด คอนโซล STR_ABOUT_MENU_AI_DEBUG :ดีบัก สคริปต์ AI/Game STR_ABOUT_MENU_SCREENSHOT :จับภาพหน้าจอ (Ctrl+S) -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :จับภาพหน้าจอในแบบขยายใหญ่สุด -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :ค่าเริ่มต้นของการขยายภาพในการจับหน้าจอ -STR_ABOUT_MENU_GIANT_SCREENSHOT :จับภาพหน้าจอทั้งแผนที่ (Ctrl+G) STR_ABOUT_MENU_ABOUT_OPENTTD :เกี่ยวกับ 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :ตัวจัดแนว Sprite STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :เปิด/ปิด bounding boxes @@ -636,9 +631,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}กำหนดเอง 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}ระดับเสียงดนตรี STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}ระดับเสียงเอฟเฟกต์ -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}ต่ำสุด -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}สูงสุด -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -849,6 +841,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}ใหม่ {STRING} มีจำหน่ายแล้ว - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} ไม่ต้องการรับ {STRING} อีกต่อไป STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} ไม่รับ {STRING} หรือ {STRING} แล้ว STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} ขณะนี้ยอมรับ {STRING} @@ -1635,7 +1628,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}กา STR_CONFIG_SETTING_AI :{ORANGE}คู่แข่ง STR_CONFIG_SETTING_AI_NPC :{ORANGE}ผู้เล่นคอมพิวเตอร์ -STR_CONFIG_SETTING_PATHFINDER_OPF :ดั้งเดิม STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(แนะนำ) @@ -1718,13 +1710,9 @@ STR_QUIT_NO :{BLACK}ไม # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :ระบบปฏิบัติการ Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -2350,6 +2338,7 @@ 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}สลับโหมด สร้าง/ลบ รางสำหรับรถราง + # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}ทิศทางของอู่รถ STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}เลือกทิศทางของอู่รถ @@ -3192,8 +3181,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}โค STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}ชิ้นส่วนทางรถไฟ: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}เสาอาณัติสัญญาณ STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}ชิ้นส่วนถนน: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}ถนน -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}ทางรถราง STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}คลอง: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}คลอง STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}สถานี: @@ -3204,8 +3191,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}อุตสาหกรรม STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- ไม่มี - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% ได้รับการขนส่ง) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% ได้รับการขนส่ง) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}ชื่อของอุตสาหกรรม - คลิ๊กที่ชื่อเพื่อไปยังจุดศูนย์กลาง @@ -3267,6 +3252,7 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :พาหนะ STR_GROUP_DEFAULT_SHIPS :พาหนะที่ไม่ได้จัดกลุ่ม STR_GROUP_DEFAULT_AIRCRAFTS :พาหนะที่ไม่ได้จัดกลุ่ม + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}กลุ่ม - คลิ๊กที่กลุ่มเพื่อดูรายการยานพาหนะในกลุ่ม STR_GROUP_CREATE_TOOLTIP :{BLACK}กดเพื่อสร้างกลุ่ม STR_GROUP_DELETE_TOOLTIP :{BLACK}ลบกลุ่มที่เลือก @@ -3286,10 +3272,13 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :รถไฟฟ STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :รถไฟฟ้ารางเดี่ยวใหม่ STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Maglev (รถไฟพลังแม่เหล็ก) ใหม่ -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :ประเถทไฟที่สามารถซื้อได้ STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :ประเถทรถที่สามารถซื้อได้ + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :ประเถทไฟที่สามารถซื้อได้ STR_BUY_VEHICLE_SHIP_CAPTION :ประเถทเรือที่สามารถซื้อได้ STR_BUY_VEHICLE_AIRCRAFT_CAPTION :ประเถทอากาศยานที่สามารถซื้อได้ +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}มูลค่า: {GOLD}{CURRENCY_LONG}{BLACK} น้ำหนัก: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}ความเร็ว: {GOLD}{VELOCITY}{BLACK} พลังขับเคลื่อน: {GOLD}{POWER} @@ -3322,11 +3311,13 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}ซื STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}ซื้อเรือ STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}ซื้อเครื่องบิน + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}ซื้อรถไฟที่เลือกไว้ เมื่อกด Shift+คลิกเมาส์ จะแสดงมูลค่าโดยประมาณโดยไม่ทำการซื้อ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}ซื้อรถที่เลือกไว้ เมื่อกด Shift+คลิกเมาส์ จะแสดงมูลค่าโดยประมาณโดยไม่ทำการซื้อ STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}ซื้อเรือที่เลือกไว้ เมื่อกด Shift+คลิกเมาส์ จะแสดงมูลค่าโดยประมาณโดยไม่ทำการซื้อ STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}ซื้อเครื่องบินที่เลือกไว้ เมื่อกด Shift+คลิกเมาส์ จะแสดงมูลค่าโดยประมาณโดยไม่ทำการซื้อ + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}เปลี่ยนชื่อ STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}เปลี่ยนชื่อ STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}เปลี่ยนชื่อ @@ -3427,13 +3418,16 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}คุ # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}ข้อความจากผู้ผลิตยานพาหนะ STR_ENGINE_PREVIEW_MESSAGE :{GOLD}เราได้ออกแบบ {STRING} ใหม่ - หากคุณต้องการที่จะนำไปทดลองใช้ เราจะให้คุณนำไปใช้งานก่อนที่จะนำออกไปจำหน่ายในตลาดปกติ{}คุณต้องการนำไปทดลองใช้หรือไม่ ? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :หัวรถจักร -STR_ENGINE_PREVIEW_ROAD_VEHICLE :ยานพาหนะทางบก -STR_ENGINE_PREVIEW_AIRCRAFT :อากาศยาน -STR_ENGINE_PREVIEW_SHIP :ยานพาหนะทางน้ำ STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :รถไฟรางเดี่ยว STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :รถไฟรางแม่เหล็กไฟฟ้า +STR_ENGINE_PREVIEW_ROAD_VEHICLE :ยานพาหนะทางบก + +STR_ENGINE_PREVIEW_AIRCRAFT :อากาศยาน +STR_ENGINE_PREVIEW_SHIP :ยานพาหนะทางน้ำ + STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}มูลค่า: {CURRENCY_LONG} น้ำหนัก: {WEIGHT_SHORT}{}ความเร็ว: {VELOCITY}พลังขับเคลื่อน: {POWER}{}ค่าปฏิบัติการ: {CURRENCY_LONG}/ปี{}ความจุ: {CARGO_LONG} STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}มูลค่า: {CURRENCY_LONG} น้ำหนัก: {WEIGHT_SHORT}{}ความเร็ว: {VELOCITY}พลังขับเคลื่อน: {POWER} กำัลังลากจูงสูงสุด: {6:FORCE}{}ค่าปฎิบัติการ: {4:CURRENCY_LONG}/ปี{}ความจุ: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}มูลค่า: {CURRENCY_LONG} ความเร็วสูงสุด: {VELOCITY}{}ความจุ: {CARGO_LONG}{}ค่าปฏิบัติการ: {CURRENCY_LONG}/ปี @@ -3471,6 +3465,7 @@ STR_REPLACE_ELRAIL_VEHICLES :ยานพา STR_REPLACE_MONORAIL_VEHICLES :ยานพาหนะประเภทรถไฟรางเดี่ยว STR_REPLACE_MAGLEV_VEHICLES :รถไฟพลังงานแม่แหล็ก + STR_REPLACE_REMOVE_WAGON :{BLACK}ขายรถพ่วง: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}ทำให้การแทนที่ขบวนรถไฟทำให้ความยาวของขบวนยังเท่าเดิม @@ -3914,6 +3909,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}เล STR_AI_LIST_CANCEL :{BLACK}ยกเลิก STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}ไม่สามารถเปลี่ยน script + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parameters STR_AI_SETTINGS_CAPTION_AI :AI @@ -4183,7 +4179,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 :{WHITE}ทางตัดเสมอระดับทางไม่อนุญาตให้ตัดผ่านทางประเภทนี้ +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}ทางตัดเสมอระดับทางไม่อนุญาตให้ตัดผ่านทางประเภทนี้ STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}ไม่สามารถสร้างเสาอาณัติสัญญาณได้... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}บริเวณนี้ไม่สามารถสร้างรางรถไฟได้... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}ตรงนี้ไม่สามารถลบรางรถไฟออกไปได้ diff --git a/src/lang/traditional_chinese.txt b/src/lang/traditional_chinese.txt index 2bef0de060..940d41f343 100644 --- a/src/lang/traditional_chinese.txt +++ b/src/lang/traditional_chinese.txt @@ -10,8 +10,6 @@ ##grflangid 0x0c -# $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. # 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. @@ -472,9 +470,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :切換主控台 STR_ABOUT_MENU_AI_DEBUG :AI/遊戲腳本除錯 STR_ABOUT_MENU_SCREENSHOT :擷取畫面 -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :最近鏡截圖 -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :在預設的縮放範圍截圖 -STR_ABOUT_MENU_GIANT_SCREENSHOT :擷取全場景畫面 STR_ABOUT_MENU_ABOUT_OPENTTD :關於「OpenTTD」 STR_ABOUT_MENU_SPRITE_ALIGNER :子畫面定位工具 STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :切換邊界框 @@ -644,9 +639,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}自訂二 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}背景音樂音量 STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}音效音量 -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}最小 -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}最大 -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -858,6 +850,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}{STRING} 問世了! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} 不再接受 {STRING} STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} 不再接受 {STRING} 或 {STRING} STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} 現在接受 {STRING} @@ -1684,7 +1677,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}貨物 STR_CONFIG_SETTING_AI :{ORANGE}競爭對手 STR_CONFIG_SETTING_AI_NPC :{ORANGE}電腦玩家 -STR_CONFIG_SETTING_PATHFINDER_OPF :預設 STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(建議) @@ -1767,13 +1759,9 @@ STR_QUIT_NO :{BLACK}否 # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -1802,6 +1790,7 @@ STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}變更 STR_CHEAT_SETUP_PROD :{LTBLUE}允許修改產量:{ORANGE}{STRING} # Livery window +STR_LIVERY_CAPTION :{WHITE}{COMPANY} 的配色 STR_LIVERY_GENERAL_TOOLTIP :{BLACK}顯示通用配色 STR_LIVERY_TRAIN_TOOLTIP :{BLACK}顯示列車配色 @@ -2401,6 +2390,7 @@ 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}切換鋪設電車軌 + # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}車廠方向 STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}選擇車廠方向 @@ -3260,8 +3250,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}{COMPANY STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}鐵路區塊: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}號誌 STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}道路區塊: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}道路 -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}路面電車 STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}水道或海運設施: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}運河 STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}車站: @@ -3272,8 +3260,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}每年{C # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}工業 STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- 無 - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} (已運送 {COMMA}%) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} (已運送 {COMMA}%/{COMMA}%) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}工業名稱 - 點選名稱可將工業置於畫面中央。 按住 Ctrl 點選可於工業位置開啟新視窗視野 @@ -3335,6 +3321,7 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :未分組的車 STR_GROUP_DEFAULT_SHIPS :未分組的船舶 STR_GROUP_DEFAULT_AIRCRAFTS :未分組的飛機 + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}群組 - 點選群組以顯示其中的運輸工具清單。拖曳群組標籤以排列群組的次序和層級。 STR_GROUP_CREATE_TOOLTIP :{BLACK}點選可建立群組 STR_GROUP_DELETE_TOOLTIP :{BLACK}移除所選群組 @@ -3356,10 +3343,13 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :新購電氣化 STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :新購單軌車輛 STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :新購磁浮車輛 -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :新購鐵路列車 STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :新購車輛 + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :新購鐵路列車 STR_BUY_VEHICLE_SHIP_CAPTION :新購船舶 STR_BUY_VEHICLE_AIRCRAFT_CAPTION :新購飛機 +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}費用:{GOLD}{CURRENCY_LONG}{BLACK} 載重:{GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}速度:{GOLD}{VELOCITY}{BLACK} 功率:{GOLD}{POWER} @@ -3392,11 +3382,13 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}購買 STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}購買船舶 STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}購買飛機 + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}購買選定的列車。按住 Shift 點選則只會顯示預估的購買費用 STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}購買選定的車輛。按住 Shift 點選則只會顯示預估的購買費用 STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}購買選定的船舶。按住 Shift 點選則只會顯示預估的購買費用 STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}購買選定的飛機。按住 Shift 點選則只會顯示預估的購買費用 + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}重新命名 STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}重新命名 STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}重新命名 @@ -3505,13 +3497,16 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}您正 # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}運輸工具製造商的訊息 STR_ENGINE_PREVIEW_MESSAGE :{GOLD}我們剛設計了一種新{STRING} - 您有興趣獨家使用它一年,讓我們在正式上市之前先 觀察它的表現嗎? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :鐵路機車頭 -STR_ENGINE_PREVIEW_ROAD_VEHICLE :車輛 -STR_ENGINE_PREVIEW_AIRCRAFT :飛機 -STR_ENGINE_PREVIEW_SHIP :船舶 STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :單軌機車頭 STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :磁浮機車頭 +STR_ENGINE_PREVIEW_ROAD_VEHICLE :車輛 + +STR_ENGINE_PREVIEW_AIRCRAFT :飛機 +STR_ENGINE_PREVIEW_SHIP :船舶 + STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}費用:{CURRENCY_LONG} 載重:{WEIGHT_SHORT}{}速度:{VELOCITY} 功率:{POWER}{}營運成本:{CURRENCY_LONG} / 年{}容量:{CARGO_LONG} STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}費用:{CURRENCY_LONG} 載重:{WEIGHT_SHORT}{}速度:{VELOCITY} 功率:{POWER} 最大牽引力:{6:FORCE}{}營運成本:{4:CURRENCY_LONG}/年{}容量:{5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}費用:{CURRENCY_LONG} 最高速度:{VELOCITY}{}容量:{CARGO_LONG}{}營運成本:{CURRENCY_LONG}/年 @@ -3552,6 +3547,7 @@ STR_REPLACE_ELRAIL_VEHICLES :電氣化列車 STR_REPLACE_MONORAIL_VEHICLES :單軌列車 STR_REPLACE_MAGLEV_VEHICLES :磁浮列車 + STR_REPLACE_REMOVE_WAGON :{BLACK}移除車廂:{ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}如果替換後的車廂較長的話,讓自動替換功能移除多餘的車廂 (從頭開始) 以便維持列車長度 @@ -3999,6 +3995,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}選擇 STR_AI_LIST_CANCEL :{BLACK}取消 STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}不改變腳本 + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} 參數 STR_AI_SETTINGS_CAPTION_AI :AI @@ -4270,7 +4267,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 :{WHITE}這種軌道不能建設平交道 +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}這種軌道不能建設平交道 STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}無法在此興建號誌... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}無法在此鋪設鐵路... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}不能從這邊移除鐵路... diff --git a/src/lang/turkish.txt b/src/lang/turkish.txt index a93c8ff15f..dc5eeaf8f0 100644 --- a/src/lang/turkish.txt +++ b/src/lang/turkish.txt @@ -11,8 +11,6 @@ ##case tamlanan -# $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. # 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. @@ -476,9 +474,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Konsolu aç/kapa STR_ABOUT_MENU_AI_DEBUG :YZ/Oyun betik hata ayıklama STR_ABOUT_MENU_SCREENSHOT :Ekran görüntüsü -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Tamamen yakınlaştırılmış ekran görüntüsü -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Varsayılan yakınlıkta ekran görüntüsü -STR_ABOUT_MENU_GIANT_SCREENSHOT :Tüm harita ekran görüntüsü STR_ABOUT_MENU_SHOW_FRAMERATE :Kare oranını göster STR_ABOUT_MENU_ABOUT_OPENTTD :'OpenTTD' Hakkında STR_ABOUT_MENU_SPRITE_ALIGNER :Nesne hizalayıcı @@ -649,9 +644,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Özel 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Müzik Sesi STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Efekt Sesi -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}ASGARİ -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}AZAMİ -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -868,6 +860,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}Yeni {STRING} artık kullanılabilir! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} artık {STRING} kabul etmiyor STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} artık {STRING} veya {STRING} kabul etmiyor STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} artık {STRING} kabul ediyor @@ -1709,7 +1702,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Kargo d STR_CONFIG_SETTING_AI :{ORANGE}Rakipler STR_CONFIG_SETTING_AI_NPC :{ORANGE}Bilgisayar oyuncuları -STR_CONFIG_SETTING_PATHFINDER_OPF :Özgün STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Önerilen) @@ -1793,13 +1785,9 @@ STR_QUIT_NO :{BLACK}Hayır # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -2430,6 +2418,7 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Tramvay STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Yol yap/sil arasında geçiş yap STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Tramvay yapımı/yıkımı + # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Garaj Yönü STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}Garaj yönünü seç @@ -3348,8 +3337,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}{COMPANY STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Demiryolu parçaları: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Sinyaller STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Karayolu parçaları: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Karayolu -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Tramvay STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Su kareleri: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Kanallar STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}İstasyonlar: @@ -3360,8 +3347,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Fabrikalar STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Hiçbiri - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} (%{COMMA} taşındı) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} (%{COMMA}/%{COMMA} taşındı) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Fabrika adları - görüntüyü fabrikada merkezlemek için adına tıklayın. Ctrl ile tıklama fabrikanın konumunu gösteren yeni bir pencere açar @@ -3429,6 +3414,7 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Gruplanmamış STR_GROUP_DEFAULT_SHIPS :Gruplanmamış gemiler STR_GROUP_DEFAULT_AIRCRAFTS :Gruplanmamış uçaklar + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Gruplar - gruba ait araçları listelemek için grubun üzerine tıklayın. Hiyerarşiyi düzenlemek için grupları sürükleyip bırakın. STR_GROUP_CREATE_TOOLTIP :{BLACK}Grup oluşturmak için tıklayın STR_GROUP_DELETE_TOOLTIP :{BLACK}Seçili grubu sil @@ -3455,10 +3441,13 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Yeni Elektrikli STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Yeni Monoray STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Yeni Maglev -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Trenler STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Yeni Karayolu Araçları + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Trenler STR_BUY_VEHICLE_SHIP_CAPTION :Yeni gemi STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Yeni Hava Aracı +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Fiyat: {GOLD}{CURRENCY_LONG}{BLACK} Ağırlık: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Hız: {GOLD}{VELOCITY}{BLACK} Güç: {GOLD}{POWER} @@ -3493,11 +3482,13 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Araç Sa STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Gemi Satın Al STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Uçak Satın Al + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Seçili treni satın al. Shift ile tıklama satın almadan tahmini maliyeti gösterir. STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}İşaretli aracı al. Shift ile tıklama satın almadan tahmini maliyeti gösterir STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Seçili gemiyi satın al. Shift ile tıklama satın almadan tahmini maliyeti gösterir STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Seçili uçağı satın al. Shift ile tıklama satın almadan tahmini maliyeti gösterir + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Yeni isim STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}İsim STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}İsim @@ -3606,13 +3597,16 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Garajda # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Araç üreticisinden mesaj STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Yeni bir {STRING} tasarladık - bizim için bunu bir yıl denemeyi kabul ediyor musunuz? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :lokomotif -STR_ENGINE_PREVIEW_ROAD_VEHICLE :karayolu aracı -STR_ENGINE_PREVIEW_AIRCRAFT :uçak -STR_ENGINE_PREVIEW_SHIP :gemi STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :monoray lokomotifi STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :maglev lokomotifi +STR_ENGINE_PREVIEW_ROAD_VEHICLE :karayolu aracı + +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_MAX_SPEED_CAP_RUNCOST :{BLACK}Maliyet: {CURRENCY_LONG} Azami Hız: {VELOCITY}{}Kapasite: {CARGO_LONG}{}İşletme Gideri: {CURRENCY_LONG}/yıl @@ -3658,6 +3652,7 @@ STR_REPLACE_ELRAIL_VEHICLES :Elektrikli Tren STR_REPLACE_MONORAIL_VEHICLES :Monoray Araçları STR_REPLACE_MAGLEV_VEHICLES :Maglev Araçları + STR_REPLACE_REMOVE_WAGON :{BLACK}Vagon kaldırma: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Otomatik yenilemede tren boyutunun artması gerekiyorsa vagonları kaldır (en önden başlayarak yeterli sayıda vagon silinir) @@ -4108,6 +4103,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Vurgulan STR_AI_LIST_CANCEL :{BLACK}İptal STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Betiği değiştirme + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parametreler STR_AI_SETTINGS_CAPTION_AI :YZ @@ -4310,7 +4306,6 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... bu y STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... yol yanlış yönde STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... yol üstü duraklar köşe üzerine inşa edilemez STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... yol üstü duraklar kavşak üzerine inşa edilemez -STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... yol tek yön ya da engellenmiş # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}İstasyonun parçasi kaldırılamaz... @@ -4380,7 +4375,7 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Önce i STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Uygun ray yok STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Önce ray kaldırılmalı STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Yol tek yönlü veya kapalı -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Bu ray türü için hemzemin geçit yapılamaz +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Bu ray türü için hemzemin geçit yapılamaz STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Buraya sinyal yapılamıyor... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Buraya ray yapılamıyor... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Buradan ray kaldırılamıyor... diff --git a/src/lang/ukrainian.txt b/src/lang/ukrainian.txt index 2a91c56fa9..d5a6547c1f 100644 --- a/src/lang/ukrainian.txt +++ b/src/lang/ukrainian.txt @@ -12,8 +12,6 @@ ##case r d z -# $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. # 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. @@ -362,6 +360,8 @@ STR_TOOLTIP_FILTER_CRITERIA :{BLACK}Обер STR_BUTTON_SORT_BY :{BLACK}Сортувати STR_BUTTON_LOCATION :{BLACK}Показати STR_BUTTON_RENAME :{BLACK}Назва +STR_BUTTON_CATCHMENT :{BLACK}Покриття +STR_TOOLTIP_CATCHMENT :{BLACK}Вкл./викл. відображення області покриття STR_TOOLTIP_CLOSE_WINDOW :{BLACK}Закрити вікно STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Заголовок вікна - потягніть для переміщення вікна @@ -390,6 +390,7 @@ STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT_TOOLTIP :{BLACK}нати STR_BUTTON_DEFAULT :{BLACK}Стандартно STR_BUTTON_CANCEL :{BLACK}Відміна STR_BUTTON_OK :{BLACK}Так +STR_WARNING_PASSWORD_SECURITY :{YELLOW}Попередження: Адміністратори серверів можуть мати можливість читати будь-який текст, введений тут. # On screen keyboard window STR_OSK_KEYBOARD_LAYOUT :`1234567890-=\йцукенгшщзхїфівапролджє ячсмитьбю. . @@ -463,6 +464,7 @@ STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN :{BLACK}Збіл STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT :{BLACK}Зменшити STR_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Будувати залізницю STR_TOOLBAR_TOOLTIP_BUILD_ROADS :{BLACK}Будувати дороги +STR_TOOLBAR_TOOLTIP_BUILD_TRAMWAYS :{BLACK}Будувати трамвайну колію STR_TOOLBAR_TOOLTIP_BUILD_SHIP_DOCKS :{BLACK}Будувати порти STR_TOOLBAR_TOOLTIP_BUILD_AIRPORTS :{BLACK}Будувати аеропорти STR_TOOLBAR_TOOLTIP_LANDSCAPING :{BLACK}Змінити ландшафт @@ -483,6 +485,7 @@ STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION :{BLACK}Ство STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Створення міст STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION :{BLACK}Створення виробництва STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Будівництво доріг +STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Будівництво трамвайних колій STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Насадження дерев. Утримуйте Shift для показу витрат на висаджування STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Встановити позначку STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Встановити об'єкт. Утримуйте Shift для показу витрат на розміщення @@ -567,7 +570,7 @@ STR_RAIL_MENU_MAGLEV_CONSTRUCTION :Будівни ############ range for road construction menu starts STR_ROAD_MENU_ROAD_CONSTRUCTION :Будівництво автомобільних доріг -STR_ROAD_MENU_TRAM_CONSTRUCTION :Будівництво трамвайних доріг +STR_ROAD_MENU_TRAM_CONSTRUCTION :Будівництво трамвайних колій ############ range ends here ############ range for waterways construction menu starts @@ -600,9 +603,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Вкл./відкл. консоль STR_ABOUT_MENU_AI_DEBUG :Налагодження АІ / Ігрового Скрипта STR_ABOUT_MENU_SCREENSHOT :Знімок екрану -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Знімок екрану з максимальним збільшенням -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Знімок екрану зі стандартним збільшенням -STR_ABOUT_MENU_GIANT_SCREENSHOT :Знімок всієї карти STR_ABOUT_MENU_SHOW_FRAMERATE :Швидкість генерації гри STR_ABOUT_MENU_ABOUT_OPENTTD :Про гру 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Вирівнювання спрайтів @@ -776,9 +776,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Набір 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Гучність музики STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Гучність ефектів -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}Мін. -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}Макс. -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -995,6 +992,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}Відтепер в наявності новий {STRING}! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} більше не приймає {STRING} STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} більше не приймає {STRING} або {STRING} STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} тепер приймає {STRING} @@ -1061,6 +1059,9 @@ STR_GAME_OPTIONS_CURRENCY_GEL :Грузинс STR_GAME_OPTIONS_CURRENCY_IRR :Іранський ріал (IRR) STR_GAME_OPTIONS_CURRENCY_RUB :Російський новий рубель (RUB) STR_GAME_OPTIONS_CURRENCY_MXN :Мексиканське песо (MXN) +STR_GAME_OPTIONS_CURRENCY_NTD :Новий тайваньський долар (NTD) +STR_GAME_OPTIONS_CURRENCY_CNY :Китайські ренміні (CNY) +STR_GAME_OPTIONS_CURRENCY_HKD :Гонконгський долар (HKD) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Сторона руху транспорту @@ -1312,6 +1313,8 @@ STR_CONFIG_SETTING_AUTOSLOPE :Дозволи 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 :При включенні видалення міських будівель та інфраструктури стає біль простішим STR_CONFIG_SETTING_TRAIN_LENGTH :Максимальна довжина потягів: {STRING} @@ -1328,7 +1331,7 @@ STR_CONFIG_SETTING_TRAIN_SLOPE_STEEPNESS_HELPTEXT :Налашту STR_CONFIG_SETTING_PERCENTAGE :{COMMA}% STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS :Крутизна схилів для дорожнього транспорту: {STRING} STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS_HELPTEXT :Налаштування крутизни схилів для дорожнього транспорту. Чим вище значення, тим складніше підйом на схилах. -STR_CONFIG_SETTING_FORBID_90_DEG :Заборонити поїздам і кораблям повертати на 90°: {STRING} +STR_CONFIG_SETTING_FORBID_90_DEG :Заборонити поїздам повертати на 90°: {STRING} STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :При включенні прямокутні перетини шляхів не будуть вважатися поворотами. Для повороту необходно прокладати шляхи під кутом 45°. STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS :Станції можуть складатися з не суміжних частин: {STRING} STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS_HELPTEXT :Дозволяє об'єднання в одну станцію частин, що не примикають одна до одної. Щоб приєднати нову станцію до існуючої необхідно використовувати Ctrl+Click при будівництві. @@ -1385,7 +1388,7 @@ STR_CONFIG_SETTING_PLANE_SPEED :Множник STR_CONFIG_SETTING_PLANE_SPEED_HELPTEXT :Налаштування співвідношення швідкості повітряного транспорту та швидкості інших видів транспорту з метою зменьшення високих прибутків від авіації. STR_CONFIG_SETTING_PLANE_SPEED_VALUE :1 / {COMMA} STR_CONFIG_SETTING_PLANE_CRASHES :Частота повітряних катастроф: {STRING} -STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Налаштування частоти повітряних катастроф +STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Налаштування частоти повітряних катастроф.{}* Великі літаки мають більший ризик катастрофив малих аеропортах STR_CONFIG_SETTING_PLANE_CRASHES_NONE :Немає STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :Низька STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :Нормальна @@ -1445,7 +1448,7 @@ STR_CONFIG_SETTING_TERRAIN_TYPE_HELPTEXT :(Тільки T STR_CONFIG_SETTING_INDUSTRY_DENSITY :Густота підприємств: {STRING} STR_CONFIG_SETTING_INDUSTRY_DENSITY_HELPTEXT :Встановіть кількість підприємств, що будуть створені і кількість підприємств, що існуватимуть впродовж гри STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE :Макс. відстань від краю карти до нафтопереробних заводів: {STRING} -STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :Нафтопереробні заводи завжди будуються не далеко від краю карти або узбережжя. +STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :Обмеження того, наскільки далеко може бути побудований кордон нафтопереробних заводів та нафтових установок. На островних картах це гарантує, що вони знаходяться біля узбережжя. На картах більше 256 плиток це значення збільшується. STR_CONFIG_SETTING_SNOWLINE_HEIGHT :Рівень снігової шапки: {STRING} STR_CONFIG_SETTING_SNOWLINE_HEIGHT_HELPTEXT :Контроль висоти, вище якої лежить сніг в субарктичному ландшафті. Сніг впливає на генерування підприємств та на умови росту міст STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN :Грубість ландшафту: {STRING} @@ -1609,6 +1612,9 @@ 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_OPCODES_HELPTEXT :Максимально допустима кількість розрахунків, що можуть виконати скрипти віртуальних гравців впродовж одного ходу. +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY :Максимальне використаня пам'яті скриптом: {STRING} +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_HELPTEXT :Скільки пам'яті може зайняти один сценарій до примусового припинення. Це може знадобитися збільшити для великих карт. +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_VALUE :{COMMA} MiB STR_CONFIG_SETTING_SERVINT_ISPERCENT :Інтервали техогляду вказано у відсотках: {STRING} STR_CONFIG_SETTING_SERVINT_ISPERCENT_HELPTEXT :Налаштування способу визначення необхідності проведення техогляду: через вказаний проміжок часу після попереднього техогляду чи коли поточна надійність транспортного засобу стане нижчою від максимальної його надійності на вказаний процент. @@ -1671,6 +1677,8 @@ STR_CONFIG_SETTING_SMOOTH_ECONOMY :Стабіль STR_CONFIG_SETTING_SMOOTH_ECONOMY_HELPTEXT :При включенні обсяги виробництва підприємств змінюються часто, але не дуже суттєво. Зазвичай ця опція не впливає на підприємства, додані за допомогою NewGRF. STR_CONFIG_SETTING_ALLOW_SHARES :Дозволити придбання акції інших компаній: {STRING} STR_CONFIG_SETTING_ALLOW_SHARES_HELPTEXT :При включенні дозволяє придбання та продаж акцій команій. Акції компанії стають доступними після досягнення деякого віку. +STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES :Мінімальний вік компанії для торгівлі акціями: {STRING} +STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES_HELPTEXT :Встановіть мінімальний вік компанії, щоб інші могли купувати та продавати акції у них. STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE :Відсоток прибутку за часткове перевезення: {STRING} STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE_HELPTEXT :Налаштування проценту прибутку, що нараховується за часткове перевезення вантажу. За допомогою даної опції можна контролювати розподіл прибутків між учасниками багатоланкових перевезень. STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY :При протягуванні встановлювати сигнали через {STRING} @@ -1711,6 +1719,10 @@ STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :Дозволя STR_CONFIG_SETTING_TOWN_FOUNDING_FORBIDDEN :Заборонено STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED :Дозволено STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED_CUSTOM_LAYOUT :Дозволено (з вибором дорожньої сітки) +STR_CONFIG_SETTING_TOWN_CARGOGENMODE :Кількість вантажів та пасажирів у містах: {STRING} +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_HELPTEXT :Скільки вантажів генерується будинками в містах відносно населення.{}Квадратична залежність: Вдвічі більше місто генерує вчетверо більше вантажів.{}Лінійна: Вдвічі більше місто генерує вдвічі більше вантажів. +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_ORIGINAL :Квадратична(оригінальна) +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_BITCOUNT :лінійна залежність STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :Поява дерев під час гри: {STRING} STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :Налаштування випадкової появи дерев на карті в процесі гри. Ця настройка також впливає на відповідні підприємства, такі як лісопилки. @@ -1838,7 +1850,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Роз STR_CONFIG_SETTING_AI :{ORANGE}Конкуренти STR_CONFIG_SETTING_AI_NPC :{ORANGE}Віртуальні гравці -STR_CONFIG_SETTING_PATHFINDER_OPF :стандартний STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(рекомендовано) @@ -1922,13 +1933,9 @@ STR_QUIT_NO :{BLACK}Ні # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -2266,7 +2273,7 @@ STR_NETWORK_CHAT_ALL :[Всім] {STR STR_NETWORK_CHAT_OSKTITLE :{BLACK}Введіть текст для мережевого чату # Network messages -STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}Не знайдено мережевого пристрою або скомпільовано без ENABLE_NETWORK +STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}Не знайдено мережевого пристрою STR_NETWORK_ERROR_NOSERVER :{WHITE}Не знайдено жодної мережевої гри STR_NETWORK_ERROR_NOCONNECTION :{WHITE}Сервер не відповів на запит STR_NETWORK_ERROR_NEWGRF_MISMATCH :{WHITE}Не можна з'єднатись внаслідок неспівпадання NewGRF @@ -2543,7 +2550,7 @@ STR_BRIDGE_TUBULAR_SILICON :Трубчас # Road construction toolbar STR_ROAD_TOOLBAR_ROAD_CONSTRUCTION_CAPTION :{WHITE}Автомобільне будівництво -STR_ROAD_TOOLBAR_TRAM_CONSTRUCTION_CAPTION :{WHITE}Трамвайне будівництво +STR_ROAD_TOOLBAR_TRAM_CONSTRUCTION_CAPTION :{WHITE}Будівництво трамвайних колій STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_SECTION :{BLACK}Будувати дорогу. Ctrl переключає побудову/знесення для будівництва доріг. Утримуйте Shift для показу витрат STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION :{BLACK}Будувати трамвайну колію. Ctrl переключає побудову/знесення для будівництва трамвайної колії. Утримуйте Shift для показу витрат на будівництво STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOROAD :{BLACK}Будувати дорогу в режимі Автобудування. Ctrl переключає побудову/знесення для будівництва доріг. Утримуйте Shift для показу витрат на будівництво @@ -2561,6 +2568,11 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL :{BLACK}Буду STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Побудувати трамвайний тунель. Утримуйте Shift для показу витрат на придбання STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Будувати/зруйнувати дорогу STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Будувати/демонтувати колію +STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_ROAD :{BLACK}Модернізувати дорогу. Утримуйте Shift для показу витрат на модернізацію +STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_TRAM :{BLACK}Convert/Перетворення / оновлення типу трамваю. Shift перемикає будівництво / показ кошторису витрат + +STR_ROAD_NAME_ROAD :Дорога +STR_ROAD_NAME_TRAM :Трамвай # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Орієнтація депо @@ -2745,8 +2757,11 @@ STR_LAND_AREA_INFORMATION_NEWGRF_NAME :{BLACK}NewGRF: STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED :{BLACK}Приймає: {LTBLUE} STR_LAND_AREA_INFORMATION_CARGO_EIGHTS :({COMMA}/8 {STRING}) STR_LANG_AREA_INFORMATION_RAIL_TYPE :{BLACK}Тип зал.колії: {LTBLUE}{STRING} +STR_LANG_AREA_INFORMATION_ROAD_TYPE :{BLACK}Тип дороги: {LTBLUE}{STRING} +STR_LANG_AREA_INFORMATION_TRAM_TYPE :{BLACK}Тип трамваю: {LTBLUE}{STRING} STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT :{BLACK}Ліміт швидкості залізниці: {LTBLUE}{VELOCITY} STR_LANG_AREA_INFORMATION_ROAD_SPEED_LIMIT :{BLACK}Ліміт швидкості авто: {LTBLUE}{VELOCITY} +STR_LANG_AREA_INFORMATION_TRAM_SPEED_LIMIT :{BLACK}Обмеження швидкості руху трамваїв: {LTBLUE}{VELOCITY} # Description of land area of different tiles STR_LAI_CLEAR_DESCRIPTION_ROCKS :Каміння @@ -2856,6 +2871,7 @@ STR_FRAMERATE_SPEED_FACTOR :{BLACK}Наяв STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK} Як швидко гра біжить в даний час, в порівнянні з очікуваною швидкістю при звичайній швидкості моделювання. STR_FRAMERATE_CURRENT :{WHITE}Зараз STR_FRAMERATE_AVERAGE :{WHITE}Середнє +STR_FRAMERATE_MEMORYUSE :{WHITE}Пам'ять STR_FRAMERATE_DATA_POINTS :{BLACK}Дані отримано з {COMMA} вимірюван {P "ня" "нь" "нь" } STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL} мс STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL} ms @@ -2863,6 +2879,9 @@ STR_FRAMERATE_MS_BAD :{RED}{DECIMAL} STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL} кадрів/сек STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL} кадр{P "" "и" "ів"}/сек STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL} кадрів/сек +STR_FRAMERATE_BYTES_GOOD :{LTBLUE}{BYTES} +STR_FRAMERATE_BYTES_WARN :{YELLOW}{BYTES} +STR_FRAMERATE_BYTES_BAD :{RED}{BYTES} STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} мс STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} с ############ Leave those lines in this order!! @@ -3130,6 +3149,7 @@ STR_NEWGRF_ERROR_GRM_FAILED :Недосту STR_NEWGRF_ERROR_FORCEFULLY_DISABLED :{1:STRING} був вимкнений {STRING} STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT :Некоректний або невідомий формат розміщення спрайтів (спрайт {3:NUM}) STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG :Дуже багато елементів у списку значень (спрайт {3:NUM}, властивість {4:HEX}) +STR_NEWGRF_ERROR_INDPROD_CALLBACK :Невірна обробка продукції підприємства (спрайт {3:NUM}, "{2:STRING}") # NewGRF related 'general' warnings STR_NEWGRF_POPUP_CAUTION_CAPTION :{WHITE}Обережно! @@ -3161,6 +3181,7 @@ STR_NEWGRF_BUGGY :{WHITE}NewGRF ' STR_NEWGRF_BUGGY_ARTICULATED_CARGO :{WHITE}Інформація про вантаж/переобладнання для '{1:ENGINE}' відрізняється від списку покупки після побудови. Це може спричинити невідповідності під час автооновлення/заміни STR_NEWGRF_BUGGY_ENDLESS_PRODUCTION_CALLBACK :{WHITE}'{1:STRING}' спричинив нескінченний цикл у виклику виробництва STR_NEWGRF_BUGGY_UNKNOWN_CALLBACK_RESULT :{WHITE}Виклик {1:HEX} повернув невідомий/неправильний результат {2:HEX} +STR_NEWGRF_BUGGY_INVALID_CARGO_PRODUCTION_CALLBACK :{WHITE}'{1:STRING}'повернув недійсний тип вантажу у виробничому зворотному режимі о {2:HEX} # 'User removed essential NewGRFs'-placeholders for stuff without specs STR_NEWGRF_INVALID_CARGO :<невідомий вантаж> @@ -3227,6 +3248,8 @@ STR_TOWN_VIEW_RENAME_TOWN_BUTTON :Перейме # Town local authority window STR_LOCAL_AUTHORITY_CAPTION :{WHITE}{TOWN} - місцева влада +STR_LOCAL_AUTHORITY_ZONE :{BLACK}Зона +STR_LOCAL_AUTHORITY_ZONE_TOOLTIP :{BLACK}Показати зону в межах місцевих повноважень STR_LOCAL_AUTHORITY_COMPANY_RATINGS :{BLACK}Рейтинги компаній: STR_LOCAL_AUTHORITY_COMPANY_RATING :{YELLOW}{COMPANY} {COMPANY_NUM}: {ORANGE}{STRING} STR_LOCAL_AUTHORITY_ACTIONS_TITLE :{BLACK}Доступні дії: @@ -3484,8 +3507,7 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Інфр STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Залізничні ділянки: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}З сигналами STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Дорожні ділянки: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Автомобільні -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Трамвайні +STR_COMPANY_INFRASTRUCTURE_VIEW_TRAM_SECT :{GOLD}Трамвайні вагони: STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Судноплавні ділянки: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Канали STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Станції: @@ -3496,9 +3518,12 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Підприємства STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- немає - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% перевезено) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% перевезено) +STR_INDUSTRY_DIRECTORY_ITEM_INFO :{BLACK}{CARGO_LONG}{STRING}{YELLOW} ({COMMA}% перевезено){BLACK} STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} +STR_INDUSTRY_DIRECTORY_ITEM_PROD1 :{ORANGE}{INDUSTRY} {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PROD2 :{ORANGE}{INDUSTRY} {STRING}, {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PROD3 :{ORANGE}{INDUSTRY} {STRING}, {STRING}, {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PRODMORE :{ORANGE}{INDUSTRY} {STRING}, {STRING}, {STRING} і {NUM} ще... STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Назви підприємств - клацніть мишою на назву, щоб показати підприємство у центрі екрану. Ctrl+клац мишою відкриває нове вікно з видом на підприємство # Industry view @@ -3565,6 +3590,8 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Незгруп STR_GROUP_DEFAULT_SHIPS :Незгруповані кораблі STR_GROUP_DEFAULT_AIRCRAFTS :Незгруповані літаки +STR_GROUP_COUNT_WITH_SUBGROUP :{TINY_FONT}{COMMA} (+{COMMA}) + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Групи - клацніть мишою на групі, щоб побачити список транспорту цієї групи. Перетягуйте групи, щоб змінити ієрархію. STR_GROUP_CREATE_TOOLTIP :{BLACK}Клацніть мишою, щоб створити групу STR_GROUP_DELETE_TOOLTIP :{BLACK}Стерти вибрану групу @@ -3591,12 +3618,18 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Новий ел STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Новий монорейковий поїзд STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Новий магнітний поїзд -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Нові потяги STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Нові автомобілі +STR_BUY_VEHICLE_TRAM_VEHICLE_CAPTION :Нові трамваї + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Нові потяги +STR_BUY_VEHICLE_ROAD_VEHICLE_ALL_CAPTION :Нові автомобілі STR_BUY_VEHICLE_SHIP_CAPTION :Нові кораблі STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Нові літаки +############ range for vehicle availability ends 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} @@ -3607,8 +3640,10 @@ STR_PURCHASE_INFO_REFITTABLE :(змінюєт STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Рік випуску: {GOLD}{NUM}{BLACK} Вік: {GOLD}{COMMA} р{P ік оки оків} STR_PURCHASE_INFO_RELIABILITY :{BLACK}Надійність: {GOLD}{COMMA}% STR_PURCHASE_INFO_COST :{BLACK}Ціна: {GOLD}{CURRENCY_LONG} +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} @@ -3629,11 +3664,21 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Купи STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Купити STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Купити +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Купити і переобладнати авто +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Купити і переобладнати авто +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Купіть і переобладнайте корабель +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Купуйте та переобладнайте літаки + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Купити вибраний поїзд. Утримуйте Shift для показу витрат на придбання STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Купити вибране авто. Утримуйте Shift для показу витрат на придбання STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Купити вибраний корабель. Утримуйте Shift для показу витрат на придбання STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Купити вибраний літак. Утримуйте Shift для показу витрат на придбання +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Придбайте та переобладнайте виділений поїзд. Shift + Click показує орієнтовну вартість без покупки +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Придбайте та переобладнайте авто. Shift + Click показує орієнтовну вартість без покупки +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Придбайте та переобладнайте виділене судно. Shift + Click показує орієнтовну вартість без покупки +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Придбайте та переобладнайте виділені літаки. Shift + Click показує орієнтовну вартість без покупки + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Назва STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Зміна назви STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Зміна назви @@ -3742,13 +3787,18 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Ви в # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Повідомлення від виробника транспорту STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Ми розробили новий {STRING} - чи бажаєте ексклюзивно користуватись ним протягом року, так ми побачимо, як він зарекомендує себе, перед тим як буде доступним для всіх? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :локомотив -STR_ENGINE_PREVIEW_ROAD_VEHICLE :автомобіль -STR_ENGINE_PREVIEW_AIRCRAFT :літак -STR_ENGINE_PREVIEW_SHIP :корабель +STR_ENGINE_PREVIEW_ELRAIL_LOCOMOTIVE :електрифікований залізничний локомотив STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :монорейковий локомотив STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :магнітний локомотив +STR_ENGINE_PREVIEW_ROAD_VEHICLE :автомобіль +STR_ENGINE_PREVIEW_TRAM_VEHICLE :трамваї + +STR_ENGINE_PREVIEW_AIRCRAFT :літак +STR_ENGINE_PREVIEW_SHIP :корабель + STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Ціна: {CURRENCY_LONG} Вага: {WEIGHT_SHORT}{}Швидкість: {VELOCITY}{}Потужність: {POWER}{}Вартість експлуатації: {CURRENCY_LONG}/рік{}Місткість: {CARGO_LONG} STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Вартість: {CURRENCY_LONG} Вага: {WEIGHT_SHORT}{}Швидкість: {VELOCITY} Потужність: {POWER} Макс. тяга: {6:FORCE}{}Вартість експлуатації: {4:CURRENCY_LONG}/рік{}Місткість: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Вартість: {CURRENCY_LONG} Макс. швидкість: {VELOCITY}{}Місткість: {CARGO_LONG}{}Вартість експлуатації: {CURRENCY_LONG}/рік @@ -3786,14 +3836,19 @@ STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK}Пере STR_REPLACE_ENGINES :Локомотиви STR_REPLACE_WAGONS :Вагони STR_REPLACE_ALL_RAILTYPE :Весь з/д транспорт +STR_REPLACE_ALL_ROADTYPE :Всі автомобілі STR_REPLACE_HELP_RAILTYPE :{BLACK}Виберіть тип колії, для якого ви збираєтесь оновити потяги +STR_REPLACE_HELP_ROADTYPE :{BLACK}Виберіть тип дороги, на який хочете замінити двигуни STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Показує, яким потягом буде замінено потяг, вибраний ліворуч STR_REPLACE_RAIL_VEHICLES :Неелектрифіковані поїзди STR_REPLACE_ELRAIL_VEHICLES :Електрифіковані поїзди STR_REPLACE_MONORAIL_VEHICLES :Монорейкові поїзди STR_REPLACE_MAGLEV_VEHICLES :Магнітні поїзди +STR_REPLACE_ROAD_VEHICLES :Авто +STR_REPLACE_TRAM_VEHICLES :Трамвайні транспортні засоби + STR_REPLACE_REMOVE_WAGON :{BLACK}Ліквідація зайвих вагонів: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Дозволити автооновленню видаляти вагони, зберігаючи довжину потягу (починаючи спереду), якщо оновлення робить поїзд довшим @@ -4244,6 +4299,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Вибр STR_AI_LIST_CANCEL :{BLACK}Відміна STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Не міняти скрипт + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Параметри STR_AI_SETTINGS_CAPTION_AI :АІ @@ -4446,7 +4502,6 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... ця STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... дорога не в тому напрямку STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... проїзні зупинки не можуть мати поворотів STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... проїзні зупинки не можуть мати перехресть -STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... дорога одностороння або заблокована # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Не можна зруйнувати частину станції... @@ -4462,7 +4517,7 @@ STR_ERROR_MUST_DEMOLISH_RAILROAD :{WHITE}Споч STR_ERROR_MUST_DEMOLISH_BUS_STATION_FIRST :{WHITE}Спочатку зруйнуйте зупинку STR_ERROR_MUST_DEMOLISH_TRUCK_STATION_FIRST :{WHITE}Спочатку зруйнуйте вантажну станцію STR_ERROR_MUST_DEMOLISH_PASSENGER_TRAM_STATION_FIRST :{WHITE}Спочатку треба знести пасажирську трамвайну станцію -STR_ERROR_MUST_DEMOLISH_CARGO_TRAM_STATION_FIRST :{WHITE}Спочатку треба знести вантажну трамвайну станцію +STR_ERROR_MUST_DEMOLISH_CARGO_TRAM_STATION_FIRST :{WHITE}Спочатку зруйнуйте товарну трамвайну станцію STR_ERROR_MUST_DEMOLISH_DOCK_FIRST :{WHITE}Спочатку зруйнуйте порт STR_ERROR_MUST_DEMOLISH_AIRPORT_FIRST :{WHITE}Спочатку зруйнуйте аеропорт @@ -4516,7 +4571,8 @@ 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 :{WHITE}Переїзди для такого виду колії є забороненими +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Переїзди для такого виду колії є забороненими +STR_ERROR_CROSSING_DISALLOWED_ROAD :{WHITE}Переїзди для такого виду дороги є забороненими STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Неможливо будувати сигнали тут... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Неможливо будувати колію тут... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Неможливо прибрати колію звідси... @@ -4536,6 +4592,12 @@ STR_ERROR_CAN_T_REMOVE_ROAD_FROM :{WHITE}Немо STR_ERROR_CAN_T_REMOVE_TRAMWAY_FROM :{WHITE}Не можна прибрати трамвайну колію звідси... STR_ERROR_THERE_IS_NO_ROAD :{WHITE}... тут немає дороги STR_ERROR_THERE_IS_NO_TRAMWAY :{WHITE}... тут немає трамвайних шляхів +STR_ERROR_CAN_T_CONVERT_ROAD :{WHITE}Тут не можна модернізувати дорогу... +STR_ERROR_CAN_T_CONVERT_TRAMWAY :{WHITE}Тут не можна перетворити тип трамваю ... +STR_ERROR_NO_SUITABLE_ROAD :{WHITE}Немає підходящої дороги +STR_ERROR_NO_SUITABLE_TRAMWAY :{WHITE}Немає підходящої трамвайної колії +STR_ERROR_INCOMPATIBLE_ROAD :{WHITE}... несумісна дорога +STR_ERROR_INCOMPATIBLE_TRAMWAY :{WHITE}... несумісний трамвай # Waterway construction errors STR_ERROR_CAN_T_BUILD_CANALS :{WHITE}Неможливо будувати канал тут... @@ -4588,6 +4650,7 @@ STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Не м STR_ERROR_GROUP_CAN_T_DELETE :{WHITE}Не можна стерти групу... STR_ERROR_GROUP_CAN_T_RENAME :{WHITE}Не можна перейменувати групу... STR_ERROR_GROUP_CAN_T_SET_PARENT :{WHITE}Неможливо встановити головну групу... +STR_ERROR_GROUP_CAN_T_SET_PARENT_RECURSION :{WHITE}... ієрархія груп не може містити циклів STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}Не можна позбутися всього транспорту цієї групи... STR_ERROR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}Не можна додати цей транспорт у групу... STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}Не можна додати спільний транспорт у групу... diff --git a/src/lang/unfinished/chuvash.txt b/src/lang/unfinished/chuvash.txt index 7366b99fcf..44deeae30f 100644 --- a/src/lang/unfinished/chuvash.txt +++ b/src/lang/unfinished/chuvash.txt @@ -10,8 +10,6 @@ ##grflangid 0x0b -# $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. # 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. @@ -274,7 +272,6 @@ STR_TOOLBAR_SOUND_MUSIC :Сасӑ/Юрӑ ############ range for about menu starts STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_SCREENSHOT :Экран сӑнӗ -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Яланхилле экран сӑнӗ STR_ABOUT_MENU_ABOUT_OPENTTD :'OpenTTD' çинчен ############ range ends here @@ -393,9 +390,6 @@ STR_PERFORMANCE_DETAIL_TOTAL :{BLACK}Пурӗ ############ End of order list # Music window -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}ЧИ САХ(MIN) -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}ЧИ НУМ(MAX) -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -468,6 +462,7 @@ STR_NEWS_MESSAGE_CAPTION :{WHITE}Пӗлт + # Extra view window # Game options window @@ -662,13 +657,9 @@ STR_QUIT_NO :{BLACK}Ҫук # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -864,6 +855,7 @@ STR_CONTENT_DETAIL_VERSION :{SILVER}Вер # Road construction toolbar + # Road depot construction window # Road vehicle station construction window @@ -1138,9 +1130,15 @@ STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Ҫу + # Build vehicle window +############ range for vehicle availability starts +############ range for vehicle availability ends + + + @@ -1176,6 +1174,9 @@ STR_DEPOT_VEHICLE_TOOLTIP_CARGO :{}{CARGO_LONG} # Engine preview window + + + # Autoreplace window @@ -1184,6 +1185,7 @@ STR_DEPOT_VEHICLE_TOOLTIP_CARGO :{}{CARGO_LONG} + # Vehicle view STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE} @@ -1296,6 +1298,7 @@ STR_AI_CONFIG_CHANGE_NONE : STR_AI_LIST_VERSION :{LTBLUE}Верси: {ORANGE}{NUM} + # AI Parameters STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} diff --git a/src/lang/unfinished/frisian.txt b/src/lang/unfinished/frisian.txt index 4d4101b1aa..3af7f6a751 100644 --- a/src/lang/unfinished/frisian.txt +++ b/src/lang/unfinished/frisian.txt @@ -10,8 +10,6 @@ ##grflangid 0x32 -# $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. # 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. @@ -472,9 +470,6 @@ 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_ZOOMIN_SCREENSHOT :Tichtby helle skermôfbylding -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Standerdzoom skermôfbylding -STR_ABOUT_MENU_GIANT_SCREENSHOT :Skermôfbylding fan 'e hiele wrâld STR_ABOUT_MENU_ABOUT_OPENTTD :Oer 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Flakken rjochtsje STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Skeakel seleksjekaders oan/út @@ -644,9 +639,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Oanpast 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Musykfolume STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Effektenfolume -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}MIN -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}MAKS -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -858,6 +850,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}Neie {STRING} is no beskikber! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} akseptearret gjin {STRING} mear STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} akseptearret gjin {STRING} en {STRING} mear STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} akseptearrret no {STRING} @@ -1635,7 +1628,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Frachtd STR_CONFIG_SETTING_AI :{ORANGE}Tsjinstânners STR_CONFIG_SETTING_AI_NPC :{ORANGE}Computer spilers -STR_CONFIG_SETTING_PATHFINDER_OPF :Orizjiniel STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Recommended) @@ -1701,13 +1693,9 @@ STR_QUIT_NO :{BLACK}Nee # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -2205,6 +2193,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 + # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Autodepot rjochting STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}Kies rjochting foar autodepot @@ -3014,8 +3003,6 @@ 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_ROAD :{WHITE}Dyk -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Tramwei STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Stasjons: STR_COMPANY_INFRASTRUCTURE_VIEW_STATIONS :{WHITE}Stasjontegels STR_COMPANY_INFRASTRUCTURE_VIEW_AIRPORTS :{WHITE}Fleanfjilden @@ -3024,8 +3011,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Yndustryen STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Gjin - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% transportearre) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% transportearre) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} # Industry view @@ -3077,6 +3062,7 @@ STR_GROUP_ALL_AIRCRAFTS :Alle fleantugen STR_GROUP_DEFAULT_SHIPS :Net groepearre skepen + STR_GROUP_CREATE_TOOLTIP :{BLACK}Klik om in groep oan te meitsje STR_GROUP_DELETE_TOOLTIP :{BLACK}Smit de selektearre groep fuort STR_GROUP_RENAME_TOOLTIP :{BLACK}Feroarje de namme fan de selektearre groep @@ -3093,8 +3079,11 @@ 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 + +############ range for vehicle availability starts STR_BUY_VEHICLE_SHIP_CAPTION :Nije Skepen STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Nije fleantugen +############ range for vehicle availability ends STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Snelheid: {GOLD}{VELOCITY}{BLACK} Kracht: {GOLD}{POWER} STR_PURCHASE_INFO_SPEED :{BLACK}Snelheid: {GOLD}{VELOCITY} @@ -3120,11 +3109,13 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Keapje a STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Keapje boat STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Keapje fleantúg + 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_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 @@ -3202,13 +3193,16 @@ STR_DEPOT_MASS_START_DEPOT_SHIP_TOOLTIP :{BLACK}Klik om # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Berjocht fan fiertúgenfabrikant STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Wy hawwe sakrekt in nije {STRING} ûntwurpen - bisto ynteressearre yn in jier lang eksklusyf gebrûk fan dit fiertúch, sadat wy kinne sjen oft it goed wurket foardat wy it wrâldwiid beskikber meitsjen? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :lokomotyf -STR_ENGINE_PREVIEW_ROAD_VEHICLE :wein -STR_ENGINE_PREVIEW_AIRCRAFT :fleantúch -STR_ENGINE_PREVIEW_SHIP :skip STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :monorail lokomotyf STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :maglevlokomotyf +STR_ENGINE_PREVIEW_ROAD_VEHICLE :wein + +STR_ENGINE_PREVIEW_AIRCRAFT :fleantúch +STR_ENGINE_PREVIEW_SHIP :skip + STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Kosten: {CURRENCY_LONG} Gewicht: {WEIGHT_SHORT}{}Snelheid: {VELOCITY} Kracht: {POWER}{}Underhâldskosten: {CURRENCY_LONG}/jr{}Kapasiteit: {CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Kosten: {CURRENCY_LONG} Maks. Faasje: {VELOCITY}{}Kapasiteit: {CARGO_LONG}{}Underhâldskosten: {CURRENCY_LONG}/jr @@ -3232,6 +3226,7 @@ STR_REPLACE_MONORAIL_VEHICLES :Monorail weinen STR_REPLACE_MAGLEV_VEHICLES :Maglev treinen + # Vehicle view STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE} @@ -3577,6 +3572,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Selektea STR_AI_LIST_CANCEL :{BLACK}Annulearje STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Skript net feroare + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parameters STR_AI_SETTINGS_CAPTION_AI :AI @@ -3823,7 +3819,7 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Stopljoc STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Spoar is net geskikt STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Spoar moat der earst wei STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Dyk is in ienrjochtingsdyk of blokearre -STR_ERROR_CROSSING_DISALLOWED :{WHITE}In oergong is net tastien foar dit type spoar +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}In oergong is net tastien foar dit type spoar STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Kin hjir gjin stopljochten boue... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Kin hjir gjin spoarwei boue STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Kin hjir gjin spoar fuorthelje... diff --git a/src/lang/unfinished/ido.txt b/src/lang/unfinished/ido.txt index dcc3027782..e709ba47c9 100644 --- a/src/lang/unfinished/ido.txt +++ b/src/lang/unfinished/ido.txt @@ -10,8 +10,6 @@ ##grflangid 0x06 -# $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. # 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. @@ -371,7 +369,6 @@ STR_PERFORMANCE_DETAIL_PERCENT :{WHITE}{NUM}% ############ End of order list # Music window -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -454,6 +451,7 @@ STR_NEWS_MESSAGE_CAPTION :{WHITE}Sendajo + # Extra view window # Game options window @@ -701,6 +699,7 @@ STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}Aceptas: # Road construction toolbar + # Road depot construction window # Road vehicle station construction window @@ -972,9 +971,15 @@ STR_GROUP_DEFAULT_AIRCRAFTS :Negrupigita aer + # Build vehicle window +############ range for vehicle availability starts +############ range for vehicle availability ends + + + @@ -1012,6 +1017,9 @@ STR_DEPOT_VEHICLE_TOOLTIP_CARGO :{}{CARGO_LONG} # Engine preview window + + + # Autoreplace window STR_REPLACE_VEHICLE_TRAIN :Treno STR_REPLACE_VEHICLE_ROAD_VEHICLE :Voy-vehilo @@ -1024,6 +1032,7 @@ STR_REPLACE_VEHICLE_AIRCRAFT :Aeronavo + # Vehicle view STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE} @@ -1143,6 +1152,7 @@ STR_AI_CONFIG_CHANGE_NONE : + # AI Parameters STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} diff --git a/src/lang/unfinished/macedonian.txt b/src/lang/unfinished/macedonian.txt index c080592407..4a623223f4 100644 --- a/src/lang/unfinished/macedonian.txt +++ b/src/lang/unfinished/macedonian.txt @@ -10,8 +10,6 @@ ##grflangid 0x26 -# $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. # 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. @@ -446,8 +444,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Вклучи конзола STR_ABOUT_MENU_AI_DEBUG :АИ / игри сценарио де-бубачки STR_ABOUT_MENU_SCREENSHOT :Слика од екранот -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Зумира екранот -STR_ABOUT_MENU_GIANT_SCREENSHOT :Целата сајтот екранот STR_ABOUT_MENU_ABOUT_OPENTTD :За 'ОтвориTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :самовила усогласат STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Вклучи одблеснува кутии @@ -616,9 +612,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Свое 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Гласност на музка STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Гласност на ефекти -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}МИН -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}MAX -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -778,6 +771,7 @@ STR_NEWS_AIRCRAFT_DEST_TOO_FAR :{WHITE}{VEHICLE + # Extra view window # Game options window @@ -952,9 +946,6 @@ STR_QUIT_NO :{BLACK}Не STR_OSNAME_WINDOWS :Windows STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -1091,6 +1082,7 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_PASSENGER_TRAM_STATION :{BLACK}Изгр STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_BRIDGE :{BLACK}Изгради трамвајски мост STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Изгради трамвајски тунел + # Road depot construction window # Road vehicle station construction window @@ -1402,8 +1394,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Инфр STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}железнички парчиња: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}сигнали STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Патот парчиња: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}патот -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}трамвај STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Вода плочки: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}каналите STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}станици: @@ -1451,10 +1441,14 @@ STR_VEHICLE_LIST_SEND_SHIP_TO_DEPOT :Испрати + # Build vehicle window + +############ range for vehicle availability starts STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Шински возила STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Нов авион +############ range for vehicle availability ends STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Опсег: {GOLD}{COMMA} плочки @@ -1462,8 +1456,10 @@ STR_BUY_VEHICLE_AIRCRAFT_LIST_TOOLTIP :{BLACK}Лист STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Направи авион + STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Направи авион од селектираниот тип + STR_BUY_VEHICLE_AIRCRAFT_RENAME_BUTTON :{BLACK}Преименувај STR_BUY_VEHICLE_AIRCRAFT_RENAME_TOOLTIP :{BLACK}Преименувај го типот на авиони @@ -1505,6 +1501,9 @@ STR_DEPOT_AIRCRAFT_LOCATION_TOOLTIP :{BLACK}Цент # Engine preview window + + + # Autoreplace window STR_REPLACE_VEHICLE_TRAIN :Воз STR_REPLACE_VEHICLE_ROAD_VEHICLE :Патно возило @@ -1517,6 +1516,7 @@ STR_REPLACE_VEHICLE_AIRCRAFT :Летало + # Vehicle view STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE} @@ -1672,6 +1672,7 @@ STR_AI_LIST_CAPTION_GAMESCRIPT :GameScripts + # AI Parameters STR_AI_SETTINGS_CAPTION_AI :АИ STR_AI_SETTINGS_CAPTION_GAMESCRIPT :GameScript @@ -1768,7 +1769,7 @@ STR_ERROR_AUTOREPLACE_NOTHING_TO_DO :{WHITE}Не а STR_ERROR_AUTOREPLACE_MONEY_LIMIT :(лимит на пари) # Rail construction errors -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Ниво, нема премини се дозволени за овој вид железнички +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Ниво, нема премини се дозволени за овој вид железнички STR_ERROR_THERE_IS_NO_RAILROAD_TRACK :{WHITE}... не постои железничка пруга STR_ERROR_THERE_ARE_NO_SIGNALS :{WHITE}... постојат никакви сигнали diff --git a/src/lang/unfinished/maltese.txt b/src/lang/unfinished/maltese.txt index f25027744e..2728fd297f 100644 --- a/src/lang/unfinished/maltese.txt +++ b/src/lang/unfinished/maltese.txt @@ -10,8 +10,6 @@ ##grflangid 0x09 -# $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. # 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. @@ -340,7 +338,6 @@ STR_PERFORMANCE_DETAIL_PERCENT :{WHITE}{NUM}% ############ End of order list # Music window -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -388,6 +385,7 @@ STR_NEWS_VEHICLE_IS_LOST :{WHITE}{VEHICLE + # Extra view window # Game options window @@ -628,6 +626,7 @@ STR_SELECT_BRIDGE_SCENEDIT_INFO :{GOLD}{STRING}, # Road construction toolbar + # Road depot construction window # Road vehicle station construction window @@ -844,9 +843,15 @@ STR_FINANCES_POSITIVE_INCOME :{BLACK}+{CURREN + # Build vehicle window +############ range for vehicle availability starts +############ range for vehicle availability ends + + + @@ -884,6 +889,9 @@ STR_DEPOT_VEHICLE_TOOLTIP_CARGO :{}{CARGO_LONG} # Engine preview window + + + # Autoreplace window @@ -892,6 +900,7 @@ STR_DEPOT_VEHICLE_TOOLTIP_CARGO :{}{CARGO_LONG} + # Vehicle view STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE} @@ -1012,6 +1021,7 @@ STR_AI_CONFIG_CHANGE_NONE : + # AI Parameters diff --git a/src/lang/unfinished/marathi.txt b/src/lang/unfinished/marathi.txt index cfc34dcc4b..6ef399f161 100644 --- a/src/lang/unfinished/marathi.txt +++ b/src/lang/unfinished/marathi.txt @@ -10,8 +10,6 @@ ##grflangid 0x11 -# $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. # 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. @@ -438,9 +436,6 @@ STR_NEWS_MENU_MESSAGE_HISTORY_MENU :निरोप STR_ABOUT_MENU_LAND_BLOCK_INFO :जागाची माहिती STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_SCREENSHOT :द्श्य -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :द्श्य मोठे करा -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :स्थिर द्श्य -STR_ABOUT_MENU_GIANT_SCREENSHOT :संपूर्ण नकाशा स्क्रीनशॉट STR_ABOUT_MENU_ABOUT_OPENTTD :ओपेन टीटीडी बद्दल ############ range ends here @@ -603,9 +598,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}सानुकूल २ STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}संगीत आवाज STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}प्रभाव आवाज -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}कमी -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}अधिक -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -687,6 +679,7 @@ STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLAC + # Extra view window # Game options window @@ -1031,6 +1024,7 @@ STR_BRIDGE_NAME_WOODEN :लाकडी # Road construction toolbar + # Road depot construction window # Road vehicle station construction window @@ -1304,6 +1298,7 @@ STR_GROUP_ALL_AIRCRAFTS :सर्व + STR_GROUP_REMOVE_ALL_VEHICLES :सगळे वाहने काढा @@ -1311,8 +1306,11 @@ STR_GROUP_REMOVE_ALL_VEHICLES :सगळे # Build vehicle window STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :नवीन रस्त्यावरचे वाहन + +############ range for vehicle availability starts STR_BUY_VEHICLE_SHIP_CAPTION :नवीन जहाज STR_BUY_VEHICLE_AIRCRAFT_CAPTION :नवीन विमान +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}किंमत: {GOLD}{CURRENCY_LONG}{BLACK} वजन: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}गती: {GOLD}{VELOCITY}{BLACK} शक्ती: {GOLD}{POWER} @@ -1330,6 +1328,8 @@ STR_PURCHASE_INFO_COST_SPEED :{BLACK}कि + + # Depot window STR_DEPOT_CAPTION :{WHITE}{DEPOT} @@ -1353,6 +1353,9 @@ STR_DEPOT_VEHICLE_TOOLTIP_CARGO :{}{CARGO_LONG} # Engine preview window + + + STR_ENGINE_PREVIEW_AIRCRAFT :विमान STR_ENGINE_PREVIEW_SHIP :जहाज @@ -1367,6 +1370,7 @@ STR_REPLACE_VEHICLE_AIRCRAFT :विमान + # Vehicle view STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE} @@ -1480,6 +1484,7 @@ STR_AI_CONFIG_CHANGE_NONE : + # AI Parameters STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING} diff --git a/src/lang/unfinished/persian.txt b/src/lang/unfinished/persian.txt index cf9c0098ae..907bd0935c 100644 --- a/src/lang/unfinished/persian.txt +++ b/src/lang/unfinished/persian.txt @@ -10,8 +10,6 @@ ##grflangid 0x62 -# $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. # 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. @@ -461,9 +459,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :باز و بسته کردن کنسول STR_ABOUT_MENU_AI_DEBUG :خطایابی هوش مصنوعی STR_ABOUT_MENU_SCREENSHOT :تصویر از بازی -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :عکس از صفحه تمام بزرگنمایی شده -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :اندازه پیش فرض عکس برداری از صفحه -STR_ABOUT_MENU_GIANT_SCREENSHOT :تصویر از همه نقشه STR_ABOUT_MENU_ABOUT_OPENTTD :'OpenTTD' درباره STR_ABOUT_MENU_SPRITE_ALIGNER :تراز کردن تصویر گرافیکی STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :باز/بسته کردن محدوده جعبه ها @@ -633,9 +628,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}انتخابی 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}شدت صدای موسیقی STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}شدت صدای محیط -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}کمینه -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}بیشینه -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -847,6 +839,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK} {STRING} جدید هم اکنون قابل دسترسی است! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} دیگر {STRING} قبول نمی کند STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} دیگر {STRING} و {STRING} قبول نمی کند STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} از این پس {STRING} را هم قبول می کند @@ -1414,7 +1407,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}توز STR_CONFIG_SETTING_AI :{ORANGE}رقیبان STR_CONFIG_SETTING_AI_NPC :{ORANGE}بازیگران رایانه -STR_CONFIG_SETTING_PATHFINDER_OPF :اصلی STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(توصیه می گردد) @@ -1484,13 +1476,9 @@ STR_QUIT_NO :{BLACK}خیر # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :هایکو -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -2109,6 +2097,7 @@ 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}تغییر حالت بین ساخت/جذف برای ساخت و ساز تراموا + # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}جهت گاراژ خودروی جاده ای STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}جهت گاراژ خودرو جاده ای را انتخاب نمایید @@ -2881,8 +2870,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}زیرس STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}قطعه های ریل: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}نشانگرها STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}قطعه های راه: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}راه -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}تراموا STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}قسمتهای زیر آب: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}کانال ها STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}ایستگاه ها: @@ -2893,7 +2880,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :کارخانه ها STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- هیچ - -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% انتقال داده شده) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} # Industry view @@ -2943,14 +2929,18 @@ STR_VEHICLE_LIST_SEND_AIRCRAFT_TO_HANGAR :فرستادن + # Build vehicle window STR_BUY_VEHICLE_TRAIN_RAIL_CAPTION :قطار جدید STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :قطار جدید مونوریل STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :قطار جدید ریل مغناطیسی -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :وسایل ریل خط آهن STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :ماشین های جدید + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :وسایل ریل خط آهن STR_BUY_VEHICLE_AIRCRAFT_CAPTION :هواپیمای جدید +############ range for vehicle availability ends STR_PURCHASE_INFO_SPEED_OCEAN :{BLACK}سرعت در اقیانوس: {GOLD}{VELOCITY} STR_PURCHASE_INFO_SPEED_CANAL :{BLACK}سرعت در کانال/رودخانه: {GOLD}{VELOCITY} @@ -2965,10 +2955,12 @@ STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_BUTTON :{BLACK}ساخت STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}خرید وسیله نقلیه STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}خرید هواپیما + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}خرید قطار مشخص شده. Shift+Click کنید تا قبل از خرید، مبلغ تقریبی آنرا نمایش دهد STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}خرید کشتی مشخص شده . Shift+Click کنید تا هزینه تقریبی نمایش داده شود STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}خرید هواپیمای مشخص شده. برای مشاهده هزینه تقریبی Shift+Click کنید + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}تغییر نام STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}تغییر نام STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}نام گذاری مجدد @@ -3039,13 +3031,16 @@ STR_DEPOT_AIRCRAFT_LOCATION_TOOLTIP :{BLACK}نمای # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}پیغام از سازنده ی وسیله نقلیه STR_ENGINE_PREVIEW_MESSAGE :{GOLD}ما به تازگی {STRING} را طراحی کرده ایم- آیا مایلید در یک سال اولان را به شگل انحصاری مورد تست قرار دهید تا نحوه عملکرد وسیله را قبل از عرضه ی جهانی مورد بررسی قرار دهیم؟ + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :لوکوموتیو راه آهن -STR_ENGINE_PREVIEW_ROAD_VEHICLE :ماشین جاده ای -STR_ENGINE_PREVIEW_AIRCRAFT :هواپیما -STR_ENGINE_PREVIEW_SHIP :کشتی STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :لوکوموتیو مونوریل STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :لوکوموتیو ریل مغناطیسی +STR_ENGINE_PREVIEW_ROAD_VEHICLE :ماشین جاده ای + +STR_ENGINE_PREVIEW_AIRCRAFT :هواپیما +STR_ENGINE_PREVIEW_SHIP :کشتی + # Autoreplace window STR_REPLACE_VEHICLE_TRAIN :قطار @@ -3065,6 +3060,7 @@ STR_REPLACE_HELP_STOP_BUTTON :{BLACK}برای STR_REPLACE_ELRAIL_VEHICLES :وسایل نقلیه ریلی برقی + # Vehicle view STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE} @@ -3288,6 +3284,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}انتخ STR_AI_LIST_CANCEL :{BLACK}لغو STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}کد را تغییر نده + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} پارامترها STR_AI_SETTINGS_CAPTION_AI :هوش مصنوعی(AI) diff --git a/src/lang/unfinished/urdu.txt b/src/lang/unfinished/urdu.txt index 9f11fa11de..30d80d58a1 100644 --- a/src/lang/unfinished/urdu.txt +++ b/src/lang/unfinished/urdu.txt @@ -11,8 +11,6 @@ ##gender m f -# $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. # 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. @@ -454,9 +452,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :حائطھ تدویم STR_ABOUT_MENU_AI_DEBUG :AI debug STR_ABOUT_MENU_SCREENSHOT :اسکرین کی تصویر -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :مکمل قریب سے اسکرین کی تصویر -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :پہلے سے طے شدہ قربت سے اسکرین کی تصویر -STR_ABOUT_MENU_GIANT_SCREENSHOT :پورے نقشے کی اسکرین کی تصویر STR_ABOUT_MENU_ABOUT_OPENTTD :Open TTD کے بارے میں STR_ABOUT_MENU_SPRITE_ALIGNER :sprite صف بندھ STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :احاطہ کرنے والے ڈبوں کی تدویم کیجئیے @@ -624,9 +619,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}اپنی مرضی کے مطابق 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}موسیقی کی آواز STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}اثرات کی آواز -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}کم -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}زیادہ -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -829,6 +821,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}نئی {STRING} اب دستیاب ہے! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}{STATION} مزید {STRING} قبول نہیں کرتا STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}{STATION} مزید {STRING} یا {STRING} قبول نہیں کرتا STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} اب قبول کرتا ہے {STRING} @@ -1311,7 +1304,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_INDUSTRIES :{ORANGE}صنع STR_CONFIG_SETTING_AI :{ORANGE}مد مقابل STR_CONFIG_SETTING_AI_NPC :{ORANGE}کمپیوٹر کے کھلاڑی -STR_CONFIG_SETTING_PATHFINDER_OPF :اصلی STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Recommended) @@ -1381,13 +1373,9 @@ STR_QUIT_NO :{BLACK}نہیں # Supported OSes STR_OSNAME_WINDOWS :ونڈوز -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :یونیکس STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -1980,6 +1968,7 @@ 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}ٹرام وے کی تعمیر / خاتمے میں تدویم کریں + # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}گاڑیوں کے ڈپو کا رخ STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}گاڑیوں کے ڈپو کا رخ منتخب کریں @@ -2307,8 +2296,6 @@ STR_COMPANY_VIEW_INFRASTRUCTURE_BUTTON :{BLACK}تفصی STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}ریل کے ٹکڑے STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}اشارے STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}سڑک کے ٹکرے -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}سڑک -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}ٹرام وے STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}پانی کی ٹائل STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}نہریں STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD} اسٹیشن: @@ -2342,6 +2329,7 @@ STR_VEHICLE_LIST_MANAGE_LIST :{BLACK}فہرس # Group window + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}گروپ ۔ اس گروپ ک تمام گاڑیاں دیکھنے کے لیے اسے دبایں۔ پکڑ کے اوپر نیچے بھی کر سکتے ہیں۔ @@ -2350,7 +2338,10 @@ STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}گروپ # Build vehicle window + +############ range for vehicle availability starts STR_BUY_VEHICLE_AIRCRAFT_CAPTION :نیا طیارہ +############ range for vehicle availability ends STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}پہنچ: {GOLD}{COMMA} ٹائلیں @@ -2359,6 +2350,8 @@ STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}پہنچ + + STR_BUY_VEHICLE_TRAIN_HIDE_TOGGLE_BUTTON :{BLACK}چهپایں STR_BUY_VEHICLE_ROAD_VEHICLE_HIDE_TOGGLE_BUTTON :{BLACK}چهپایں STR_BUY_VEHICLE_SHIP_HIDE_TOGGLE_BUTTON :{BLACK}چهپایں @@ -2405,6 +2398,9 @@ STR_DEPOT_VEHICLE_TOOLTIP_CARGO :{}{CARGO_LONG} # Engine preview window + + + # Autoreplace window STR_REPLACE_VEHICLE_VEHICLES_IN_USE :{YELLOW}استعمالکردہ گاڑیاں @@ -2415,6 +2411,7 @@ STR_REPLACE_VEHICLE_AVAILABLE_VEHICLES :{YELLOW}میس + # Vehicle view STR_VEHICLE_VIEW_CAPTION :{WHITE}{VEHICLE} @@ -2543,6 +2540,7 @@ STR_AI_CONFIG_CHANGE_NONE : + # AI Parameters diff --git a/src/lang/vietnamese.txt b/src/lang/vietnamese.txt index 75808fb5e3..85d8776620 100644 --- a/src/lang/vietnamese.txt +++ b/src/lang/vietnamese.txt @@ -10,8 +10,6 @@ ##grflangid 0x54 -# $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. # 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. @@ -189,6 +187,8 @@ STR_COLOUR_ORANGE :Cam STR_COLOUR_BROWN :Nâu STR_COLOUR_GREY :Xám STR_COLOUR_WHITE :Trắng +STR_COLOUR_RANDOM :Ngẫu nhiên +STR_COLOUR_DEFAULT :Mặc định # Units used in OpenTTD STR_UNITS_VELOCITY_IMPERIAL :{COMMA}{NBSP}mph @@ -235,6 +235,8 @@ STR_TOOLTIP_FILTER_CRITERIA :{BLACK}Chọn t STR_BUTTON_SORT_BY :{BLACK}Sắp xếp bởi STR_BUTTON_LOCATION :{BLACK}Vị trí STR_BUTTON_RENAME :{BLACK}Đổi tên +STR_BUTTON_CATCHMENT :{BLACK}Vùng che phủ +STR_TOOLTIP_CATCHMENT :{BLACK}Đổi ẩn/hiện vùng che phủ STR_TOOLTIP_CLOSE_WINDOW :{BLACK}Đóng cửa sổ STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS :{BLACK}Tiêu đề cửa sổ - kéo nó để di chuyển cửa số @@ -263,6 +265,7 @@ STR_SHOW_HIDDEN_ENGINES_VEHICLE_AIRCRAFT_TOOLTIP :{BLACK}Khi bậ STR_BUTTON_DEFAULT :{BLACK}Mặc định STR_BUTTON_CANCEL :{BLACK}Thôi STR_BUTTON_OK :{BLACK}Đồng ý +STR_WARNING_PASSWORD_SECURITY :{YELLOW}Chú ý: quản trị máy chủ có thể đọc mọi dòng chữ nhập ở đây. # On screen keyboard window STR_OSK_KEYBOARD_LAYOUT :`1234567890-=\qwertyuiop[]asdfghjkl;' zxcvbnm,./ . @@ -336,6 +339,7 @@ STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_IN :{BLACK}Thu nh STR_TOOLBAR_TOOLTIP_ZOOM_THE_VIEW_OUT :{BLACK}Nới rộng tầm nhìn STR_TOOLBAR_TOOLTIP_BUILD_RAILROAD_TRACK :{BLACK}Lắp đường ray STR_TOOLBAR_TOOLTIP_BUILD_ROADS :{BLACK}Xây đường +STR_TOOLBAR_TOOLTIP_BUILD_TRAMWAYS :{BLACK}Xây dựng đường xe điện STR_TOOLBAR_TOOLTIP_BUILD_SHIP_DOCKS :{BLACK}Xây bến cảng STR_TOOLBAR_TOOLTIP_BUILD_AIRPORTS :{BLACK}Xây sân bay STR_TOOLBAR_TOOLTIP_LANDSCAPING :{BLACK}Mở thanh địa hình để nâng cao/hạ thấp ô đất, trồng cây, etc. @@ -356,6 +360,7 @@ STR_SCENEDIT_TOOLBAR_LANDSCAPE_GENERATION :{BLACK}Tạo đ STR_SCENEDIT_TOOLBAR_TOWN_GENERATION :{BLACK}Tạo thị trấn 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_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 @@ -464,6 +469,7 @@ STR_TOOLBAR_SOUND_MUSIC :Âm thanh/nhạ ############ range for message menu starts STR_NEWS_MENU_LAST_MESSAGE_NEWS_REPORT :Thư/bản tin cuối cùng STR_NEWS_MENU_MESSAGE_HISTORY_MENU :Thông báo cũ +STR_NEWS_MENU_DELETE_ALL_MESSAGES :Xoá tất cả thông điệp ############ range ends here ############ range for about menu starts @@ -472,9 +478,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Bật/tắt bảng lệnh STR_ABOUT_MENU_AI_DEBUG :Gỡ rối AI / Game script STR_ABOUT_MENU_SCREENSHOT :Ảnh chụp màn hình -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Phóng to đầy đủ ảnh chụp màn hình -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Phóng to mặc định ảnh chụp màn hình -STR_ABOUT_MENU_GIANT_SCREENSHOT :Ảnh màn hình toàn bản đồ STR_ABOUT_MENU_SHOW_FRAMERATE :Hiển thị tốc độ khung hình STR_ABOUT_MENU_ABOUT_OPENTTD :Giới thiệu 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Trình điều chỉnh sprite @@ -645,9 +648,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Tự Chọn 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Âm Lượng STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Hiệu Ứng Tiếng -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}Nhỏ -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}Lớn -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -864,6 +864,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}{STRING} mới đã ra lò! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}Ga, bến, cảng {STATION} không chấp nhận {STRING} nữa. STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}Ga, bến, cảng {STATION} không chấp nhận {STRING} hoặc {STRING} nữa STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}{STATION} đã chấp nhận {STRING} @@ -929,6 +930,10 @@ STR_GAME_OPTIONS_CURRENCY_CUSTOM :Tùy chọn... STR_GAME_OPTIONS_CURRENCY_GEL :Lari Georgia (GEL) STR_GAME_OPTIONS_CURRENCY_IRR :Rial Iran (IRR) STR_GAME_OPTIONS_CURRENCY_RUB :Đồng Rúp Nga mới (RUB) +STR_GAME_OPTIONS_CURRENCY_MXN :Peso México (MXN) +STR_GAME_OPTIONS_CURRENCY_NTD :Tân Đài tệ (NTD) +STR_GAME_OPTIONS_CURRENCY_CNY :Nhân dân tệ TQ (CNY) +STR_GAME_OPTIONS_CURRENCY_HKD :Đô-la Hồng Kông (HKD) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Xe cộ @@ -991,7 +996,12 @@ 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_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_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_BASE_GRF :{BLACK}Gói đồ họa STR_GAME_OPTIONS_BASE_GRF_TOOLTIP :{BLACK}Chọn gói đồ họa để sử dụng @@ -1175,6 +1185,8 @@ STR_CONFIG_SETTING_AUTOSLOPE :Cho phép thay STR_CONFIG_SETTING_AUTOSLOPE_HELPTEXT :Cho phép thay đổi nền đất dưới công trình và đường mà không cần phá hủy chúng STR_CONFIG_SETTING_CATCHMENT :Mô phỏng thực tế diện tích khu vực đón hàng: {STRING} STR_CONFIG_SETTING_CATCHMENT_HELPTEXT :Diện tích khu vực đón hàng khác nhau cho từng loại trạm và sân bay +STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES :Số lượng nhà ga có thể phục vụ các ngành công nghiệp với nhà ga có sẵn {STRING} +STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES_HELPTEXT :Nếu bật, các khu công nghiệp gắn kèm với nhà ga, cảng, bến (như là dàn khoan dầu) có thể sẽ được phục vụ bởi các công ty sở hữu nhà ga, cảng, bến xây ở gần. Nếu tắt, thì các khu công nghiệp trên chỉ cung cấp hàng cho nhà ga, cản, bến gắn kèm thôi, bất kể là có xây gần hay gắn nhà ga khác vào. STR_CONFIG_SETTING_EXTRADYNAMITE :Cho phép giải toả nhiều hơn đường, cầu ... của đô thị: {STRING} STR_CONFIG_SETTING_EXTRADYNAMITE_HELPTEXT :Dễ dàng hơn trong việc loại bỏ các công trình thuộc sở hữu thành phố STR_CONFIG_SETTING_TRAIN_LENGTH :Chiều dài tối đa của đoàn tàu: {STRING} @@ -1191,8 +1203,8 @@ STR_CONFIG_SETTING_TRAIN_SLOPE_STEEPNESS_HELPTEXT :Sự giảm t STR_CONFIG_SETTING_PERCENTAGE :{COMMA}% STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS :Sự giảm tốc tại dốc của ôtô: {STRING} STR_CONFIG_SETTING_ROAD_VEHICLE_SLOPE_STEEPNESS_HELPTEXT :Sự giảm tốc cho ôtô tại một ô dốc. Giá trị càng cao thì càng khó leo dốc -STR_CONFIG_SETTING_FORBID_90_DEG :Ngăn tàu hỏa và tàu thủy chuyển hướng 90 độ: {STRING} -STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :quay 90 độ chỉ xảy ra khi một ray ngang nối với một ray dọc ở 2 ô liền kề, khiến cho tàu hỏa cua 90 khi đến ô rẽ thay vì 45 độ như bình thường. Việc này cũng áp dụng với tàu thủy. +STR_CONFIG_SETTING_FORBID_90_DEG :Ngăn tàu hỏa chuyển hướng 90 độ: {STRING} +STR_CONFIG_SETTING_FORBID_90_DEG_HELPTEXT :quay 90 độ chỉ xảy ra khi một ray ngang nối với một ray dọc ở 2 ô liền kề, khiến cho tàu hỏa cua 90 độ khi đến ô rẽ thay vì 45 độ như bình thường. STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS :Cho phép gộp ga, bến, cảng không sát nhau: {STRING} STR_CONFIG_SETTING_DISTANT_JOIN_STATIONS_HELPTEXT :Cho phép thêm đoạn vào ga mà không phải sửa cái hiện có. Phải bấm Ctrl+Click để thêm đoạn vào ga STR_CONFIG_SETTING_INFLATION :Lạm phát: {STRING} @@ -1248,8 +1260,8 @@ STR_CONFIG_SETTING_PLANE_SPEED :Tỉ lệ tốc STR_CONFIG_SETTING_PLANE_SPEED_HELPTEXT :Thiết lập tốc độ tương đối của máy bay với phương tiện khác, nhằm giảm thu nhập của việc vận chuyển đường hàng không STR_CONFIG_SETTING_PLANE_SPEED_VALUE :1 / {COMMA} STR_CONFIG_SETTING_PLANE_CRASHES :Số vụ tai nạn máy bay: {STRING} -STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Tỉ lệ / xác suất xảy ra tai nạn máy bay -STR_CONFIG_SETTING_PLANE_CRASHES_NONE :không +STR_CONFIG_SETTING_PLANE_CRASHES_HELPTEXT :Đặt tỉ lệ/xác suất ngẫu nhiên xảy ra tai nạn máy bay.{}* Máy bay lớn luôn có xác suất tai nạn cao hơn khi hạ cánh ở các sân bay nhỏ. +STR_CONFIG_SETTING_PLANE_CRASHES_NONE :không* STR_CONFIG_SETTING_PLANE_CRASHES_REDUCED :giảm bớt STR_CONFIG_SETTING_PLANE_CRASHES_NORMAL :bình thường STR_CONFIG_SETTING_STOP_ON_TOWN_ROAD :Cho phép xây điểm dừng xe buýt trên đường của thị trấn: {STRING} @@ -1260,6 +1272,8 @@ STR_CONFIG_SETTING_DYNAMIC_ENGINES_EXISTING_VEHICLES :{WHITE}Không t STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE :Phí bảo trì cơ sở hạ tầng: {STRING} STR_CONFIG_SETTING_INFRASTRUCTURE_MAINTENANCE_HELPTEXT :Khi mở, thì hạ tầng công ty sẽ sinh ra chi phí bảo trì. Chi phí sẽ tăng theo mạng lưới giao thông bạn xây dựng, và sẽ tiêu tốn của công ty lớn nhiều hơn công ty nhỏ +STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR :Màu bắt đầu của công ty: {STRING} +STR_CONFIG_SETTING_COMPANY_STARTING_COLOUR_HELPTEXT :Thay đổi màu sắc mặc định khi bắt đầu công ty STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS :Sân bay không bao giờ thành đồ cổ: {STRING} STR_CONFIG_SETTING_NEVER_EXPIRE_AIRPORTS_HELPTEXT :Bật tùy chọn này cho phép tất cả các loại sân bay không bị lỗi thời @@ -1306,7 +1320,7 @@ STR_CONFIG_SETTING_TERRAIN_TYPE_HELPTEXT :(Chỉ cho Terr STR_CONFIG_SETTING_INDUSTRY_DENSITY :Mật độ nhà máy: {STRING} STR_CONFIG_SETTING_INDUSTRY_DENSITY_HELPTEXT :Thiết lập số nhà máy sẽ được tạo ra và mức độ dùy trì trong ván chơi STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE :Khoảng cách tối đa từ lề bản đồ tới nhà máy lọc dầu: {STRING} -STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :Nhà máy hóa dầu chỉ có thể xây gần rìa bản đồ, tương ứng là ven biển với những bản đồ dạng đảo +STR_CONFIG_SETTING_OIL_REF_EDGE_DISTANCE_HELPTEXT :Giới hạn bao xa tính từ rìa bản đò tới nhà máy hóa dầu và dàn khoan dầu có thể xây. Trên các bản đồ đảo thì tương ứng là ven biển. Với bản đồ lớn 256 ô, thì giá trị này được nhân tỉ lệ lên STR_CONFIG_SETTING_SNOWLINE_HEIGHT :Độ cao tuyết phủ: {STRING} STR_CONFIG_SETTING_SNOWLINE_HEIGHT_HELPTEXT :Điều chỉnh độ cao của tuyết phủ đối với địa hình xứ lanh. Tuyết phủ có thể ảnh hưởng tới việc tạo ra nhà máy và các yêu cầu cho sự tăng trưởng đô thị STR_CONFIG_SETTING_ROUGHNESS_OF_TERRAIN :Độ gồ ghề của địa chất: {STRING} @@ -1470,6 +1484,9 @@ STR_CONFIG_SETTING_AI_IN_MULTIPLAYER :Cho phép AI STR_CONFIG_SETTING_AI_IN_MULTIPLAYER_HELPTEXT :Cho phép người chơi AI (máy tính) được tham gia trong ván chơi nhiều người STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES :#mã lệnh trước kịch bản tạm ngưng: {STRING} STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES_HELPTEXT :Số lượng tối đa các tính toán mà một kịch bản AI được phép chạy mỗi lần +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY :Bộ nhớ sử dụng tối đa mỗi kích bản: {STRING} +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_HELPTEXT :Số lượng bộ nhớ tối đa mà kịch bản có thể tiêu thụ trước khi nó bị từ chối hoạt động. Số lượng này có thể phải tăng lên nếu bản đồ lớn hơn. +STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_VALUE :{COMMA} MiB STR_CONFIG_SETTING_SERVINT_ISPERCENT :Tần suất bảo trì theo đơn vị phần trăm: {STRING} STR_CONFIG_SETTING_SERVINT_ISPERCENT_HELPTEXT :Lựa chọn liệu rằng việc bảo trì phương tiện sẽ được tiến hành sau một khoảng thời gian nhất định hay là độ tin cậy bị giảm xuống bao nhiều phần trăm so với mức tối đa @@ -1532,6 +1549,8 @@ STR_CONFIG_SETTING_SMOOTH_ECONOMY :Nền kinh tế STR_CONFIG_SETTING_SMOOTH_ECONOMY_HELPTEXT :Nếu bật, sản lượng của nhà máy sẽ thay đổi thường xuyên hơn, và thay đổi với mức độ nhỏ hơn. Thiết lập này sẽ không có tác dụng nếu kiểu nhà máy định nghĩa bởi NewGRF STR_CONFIG_SETTING_ALLOW_SHARES :Cho phép mua cổ phần của các công ty khác: {STRING} STR_CONFIG_SETTING_ALLOW_SHARES_HELPTEXT :Nếu bật, cho phép mua và bán cổ phần công ty. Cổ phần chỉ có thể mua bán nếu công ty đã tồn tại một thời gian nhất định nào đó +STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES :Tuổi công ty tối thiểu để bán cổ phần: {STRING} +STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES_HELPTEXT :Đặt số tuổi tối thiểu của công ty để cho các bên khác có thể mua và bán cổ phần STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE :Tỉ lệ lợi tức cổ phiếu chi trả cho môi giới: {STRING} STR_CONFIG_SETTING_FEEDER_PAYMENT_SHARE_HELPTEXT :Tỉ lệ thu nhập cho mỗi trung gian trên hệ thống vận tải, cho phép điều chỉnh thu nhập STR_CONFIG_SETTING_DRAG_SIGNALS_DENSITY :Khi kéo, đặt đèn tín hiệu mỗi: {STRING} @@ -1572,6 +1591,10 @@ STR_CONFIG_SETTING_TOWN_FOUNDING_HELPTEXT :Bật tùy ch STR_CONFIG_SETTING_TOWN_FOUNDING_FORBIDDEN :không cho phép STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED :cho phép STR_CONFIG_SETTING_TOWN_FOUNDING_ALLOWED_CUSTOM_LAYOUT :cho phép, tùy chọn bố trí đô thị +STR_CONFIG_SETTING_TOWN_CARGOGENMODE :Nhu cầu vận chuyển hàng đô thị: {STRING} +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_HELPTEXT :Lượng hàng hoá cần vận chuyển ở trong đô thị, tỉ lệ với tổng dân số của độ thị.{}Tăng tỉ lệ bình phương: một đô thị to gấp 2 sẽ tăng 4 lần số hành khách.{}Tăng tỉ lệ thuận: một đô thị tăng gấp 2 sẽ tăng gấp 2 lần số hành khách. +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_ORIGINAL :Tỉ lệ bình phương (nguyên bản) +STR_CONFIG_SETTING_TOWN_CARGOGENMODE_BITCOUNT :Tuyến tính STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT :Trồng cây trong trò chơi: {STRING} STR_CONFIG_SETTING_EXTRA_TREE_PLACEMENT_HELPTEXT :Điều khiển sự xuất hiện tự dộng của cây cối khi đang chơi. Điều này có thể ảnh hưởng đến những nhà máy dựa vào cây cối, ví dự như nhà máy chế biến gỗgỗ @@ -1699,7 +1722,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Phân b STR_CONFIG_SETTING_AI :{ORANGE}Đối Thủ STR_CONFIG_SETTING_AI_NPC :{ORANGE}Nhân vật máy -STR_CONFIG_SETTING_PATHFINDER_OPF :Nguyên bản STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Nên dùng) @@ -1783,13 +1805,9 @@ STR_QUIT_NO :{BLACK}Không # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -1818,6 +1836,7 @@ STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Thay đ STR_CHEAT_SETUP_PROD :{LTBLUE}Cho phép khả năng sửa giá trị sản xuất: {ORANGE}{STRING} # Livery window +STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Cách Phối Màu Mới STR_LIVERY_GENERAL_TOOLTIP :{BLACK}Hiển thị phối màu chung STR_LIVERY_TRAIN_TOOLTIP :{BLACK}Hiển thị phối màu tàu hỏa @@ -2077,6 +2096,7 @@ STR_NETWORK_CONNECTION_DISCONNECT :{BLACK}Ngắt k STR_NETWORK_NEED_GAME_PASSWORD_CAPTION :{WHITE}Server yêu cầu xác thực. Nhập mật khẩu STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION :{WHITE}Công ty yêu cầu xác thực. Nhập mật khẩu +STR_NETWORK_COMPANY_LIST_CLIENT_LIST_CAPTION :{WHITE}Danh sách máy trạm # Network company list added strings STR_NETWORK_COMPANY_LIST_CLIENT_LIST :Danh sách máy trạm @@ -2125,7 +2145,7 @@ STR_NETWORK_CHAT_ALL :[Chung] {STRING STR_NETWORK_CHAT_OSKTITLE :{BLACK}Nhập thông điệp tán gẫu # Network messages -STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}Không có thiết bị mạng hoặc không thiết lập ENABLE_NETWORK +STR_NETWORK_ERROR_NOTAVAILABLE :{WHITE}Không có thiết bị kết nối mạng STR_NETWORK_ERROR_NOSERVER :{WHITE}Không tìm thấy ván chơi mạng nào STR_NETWORK_ERROR_NOCONNECTION :{WHITE}Server không trả lời yêu cầu STR_NETWORK_ERROR_NEWGRF_MISMATCH :{WHITE}Không thể kết nối vì NewGRF không hợp @@ -2378,7 +2398,7 @@ STR_BUILD_SIGNAL_ELECTRIC_PBS_TOOLTIP :{BLACK}Đèn t STR_BUILD_SIGNAL_ELECTRIC_PBS_OWAY_TOOLTIP :{BLACK}Đèn tín hiệu giành đường một chiều (điện){}Đèn tín hiệu giành đường cho phép nhiều hơn 1 đoàn tàu có thể đi vào 1 khu vực khoá, nếu như mỗi đoàn tàu có thể giành lấy một con đường tới một điểm đến một cách an toàn. Đèn tín hiệu giành đường tiêu chuẩn cho thể cho phép đi qua từ phía sau của đèn. STR_BUILD_SIGNAL_CONVERT_TOOLTIP :{BLACK}Chuyển đổi đèn tín hiệu{}Khi sử dụng, nháy vào đèn hiệu đang có, sẽ chuyển đổi loại đèn đã chọn, Ctrl+Click sẽ đổi loại đèn. Shift để hiện chi phí dự tính STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_TOOLTIP :{BLACK}Mật độ khi kéo chuỗi đèn hiệu -STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_DECREASE_TOOLTIP :{BLACK}Giảm mật độ kéo chuỗi đèn hiệu +STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_DECREASE_TOOLTIP :{BLACK}Giảm khoảng cách kéo chuỗi đèn hiệu STR_BUILD_SIGNAL_DRAG_SIGNALS_DENSITY_INCREASE_TOOLTIP :{BLACK}Tăng mật độ kéo chuỗi đèn hiệu # Bridge selection window @@ -2417,6 +2437,11 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL :{BLACK}Xây h STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Xây hầm xe điện. Shift để xem chi phí dự tính STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}Bật chế độ xây/phá đường bộ STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Bật chế độ xây/phá đường xe điện +STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_ROAD :{BLACK}Chuyển đổi/nâng cấp kiểu đường ô-tô. Shift đổi chế độ xây/xem chi phí dự tính +STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_TRAM :{BLACK}Chuyển đổi/nâng cấp loại xe điện. Shift để đổi chế độ mua/xem giá dự tính + +STR_ROAD_NAME_ROAD :Đường ô-tô +STR_ROAD_NAME_TRAM :Đường xe điện # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Hướng Của Xưởng Ôtô @@ -2601,8 +2626,11 @@ STR_LAND_AREA_INFORMATION_NEWGRF_NAME :{BLACK}NewGRF: STR_LAND_AREA_INFORMATION_CARGO_ACCEPTED :{BLACK}Hàng hoá chấp nhận: {LTBLUE} STR_LAND_AREA_INFORMATION_CARGO_EIGHTS :({COMMA}/8 {STRING}) STR_LANG_AREA_INFORMATION_RAIL_TYPE :{BLACK}Kiểu đường ray: {LTBLUE}{STRING} +STR_LANG_AREA_INFORMATION_ROAD_TYPE :{BLACK}Kiểu đường: {LTBLUE}{STRING} +STR_LANG_AREA_INFORMATION_TRAM_TYPE :{BLACK}Kiểu xe điện: {LTBLUE}{STRING} STR_LANG_AREA_INFORMATION_RAIL_SPEED_LIMIT :{BLACK}Giới hạn tốc độ đường ray: {LTBLUE}{VELOCITY} STR_LANG_AREA_INFORMATION_ROAD_SPEED_LIMIT :{BLACK}Hạn chế tốc độ đường bộ: {LTBLUE}{VELOCITY} +STR_LANG_AREA_INFORMATION_TRAM_SPEED_LIMIT :{BLACK}Tốc độ xe điện giới hạn: {LTBLUE}{VELOCITY} # Description of land area of different tiles STR_LAI_CLEAR_DESCRIPTION_ROCKS :Đá @@ -2704,36 +2732,43 @@ STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD # Framerate display window STR_FRAMERATE_CAPTION :{WHITE}Tốc độ khung hình STR_FRAMERATE_CAPTION_SMALL :{STRING}{WHITE} ({DECIMAL}x) -STR_FRAMERATE_RATE_GAMELOOP :{WHITE}Tốc độ khung giả lập game: {STRING} +STR_FRAMERATE_RATE_GAMELOOP :{BLACK}Tốc độ khung giả lập game: {STRING} STR_FRAMERATE_RATE_GAMELOOP_TOOLTIP :{BLACK}Số nhịp đếm giả lập trong mỗi giây -STR_FRAMERATE_RATE_BLITTER :{WHITE}Tốc độ khung hình: {STRING} +STR_FRAMERATE_RATE_BLITTER :{BLACK}Tốc độ khung hình: {STRING} STR_FRAMERATE_RATE_BLITTER_TOOLTIP :{BLACK}Số khu hình vẽ lại mỗi giây. -STR_FRAMERATE_SPEED_FACTOR :{WHITE}Chỉ số vận tốc game hiện tại: {DECIMAL}x +STR_FRAMERATE_SPEED_FACTOR :{BLACK}Chỉ số vận tốc game hiện tại: {DECIMAL}x STR_FRAMERATE_SPEED_FACTOR_TOOLTIP :{BLACK}Tốc độ chạy game hiện tại, so với tốc độ bình thường STR_FRAMERATE_CURRENT :{WHITE}Hiện tại STR_FRAMERATE_AVERAGE :{WHITE}Trung bình -STR_FRAMERATE_DATA_POINTS :{WHITE}Dữ liệu được tính theo số đo {COMMA} -STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL}{WHITE} ms -STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL}{WHITE} ms -STR_FRAMERATE_MS_BAD :{RED}{DECIMAL}{WHITE} ms -STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL}{WHITE} khung/s -STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL}{WHITE} khung/s -STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL}{WHITE} khung/s +STR_FRAMERATE_MEMORYUSE :{WHITE}Bộ nhớ +STR_FRAMERATE_DATA_POINTS :{BLACK}Dữ liệu được tính theo số đo {COMMA} +STR_FRAMERATE_MS_GOOD :{LTBLUE}{DECIMAL} ms +STR_FRAMERATE_MS_WARN :{YELLOW}{DECIMAL} ms +STR_FRAMERATE_MS_BAD :{RED}{DECIMAL} ms +STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL} khung/s +STR_FRAMERATE_FPS_WARN :{YELLOW}{DECIMAL} khung/s +STR_FRAMERATE_FPS_BAD :{RED}{DECIMAL} khung/s +STR_FRAMERATE_BYTES_GOOD :{LTBLUE}{BYTES} +STR_FRAMERATE_BYTES_WARN :{YELLOW}{BYTES} +STR_FRAMERATE_BYTES_BAD :{RED}{BYTES} STR_FRAMERATE_GRAPH_MILLISECONDS :{TINY_FONT}{COMMA} ms STR_FRAMERATE_GRAPH_SECONDS :{TINY_FONT}{COMMA} s ############ Leave those lines in this order!! -STR_FRAMERATE_GAMELOOP :{WHITE}Tổng vòng lặp khung hình game: -STR_FRAMERATE_GL_ECONOMY :{WHITE} Xử lý bốc dỡ hàng: -STR_FRAMERATE_GL_TRAINS :{WHITE} Nhịp của tàu hoả: -STR_FRAMERATE_GL_ROADVEHS :{WHITE} Nhịp của xe ô-tô -STR_FRAMERATE_GL_SHIPS :{WHITE} Số nhịp của tàu thủy: -STR_FRAMERATE_GL_AIRCRAFT :{WHITE} Số nhịp của máy bay: -STR_FRAMERATE_GL_LANDSCAPE :{WHITE} Nhịp của bản đồ game: -STR_FRAMERATE_GL_LINKGRAPH :{WHITE} Độ trễ tính toán đồ thị: -STR_FRAMERATE_DRAWING :{WHITE}Cách vẽ đồ hoạ game: -STR_FRAMERATE_DRAWING_VIEWPORTS :{WHITE} Khung nhìn toàn bản đồ: -STR_FRAMERATE_VIDEO :Nguồn xuất hình: -STR_FRAMERATE_SOUND :{WHITE}Trộn âm thanh: +STR_FRAMERATE_GAMELOOP :{BLACK}Tổng vòng lặp khung hình game: +STR_FRAMERATE_GL_ECONOMY :{BLACK} Xử lý bốc dỡ hàng: +STR_FRAMERATE_GL_TRAINS :{BLACK} Nhịp của tàu hoả: +STR_FRAMERATE_GL_ROADVEHS :{BLACK} Nhịp của xe ô-tô +STR_FRAMERATE_GL_SHIPS :{BLACK} Số nhịp của tàu thủy: +STR_FRAMERATE_GL_AIRCRAFT :{BLACK} Số nhịp của máy bay: +STR_FRAMERATE_GL_LANDSCAPE :{BLACK} Nhịp của bản đồ game: +STR_FRAMERATE_GL_LINKGRAPH :{BLACK} Độ trễ tính toán đồ thị: +STR_FRAMERATE_DRAWING :{BLACK}Cách vẽ đồ hoạ game: +STR_FRAMERATE_DRAWING_VIEWPORTS :{BLACK} Khung nhìn toàn bản đồ: +STR_FRAMERATE_VIDEO :{BLACK}Nguồn xuất hình: +STR_FRAMERATE_SOUND :{BLACK}Trộn âm thanh: +STR_FRAMERATE_ALLSCRIPTS :{BLACK} Tổng số GS/AI: +STR_FRAMERATE_GAMESCRIPT :{BLACK} Kịch bản ván chơi: +STR_FRAMERATE_AI :{BLACK} AI {NUM} {STRING} ############ End of leave-in-this-order ############ Leave those lines in this order!! STR_FRAMETIME_CAPTION_GAMELOOP :Vòng lặp khung hình game @@ -2748,6 +2783,9 @@ STR_FRAMETIME_CAPTION_DRAWING :Cách vẽ đ STR_FRAMETIME_CAPTION_DRAWING_VIEWPORTS :Khung vẽ cả bản đồ game STR_FRAMETIME_CAPTION_VIDEO :Ngõ xuất hình STR_FRAMETIME_CAPTION_SOUND :Trộn âm thanh +STR_FRAMETIME_CAPTION_ALLSCRIPTS :Tổng số kịch bản GS/AI +STR_FRAMETIME_CAPTION_GAMESCRIPT :Kịch bản ván chơi +STR_FRAMETIME_CAPTION_AI :AI {NUM} {STRING} ############ End of leave-in-this-order @@ -2773,6 +2811,9 @@ 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_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_OSKTITLE :{BLACK}Nhập tên của ván chơi để lưu @@ -2890,7 +2931,12 @@ STR_NEWGRF_SETTINGS_VERSION :{BLACK}Phiên b STR_NEWGRF_SETTINGS_MIN_VERSION :{BLACK}Phiên bản phù hợp tối thiểu: {SILVER}{NUM} STR_NEWGRF_SETTINGS_MD5SUM :{BLACK}MD5sum: {SILVER}{STRING} STR_NEWGRF_SETTINGS_PALETTE :{BLACK}Bảng màu: {SILVER}{STRING} +STR_NEWGRF_SETTINGS_PALETTE_DEFAULT :Mặc định (D) +STR_NEWGRF_SETTINGS_PALETTE_DEFAULT_32BPP :Mặc định (D) / 32 bpp +STR_NEWGRF_SETTINGS_PALETTE_LEGACY :Kiểu cũ (W) +STR_NEWGRF_SETTINGS_PALETTE_LEGACY_32BPP :Kiểu cũ (W) / 32 bpp STR_NEWGRF_SETTINGS_PARAMETER :{BLACK}Tham số: {SILVER}{STRING} +STR_NEWGRF_SETTINGS_PARAMETER_NONE :Không STR_NEWGRF_SETTINGS_NO_INFO :{BLACK}Không có thông tin gì cả STR_NEWGRF_SETTINGS_NOT_FOUND :{RED}File hợp lệ không có @@ -2971,6 +3017,8 @@ STR_NEWGRF_ERROR_READ_BOUNDS :Đọc quá gi STR_NEWGRF_ERROR_GRM_FAILED :Dữ liệu GRF theo yêu cầu không hợp lệ (sprite {3:NUM}) STR_NEWGRF_ERROR_FORCEFULLY_DISABLED :{1:STRING} bị tắt bởi {STRING} STR_NEWGRF_ERROR_INVALID_SPRITE_LAYOUT :Định dạng Sprite không hợp lệ hoặc chưa định nghĩa (sprite {3:NUM}) +STR_NEWGRF_ERROR_LIST_PROPERTY_TOO_LONG :Có quá phần trong danh sách tài sản (sprite {3:NUM}, tài sản {4:HEX}) +STR_NEWGRF_ERROR_INDPROD_CALLBACK :Lại nhà máy sản xuất không hợp lệ (sprite {3:NUM}, "{2:STRING}") # NewGRF related 'general' warnings STR_NEWGRF_POPUP_CAUTION_CAPTION :{WHITE}Chú Ý! @@ -3002,6 +3050,7 @@ STR_NEWGRF_BUGGY :{WHITE}NewGRF ' STR_NEWGRF_BUGGY_ARTICULATED_CARGO :{WHITE}Danh mục hàng hoá/cải biến được cho '{1:ENGINE}' khác với danh mục mua được sau khi đã có. Việc này khiến cho việc tự thay thế hay là tự cải biến không chính xác. STR_NEWGRF_BUGGY_ENDLESS_PRODUCTION_CALLBACK :{WHITE}'{1:STRING}' gây ra một vòng lặp vô tận khi gọi hàm callback. STR_NEWGRF_BUGGY_UNKNOWN_CALLBACK_RESULT :{WHITE}Hàm callback {1:HEX} gửi trả kết quả sai/không rõ {2:HEX} +STR_NEWGRF_BUGGY_INVALID_CARGO_PRODUCTION_CALLBACK :{WHITE}'{1:STRING}' trả về loại hàng hoá sản xuất không hợp lệ khi gọi lại tại {2:HEX} # 'User removed essential NewGRFs'-placeholders for stuff without specs STR_NEWGRF_INVALID_CARGO : @@ -3068,6 +3117,8 @@ STR_TOWN_VIEW_RENAME_TOWN_BUTTON :Đổi tên đ # Town local authority window STR_LOCAL_AUTHORITY_CAPTION :{WHITE}Chính quyền địa phương {TOWN} +STR_LOCAL_AUTHORITY_ZONE :{BLACK}Khu vực +STR_LOCAL_AUTHORITY_ZONE_TOOLTIP :{BLACK}Hiện vùng sáng nằm trong phạm vi của chính quyền địa phương STR_LOCAL_AUTHORITY_COMPANY_RATINGS :{BLACK}Uy tín công ty vận tải: STR_LOCAL_AUTHORITY_COMPANY_RATING :{YELLOW}{COMPANY} {COMPANY_NUM}: {ORANGE}{STRING} STR_LOCAL_AUTHORITY_ACTIONS_TITLE :{BLACK}Các thao tác: @@ -3096,6 +3147,7 @@ STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}Đút l # Goal window STR_GOALS_CAPTION :{WHITE}Mục Tiêu Của {COMPANY} STR_GOALS_SPECTATOR_CAPTION :{WHITE}Mục Tiêu Chung +STR_GOALS_SPECTATOR :Các mục tiêu chung STR_GOALS_GLOBAL_TITLE :{BLACK}Các mục tiêu chung: STR_GOALS_TEXT :{ORANGE}{STRING} STR_GOALS_NONE :{ORANGE}- Không - @@ -3144,6 +3196,7 @@ STR_SUBSIDIES_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER :{BLACK}Nháy v # Story book window STR_STORY_BOOK_CAPTION :{WHITE}{COMPANY} Tình Tiết STR_STORY_BOOK_SPECTATOR_CAPTION :{WHITE}Bảng Tình Tiết Chung +STR_STORY_BOOK_SPECTATOR :Nhật ký chung STR_STORY_BOOK_TITLE :{YELLOW}{STRING} STR_STORY_BOOK_GENERIC_PAGE_ITEM :Trang {NUM} STR_STORY_BOOK_SEL_PAGE_TOOLTIP :{BLACK}Chuyển tới trang cụ thể bằng cách chọn trong danh sách sổ xuống @@ -3323,8 +3376,7 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Hạ t STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Ô đường ray: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Tín hiệu STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Ô đường bộ: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Đường bộ -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Xe điện +STR_COMPANY_INFRASTRUCTURE_VIEW_TRAM_SECT :{GOLD}Các đoạn xe điện: STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Ô là nước: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Kênh đào STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Ga, bến: @@ -3335,9 +3387,12 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Nhà máy STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Không Có - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% đã vận chuyển) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% đã vận chuyển) +STR_INDUSTRY_DIRECTORY_ITEM_INFO :{BLACK}{CARGO_LONG}{STRING}{YELLOW} ({COMMA}% đã vận chuyển){BLACK} STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} +STR_INDUSTRY_DIRECTORY_ITEM_PROD1 :{ORANGE}{INDUSTRY} {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PROD2 :{ORANGE}{INDUSTRY} {STRING}, {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PROD3 :{ORANGE}{INDUSTRY} {STRING}, {STRING}, {STRING} +STR_INDUSTRY_DIRECTORY_ITEM_PRODMORE :{ORANGE}{INDUSTRY} {STRING}, {STRING}, {STRING} và hơn {NUM}... STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Tên các nhà máy - nháy vào tên để xem vị trí nhà máy. Ctrl+Click mở cửa sổ mới để xem # Industry view @@ -3348,6 +3403,9 @@ STR_INDUSTRY_VIEW_LOCATION_TOOLTIP :{BLACK}Xem vị STR_INDUSTRY_VIEW_PRODUCTION_LEVEL :{BLACK}Mức sản lượng: {YELLOW}{COMMA}% STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE :{YELLOW}Nhà máy này đã thông báo sắp đóng cửa! +STR_INDUSTRY_VIEW_REQUIRES_N_CARGO :{BLACK}Yêu cầu: {YELLOW}{STRING}{STRING} +STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Sản lượng: {YELLOW}{STRING}{STRING} +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} @@ -3401,10 +3459,13 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Xe ôtô chưa STR_GROUP_DEFAULT_SHIPS :Tày thuỷ chưa lập nhóm STR_GROUP_DEFAULT_AIRCRAFTS :Máy bay chưa lập nhóm +STR_GROUP_COUNT_WITH_SUBGROUP :{TINY_FONT}{COMMA} (+{COMMA}) + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Nhóm - chọn nhóm để hiển thị các phương tiện thuộc nhóm. Kéo thả nhóm để sắp xếp lại danh sách. STR_GROUP_CREATE_TOOLTIP :{BLACK}Ấn vào để tạo nhóm STR_GROUP_DELETE_TOOLTIP :{BLACK}Xoá nhóm đã chọn STR_GROUP_RENAME_TOOLTIP :{BLACK}Đổi tên nhóm +STR_GROUP_LIVERY_TOOLTIP :{BLACK}Thay đổi phục trang cho nhóm được chọn STR_GROUP_REPLACE_PROTECTION_TOOLTIP :{BLACK}Không để nhóm này tự thay thế (thiết lập chung) khi hết hạn STR_QUERY_GROUP_DELETE_CAPTION :{WHITE}Xóa Nhóm @@ -3426,12 +3487,18 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Tàu Điện M STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Tàu Đơn Ray Mới STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Tàu Đệm Từ Mới -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Tàu Hỏa Mới STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Xe Cộ Mới +STR_BUY_VEHICLE_TRAM_VEHICLE_CAPTION :Kiểu xe điện mới + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Tàu Hỏa Mới +STR_BUY_VEHICLE_ROAD_VEHICLE_ALL_CAPTION :Thêm xe ô-tô mới STR_BUY_VEHICLE_SHIP_CAPTION :Tàu Mới STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Máy Bay Mới +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Chi phí: {GOLD}{CURRENCY_LONG}{BLACK} Tải trọng: {GOLD}{WEIGHT_SHORT} +STR_PURCHASE_INFO_COST_REFIT_WEIGHT :{BLACK}Giá: {GOLD}{CURRENCY_LONG}{BLACK} (Giá cải biến: {GOLD}{CURRENCY_LONG}{BLACK}) Trọng lượng: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Tốc độ: {GOLD}{VELOCITY}{BLACK} Công suất: {GOLD}{POWER} STR_PURCHASE_INFO_SPEED :{BLACK}Tốc độ: {GOLD}{VELOCITY} STR_PURCHASE_INFO_SPEED_OCEAN :{BLACK}Tốc độ trên biển: {GOLD}{VELOCITY} @@ -3442,12 +3509,15 @@ STR_PURCHASE_INFO_REFITTABLE :(cải biến STR_PURCHASE_INFO_DESIGNED_LIFE :{BLACK}Thiết kế: {GOLD}{NUM}{BLACK} Niên hạn: {GOLD}{COMMA} năm STR_PURCHASE_INFO_RELIABILITY :{BLACK}Độ tin cậy tối đa: {GOLD}{COMMA}% STR_PURCHASE_INFO_COST :{BLACK}Giá thành: {GOLD}{CURRENCY_LONG} +STR_PURCHASE_INFO_COST_REFIT :{BLACK}Giá: {GOLD}{CURRENCY_LONG}{BLACK} (Giá cải biến: {GOLD}{CURRENCY_LONG}{BLACK}) STR_PURCHASE_INFO_WEIGHT_CWEIGHT :{BLACK}Tải trọng: {GOLD}{WEIGHT_SHORT} ({WEIGHT_SHORT}) STR_PURCHASE_INFO_COST_SPEED :{BLACK}Giá thành: {GOLD}{CURRENCY_LONG}{BLACK} Tốc độ: {GOLD}{VELOCITY} +STR_PURCHASE_INFO_COST_REFIT_SPEED :{BLACK}Giá: {GOLD}{CURRENCY_LONG}{BLACK} (Giá cải biến: {GOLD}{CURRENCY_LONG}{BLACK}) Tốc độ: {GOLD}{VELOCITY} STR_PURCHASE_INFO_AIRCRAFT_CAPACITY :{BLACK}Sức chứa: {GOLD}{CARGO_LONG}, {CARGO_LONG} STR_PURCHASE_INFO_PWAGPOWER_PWAGWEIGHT :{BLACK}Công suất toa xe: {GOLD}+{POWER}{BLACK} Tải trọng: {GOLD}+{WEIGHT_SHORT} STR_PURCHASE_INFO_REFITTABLE_TO :{BLACK}Cải biến thành: {GOLD}{STRING} STR_PURCHASE_INFO_ALL_TYPES :Tất cả kiểu hàng hoá +STR_PURCHASE_INFO_NONE :Không STR_PURCHASE_INFO_ALL_BUT :Tất cả trừ {CARGO_LIST} STR_PURCHASE_INFO_MAX_TE :{BLACK}Lực kéo tối đa: {GOLD}{FORCE} STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Tầm xa: {GOLD}{COMMA} ô @@ -3463,11 +3533,21 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Mua P.Ti STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Mua tàu STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Mua Máy Bay +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Mua và cải biến ô-tô +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Mua và cải biến ô-tô +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Mua và cải biến tàu thuỷ +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Mua và cải biến máy bay + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Mua tàu hỏa đã ấn định. Shift+Click để xem giá mua dự tính STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Mua xe đã ấn định. Shift+Click để xem giá mua dự tính STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Mua tàu đã ấn định. Shift+Click để xem giá mua dự tính STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Mua máy bay đã ấn định. Shift+Click để xem giá mua dự tính +STR_BUY_VEHICLE_TRAIN_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Mua và cải biến toa tầu được chọn. Shift+Click để xem giá mua dự tính +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Mua và cải biến ô-tô đang chọn. Shift+Click để xem giá mua dự tính +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Mua và cải biến tàu thuỷ đã chọn. Shift+Click để dự tính giá mà không mua +STR_BUY_VEHICLE_AIRCRAFT_BUY_REFIT_VEHICLE_TOOLTIP :{BLACK}Mua và cải biến máy bay được chọn. Shift+Click để xem chi phí dự tính + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Thay tên STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Thay tên STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Thay tên @@ -3576,13 +3656,18 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Bạn # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Thông cáo từ nhà sản xuất phương tiện vận tải STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Chúng tôi vừa thiết kế một {STRING} mới - bạn có muốn mua nó trước khi chúng tôi hoàn thiện 1 năm, để chúng tôi đánh giá nó trước khi bán rộng rãi? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :đầu máy tầu hoả -STR_ENGINE_PREVIEW_ROAD_VEHICLE :ôtô -STR_ENGINE_PREVIEW_AIRCRAFT :máy bay -STR_ENGINE_PREVIEW_SHIP :tàu thuỷ +STR_ENGINE_PREVIEW_ELRAIL_LOCOMOTIVE :ngành vận tải đường sắt điện lực STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :đầu máy ray đơn STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :đầu máy đệm từ +STR_ENGINE_PREVIEW_ROAD_VEHICLE :ôtô +STR_ENGINE_PREVIEW_TRAM_VEHICLE :toa xe điện + +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_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 @@ -3620,14 +3705,19 @@ STR_REPLACE_ENGINE_WAGON_SELECT_HELP :{BLACK}Chuyển STR_REPLACE_ENGINES :Đầu máy STR_REPLACE_WAGONS :Toa xe STR_REPLACE_ALL_RAILTYPE :Tất cả toa xe đầu máy +STR_REPLACE_ALL_ROADTYPE :Tất cả các xe ô-tô STR_REPLACE_HELP_RAILTYPE :{BLACK}Chọn kiểu đường ray bạn muốn thay thế +STR_REPLACE_HELP_ROADTYPE :{BLACK}Chọn loại đường bạn muốn thay ô-tô thành vậy STR_REPLACE_HELP_REPLACE_INFO_TAB :{BLACK}Hiện thị đầu máy nào đang được thay thế, nếu có STR_REPLACE_RAIL_VEHICLES :Đầu máy/toa tàu hoả STR_REPLACE_ELRAIL_VEHICLES :Đầu máy/toa xe điện STR_REPLACE_MONORAIL_VEHICLES :Đầu máy ray đơn STR_REPLACE_MAGLEV_VEHICLES :Đầu máy đệm từ +STR_REPLACE_ROAD_VEHICLES :Các xe ô-tô +STR_REPLACE_TRAM_VEHICLES :Các xe điện + STR_REPLACE_REMOVE_WAGON :{BLACK}Xoá bỏ toa xe: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Tự động thay thế sẽ giữ nguyên độ dài đoàn tàu bằng cách bỏ bớt toa xe (bỏ từ phía đầu), nếu như việc thay thế đầu máy làm đoàn tàu dài hơn. @@ -3847,6 +3937,7 @@ STR_ORDER_CONDITIONAL_AGE :Tuổi phương STR_ORDER_CONDITIONAL_REQUIRES_SERVICE :Yêu cầu bảo trì STR_ORDER_CONDITIONAL_UNCONDITIONALLY :Luôn luôn STR_ORDER_CONDITIONAL_REMAINING_LIFETIME :Thời gian sử dụng còn lại (năm) +STR_ORDER_CONDITIONAL_MAX_RELIABILITY :Mức độ tin cậy tối đa STR_ORDER_CONDITIONAL_COMPARATOR_TOOLTIP :{BLACK}Cách so sánh dữ kiện của phương tiện với giá trị cho trước STR_ORDER_CONDITIONAL_COMPARATOR_EQUALS :bằng với @@ -4077,6 +4168,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Chấp n STR_AI_LIST_CANCEL :{BLACK}Huỷ bỏ STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Không đổi tập lệnh + # AI Parameters STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Các Thông Số STR_AI_SETTINGS_CAPTION_AI :AI @@ -4279,7 +4371,6 @@ STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD :{WHITE}... đâ STR_ERROR_DRIVE_THROUGH_DIRECTION :{WHITE}... đường quay mặt sai hướng STR_ERROR_DRIVE_THROUGH_CORNER :{WHITE}... đi qua điểm dừng không thể đi qua góc STR_ERROR_DRIVE_THROUGH_JUNCTION :{WHITE}... đi qua điểm dừng không thể có ngã rẽ -STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD :{WHITE}... đường 1 chiều hoặc bị chặn # Station destruction related errors STR_ERROR_CAN_T_REMOVE_PART_OF_STATION :{WHITE}Không thể xoá bỏ một phần của ga... @@ -4349,7 +4440,8 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Phải b STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Không có đường ray thích hợp STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Phải phá bỏ đường ray trước STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Đường một chiều hoặc bị chặn -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Đường giao nhau không cho phép với loại ray này +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Đường giao nhau không cho phép với loại ray này +STR_ERROR_CROSSING_DISALLOWED_ROAD :{WHITE}Tạo đường dốc khác độ cao không được phép với loại đường này STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Không thể xây đèn hiệu ở đây... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Không thể xây đường ray ở đây... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Không thể phá bỏ đường ray ở đây... @@ -4369,6 +4461,12 @@ STR_ERROR_CAN_T_REMOVE_ROAD_FROM :{WHITE}Không t STR_ERROR_CAN_T_REMOVE_TRAMWAY_FROM :{WHITE}Không thể phá dỡ đường xe điện ở đây... STR_ERROR_THERE_IS_NO_ROAD :{WHITE}... không có đường bộ STR_ERROR_THERE_IS_NO_TRAMWAY :{WHITE}... không có đường ray xe điện +STR_ERROR_CAN_T_CONVERT_ROAD :{WHITE}Không thể chuyển đổi loại đường ở đây... +STR_ERROR_CAN_T_CONVERT_TRAMWAY :{WHITE}Không thể chuyển đổi kiểu xe điện ở đây... +STR_ERROR_NO_SUITABLE_ROAD :{WHITE}Không có đường ô-tô thích hợp +STR_ERROR_NO_SUITABLE_TRAMWAY :{WHITE}Không có đường xe điện phù hợp +STR_ERROR_INCOMPATIBLE_ROAD :{WHITE}... đường không tương thích +STR_ERROR_INCOMPATIBLE_TRAMWAY :{WHITE}... xe điện không phù hợp # Waterway construction errors STR_ERROR_CAN_T_BUILD_CANALS :{WHITE}Không thể xây kênh đào ở đây... @@ -4421,6 +4519,7 @@ STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Không t STR_ERROR_GROUP_CAN_T_DELETE :{WHITE}Không thể xoá bỏ nhóm... STR_ERROR_GROUP_CAN_T_RENAME :{WHITE}Không thể đổi tên nhóm... STR_ERROR_GROUP_CAN_T_SET_PARENT :{WHITE}Không thể thiết đặt nhóm cha... +STR_ERROR_GROUP_CAN_T_SET_PARENT_RECURSION :{WHITE}... lặp ở trong nhóm phân cấp là không được STR_ERROR_GROUP_CAN_T_REMOVE_ALL_VEHICLES :{WHITE}Không thể bỏ các phương tiện trong nhóm này... STR_ERROR_GROUP_CAN_T_ADD_VEHICLE :{WHITE}Không thể thêm phương tiện vào nhóm này... STR_ERROR_GROUP_CAN_T_ADD_SHARED_VEHICLE :{WHITE}Không thể thêm phương tiện được chia sẻ vào nhóm... diff --git a/src/lang/welsh.txt b/src/lang/welsh.txt index 6f16e5b3d7..bde64703d5 100644 --- a/src/lang/welsh.txt +++ b/src/lang/welsh.txt @@ -10,8 +10,6 @@ ##grflangid 0x0f -# $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. # 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. @@ -472,9 +470,6 @@ STR_ABOUT_MENU_SEPARATOR : STR_ABOUT_MENU_TOGGLE_CONSOLE :Toglu Consol STR_ABOUT_MENU_AI_DEBUG :Dadnamu AI / Sgript Gêm STR_ABOUT_MENU_SCREENSHOT :Ciplun -STR_ABOUT_MENU_ZOOMIN_SCREENSHOT :Ciplun lefel mwyhád uchaf -STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT :Ciplun pellter rhagosodedig -STR_ABOUT_MENU_GIANT_SCREENSHOT :Ciplun o'r map cyfan STR_ABOUT_MENU_ABOUT_OPENTTD :Gwybodaeth am 'OpenTTD' STR_ABOUT_MENU_SPRITE_ALIGNER :Aliniwr corluniau STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES :Toglo bocsys ffinio @@ -644,9 +639,6 @@ STR_MUSIC_PLAYLIST_CUSTOM_1 :{TINY_FONT}{BLA STR_MUSIC_PLAYLIST_CUSTOM_2 :{TINY_FONT}{BLACK}Cyfaddas 2 STR_MUSIC_MUSIC_VOLUME :{TINY_FONT}{BLACK}Lefel Sain Cerddoriaeth STR_MUSIC_EFFECTS_VOLUME :{TINY_FONT}{BLACK}Lefel Sain Effeithiau -STR_MUSIC_RULER_MIN :{TINY_FONT}{BLACK}ISAF -STR_MUSIC_RULER_MAX :{TINY_FONT}{BLACK}UCHAF -STR_MUSIC_RULER_MARKER :{TINY_FONT}{BLACK}' STR_MUSIC_TRACK_NONE :{TINY_FONT}{DKGREEN}-- STR_MUSIC_TRACK_DIGIT :{TINY_FONT}{DKGREEN}{ZEROFILL_NUM} STR_MUSIC_TITLE_NONE :{TINY_FONT}{DKGREEN}------ @@ -674,6 +666,7 @@ STR_PLAYLIST_TRACK_NAME :{TINY_FONT}{LTB STR_PLAYLIST_TRACK_INDEX :{TINY_FONT}{BLACK}Indecs Traciau STR_PLAYLIST_PROGRAM :{TINY_FONT}{BLACK}Rhaglen - '{STRING}' STR_PLAYLIST_CLEAR :{TINY_FONT}{BLACK}Clirio +STR_PLAYLIST_CHANGE_SET :{BLACK}Newid set STR_PLAYLIST_TOOLTIP_CLEAR_CURRENT_PROGRAM_CUSTOM1 :{BLACK}Clirio'r rhaglen gyfredol (Cyfaddas 1 neu Cyfaddas 2) STR_PLAYLIST_TOOLTIP_CLICK_TO_ADD_TRACK :{BLACK}Cliciwch i ychwanegu trac cerddoriaeth i'r rhaglen gyfredol (Cyfaddas 1 Neu Cyfaddas 2 yn unig) STR_PLAYLIST_TOOLTIP_CLICK_TO_REMOVE_TRACK :{BLACK}Cliciwch i dynnu trac cerddoriaeth o'r rhaglen gyfredol (Cyfaddas 1 Neu Cyfaddas 2 yn unig) @@ -858,6 +851,7 @@ STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE :{BIG_FONT}{BLAC STR_NEWS_NEW_VEHICLE_TYPE :{BIG_FONT}{BLACK}{ENGINE} STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE :{BLACK}Mae {STRING} newydd yn awr ar gael! - {ENGINE} + STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO :{WHITE}Nid yw {STATION} bellach yn derbyn {STRING} STR_NEWS_STATION_NO_LONGER_ACCEPTS_CARGO_OR_CARGO :{WHITE}Nid yw {STATION} bellach yn derbyn {STRING} na {STRING} STR_NEWS_STATION_NOW_ACCEPTS_CARGO :{WHITE}Mae {STATION} nawr yn derbyn {STRING} @@ -922,6 +916,8 @@ STR_GAME_OPTIONS_CURRENCY_ZAR :Rand De Affrica STR_GAME_OPTIONS_CURRENCY_CUSTOM :Addasedig... STR_GAME_OPTIONS_CURRENCY_GEL :Lari Georgia (GEL) 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) ############ end of currency region STR_GAME_OPTIONS_ROAD_VEHICLES_FRAME :{BLACK}Cerbydau Ffordd @@ -1686,7 +1682,6 @@ STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST :{ORANGE}Dosrani STR_CONFIG_SETTING_AI :{ORANGE}Cystadleuwyr STR_CONFIG_SETTING_AI_NPC :{ORANGE}Chwaraewyr Cyfrifiadurol -STR_CONFIG_SETTING_PATHFINDER_OPF :Gwreiddiol STR_CONFIG_SETTING_PATHFINDER_NPF :NPF STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Argymellir) @@ -1770,13 +1765,9 @@ STR_QUIT_NO :{BLACK}Na # Supported OSes STR_OSNAME_WINDOWS :Windows -STR_OSNAME_DOS :DOS STR_OSNAME_UNIX :Unix STR_OSNAME_OSX :OS{NBSP}X -STR_OSNAME_BEOS :BeOS STR_OSNAME_HAIKU :Haiku -STR_OSNAME_MORPHOS :MorphOS -STR_OSNAME_AMIGAOS :AmigaOS STR_OSNAME_OS2 :OS/2 STR_OSNAME_SUNOS :SunOS @@ -1805,6 +1796,7 @@ STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Newid y STR_CHEAT_SETUP_PROD :{LTBLUE}Galluogi newid graddfeydd cynhyrchu: {ORANGE}{STRING} # Livery window +STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Cynllun Lliw STR_LIVERY_GENERAL_TOOLTIP :{BLACK}Dangos cynllun lliw cyffredinol STR_LIVERY_TRAIN_TOOLTIP :{BLACK}Dangos cynllun lliw trenau @@ -2404,6 +2396,7 @@ STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL :{BLACK}Adeiladu STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD :{BLACK}toglu adeiladu/clirio ar gyfer adeiladu ffyrdd STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS :{BLACK}Toglu adeiladu/dileu ar gyfer adeiladu tramffordd + # Road depot construction window STR_BUILD_DEPOT_ROAD_ORIENTATION_CAPTION :{WHITE}Cyfeiriad Depo Ffordd STR_BUILD_DEPOT_ROAD_ORIENTATION_SELECT_TOOLTIP :{BLACK}Dewiswch gyfeiriad depo cerbyd ffordd @@ -2688,9 +2681,14 @@ STR_ABOUT_VERSION :{BLACK}fersiwn STR_ABOUT_COPYRIGHT_OPENTTD :{BLACK}OpenTTD {COPYRIGHT}2002-2019 Y tîm OpenTTD # Framerate display window +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. +STR_FRAMERATE_FPS_GOOD :{LTBLUE}{DECIMAL} frâm yr eiliad ############ Leave those lines in this order!! +STR_FRAMERATE_GL_ECONOMY :{BLACK} Trin cargo: ############ End of leave-in-this-order ############ Leave those lines in this order!! +STR_FRAMETIME_CAPTION_VIDEO :Allbwn fideo ############ End of leave-in-this-order @@ -2945,6 +2943,7 @@ STR_NEWGRF_BUGGY :{WHITE}Mae NewG STR_NEWGRF_BUGGY_ARTICULATED_CARGO :{WHITE}Mae'r wybodaeth llwyth/ailffitio ar gyfer '{1:ENGINE}' yn wahanol i'r rhestr brynu wedi'r adeiladu. Gall hyn beri i awtoadnewyddu/-ddisodli fethu ag ailfitio'n gywir STR_NEWGRF_BUGGY_ENDLESS_PRODUCTION_CALLBACK :{WHITE}'{1:STRING}' wedi creu lŵp diddiwedd yn y system adalw cynhyrchu STR_NEWGRF_BUGGY_UNKNOWN_CALLBACK_RESULT :{WHITE}Dychwelodd adalwad {1:HEX} ganlyniad anhysbys/annilys {2:HEX} +STR_NEWGRF_BUGGY_INVALID_CARGO_PRODUCTION_CALLBACK :{WHITE}'{1:STRING}' wedi dychwelyd math cargo annilys yn yr adalwad cynhyrchu yn {2:HEX} # 'User removed essential NewGRFs'-placeholders for stuff without specs STR_NEWGRF_INVALID_CARGO : @@ -3264,8 +3263,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_CAPTION :{WHITE}Tanadeil STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT :{GOLD}Darnau rheilffordd: STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS :{WHITE}Signalau STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD_SECT :{GOLD}Darnau ffordd: -STR_COMPANY_INFRASTRUCTURE_VIEW_ROAD :{WHITE}Ffordd -STR_COMPANY_INFRASTRUCTURE_VIEW_TRAMWAY :{WHITE}Tramffordd STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT :{GOLD}Teiliau dŵr: STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS :{WHITE}Camlesi STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT :{GOLD}Gorsafoedd: @@ -3276,8 +3273,6 @@ STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL :{WHITE}{CURRENC # Industry directory STR_INDUSTRY_DIRECTORY_CAPTION :{WHITE}Diwydiannau STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Dim - -STR_INDUSTRY_DIRECTORY_ITEM :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}){YELLOW} ({COMMA}% wedi'i gludo) -STR_INDUSTRY_DIRECTORY_ITEM_TWO :{ORANGE}{INDUSTRY}{BLACK} ({CARGO_LONG}{STRING}/{CARGO_LONG}{STRING}){YELLOW} ({COMMA}%/{COMMA}% wedi'i gludo) STR_INDUSTRY_DIRECTORY_ITEM_NOPROD :{ORANGE}{INDUSTRY} STR_INDUSTRY_DIRECTORY_LIST_CAPTION :{BLACK}Enwau diwydiannau - cliciwch ar enw i ganoli'r sgrin ar ddiwydiant. Mae Ctrl+Clic yn agor ffenest golwg newydd ar leoliad y diwydiant @@ -3342,6 +3337,7 @@ STR_GROUP_DEFAULT_ROAD_VEHICLES :Cerbydau ffordd STR_GROUP_DEFAULT_SHIPS :Llongau heb eu grwpio STR_GROUP_DEFAULT_AIRCRAFTS :Awyrenau heb eu grwpio + STR_GROUPS_CLICK_ON_GROUP_FOR_TOOLTIP :{BLACK}Grŵp - cliciwch ar grŵp i restru pob cerbyd yn y grŵp hwn. Gallwch glico a llusgo grwpiau i drefnu'r hierarchaeth. STR_GROUP_CREATE_TOOLTIP :{BLACK}Cliciwch i greu grŵp STR_GROUP_DELETE_TOOLTIP :{BLACK}Dileu'r grŵp a ddewiswyd @@ -3367,10 +3363,13 @@ STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION :Cerbydau Rheilf STR_BUY_VEHICLE_TRAIN_MONORAIL_CAPTION :Cerbydau Monoreilffordd Newydd STR_BUY_VEHICLE_TRAIN_MAGLEV_CAPTION :Cerbydau Maglef Newydd -STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Cerbydau Rheilffordd Newydd STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION :Cerbydau Ffordd Newydd + +############ range for vehicle availability starts +STR_BUY_VEHICLE_TRAIN_ALL_CAPTION :Cerbydau Rheilffordd Newydd STR_BUY_VEHICLE_SHIP_CAPTION :Llongau Newydd STR_BUY_VEHICLE_AIRCRAFT_CAPTION :Awyrennau Newydd +############ range for vehicle availability ends STR_PURCHASE_INFO_COST_WEIGHT :{BLACK}Cost: {GOLD}{CURRENCY_LONG}{BLACK} Pwysau: {GOLD}{WEIGHT_SHORT} STR_PURCHASE_INFO_SPEED_POWER :{BLACK}Cyflymder: {GOLD}{VELOCITY}{BLACK} Pŵer: {GOLD}{POWER} @@ -3404,11 +3403,15 @@ STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_BUTTON :{BLACK}Prynu Ce STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_BUTTON :{BLACK}Prynu Llong STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_BUTTON :{BLACK}Prynu Awyren +STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Prynu ac Ailffitio Cerbyd +STR_BUY_VEHICLE_SHIP_BUY_REFIT_VEHICLE_BUTTON :{BLACK}Prynu ac Ailffitio Llong + STR_BUY_VEHICLE_TRAIN_BUY_VEHICLE_TOOLTIP :{BLACK}Adeiladu'r cerbyd trên sydd wedi'i amlygu. Mae Shift+Clic yn dangos amcangyfrif o'r gost STR_BUY_VEHICLE_ROAD_VEHICLE_BUY_VEHICLE_TOOLTIP :{BLACK}Adeiladu'r cerbyd ffordd sydd wedi'i amlygu. Mae Shift+Clic yn dangos amcangyfrif o'r gost STR_BUY_VEHICLE_SHIP_BUY_VEHICLE_TOOLTIP :{BLACK}Adeiladu'r llong sydd wedi'i hamlygu. Mae Shift+Clic yn dfangos amcangyfrif o'r gost STR_BUY_VEHICLE_AIRCRAFT_BUY_VEHICLE_TOOLTIP :{BLACK}Adeiladu'r awyren sydd wedi'i hamlygu. Mae Shift+Clic yn dangos amcangyfrif o'r gost + STR_BUY_VEHICLE_TRAIN_RENAME_BUTTON :{BLACK}Ailenwi STR_BUY_VEHICLE_ROAD_VEHICLE_RENAME_BUTTON :{BLACK}Ailenwi STR_BUY_VEHICLE_SHIP_RENAME_BUTTON :{BLACK}Ailenwi @@ -3517,13 +3520,16 @@ STR_DEPOT_SELL_CONFIRMATION_TEXT :{YELLOW}Rydych # Engine preview window STR_ENGINE_PREVIEW_CAPTION :{WHITE}Neges gan wneuthurwr cerbydau STR_ENGINE_PREVIEW_MESSAGE :{GOLD}Rydyn ni newydd gynllunio {STRING} newydd - a fyddai gennych chi ddiddordeb mewn cael defnydd cyfyngol o'r cerbyd hwn am flwyddyn er mwyn i ni gael profi ei berfformiad cyn y bydd ar gael i bawb? + STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE :trên -STR_ENGINE_PREVIEW_ROAD_VEHICLE :cerbyd ffordd -STR_ENGINE_PREVIEW_AIRCRAFT :awyren -STR_ENGINE_PREVIEW_SHIP :llong STR_ENGINE_PREVIEW_MONORAIL_LOCOMOTIVE :trên monoreilffordd STR_ENGINE_PREVIEW_MAGLEV_LOCOMOTIVE :trên maglef +STR_ENGINE_PREVIEW_ROAD_VEHICLE :cerbyd ffordd + +STR_ENGINE_PREVIEW_AIRCRAFT :awyren +STR_ENGINE_PREVIEW_SHIP :llong + STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Côst: {CURRENCY_LONG} Pwysau: {WEIGHT_SHORT}{}Cyflymder: {VELOCITY} Pŵer: {POWER}{}Côst Rhedeg: {CURRENCY_LONG}/bl{}Gallu cludo: {CARGO_LONG} STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Cost: {CURRENCY_LONG} Pwysau: {WEIGHT_SHORT}{}Cyflymder: {VELOCITY} Pŵer: {POWER} Grym Uchaf: {6:FORCE}{}Cost Rhedeg: {4:CURRENCY_LONG}/bl{}Cynhwysedd: {5:CARGO_LONG} STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Cost: {CURRENCY_LONG} Cyflym. Uchaf: {VELOCITY}{}Cynhwysedd: {CARGO_LONG}{}Cost Rhedeg: {CURRENCY_LONG}/bl @@ -3569,6 +3575,7 @@ STR_REPLACE_ELRAIL_VEHICLES :Cerbydau Rheilf STR_REPLACE_MONORAIL_VEHICLES :Cerbydau Monoreilffordd STR_REPLACE_MAGLEV_VEHICLES :Cerbydau Maglef + STR_REPLACE_REMOVE_WAGON :{BLACK}Tynnu wagenni: {ORANGE}{STRING} STR_REPLACE_REMOVE_WAGON_HELP :{BLACK}Gwneud i awtoddisodli gadw hyd y trên yr un peth drwy dynnu wagenni (gan ddechrau yn y blaen), os byddai newid yr injan yn gwneud y trên yn hirach @@ -3788,6 +3795,7 @@ STR_ORDER_CONDITIONAL_AGE :Oed (blynyddoed STR_ORDER_CONDITIONAL_REQUIRES_SERVICE :Angen gwasanaeth STR_ORDER_CONDITIONAL_UNCONDITIONALLY :Bob tro STR_ORDER_CONDITIONAL_REMAINING_LIFETIME :Oes yn weddill (blynyddoedd) +STR_ORDER_CONDITIONAL_MAX_RELIABILITY :Dibynadwyedd uchafsymol STR_ORDER_CONDITIONAL_COMPARATOR_TOOLTIP :{BLACK}Sut i gymharu'r data cerbyd i'r gwerth a roddwyd STR_ORDER_CONDITIONAL_COMPARATOR_EQUALS :yn hafal i @@ -4018,6 +4026,7 @@ STR_AI_LIST_ACCEPT_TOOLTIP :{BLACK}Dewis y 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 STR_AI_SETTINGS_CAPTION_AI :AI @@ -4289,7 +4298,7 @@ STR_ERROR_MUST_REMOVE_SIGNALS_FIRST :{WHITE}Rhaid ty STR_ERROR_NO_SUITABLE_RAILROAD_TRACK :{WHITE}Dim trac rheilffordd addas STR_ERROR_MUST_REMOVE_RAILROAD_TRACK :{WHITE}Rhaid tynnu'r trac rheilffordd yn gyntaf STR_ERROR_CROSSING_ON_ONEWAY_ROAD :{WHITE}Mae'r ffordd yn ffordd un-ffordd, neu wedi'i blocio -STR_ERROR_CROSSING_DISALLOWED :{WHITE}Ni chaniateir croesfannau ar y cledrau yma +STR_ERROR_CROSSING_DISALLOWED_RAIL :{WHITE}Ni chaniateir croesfannau ar y cledrau yma STR_ERROR_CAN_T_BUILD_SIGNALS_HERE :{WHITE}Methu adeiladu signalau yma... STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK :{WHITE}Methu adeiladu trac rheilffordd yma... STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK :{WHITE}Methu tynnu trac rheilffordd oddi yma... @@ -4309,6 +4318,7 @@ STR_ERROR_CAN_T_REMOVE_ROAD_FROM :{WHITE}Methu cl STR_ERROR_CAN_T_REMOVE_TRAMWAY_FROM :{WHITE}Methu dileu tramffordd oddi yma... STR_ERROR_THERE_IS_NO_ROAD :{WHITE}... nid oes ffordd yno STR_ERROR_THERE_IS_NO_TRAMWAY :{WHITE}... nid oes tramffordd yno +STR_ERROR_NO_SUITABLE_ROAD :{WHITE}Dim lôn addas # Waterway construction errors STR_ERROR_CAN_T_BUILD_CANALS :{WHITE}Methu adeiladu camlesi yma... @@ -4471,6 +4481,8 @@ STR_BASESOUNDS_DOS_DESCRIPTION :Effeithiau sain STR_BASESOUNDS_WIN_DESCRIPTION :Effeithiau sain gwreiddiol fersiwn Windows o Transport Tycoon Deluxe. STR_BASESOUNDS_NONE_DESCRIPTION :Pecyn sain heb unrhyw effeithiau sain ynddo. STR_BASEMUSIC_WIN_DESCRIPTION :Cerddoriaeth gwreiddiol fersion Windows o Transport Tycoon Deluxe. +STR_BASEMUSIC_DOS_DESCRIPTION :Cerddoriaeth gwreiddiol fersiwn DOS o Transport Tycoon Deluxe. +STR_BASEMUSIC_TTO_DESCRIPTION :Cerddoriaeth gwreiddiol fersion DOS o Transport Tycoon Deluxe (Gwreiddiol/Golygydd Byd). STR_BASEMUSIC_NONE_DESCRIPTION :Pecyn cerddoriaeth heb unrhyw gerddoriaeth ynddo. ##id 0x2000 diff --git a/src/language.h b/src/language.h index ec241dbd8c..aec5d9c85f 100644 --- a/src/language.h +++ b/src/language.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. @@ -13,9 +11,9 @@ #define LANGUAGE_H #include "core/smallvec_type.hpp" -#ifdef WITH_ICU_SORT +#ifdef WITH_ICU_I18N #include -#endif /* WITH_ICU_SORT */ +#endif /* WITH_ICU_I18N */ #include "strings_type.h" static const uint8 CASE_GENDER_LEN = 16; ///< The (maximum) length of a case/gender string. @@ -96,7 +94,7 @@ struct LanguageMetadata : public LanguagePackHeader { }; /** Type for the list of language meta data. */ -typedef SmallVector LanguageList; +typedef std::vector LanguageList; /** The actual list of language meta data. */ extern LanguageList _languages; @@ -104,9 +102,9 @@ extern LanguageList _languages; /** The currently loaded language. */ extern const LanguageMetadata *_current_language; -#ifdef WITH_ICU_SORT +#ifdef WITH_ICU_I18N extern icu::Collator *_current_collator; -#endif /* WITH_ICU_SORT */ +#endif /* WITH_ICU_I18N */ bool ReadLanguagePack(const LanguageMetadata *lang); const LanguageMetadata *GetLanguage(byte newgrflangid); diff --git a/src/linkgraph/demands.h b/src/linkgraph/demands.h index 8a639b8b15..6fe3768341 100644 --- a/src/linkgraph/demands.h +++ b/src/linkgraph/demands.h @@ -23,7 +23,7 @@ private: }; /** - * Stateless, thread safe demand hander. Doesn't do anything but call DemandCalculator. + * Stateless, thread safe demand handler. Doesn't do anything but call DemandCalculator. */ class DemandHandler : public ComponentHandler { public: diff --git a/src/linkgraph/flowmapper.cpp b/src/linkgraph/flowmapper.cpp index b78b30335e..2e0257fc1b 100644 --- a/src/linkgraph/flowmapper.cpp +++ b/src/linkgraph/flowmapper.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. diff --git a/src/linkgraph/flowmapper.h b/src/linkgraph/flowmapper.h index 6f874e5b30..90ccd9fe52 100644 --- a/src/linkgraph/flowmapper.h +++ b/src/linkgraph/flowmapper.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/linkgraph/init.h b/src/linkgraph/init.h index a39a0f8205..377c886311 100644 --- a/src/linkgraph/init.h +++ b/src/linkgraph/init.h @@ -6,7 +6,7 @@ #include "linkgraphjob_base.h" /** - * Stateless, thread safe initialization hander. Initializes node and edge + * Stateless, thread safe initialization handler. Initializes node and edge * annotations. */ class InitHandler : public ComponentHandler { diff --git a/src/linkgraph/linkgraph.cpp b/src/linkgraph/linkgraph.cpp index 34b3a4aa09..5185d07b7b 100644 --- a/src/linkgraph/linkgraph.cpp +++ b/src/linkgraph/linkgraph.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. @@ -139,7 +137,10 @@ void LinkGraph::RemoveNode(NodeID id) node_edges[id] = node_edges[last_node]; } Station::Get(this->nodes[last_node].station)->goods[this->cargo].node = id; - this->nodes.Erase(this->nodes.Get(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 @@ -159,7 +160,7 @@ NodeID LinkGraph::AddNode(const Station *st) const GoodsEntry &good = st->goods[this->cargo]; NodeID new_node = this->Size(); - this->nodes.Append(); + 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, @@ -281,7 +282,7 @@ void LinkGraph::Init(uint size) { assert(this->Size() == 0); this->edges.Resize(size, size); - this->nodes.Resize(size); + this->nodes.resize(size); for (uint i = 0; i < size; ++i) { this->nodes[i].Init(); diff --git a/src/linkgraph/linkgraph.h b/src/linkgraph/linkgraph.h index 799f22c780..997d946230 100644 --- a/src/linkgraph/linkgraph.h +++ b/src/linkgraph/linkgraph.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. @@ -435,7 +433,7 @@ public: void RemoveEdge(NodeID to); }; - typedef SmallVector NodeVector; + typedef std::vector NodeVector; typedef SmallMatrix EdgeMatrix; /** Minimum effective distance for timeout calculation. */ @@ -496,7 +494,7 @@ public: * Get the current size of the component. * @return Size. */ - inline uint Size() const { return this->nodes.Length(); } + inline uint Size() const { return (uint)this->nodes.size(); } /** * Get date of last compression. @@ -536,6 +534,4 @@ protected: EdgeMatrix edges; ///< Edges in the component. }; -#define FOR_ALL_LINK_GRAPHS(var) FOR_ALL_ITEMS_FROM(LinkGraph, link_graph_index, var, 0) - #endif /* LINKGRAPH_H */ diff --git a/src/linkgraph/linkgraph_base.h b/src/linkgraph/linkgraph_base.h index 6e56af9a9c..eb86c0c64e 100644 --- a/src/linkgraph/linkgraph_base.h +++ b/src/linkgraph/linkgraph_base.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/linkgraph/linkgraph_gui.cpp b/src/linkgraph/linkgraph_gui.cpp index dbf134ce28..10d1944982 100644 --- a/src/linkgraph/linkgraph_gui.cpp +++ b/src/linkgraph/linkgraph_gui.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. @@ -58,8 +56,7 @@ void LinkGraphOverlay::RebuildCache() DrawPixelInfo dpi; this->GetWidgetDpi(&dpi); - const Station *sta; - FOR_ALL_STATIONS(sta) { + for (const Station *sta : Station::Iterate()) { if (sta->rect.IsEmpty()) continue; Point pta = this->GetStationMiddle(sta); @@ -301,7 +298,7 @@ void LinkGraphOverlay::DrawStationDots(const DrawPixelInfo *dpi) const { for (StationSupplyList::const_iterator i(this->cached_stations.begin()); i != this->cached_stations.end(); ++i) { const Station *st = Station::GetIfValid(i->first); - if (st == NULL) continue; + if (st == nullptr) continue; Point pt = this->GetStationMiddle(st); if (!this->IsPointVisible(pt, dpi, 3 * this->scale)) continue; @@ -345,7 +342,7 @@ void LinkGraphOverlay::DrawStationDots(const DrawPixelInfo *dpi) const */ Point LinkGraphOverlay::GetStationMiddle(const Station *st) const { - if (this->window->viewport != NULL) { + if (this->window->viewport != nullptr) { return GetViewportStationMiddle(this->window->viewport, st); } else { /* assume this is a smallmap */ @@ -399,7 +396,7 @@ NWidgetBase *MakeCargoesLegendLinkGraphGUI(int *biggest_index) { static const uint ENTRIES_PER_ROW = CeilDiv(NUM_CARGO, 5); NWidgetVertical *panel = new NWidgetVertical(NC_EQUALSIZE); - NWidgetHorizontal *row = NULL; + NWidgetHorizontal *row = nullptr; for (uint i = 0; i < NUM_CARGO; ++i) { if (i % ENTRIES_PER_ROW == 0) { if (row) panel->Add(row); @@ -564,7 +561,7 @@ bool LinkGraphLegendWindow::OnTooltip(Point pt, int widget, TooltipCloseConditio { if (IsInsideMM(widget, WID_LGL_COMPANY_FIRST, WID_LGL_COMPANY_LAST + 1)) { if (this->IsWidgetDisabled(widget)) { - GuiShowTooltips(this, STR_LINKGRAPH_LEGEND_SELECT_COMPANIES, 0, NULL, close_cond); + GuiShowTooltips(this, STR_LINKGRAPH_LEGEND_SELECT_COMPANIES, 0, nullptr, close_cond); } else { uint64 params[2]; CompanyID cid = (CompanyID)(widget - WID_LGL_COMPANY_FIRST); diff --git a/src/linkgraph/linkgraph_gui.h b/src/linkgraph/linkgraph_gui.h index 17fcd28b28..8e85470588 100644 --- a/src/linkgraph/linkgraph_gui.h +++ b/src/linkgraph/linkgraph_gui.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. @@ -104,11 +102,11 @@ public: LinkGraphLegendWindow(WindowDesc *desc, int window_number); void SetOverlay(LinkGraphOverlay *overlay); - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize); - virtual void DrawWidget(const Rect &r, int widget) const; - virtual bool OnTooltip(Point pt, int widget, TooltipCloseCondition close_cond); - virtual void OnClick(Point pt, int widget, int click_count); - virtual void OnInvalidateData(int data = 0, bool gui_scope = true); + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override; + void DrawWidget(const Rect &r, int widget) const override; + bool OnTooltip(Point pt, int widget, TooltipCloseCondition close_cond) override; + void OnClick(Point pt, int widget, int click_count) override; + void OnInvalidateData(int data = 0, bool gui_scope = true) override; private: LinkGraphOverlay *overlay; diff --git a/src/linkgraph/linkgraph_type.h b/src/linkgraph/linkgraph_type.h index 6a3239b089..a2618ae84f 100644 --- a/src/linkgraph/linkgraph_type.h +++ b/src/linkgraph/linkgraph_type.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. @@ -21,7 +19,7 @@ static const LinkGraphID INVALID_LINK_GRAPH_JOB = UINT16_MAX; typedef uint16 NodeID; static const NodeID INVALID_NODE = UINT16_MAX; -enum DistributionType { +enum DistributionType : byte { DT_BEGIN = 0, DT_MIN = 0, DT_MANUAL = 0, ///< Manual distribution. No link graph calculations are run. @@ -37,7 +35,6 @@ enum DistributionType { * Define basic enum properties */ template <> struct EnumPropsT : MakeEnumPropsT {}; -typedef TinyEnumT DistributionTypeByte; // typedefing-enumification of DistributionType /** * Special modes for updating links. 'Restricted' means that vehicles with diff --git a/src/linkgraph/linkgraphjob.cpp b/src/linkgraph/linkgraphjob.cpp index 537303cf35..2d7b407da7 100644 --- a/src/linkgraph/linkgraphjob.cpp +++ b/src/linkgraph/linkgraphjob.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. @@ -39,7 +37,6 @@ LinkGraphJob::LinkGraphJob(const LinkGraph &orig) : * This is on purpose. */ link_graph(orig), settings(_settings_game.linkgraph), - thread(NULL), join_date(_date + _settings_game.linkgraph.recalc_time) { } @@ -61,10 +58,9 @@ void LinkGraphJob::EraseFlows(NodeID from) */ void LinkGraphJob::SpawnThread() { - if (!ThreadObject::New(&(LinkGraphSchedule::Run), this, &this->thread, "ottd:linkgraph")) { - this->thread = NULL; + if (!StartNewThread(&this->thread, "ottd:linkgraph", &(LinkGraphSchedule::Run), this)) { /* Of course this will hang a bit. - * On the other hand, if you want to play games which make this hang noticably + * On the other hand, if you want to play games which make this hang noticeably * on a platform without threads then you'll probably get other problems first. * OK: * If someone comes and tells me that this hangs for him/her, I'll implement a @@ -79,10 +75,8 @@ void LinkGraphJob::SpawnThread() */ void LinkGraphJob::JoinThread() { - if (this->thread != NULL) { - this->thread->Join(); - delete this->thread; - this->thread = NULL; + if (this->thread.joinable()) { + this->thread.join(); } } @@ -106,7 +100,7 @@ LinkGraphJob::~LinkGraphJob() /* The station can have been deleted. Remove all flows originating from it then. */ Station *st = Station::GetIfValid(from.Station()); - if (st == NULL) { + if (st == nullptr) { this->EraseFlows(node_id); continue; } @@ -126,7 +120,7 @@ LinkGraphJob::~LinkGraphJob() if (from[it->first].Flow() == 0) continue; StationID to = (*this)[it->first].Station(); Station *st2 = Station::GetIfValid(to); - if (st2 == NULL || st2->goods[this->Cargo()].link_graph != this->link_graph.index || + 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) { /* Edge has been removed. Delete flows. */ @@ -179,7 +173,7 @@ LinkGraphJob::~LinkGraphJob() void LinkGraphJob::Init() { uint size = this->Size(); - this->nodes.Resize(size); + this->nodes.resize(size); this->edges.Resize(size, size); for (uint i = 0; i < size; ++i) { this->nodes[i].Init(this->link_graph[i].Supply()); @@ -244,7 +238,7 @@ 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 != NULL) { + if (this->parent != nullptr) { LinkGraphJob::Edge edge = job[this->parent->node][this->node]; if (max_saturation != UINT_MAX) { uint usable_cap = edge.Capacity() * max_saturation / 100; @@ -274,6 +268,6 @@ Path::Path(NodeID n, bool source) : capacity(source ? UINT_MAX : 0), free_capacity(source ? INT_MAX : INT_MIN), flow(0), node(n), origin(source ? n : INVALID_NODE), - num_children(0), parent(NULL) + num_children(0), parent(nullptr) {} diff --git a/src/linkgraph/linkgraphjob.h b/src/linkgraph/linkgraphjob.h index b4587a7842..9344ea2462 100644 --- a/src/linkgraph/linkgraphjob.h +++ b/src/linkgraph/linkgraphjob.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. @@ -12,7 +10,7 @@ #ifndef LINKGRAPHJOB_H #define LINKGRAPHJOB_H -#include "../thread/thread.h" +#include "../thread.h" #include "linkgraph.h" #include @@ -50,7 +48,7 @@ private: void Init(uint supply); }; - typedef SmallVector NodeAnnotationVector; + typedef std::vector NodeAnnotationVector; typedef SmallMatrix EdgeAnnotationMatrix; friend const SaveLoad *GetLinkGraphJobDesc(); @@ -59,7 +57,7 @@ private: 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. - ThreadObject *thread; ///< Thread the job is running in or NULL if it's running in the main thread. + 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. @@ -266,7 +264,7 @@ 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. */ - LinkGraphJob() : settings(_settings_game.linkgraph), thread(NULL), + LinkGraphJob() : settings(_settings_game.linkgraph), join_date(INVALID_DATE) {} LinkGraphJob(const LinkGraph &orig); @@ -336,8 +334,6 @@ public: inline const LinkGraph &Graph() const { return this->link_graph; } }; -#define FOR_ALL_LINK_GRAPH_JOBS(var) FOR_ALL_ITEMS_FROM(LinkGraphJob, link_graph_job_index, var, 0) - /** * A leg of a path in the link graph. Paths can form trees by being "forked". */ @@ -403,9 +399,9 @@ public: */ inline void Detach() { - if (this->parent != NULL) { + if (this->parent != nullptr) { this->parent->num_children--; - this->parent = NULL; + this->parent = nullptr; } } @@ -415,7 +411,7 @@ public: protected: /** - * Some boundaries to clamp agains in order to avoid integer overflows. + * Some boundaries to clamp against in order to avoid integer overflows. */ enum PathCapacityBoundaries { PATH_CAP_MULTIPLIER = 16, diff --git a/src/linkgraph/linkgraphjob_base.h b/src/linkgraph/linkgraphjob_base.h index 0a29166ee9..a05d6ef8d6 100644 --- a/src/linkgraph/linkgraphjob_base.h +++ b/src/linkgraph/linkgraphjob_base.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/linkgraph/linkgraphschedule.cpp b/src/linkgraph/linkgraphschedule.cpp index 8c508d8173..964744509e 100644 --- a/src/linkgraph/linkgraphschedule.cpp +++ b/src/linkgraph/linkgraphschedule.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. @@ -69,13 +67,11 @@ void LinkGraphSchedule::JoinNext() } /** - * Run all handlers for the given Job. This method is tailored to - * ThreadObject::New. - * @param j Pointer to a link graph job. + * Run all handlers for the given Job. + * @param job Pointer to a link graph job. */ -/* static */ void LinkGraphSchedule::Run(void *j) +/* static */ void LinkGraphSchedule::Run(LinkGraphJob *job) { - LinkGraphJob *job = (LinkGraphJob *)j; for (uint i = 0; i < lengthof(instance.handlers); ++i) { instance.handlers[i]->Run(*job); } @@ -111,10 +107,8 @@ void LinkGraphSchedule::SpawnAll() */ void LinkGraphSchedule::ShiftDates(int interval) { - LinkGraph *lg; - FOR_ALL_LINK_GRAPHS(lg) lg->ShiftDates(interval); - LinkGraphJob *lgj; - FOR_ALL_LINK_GRAPH_JOBS(lgj) lgj->ShiftJoinDate(interval); + for (LinkGraph *lg : LinkGraph::Iterate()) lg->ShiftDates(interval); + for (LinkGraphJob *lgj : LinkGraphJob::Iterate()) lgj->ShiftJoinDate(interval); } /** diff --git a/src/linkgraph/linkgraphschedule.h b/src/linkgraph/linkgraphschedule.h index ec22be3161..62ca2b0c17 100644 --- a/src/linkgraph/linkgraphschedule.h +++ b/src/linkgraph/linkgraphschedule.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. @@ -53,7 +51,7 @@ public: static const uint SPAWN_JOIN_TICK = 21; ///< Tick when jobs are spawned or joined every day. static LinkGraphSchedule instance; - static void Run(void *j); + static void Run(LinkGraphJob *job); static void Clear(); void SpawnNext(); diff --git a/src/linkgraph/mcf.cpp b/src/linkgraph/mcf.cpp index 544584ef61..c8c031ea3b 100644 --- a/src/linkgraph/mcf.cpp +++ b/src/linkgraph/mcf.cpp @@ -104,7 +104,7 @@ public: * @param job Job to iterate on. */ GraphEdgeIterator(LinkGraphJob &job) : job(job), - i(NULL, NULL, INVALID_NODE), end(NULL, NULL, INVALID_NODE) + i(nullptr, nullptr, INVALID_NODE), end(nullptr, nullptr, INVALID_NODE) {} /** @@ -262,7 +262,7 @@ void MultiCommodityFlow::Dijkstra(NodeID source_node, PathVector &paths) Tedge_iterator iter(this->job); uint size = this->job.Size(); AnnoSet annos; - paths.resize(size, NULL); + paths.resize(size, nullptr); for (NodeID node = 0; node < size; ++node) { Tannotation *anno = new Tannotation(node, node == source_node); anno->UpdateAnnotation(); @@ -305,16 +305,16 @@ void MultiCommodityFlow::Dijkstra(NodeID source_node, PathVector &paths) void MultiCommodityFlow::CleanupPaths(NodeID source_id, PathVector &paths) { Path *source = paths[source_id]; - paths[source_id] = NULL; + paths[source_id] = nullptr; for (PathVector::iterator i = paths.begin(); i != paths.end(); ++i) { Path *path = *i; - if (path == NULL) continue; + if (path == nullptr) continue; if (path->GetParent() == source) path->Detach(); - while (path != source && path != NULL && path->GetFlow() == 0) { + while (path != source && path != nullptr && path->GetFlow() == 0) { Path *parent = path->GetParent(); path->Detach(); if (path->GetNumChildren() == 0) { - paths[path->GetNode()] = NULL; + paths[path->GetNode()] = nullptr; delete path; } path = parent; @@ -404,7 +404,7 @@ bool MCF1stPass::EliminateCycles(PathVector &path, NodeID origin_id, NodeID next /* this node has already been searched */ if (at_next_pos == Path::invalid_path) return false; - if (at_next_pos == NULL) { + 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(); @@ -450,7 +450,7 @@ bool MCF1stPass::EliminateCycles(PathVector &path, NodeID origin_id, NodeID next * could be found in this branch, thus it has to be searched again next * time we spot it. */ - path[next_id] = found ? NULL : Path::invalid_path; + path[next_id] = found ? nullptr : Path::invalid_path; return found; } @@ -474,11 +474,11 @@ bool MCF1stPass::EliminateCycles() { bool cycles_found = false; uint size = this->job.Size(); - PathVector path(size, NULL); + PathVector path(size, nullptr); for (NodeID node = 0; node < size; ++node) { /* Starting at each node in the graph find all cycles involving this * node. */ - std::fill(path.begin(), path.end(), (Path *)NULL); + std::fill(path.begin(), path.end(), (Path *)nullptr); cycles_found |= this->EliminateCycles(path, node, node); } return cycles_found; @@ -494,18 +494,22 @@ MCF1stPass::MCF1stPass(LinkGraphJob &job) : MultiCommodityFlow(job) uint size = job.Size(); uint accuracy = job.Settings().accuracy; bool more_loops; + std::vector finished_sources(size); do { more_loops = false; for (NodeID source = 0; source < size; ++source) { + if (finished_sources[source]) continue; + /* First saturate the shortest paths. */ this->Dijkstra(source, paths); + bool source_demand_left = false; for (NodeID dest = 0; dest < size; ++dest) { Edge edge = job[source][dest]; if (edge.UnsatisfiedDemand() > 0) { Path *path = paths[dest]; - assert(path != NULL); + 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*. */ @@ -518,8 +522,10 @@ MCF1stPass::MCF1stPass(LinkGraphJob &job) : MultiCommodityFlow(job) path->GetFreeCapacity() > INT_MIN) { this->PushFlow(edge, path, accuracy, UINT_MAX); } + if (edge.UnsatisfiedDemand() > 0) source_demand_left = true; } } + finished_sources[source] = !source_demand_left; this->CleanupPaths(source, paths); } } while (more_loops || this->EliminateCycles()); @@ -537,18 +543,27 @@ MCF2ndPass::MCF2ndPass(LinkGraphJob &job) : MultiCommodityFlow(job) uint size = job.Size(); uint accuracy = job.Settings().accuracy; bool demand_left = true; + std::vector finished_sources(size); while (demand_left) { demand_left = false; for (NodeID source = 0; source < size; ++source) { + if (finished_sources[source]) continue; + this->Dijkstra(source, paths); + + 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) demand_left = true; + if (edge.UnsatisfiedDemand() > 0) { + demand_left = true; + source_demand_left = true; + } } } + finished_sources[source] = !source_demand_left; this->CleanupPaths(source, paths); } } diff --git a/src/linkgraph/refresh.cpp b/src/linkgraph/refresh.cpp index 501f063520..430e290727 100644 --- a/src/linkgraph/refresh.cpp +++ b/src/linkgraph/refresh.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. @@ -28,11 +26,11 @@ /* static */ void LinkRefresher::Run(Vehicle *v, bool allow_merge, bool is_full_loading) { /* If there are no orders we can't predict anything.*/ - if (v->orders.list == NULL) return; + if (v->orders.list == nullptr) return; /* Make sure the first order is a useful order. */ const Order *first = v->orders.list->GetNextDecisionNode(v->GetOrder(v->cur_implicit_order_index), 0); - if (first == NULL) return; + if (first == nullptr) return; HopSet seen_hops; LinkRefresher refresher(v, &seen_hops, allow_merge, is_full_loading); @@ -75,7 +73,7 @@ LinkRefresher::LinkRefresher(Vehicle *vehicle, HopSet *seen_hops, bool allow_mer memset(this->capacities, 0, sizeof(this->capacities)); /* Assemble list of capacities and set last loading stations to 0. */ - for (Vehicle *v = this->vehicle; v != NULL; v = v->Next()) { + for (Vehicle *v = this->vehicle; v != nullptr; v = v->Next()) { this->refit_capacities.push_back(RefitDesc(v->cargo_type, v->cargo_cap, v->refit_cap)); if (v->refit_cap > 0) { assert(v->cargo_type < NUM_CARGO); @@ -94,7 +92,7 @@ bool LinkRefresher::HandleRefit(CargoID refit_cargo) this->cargo = refit_cargo; RefitList::iterator refit_it = this->refit_capacities.begin(); bool any_refit = false; - for (Vehicle *v = this->vehicle; v != NULL; v = v->Next()) { + for (Vehicle *v = this->vehicle; v != nullptr; v = v->Next()) { const Engine *e = Engine::Get(v->engine_type); if (!HasBit(e->info.refit_mask, this->cargo)) { ++refit_it; @@ -164,10 +162,10 @@ void LinkRefresher::ResetRefit() */ const Order *LinkRefresher::PredictNextOrder(const Order *cur, const Order *next, uint8 flags, uint num_hops) { - /* next is good if it's either NULL (then the caller will stop the + /* next is good if it's either nullptr (then the caller will stop the * evaluation) or if it's not conditional and the caller allows it to be * chosen (by setting USE_NEXT). */ - while (next != NULL && (!HasBit(flags, USE_NEXT) || next->IsType(OT_CONDITIONAL))) { + while (next != nullptr && (!HasBit(flags, USE_NEXT) || next->IsType(OT_CONDITIONAL))) { /* After the first step any further non-conditional order is good, * regardless of previous USE_NEXT settings. The case of cur and next or @@ -177,7 +175,7 @@ const Order *LinkRefresher::PredictNextOrder(const Order *cur, const Order *next if (next->IsType(OT_CONDITIONAL)) { const Order *skip_to = this->vehicle->orders.list->GetNextDecisionNode( this->vehicle->orders.list->GetOrderAt(next->GetConditionSkipToOrder()), num_hops); - if (skip_to != NULL && num_hops < this->vehicle->orders.list->GetNumOrders()) { + if (skip_to != nullptr && num_hops < this->vehicle->orders.list->GetNumOrders()) { /* Make copies of capacity tracking lists. There is potential * for optimization here: If the vehicle never refits we don't * need to copy anything. Also, if we've seen the branched link @@ -204,7 +202,7 @@ void LinkRefresher::RefreshStats(const Order *cur, const Order *next) { StationID next_station = next->GetDestination(); Station *st = Station::GetIfValid(cur->GetDestination()); - if (st != NULL && next_station != INVALID_STATION && next_station != st->index) { + if (st != nullptr && next_station != INVALID_STATION && next_station != st->index) { for (CargoID c = 0; c < NUM_CARGO; c++) { /* Refresh the link and give it a minimum capacity. */ @@ -226,7 +224,7 @@ void LinkRefresher::RefreshStats(const Order *cur, const Order *next) * loading. Don't do that if the vehicle has been waiting for longer than the entire * order list is supposed to take, though. If that is the case the total duration is * probably far off and we'd greatly overestimate the capacity by increasing.*/ - if (this->is_full_loading && this->vehicle->orders.list != NULL && + if (this->is_full_loading && this->vehicle->orders.list != nullptr && st->index == vehicle->last_station_visited && this->vehicle->orders.list->GetTotalDuration() > (Ticks)this->vehicle->current_order_time) { @@ -250,7 +248,7 @@ void LinkRefresher::RefreshStats(const Order *cur, const Order *next) /** * Iterate over orders starting at \a cur and \a next and refresh links * associated with them. \a cur and \a next can be equal. If they're not they - * must be "neigbours" in their order list, which means \a next must be directly + * must be "neighbours" in their order list, which means \a next must be directly * reachable from \a cur without passing any further OT_GOTO_STATION or * OT_IMPLICIT orders in between. * @param cur Current order being evaluated. @@ -260,7 +258,7 @@ void LinkRefresher::RefreshStats(const Order *cur, const Order *next) */ void LinkRefresher::RefreshLinks(const Order *cur, const Order *next, uint8 flags, uint num_hops) { - while (next != NULL) { + while (next != nullptr) { if ((next->IsType(OT_GOTO_DEPOT) || next->IsType(OT_GOTO_STATION)) && next->IsRefit()) { SetBit(flags, WAS_REFIT); @@ -288,7 +286,7 @@ void LinkRefresher::RefreshLinks(const Order *cur, const Order *next, uint8 flag } next = this->PredictNextOrder(cur, next, flags, num_hops); - if (next == NULL) break; + if (next == nullptr) break; Hop hop(cur->index, next->index, this->cargo); if (this->seen_hops->find(hop) != this->seen_hops->end()) { break; diff --git a/src/linkgraph/refresh.h b/src/linkgraph/refresh.h index 42067ebcf9..0202fd7239 100644 --- a/src/linkgraph/refresh.h +++ b/src/linkgraph/refresh.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/livery.h b/src/livery.h index d6ed5bfdc7..dc01c390a7 100644 --- a/src/livery.h +++ b/src/livery.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/main_gui.cpp b/src/main_gui.cpp index 8b02a55775..59d361cb99 100644 --- a/src/main_gui.cpp +++ b/src/main_gui.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. @@ -53,9 +51,8 @@ static int _rename_id = 1; static int _rename_what = -1; -void CcGiveMoney(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) +void CcGiveMoney(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) { -#ifdef ENABLE_NETWORK if (result.Failed() || !_settings_game.economy.give_money) return; /* Inform the company of the action of one of its clients (controllers). */ @@ -68,25 +65,22 @@ void CcGiveMoney(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2 } else { NetworkServerSendChat(NETWORK_ACTION_GIVE_MONEY, DESTTYPE_TEAM, p2, msg, CLIENT_ID_SERVER, p1); } -#endif /* ENABLE_NETWORK */ } void HandleOnEditText(const char *str) { switch (_rename_what) { -#ifdef ENABLE_NETWORK - case 3: { // Give money, you can only give money in excess of loan - const Company *c = Company::GetIfValid(_local_company); - if (c == NULL) break; - Money money = min(c->money - c->current_loan, (Money)(atoi(str) / _currency->rate)); + case 3: { // Give money, you can only give money in excess of loan + const Company *c = Company::GetIfValid(_local_company); + if (c == nullptr) break; + Money money = min(c->money - c->current_loan, (Money)(atoi(str) / _currency->rate)); - uint32 money_c = Clamp(ClampToI32(money), 0, 20000000); // Clamp between 20 million and 0 + uint32 money_c = Clamp(ClampToI32(money), 0, 20000000); // Clamp between 20 million and 0 - /* Give 'id' the money, and subtract it from ourself */ - DoCommandP(0, money_c, _rename_id, CMD_GIVE_MONEY | CMD_MSG(STR_ERROR_INSUFFICIENT_FUNDS), CcGiveMoney, str); - break; - } -#endif /* ENABLE_NETWORK */ + /* Give 'id' the money, and subtract it from ourself */ + DoCommandP(0, money_c, _rename_id, CMD_GIVE_MONEY | CMD_MSG(STR_ERROR_INSUFFICIENT_FUNDS), CcGiveMoney, str); + break; + } default: NOT_REACHED(); } @@ -121,19 +115,17 @@ bool HandlePlacePushButton(Window *w, int widget, CursorID cursor, HighLightStyl } -void CcPlaySound_EXPLOSION(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) +void CcPlaySound_EXPLOSION(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) { if (result.Succeeded() && _settings_client.sound.confirm) SndPlayTileFx(SND_12_EXPLOSION, tile); } -#ifdef ENABLE_NETWORK void ShowNetworkGiveMoneyWindow(CompanyID company) { _rename_id = company; _rename_what = 3; - ShowQueryString(STR_EMPTY, STR_NETWORK_GIVE_MONEY_CAPTION, 30, NULL, CS_NUMERAL, QSF_NONE); + ShowQueryString(STR_EMPTY, STR_NETWORK_GIVE_MONEY_CAPTION, 30, nullptr, CS_NUMERAL, QSF_NONE); } -#endif /* ENABLE_NETWORK */ /** @@ -147,7 +139,7 @@ bool DoZoomInOutWindow(ZoomStateChange how, Window *w) { ViewPort *vp; - assert(w != NULL); + assert(w != nullptr); vp = w->viewport; switch (how) { @@ -181,7 +173,7 @@ bool DoZoomInOutWindow(ZoomStateChange how, Window *w) w->viewport->follow_vehicle = INVALID_VEHICLE; break; } - if (vp != NULL) { // the vp can be null when how == ZOOM_NONE + if (vp != nullptr) { // the vp can be null when how == ZOOM_NONE vp->virtual_left = w->viewport->scrollpos_x; vp->virtual_top = w->viewport->scrollpos_y; } @@ -192,7 +184,7 @@ bool DoZoomInOutWindow(ZoomStateChange how, Window *w) void ZoomInOrOutToCursorWindow(bool in, Window *w) { - assert(w != NULL); + assert(w != nullptr); if (_game_mode != GM_MENU) { ViewPort *vp = w->viewport; @@ -207,6 +199,16 @@ void ZoomInOrOutToCursorWindow(bool in, Window *w) } } +void FixTitleGameZoom() +{ + if (_game_mode != GM_MENU) return; + + ViewPort *vp = FindWindowByClass(WC_MAIN_WINDOW)->viewport; + vp->zoom = _gui_zoom; + vp->virtual_width = ScaleByZoom(vp->width, vp->zoom); + vp->virtual_height = ScaleByZoom(vp->height, vp->zoom); +} + static const struct NWidgetPart _nested_main_window_widgets[] = { NWidget(NWID_VIEWPORT, INVALID_COLOUR, WID_M_VIEWPORT), SetResize(1, 1), }; @@ -258,7 +260,7 @@ struct MainWindow : Window this->refresh.SetInterval(LINKGRAPH_DELAY); } - virtual void OnRealtimeTick(uint delta_ms) + void OnRealtimeTick(uint delta_ms) override { if (!this->refresh.Elapsed(delta_ms)) return; @@ -273,7 +275,7 @@ struct MainWindow : Window this->GetWidget(WID_M_VIEWPORT)->SetDirty(this); } - virtual void OnPaint() + void OnPaint() override { this->DrawWidgets(); if (_game_mode == GM_MENU) { @@ -293,7 +295,7 @@ struct MainWindow : Window } } - virtual EventState OnHotkey(int hotkey) + EventState OnHotkey(int hotkey) override { if (hotkey == GHK_QUIT) { HandleExitGameRequest(); @@ -399,11 +401,10 @@ struct MainWindow : Window ResetRestoreAllTransparency(); break; -#ifdef ENABLE_NETWORK case GHK_CHAT: // smart chat; send to team if any, otherwise to all if (_networking) { const NetworkClientInfo *cio = NetworkClientInfo::GetByClientID(_network_own_client_id); - if (cio == NULL) break; + if (cio == nullptr) break; ShowNetworkChatQueryWindow(NetworkClientPreferTeamChat(cio) ? DESTTYPE_TEAM : DESTTYPE_BROADCAST, cio->client_playas); } @@ -416,7 +417,7 @@ struct MainWindow : Window case GHK_CHAT_COMPANY: // send text to all team mates if (_networking) { const NetworkClientInfo *cio = NetworkClientInfo::GetByClientID(_network_own_client_id); - if (cio == NULL) break; + if (cio == nullptr) break; ShowNetworkChatQueryWindow(DESTTYPE_TEAM, cio->client_playas); } @@ -427,14 +428,13 @@ struct MainWindow : Window ShowNetworkChatQueryWindow(DESTTYPE_CLIENT, CLIENT_ID_SERVER); } break; -#endif default: return ES_NOT_HANDLED; } return ES_HANDLED; } - virtual void OnScroll(Point delta) + void OnScroll(Point delta) override { this->viewport->scrollpos_x += ScaleByZoom(delta.x, this->viewport->zoom); this->viewport->scrollpos_y += ScaleByZoom(delta.y, this->viewport->zoom); @@ -443,16 +443,16 @@ struct MainWindow : Window this->refresh.SetInterval(LINKGRAPH_DELAY); } - virtual void OnMouseWheel(int wheel) + void OnMouseWheel(int wheel) override { if (_settings_client.gui.scrollwheel_scrolling != 2) { ZoomInOrOutToCursorWindow(wheel < 0, this); } } - virtual void OnResize() + void OnResize() override { - if (this->viewport != NULL) { + if (this->viewport != nullptr) { NWidgetViewport *nvp = this->GetWidget(WID_M_VIEWPORT); nvp->UpdateViewportCoordinates(this); this->refresh.SetInterval(LINKGRAPH_DELAY); @@ -464,7 +464,7 @@ struct MainWindow : Window * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; /* Forward the message to the appropriate toolbar (ingame or scenario editor) */ @@ -519,18 +519,16 @@ static Hotkey global_hotkeys[] = { Hotkey('8' | WKC_CTRL | WKC_SHIFT, "invisibility_catenary", GHK_TOGGLE_INVISIBILITY + 7), Hotkey('X' | WKC_CTRL, "transparency_toolbar", GHK_TRANSPARENCY_TOOLBAR), Hotkey('X', "toggle_transparency", GHK_TRANSPARANCY), -#ifdef ENABLE_NETWORK Hotkey(_ghk_chat_keys, "chat", GHK_CHAT), Hotkey(_ghk_chat_all_keys, "chat_all", GHK_CHAT_ALL), Hotkey(_ghk_chat_company_keys, "chat_company", GHK_CHAT_COMPANY), Hotkey(_ghk_chat_server_keys, "chat_server", GHK_CHAT_SERVER), -#endif HOTKEY_LIST_END }; HotkeyList MainWindow::hotkeys("global", global_hotkeys); static WindowDesc _main_window_desc( - WDP_MANUAL, NULL, 0, 0, + WDP_MANUAL, nullptr, 0, 0, WC_MAIN_WINDOW, WC_NONE, 0, _nested_main_window_widgets, lengthof(_nested_main_window_widgets), diff --git a/src/map.cpp b/src/map.cpp index 85590c3e88..679c445ee1 100644 --- a/src/map.cpp +++ b/src/map.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. @@ -29,8 +27,8 @@ 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) -Tile *_m = NULL; ///< Tiles of the map -TileExtended *_me = NULL; ///< Extended Tiles of the map +Tile *_m = nullptr; ///< Tiles of the map +TileExtended *_me = nullptr; ///< Extended Tiles of the map /** @@ -254,12 +252,12 @@ uint DistanceFromEdgeDir(TileIndex tile, DiagDirection dir) * @param proc: callback testing function pointer. * @param user_data to be passed to the callback function. Depends on the implementation * @return result of the search - * @pre proc != NULL + * @pre proc != nullptr * @pre size > 0 */ bool CircularTileSearch(TileIndex *tile, uint size, TestTileOnSearchProc proc, void *user_data) { - assert(proc != NULL); + assert(proc != nullptr); assert(size > 0); if (size % 2 == 1) { @@ -292,12 +290,12 @@ bool CircularTileSearch(TileIndex *tile, uint size, TestTileOnSearchProc proc, v * @param proc callback testing function pointer. * @param user_data to be passed to the callback function. Depends on the implementation * @return result of the search - * @pre proc != NULL + * @pre proc != nullptr * @pre radius > 0 */ bool CircularTileSearch(TileIndex *tile, uint radius, uint w, uint h, TestTileOnSearchProc proc, void *user_data) { - assert(proc != NULL); + assert(proc != nullptr); assert(radius > 0); uint x = TileX(*tile) + w + 1; diff --git a/src/map_func.h b/src/map_func.h index 21d69b1382..0c8fda7be9 100644 --- a/src/map_func.h +++ b/src/map_func.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/map_type.h b/src/map_type.h index 0c57d37700..453186d88e 100644 --- a/src/map_type.h +++ b/src/map_type.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/misc.cpp b/src/misc.cpp index 8151f2dd32..dcb04fa026 100644 --- a/src/misc.cpp +++ b/src/misc.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. @@ -28,6 +26,10 @@ #include "core/pool_type.hpp" #include "game/game.hpp" #include "linkgraph/linkgraphschedule.h" +#include "station_kdtree.h" +#include "town_kdtree.h" +#include "viewport_kdtree.h" +#include "newgrf_profiling.h" #include "safeguards.h" @@ -44,6 +46,7 @@ void InitializeAirportGui(); void InitializeDockGui(); void InitializeGraphGui(); void InitializeObjectGui(); +void InitializeTownGui(); void InitializeIndustries(); void InitializeObjects(); void InitializeTrees(); @@ -67,6 +70,8 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin _thd.redsq = INVALID_TILE; if (reset_settings) MakeNewgameSettingsLive(); + _newgrf_profilers.clear(); + if (reset_date) { SetDate(ConvertYMDToDate(_settings_game.game_creation.starting_year, 0, 1), 0); InitializeOldNames(); @@ -75,6 +80,10 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin LinkGraphSchedule::Clear(); PoolBase::Clean(PT_NORMAL); + RebuildStationKdtree(); + RebuildTownKdtree(); + RebuildViewportKdtree(); + ResetPersistentNewGRFData(); InitializeSound(); @@ -90,6 +99,7 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin InitializeDockGui(); InitializeGraphGui(); InitializeObjectGui(); + InitializeTownGui(); InitializeAIGui(); InitializeTrees(); InitializeIndustries(); @@ -104,9 +114,7 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin InitializeCheats(); InitTextEffects(); -#ifdef ENABLE_NETWORK NetworkInitChatMessage(); -#endif /* ENABLE_NETWORK */ InitializeAnimatedTiles(); InitializeEconomy(); diff --git a/src/misc/array.hpp b/src/misc/array.hpp index c49f2afc44..d23fb7a0d9 100644 --- a/src/misc/array.hpp +++ b/src/misc/array.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/binaryheap.hpp b/src/misc/binaryheap.hpp index 5bd2b794ac..a967ebdf23 100644 --- a/src/misc/binaryheap.hpp +++ b/src/misc/binaryheap.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. @@ -72,7 +70,7 @@ public: { this->Clear(); free(this->data); - this->data = NULL; + this->data = nullptr; } protected: diff --git a/src/misc/blob.hpp b/src/misc/blob.hpp index b1a5b667df..7784b6af6b 100644 --- a/src/misc/blob.hpp +++ b/src/misc/blob.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. @@ -86,9 +84,9 @@ public: /** move constructor - take ownership of blob data */ inline ByteBlob(BlobHeader * const & src) { - assert(src != NULL); + assert(src != nullptr); header = src; - *const_cast(&src) = NULL; + *const_cast(&src) = nullptr; } /** destructor */ @@ -154,13 +152,13 @@ protected: header = &src[1]; } - /** blob header accessor - use it rather than using the pointer arithmetics directly - non-const version */ + /** blob header accessor - use it rather than using the pointer arithmetic directly - non-const version */ inline BlobHeader& Hdr() { return *(header - 1); } - /** blob header accessor - use it rather than using the pointer arithmetics directly - const version */ + /** blob header accessor - use it rather than using the pointer arithmetic directly - const version */ inline const BlobHeader& Hdr() const { return *(header - 1); @@ -221,7 +219,7 @@ public: /** append new bytes at the end of existing data bytes - reallocates if necessary */ inline void AppendRaw(const void *p, size_t num_bytes) { - assert(p != NULL); + assert(p != nullptr); if (num_bytes > 0) { memcpy(Append(num_bytes), p, num_bytes); } @@ -317,8 +315,8 @@ public: OnTransfer(const OnTransfer& src) : header(src.header) { - assert(src.header != NULL); - *const_cast(&src.header) = NULL; + assert(src.header != nullptr); + *const_cast(&src.header) = nullptr; } OnTransfer(CBlobT& src) : header(src.header) @@ -328,7 +326,7 @@ public: ~OnTransfer() { - assert(header == NULL); + assert(header == nullptr); } }; diff --git a/src/misc/countedobj.cpp b/src/misc/countedobj.cpp index 837d1c1770..d9b66b83da 100644 --- a/src/misc/countedobj.cpp +++ b/src/misc/countedobj.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. diff --git a/src/misc/countedptr.hpp b/src/misc/countedptr.hpp index e7b28a6267..8ced8d48e1 100644 --- a/src/misc/countedptr.hpp +++ b/src/misc/countedptr.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. @@ -34,8 +32,8 @@ protected: Tcls *m_pT; public: - /** default (NULL) construct or construct from a raw pointer */ - inline CCountedPtr(Tcls *pObj = NULL) : m_pT(pObj) + /** default (nullptr) construct or construct from a raw pointer */ + inline CCountedPtr(Tcls *pObj = nullptr) : m_pT(pObj) { AddRef(); } @@ -53,19 +51,19 @@ public: } protected: - /** add one ref to the underlaying object */ + /** add one ref to the underlying object */ inline void AddRef() { - if (m_pT != NULL) m_pT->AddRef(); + if (m_pT != nullptr) m_pT->AddRef(); } public: /** release smart pointer (and decrement ref count) if not null */ inline void Release() { - if (m_pT != NULL) { + if (m_pT != nullptr) { Tcls *pT = m_pT; - m_pT = NULL; + m_pT = nullptr; pT->Release(); } } @@ -73,21 +71,21 @@ public: /** dereference of smart pointer - const way */ inline const Tcls *operator->() const { - assert(m_pT != NULL); + assert(m_pT != nullptr); return m_pT; } /** dereference of smart pointer - non const way */ inline Tcls *operator->() { - assert(m_pT != NULL); + assert(m_pT != nullptr); return m_pT; } /** raw pointer casting operator - const way */ inline operator const Tcls*() const { - assert(m_pT == NULL); + assert(m_pT == nullptr); return m_pT; } @@ -100,7 +98,7 @@ public: /** operator & to support output arguments */ inline Tcls** operator&() { - assert(m_pT == NULL); + assert(m_pT == nullptr); return &m_pT; } @@ -121,16 +119,16 @@ public: /** assignment operator helper */ inline void Assign(Tcls *pT); - /** one way how to test for NULL value */ + /** one way how to test for nullptr value */ inline bool IsNull() const { - return m_pT == NULL; + return m_pT == nullptr; } - /** another way how to test for NULL value */ + /** 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 NULL value */ + /** 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 */ @@ -144,7 +142,7 @@ public: inline Tcls *Detach() { Tcls *pT = m_pT; - m_pT = NULL; + m_pT = nullptr; return pT; } }; @@ -154,10 +152,10 @@ inline void CCountedPtr::Assign(Tcls *pT) { /* if they are the same, we do nothing */ if (pT != m_pT) { - if (pT != NULL) pT->AddRef(); // AddRef new pointer if any + if (pT != nullptr) pT->AddRef(); // AddRef new pointer if any Tcls *pTold = m_pT; // save original ptr m_pT = pT; // update m_pT to new value - if (pTold != NULL) pTold->Release(); // release old ptr if any + if (pTold != nullptr) pTold->Release(); // release old ptr if any } } diff --git a/src/misc/dbg_helpers.cpp b/src/misc/dbg_helpers.cpp index 22ccfa3464..7d38c7e65a 100644 --- a/src/misc/dbg_helpers.cpp +++ b/src/misc/dbg_helpers.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. diff --git a/src/misc/dbg_helpers.h b/src/misc/dbg_helpers.h index acc1437d09..7c9b4c876f 100644 --- a/src/misc/dbg_helpers.h +++ b/src/misc/dbg_helpers.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. @@ -155,8 +153,8 @@ struct DumpTarget { { static size_t type_id = ++LastTypeId(); - if (s == NULL) { - /* No need to dump NULL struct. */ + if (s == nullptr) { + /* No need to dump nullptr struct. */ WriteLine("%s = ", name); return; } diff --git a/src/misc/fixedsizearray.hpp b/src/misc/fixedsizearray.hpp index c694ff7a17..db6c7808b3 100644 --- a/src/misc/fixedsizearray.hpp +++ b/src/misc/fixedsizearray.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. @@ -94,7 +92,7 @@ public: Clear(); /* free the memory block occupied by items */ free(((byte*)data) - HeaderSize); - data = NULL; + data = nullptr; } /** Clear (destroy) all items */ diff --git a/src/misc/getoptdata.cpp b/src/misc/getoptdata.cpp index 7859594dd9..df54391232 100644 --- a/src/misc/getoptdata.cpp +++ b/src/misc/getoptdata.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. @@ -26,7 +24,7 @@ int GetOptData::GetOpt() const OptionData *odata; char *s = this->cont; - if (s == NULL) { + if (s == nullptr) { if (this->numleft == 0) return -1; // No arguments left -> finished. s = this->argv[0]; @@ -37,8 +35,8 @@ int GetOptData::GetOpt() /* Is it a long option? */ for (odata = this->options; odata->flags != ODF_END; odata++) { - if (odata->longname != NULL && !strcmp(odata->longname, s)) { // Long options always use the entire argument. - this->cont = NULL; + if (odata->longname != nullptr && !strcmp(odata->longname, s)) { // Long options always use the entire argument. + this->cont = nullptr; goto set_optval; } } @@ -49,19 +47,19 @@ int GetOptData::GetOpt() /* Is it a short option? */ for (odata = this->options; odata->flags != ODF_END; odata++) { if (odata->shortname != '\0' && *s == odata->shortname) { - this->cont = (s[1] != '\0') ? s + 1 : NULL; + this->cont = (s[1] != '\0') ? s + 1 : nullptr; set_optval: // Handle option value of *odata . - this->opt = NULL; + this->opt = nullptr; switch (odata->flags) { case ODF_NO_VALUE: return odata->id; case ODF_HAS_VALUE: case ODF_OPTIONAL_VALUE: - if (this->cont != NULL) { // Remainder of the argument is the option value. + if (this->cont != nullptr) { // Remainder of the argument is the option value. this->opt = this->cont; - this->cont = NULL; + this->cont = nullptr; return odata->id; } /* No more arguments, either return an error or a value-less option. */ diff --git a/src/misc/getoptdata.h b/src/misc/getoptdata.h index 4ce916aa1e..5b1b05d75d 100644 --- a/src/misc/getoptdata.h +++ b/src/misc/getoptdata.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. @@ -25,12 +23,12 @@ struct OptionData { byte id; ///< Unique identification of this option data, often the same as #shortname. char shortname; ///< Short option letter if available, else use \c '\0'. uint16 flags; ///< Option data flags. @see OptionDataFlags - const char *longname; ///< Long option name including '-'/'--' prefix, use \c NULL if not available. + const char *longname; ///< Long option name including '-'/'--' prefix, use \c nullptr if not available. }; /** Data storage for parsing command line options. */ struct GetOptData { - char *opt; ///< Option value, if available (else \c NULL). + char *opt; ///< Option value, if available (else \c nullptr). int numleft; ///< Number of arguments left in #argv. char **argv; ///< Remaining command line arguments. const OptionData *options; ///< Command line option descriptions. @@ -43,11 +41,11 @@ struct GetOptData { * @param options Command line option descriptions. */ GetOptData(int argc, char **argv, const OptionData *options) : - opt(NULL), + opt(nullptr), numleft(argc), argv(argv), options(options), - cont(NULL) + cont(nullptr) { } @@ -58,7 +56,7 @@ struct GetOptData { * General macro for creating an option. * @param id Identification of the option. * @param shortname Short option name. Use \c '\0' if not used. - * @param longname Long option name including leading '-' or '--'. Use \c NULL if not used. + * @param longname Long option name including leading '-' or '--'. Use \c nullptr if not used. * @param flags Flags of the option. */ #define GETOPT_GENERAL(id, shortname, longname, flags) { id, shortname, flags, longname } @@ -66,21 +64,21 @@ struct GetOptData { /** * Short option without value. * @param shortname Short option name. Use \c '\0' if not used. - * @param longname Long option name including leading '-' or '--'. Use \c NULL if not used. + * @param longname Long option name including leading '-' or '--'. Use \c nullptr if not used. */ #define GETOPT_NOVAL(shortname, longname) GETOPT_GENERAL(shortname, shortname, longname, ODF_NO_VALUE) /** * Short option with value. * @param shortname Short option name. Use \c '\0' if not used. - * @param longname Long option name including leading '-' or '--'. Use \c NULL if not used. + * @param longname Long option name including leading '-' or '--'. Use \c nullptr if not used. */ #define GETOPT_VALUE(shortname, longname) GETOPT_GENERAL(shortname, shortname, longname, ODF_HAS_VALUE) /** * Short option with optional value. * @param shortname Short option name. Use \c '\0' if not used. - * @param longname Long option name including leading '-' or '--'. Use \c NULL if not used. + * @param longname Long option name including leading '-' or '--'. Use \c nullptr if not used. * @note Options with optional values are hopelessly ambiguous, eg "-opt -value", avoid them. */ #define GETOPT_OPTVAL(shortname, longname) GETOPT_GENERAL(shortname, shortname, longname, ODF_OPTIONAL_VALUE) @@ -90,23 +88,23 @@ struct GetOptData { * Short option without value. * @param shortname Short option name. Use \c '\0' if not used. */ -#define GETOPT_SHORT_NOVAL(shortname) GETOPT_NOVAL(shortname, NULL) +#define GETOPT_SHORT_NOVAL(shortname) GETOPT_NOVAL(shortname, nullptr) /** * Short option with value. * @param shortname Short option name. Use \c '\0' if not used. */ -#define GETOPT_SHORT_VALUE(shortname) GETOPT_VALUE(shortname, NULL) +#define GETOPT_SHORT_VALUE(shortname) GETOPT_VALUE(shortname, nullptr) /** * Short option with optional value. * @param shortname Short option name. Use \c '\0' if not used. * @note Options with optional values are hopelessly ambiguous, eg "-opt -value", avoid them. */ -#define GETOPT_SHORT_OPTVAL(shortname) GETOPT_OPTVAL(shortname, NULL) +#define GETOPT_SHORT_OPTVAL(shortname) GETOPT_OPTVAL(shortname, nullptr) /** Option terminator. */ -#define GETOPT_END() { '\0', '\0', ODF_END, NULL} +#define GETOPT_END() { '\0', '\0', ODF_END, nullptr} #endif /* GETOPTDATA_H */ diff --git a/src/misc/hashtable.hpp b/src/misc/hashtable.hpp index 1078f1861d..ee6b88234a 100644 --- a/src/misc/hashtable.hpp +++ b/src/misc/hashtable.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. @@ -21,42 +19,42 @@ struct CHashTableSlotT Titem_ *m_pFirst; - inline CHashTableSlotT() : m_pFirst(NULL) {} + inline CHashTableSlotT() : m_pFirst(nullptr) {} /** hash table slot helper - clears the slot by simple forgetting its items */ inline void Clear() { - m_pFirst = NULL; + m_pFirst = nullptr; } /** hash table slot helper - linear search for item with given key through the given blob - const version */ inline const Titem_ *Find(const Key &key) const { - for (const Titem_ *pItem = m_pFirst; pItem != NULL; pItem = pItem->GetHashNext()) { + for (const Titem_ *pItem = m_pFirst; pItem != nullptr; pItem = pItem->GetHashNext()) { if (pItem->GetKey() == key) { /* we have found the item, return it */ return pItem; } } - return NULL; + return nullptr; } /** hash table slot helper - linear search for item with given key through the given blob - non-const version */ inline Titem_ *Find(const Key &key) { - for (Titem_ *pItem = m_pFirst; pItem != NULL; pItem = pItem->GetHashNext()) { + for (Titem_ *pItem = m_pFirst; pItem != nullptr; pItem = pItem->GetHashNext()) { if (pItem->GetKey() == key) { /* we have found the item, return it */ return pItem; } } - return NULL; + return nullptr; } /** hash table slot helper - add new item to the slot */ inline void Attach(Titem_ &new_item) { - assert(new_item.GetHashNext() == NULL); + assert(new_item.GetHashNext() == nullptr); new_item.SetHashNext(m_pFirst); m_pFirst = &new_item; } @@ -66,12 +64,12 @@ struct CHashTableSlotT { if (m_pFirst == &item_to_remove) { m_pFirst = item_to_remove.GetHashNext(); - item_to_remove.SetHashNext(NULL); + item_to_remove.SetHashNext(nullptr); return true; } Titem_ *pItem = m_pFirst; for (;;) { - if (pItem == NULL) { + if (pItem == nullptr) { return false; } Titem_ *pNextItem = pItem->GetHashNext(); @@ -79,7 +77,7 @@ struct CHashTableSlotT pItem = pNextItem; } pItem->SetHashNext(item_to_remove.GetHashNext()); - item_to_remove.SetHashNext(NULL); + item_to_remove.SetHashNext(nullptr); return true; } @@ -87,27 +85,27 @@ struct CHashTableSlotT inline Titem_ *Detach(const Key &key) { /* do we have any items? */ - if (m_pFirst == NULL) { - return NULL; + if (m_pFirst == nullptr) { + return nullptr; } /* is it our first item? */ if (m_pFirst->GetKey() == key) { Titem_ &ret_item = *m_pFirst; m_pFirst = m_pFirst->GetHashNext(); - ret_item.SetHashNext(NULL); + ret_item.SetHashNext(nullptr); return &ret_item; } /* find it in the following items */ Titem_ *pPrev = m_pFirst; - for (Titem_ *pItem = m_pFirst->GetHashNext(); pItem != NULL; pPrev = pItem, pItem = pItem->GetHashNext()) { + for (Titem_ *pItem = m_pFirst->GetHashNext(); pItem != nullptr; pPrev = pItem, pItem = pItem->GetHashNext()) { if (pItem->GetKey() == key) { /* we have found the item, unlink and return it */ pPrev->SetHashNext(pItem->GetHashNext()); - pItem->SetHashNext(NULL); + pItem->SetHashNext(nullptr); return pItem; } } - return NULL; + return nullptr; } }; @@ -211,7 +209,7 @@ public: int hash = CalcHash(key); Slot &slot = m_slots[hash]; Titem_ *item = slot.Detach(key); - if (item != NULL) { + if (item != nullptr) { m_num_items--; } return item; @@ -221,7 +219,7 @@ public: Titem_& Pop(const Tkey &key) { Titem_ *item = TryPop(key); - assert(item != NULL); + assert(item != nullptr); return *item; } @@ -250,7 +248,7 @@ public: { int hash = CalcHash(new_item); Slot &slot = m_slots[hash]; - assert(slot.Find(new_item.GetKey()) == NULL); + assert(slot.Find(new_item.GetKey()) == nullptr); slot.Attach(new_item); m_num_items++; } diff --git a/src/misc/str.hpp b/src/misc/str.hpp index 1d9802288c..e93ce5efc3 100644 --- a/src/misc/str.hpp +++ b/src/misc/str.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. @@ -7,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 str.hpp String formating? */ +/** @file str.hpp String formatting? */ #ifndef STR_HPP #define STR_HPP @@ -91,7 +89,7 @@ struct CStrA : public CBlobT return strcmp(base::Data(), other.Data()) < 0; } - /** Add formated string (like vsprintf) at the end of existing contents. */ + /** Add formatted string (like vsprintf) at the end of existing contents. */ int AddFormatL(const char *format, va_list args) { size_t addSize = max(strlen(format), 16); @@ -126,7 +124,7 @@ struct CStrA : public CBlobT return ret; } - /** Add formated string (like sprintf) at the end of existing contents. */ + /** Add formatted string (like sprintf) at the end of existing contents. */ int CDECL WARN_FORMAT(2, 3) AddFormat(const char *format, ...) { va_list args; @@ -136,7 +134,7 @@ struct CStrA : public CBlobT return ret; } - /** Assign formated string (like sprintf). */ + /** Assign formatted string (like sprintf). */ int CDECL WARN_FORMAT(2, 3) Format(const char *format, ...) { base::Free(); diff --git a/src/misc_cmd.cpp b/src/misc_cmd.cpp index e7da13c7aa..63dfb15253 100644 --- a/src/misc_cmd.cpp +++ b/src/misc_cmd.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. @@ -154,12 +152,10 @@ CommandCost CmdPause(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, case PM_PAUSED_GAME_SCRIPT: break; -#ifdef ENABLE_NETWORK case PM_PAUSED_JOIN: case PM_PAUSED_ACTIVE_CLIENTS: if (!_networking) return CMD_ERROR; break; -#endif /* ENABLE_NETWORK */ default: return CMD_ERROR; } @@ -168,23 +164,19 @@ CommandCost CmdPause(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, ShowQuery( STR_NEWGRF_UNPAUSE_WARNING_TITLE, STR_NEWGRF_UNPAUSE_WARNING, - NULL, + nullptr, AskUnsafeUnpauseCallback ); } else { -#ifdef ENABLE_NETWORK PauseMode prev_mode = _pause_mode; -#endif /* ENABLE_NETWORK */ if (p2 == 0) { - _pause_mode = _pause_mode & ~p1; + _pause_mode = static_cast(_pause_mode & (byte)~p1); } else { - _pause_mode = _pause_mode | p1; + _pause_mode = static_cast(_pause_mode | (byte)p1); } -#ifdef ENABLE_NETWORK NetworkHandlePauseChange(prev_mode, (PauseMode)p1); -#endif /* ENABLE_NETWORK */ } SetWindowDirty(WC_STATUS_BAR, 0); @@ -229,12 +221,12 @@ CommandCost CmdChangeBankBalance(TileIndex tile, DoCommandFlag flags, uint32 p1, if (flags & DC_EXEC) { /* Change company bank balance of company. */ - Backup cur_company(_current_company, company, FILE_LINE); + Backup cur_company(_current_company, company, FILE_LINE); SubtractMoneyFromCompany(CommandCost(expenses_type, -delta)); cur_company.Restore(); } - /* This command doesn't cost anyting for deity. */ + /* This command doesn't cost anything for deity. */ CommandCost zero_cost(expenses_type, 0); return zero_cost; } @@ -265,7 +257,7 @@ CommandCost CmdGiveMoney(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 if (flags & DC_EXEC) { /* Add money to company */ - Backup cur_company(_current_company, dest_company, FILE_LINE); + Backup cur_company(_current_company, dest_company, FILE_LINE); SubtractMoneyFromCompany(CommandCost(EXPENSES_OTHER, -amount.GetCost())); cur_company.Restore(); } diff --git a/src/misc_gui.cpp b/src/misc_gui.cpp index 6403e08681..e707ebaf5d 100644 --- a/src/misc_gui.cpp +++ b/src/misc_gui.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. @@ -79,7 +77,7 @@ public: char landinfo_data[LAND_INFO_LINE_END][LAND_INFO_LINE_BUFF_SIZE]; TileIndex tile; - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { if (widget != WID_LI_BACKGROUND) return; @@ -98,7 +96,7 @@ public: } } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { if (widget != WID_LI_BACKGROUND) return; @@ -144,7 +142,7 @@ public: #undef LANDINFOD_LEVEL } - virtual void OnInit() + void OnInit() override { Town *t = ClosestTownFromTile(tile, _settings_game.economy.dist_local_authority); @@ -173,12 +171,15 @@ public: td.airport_tile_name = STR_NULL; td.railtype = STR_NULL; td.rail_speed = 0; + td.roadtype = STR_NULL; td.road_speed = 0; + td.tramtype = STR_NULL; + td.tram_speed = 0; - td.grf = NULL; + td.grf = nullptr; CargoArray acceptance; - AddAcceptedCargo(tile, acceptance, NULL); + AddAcceptedCargo(tile, acceptance, nullptr); GetTileDesc(tile, &td); uint line_nr = 0; @@ -201,7 +202,7 @@ public: /* Cost to clear/revenue when cleared */ StringID str = STR_LAND_AREA_INFORMATION_COST_TO_CLEAR_N_A; Company *c = Company::GetIfValid(_local_company); - if (c != NULL) { + if (c != nullptr) { assert(_current_company == _local_company); CommandCost costclear = DoCommand(tile, 0, 0, DC_QUERY_COST, CMD_LANDSCAPE_CLEAR); if (costclear.Succeeded()) { @@ -230,7 +231,7 @@ public: /* Local authority */ SetDParam(0, STR_LAND_AREA_INFORMATION_LOCAL_AUTHORITY_NONE); - if (t != NULL) { + if (t != nullptr) { SetDParam(0, STR_TOWN_NAME); SetDParam(1, t->index); } @@ -293,6 +294,13 @@ public: line_nr++; } + /* Road type name */ + if (td.roadtype != STR_NULL) { + SetDParam(0, td.roadtype); + GetString(this->landinfo_data[line_nr], STR_LANG_AREA_INFORMATION_ROAD_TYPE, lastof(this->landinfo_data[line_nr])); + line_nr++; + } + /* Road speed limit */ if (td.road_speed != 0) { SetDParam(0, td.road_speed); @@ -300,8 +308,22 @@ public: line_nr++; } + /* Tram type name */ + if (td.tramtype != STR_NULL) { + SetDParam(0, td.tramtype); + GetString(this->landinfo_data[line_nr], STR_LANG_AREA_INFORMATION_TRAM_TYPE, lastof(this->landinfo_data[line_nr])); + line_nr++; + } + + /* Tram speed limit */ + if (td.tram_speed != 0) { + SetDParam(0, td.tram_speed); + GetString(this->landinfo_data[line_nr], STR_LANG_AREA_INFORMATION_TRAM_SPEED_LIMIT, lastof(this->landinfo_data[line_nr])); + line_nr++; + } + /* NewGRF name */ - if (td.grf != NULL) { + if (td.grf != nullptr) { SetDParamStr(0, td.grf); GetString(this->landinfo_data[line_nr], STR_LAND_AREA_INFORMATION_NEWGRF_NAME, lastof(this->landinfo_data[line_nr])); line_nr++; @@ -335,12 +357,12 @@ public: if (!found) this->landinfo_data[LAND_INFO_MULTICENTER_LINE][0] = '\0'; } - virtual bool IsNewGRFInspectable() const + bool IsNewGRFInspectable() const override { return ::IsNewGRFInspectable(GetGrfSpecFeature(this->tile), this->tile); } - virtual void ShowNewGRFInspectWindow() const + void ShowNewGRFInspectWindow() const override { ::ShowNewGRFInspectWindow(GetGrfSpecFeature(this->tile), this->tile); } @@ -350,7 +372,7 @@ public: * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; switch (data) { @@ -389,7 +411,7 @@ static const NWidgetPart _nested_about_widgets[] = { }; static WindowDesc _about_desc( - WDP_CENTER, NULL, 0, 0, + WDP_CENTER, nullptr, 0, 0, WC_GAME_OPTIONS, WC_NONE, 0, _nested_about_widgets, lengthof(_nested_about_widgets) @@ -406,6 +428,7 @@ static const char * const _credits[] = { " Ulf Hermann (fonsinchen) - Cargo Distribution (since 1.3)", " Christoph Elsenhans (frosch) - General coding (since 0.6)", " Lo\xC3\xAF""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)", " Niels Martin Hansen (nielsm) - Music system, general coding (since 1.9)", " Owen Rudge (orudge) - Forum host, OS/2 port (since 0.1)", @@ -476,12 +499,12 @@ struct AboutWindow : public Window { this->timer.SetInterval(TIMER_INTERVAL); } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { if (widget == WID_A_WEBSITE) SetDParamStr(0, "Website: http://www.openttd.org"); } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { if (widget != WID_A_SCROLLING_TEXT) return; @@ -497,7 +520,7 @@ struct AboutWindow : public Window { *size = maxdim(*size, d); } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { if (widget != WID_A_SCROLLING_TEXT) return; @@ -512,7 +535,7 @@ struct AboutWindow : public Window { } } - virtual void OnRealtimeTick(uint delta_ms) + void OnRealtimeTick(uint delta_ms) override { uint count = this->timer.CountElapsed(delta_ms); if (count > 0) { @@ -649,7 +672,7 @@ static const NWidgetPart _nested_tooltips_widgets[] = { }; static WindowDesc _tool_tips_desc( - WDP_MANUAL, NULL, 0, 0, // Coordinates and sizes are not used, + WDP_MANUAL, nullptr, 0, 0, // Coordinates and sizes are not used, WC_TOOLTIPS, WC_NONE, WDF_NO_FOCUS, _nested_tooltips_widgets, lengthof(_nested_tooltips_widgets) @@ -678,7 +701,7 @@ struct TooltipsWindow : public Window CLRBITS(this->flags, WF_WHITE_BORDER); } - virtual Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number) + Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number) override { /* Find the free screen space between the main toolbar at the top, and the statusbar at the bottom. * Add a fixed distance 2 so the tooltip floats free from both bars. @@ -706,7 +729,7 @@ struct TooltipsWindow : public Window return pt; } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { /* There is only one widget. */ for (uint i = 0; i != this->paramcount; i++) SetDParam(i, this->params[i]); @@ -719,7 +742,7 @@ struct TooltipsWindow : public Window size->height += 2 + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; } - virtual void DrawWidget(const Rect &r, int widget) const + 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); @@ -731,7 +754,7 @@ struct TooltipsWindow : public Window 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); } - virtual void OnMouseLoop() + void OnMouseLoop() override { /* Always close tooltips when the cursor is not in our window. */ if (!_cursor.in_window) { @@ -908,7 +931,7 @@ Rect QueryString::GetBoundingRect(const Window *w, int wid, const char *from, co * @param w Window the edit box is in. * @param wid Widget index. * @param pt Position to test. - * @return Pointer to the character at the position or NULL if no character is at the position. + * @return Pointer to the character at the position or nullptr if no character is at the position. */ const char *QueryString::GetCharAtPosition(const Window *w, int wid, const Point &pt) const { @@ -926,7 +949,7 @@ const char *QueryString::GetCharAtPosition(const Window *w, int wid, const Point int top = wi->pos_y + WD_FRAMERECT_TOP; int bottom = wi->pos_y + wi->current_y - 1 - WD_FRAMERECT_BOTTOM; - if (!IsInsideMM(pt.y, top, bottom)) return NULL; + if (!IsInsideMM(pt.y, top, bottom)) return nullptr; /* Clamp caret position to be inside our current width. */ const Textbuf *tb = &this->text; @@ -974,6 +997,7 @@ struct QueryStringWindow : public Window { QueryString editbox; ///< Editbox. QueryStringFlags flags; ///< Flags controlling behaviour of the window. + Dimension warning_size; ///< How much space to use for the warning text QueryStringWindow(StringID str, StringID caption, uint max_bytes, uint max_chars, WindowDesc *desc, Window *parent, CharSetFilter afilter, QueryStringFlags flags) : Window(desc), editbox(max_bytes, max_chars) @@ -1000,13 +1024,28 @@ struct QueryStringWindow : public Window this->flags = flags; this->InitNested(WN_QUERY_STRING); + this->UpdateWarningStringSize(); this->parent = parent; this->SetFocusedWidget(WID_QS_TEXT); } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWarningStringSize() + { + 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.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; + } else { + this->warning_size = Dimension{ 0, 0 }; + } + + this->ReInit(); + } + + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { if (widget == WID_QS_DEFAULT && (this->flags & QSF_ENABLE_DEFAULT) == 0) { /* We don't want this widget to show! */ @@ -1014,19 +1053,34 @@ struct QueryStringWindow : public Window resize->width = 0; size->width = 0; } + + if (widget == WID_QS_WARNING) { + *size = this->warning_size; + } } - virtual void SetStringParameters(int widget) const + void DrawWidget(const Rect &r, int widget) const override + { + 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, + STR_WARNING_PASSWORD_SECURITY, TC_FROMSTRING, SA_CENTER); + } + } + + void SetStringParameters(int widget) const override { if (widget == WID_QS_CAPTION) SetDParam(0, this->editbox.caption); } void OnOk() { - if (this->editbox.orig == NULL || strcmp(this->editbox.text.buf, this->editbox.orig) != 0) { - /* If the parent is NULL, the editbox is handled by general function + if (this->editbox.orig == nullptr || strcmp(this->editbox.text.buf, this->editbox.orig) != 0) { + /* If the parent is nullptr, the editbox is handled by general function * HandleOnEditText */ - if (this->parent != NULL) { + if (this->parent != nullptr) { this->parent->OnQueryTextFinished(this->editbox.text.buf); } else { HandleOnEditText(this->editbox.text.buf); @@ -1035,7 +1089,7 @@ struct QueryStringWindow : public Window } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_QS_DEFAULT: @@ -1054,10 +1108,10 @@ struct QueryStringWindow : public Window ~QueryStringWindow() { - if (!this->editbox.handled && this->parent != NULL) { + if (!this->editbox.handled && this->parent != nullptr) { Window *parent = this->parent; - this->parent = NULL; // so parent doesn't try to delete us again - parent->OnQueryTextFinished(NULL); + this->parent = nullptr; // so parent doesn't try to delete us again + parent->OnQueryTextFinished(nullptr); } } }; @@ -1070,6 +1124,7 @@ static const NWidgetPart _nested_query_string_widgets[] = { NWidget(WWT_PANEL, COLOUR_GREY), NWidget(WWT_EDITBOX, COLOUR_GREY, WID_QS_TEXT), SetMinimalSize(256, 12), SetFill(1, 1), SetPadding(2, 2, 2, 2), EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY, WID_QS_WARNING), EndContainer(), NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_QS_DEFAULT), SetMinimalSize(87, 12), SetFill(1, 1), SetDataTip(STR_BUTTON_DEFAULT, STR_NULL), NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_QS_CANCEL), SetMinimalSize(86, 12), SetFill(1, 1), SetDataTip(STR_BUTTON_CANCEL, STR_NULL), @@ -1090,7 +1145,7 @@ static WindowDesc _query_string_desc( * @param caption StringID of text shown in caption of querywindow * @param maxsize maximum size in bytes or characters (including terminating '\0') depending on flags * @param parent pointer to a Window that will handle the events (ok/cancel) of this - * window. If NULL, results are handled by global function HandleOnEditText + * window. If nullptr, results are handled by global function HandleOnEditText * @param afilter filters out unwanted character input * @param flags various flags, @see QueryStringFlags */ @@ -1127,10 +1182,10 @@ struct QueryWindow : public Window { ~QueryWindow() { - if (this->proc != NULL) this->proc(this->parent, false); + if (this->proc != nullptr) this->proc(this->parent, false); } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { switch (widget) { case WID_Q_CAPTION: @@ -1144,7 +1199,7 @@ struct QueryWindow : public Window { } } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { if (widget != WID_Q_TEXT) return; @@ -1155,7 +1210,7 @@ struct QueryWindow : public Window { *size = d; } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { if (widget != WID_Q_TEXT) return; @@ -1163,7 +1218,7 @@ struct QueryWindow : public Window { this->message, TC_FROMSTRING, SA_CENTER); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_Q_YES: { @@ -1172,11 +1227,11 @@ struct QueryWindow : public Window { QueryCallbackProc *proc = this->proc; Window *parent = this->parent; /* Prevent the destructor calling the callback function */ - this->proc = NULL; + this->proc = nullptr; delete this; - if (proc != NULL) { + if (proc != nullptr) { proc(parent, true); - proc = NULL; + proc = nullptr; } break; } @@ -1186,15 +1241,15 @@ struct QueryWindow : public Window { } } - virtual EventState OnKeyPress(WChar key, uint16 keycode) + EventState OnKeyPress(WChar key, uint16 keycode) override { /* ESC closes the window, Enter confirms the action */ switch (keycode) { case WKC_RETURN: case WKC_NUM_ENTER: - if (this->proc != NULL) { + if (this->proc != nullptr) { this->proc(this->parent, true); - this->proc = NULL; + this->proc = nullptr; } FALLTHROUGH; @@ -1221,7 +1276,7 @@ static const NWidgetPart _nested_query_widgets[] = { }; static WindowDesc _query_desc( - WDP_CENTER, NULL, 0, 0, + WDP_CENTER, nullptr, 0, 0, WC_CONFIRM_POPUP_QUERY, WC_NONE, WDF_MODAL, _nested_query_widgets, lengthof(_nested_query_widgets) @@ -1232,13 +1287,13 @@ static WindowDesc _query_desc( * The window is aligned to the centre of its parent. * @param caption string shown as window caption * @param message string that will be shown for the window - * @param parent pointer to parent window, if this pointer is NULL the parent becomes + * @param parent pointer to parent window, if this pointer is nullptr the parent becomes * the main window WC_MAIN_WINDOW * @param callback callback function pointer to set in the window descriptor */ void ShowQuery(StringID caption, StringID message, Window *parent, QueryCallbackProc *callback) { - if (parent == NULL) parent = FindWindowById(WC_MAIN_WINDOW, 0); + if (parent == nullptr) parent = FindWindowById(WC_MAIN_WINDOW, 0); const Window *w; FOR_ALL_WINDOWS_FROM_BACK(w) { diff --git a/src/mixer.cpp b/src/mixer.cpp index 6014f6082e..90e3951cb0 100644 --- a/src/mixer.cpp +++ b/src/mixer.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. @@ -39,7 +37,7 @@ struct MixerChannel { static MixerChannel _channels[8]; static uint32 _play_rate = 11025; static uint32 _max_size = UINT_MAX; -static MxStreamCallback _music_stream = NULL; +static MxStreamCallback _music_stream = nullptr; /** * The theoretical maximum volume for a single sound sample. Multiple sound @@ -175,11 +173,11 @@ MixerChannel *MxAllocateChannel() for (mc = _channels; mc != endof(_channels); mc++) { if (!mc->active) { free(mc->memory); - mc->memory = NULL; + mc->memory = nullptr; return mc; } } - return NULL; + return nullptr; } void MxSetChannelRawSrc(MixerChannel *mc, int8 *mem, size_t size, uint rate, bool is16bit) @@ -238,6 +236,6 @@ bool MxInitialize(uint rate) { _play_rate = rate; _max_size = UINT_MAX / _play_rate; - _music_stream = NULL; /* rate may have changed, any music source is now invalid */ + _music_stream = nullptr; /* rate may have changed, any music source is now invalid */ return true; } diff --git a/src/mixer.h b/src/mixer.h index 9766682d6b..bd7b18a44a 100644 --- a/src/mixer.h +++ b/src/mixer.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/music.cpp b/src/music.cpp index 3d0e40bf9b..a95a9d348d 100644 --- a/src/music.cpp +++ b/src/music.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. @@ -25,11 +23,11 @@ * @param filename Name of CAT file to read from * @param entrynum Index of entry whose name to read * @return Pointer to string, caller is responsible for freeing memory, - * NULL if entrynum does not exist. + * nullptr if entrynum does not exist. */ char *GetMusicCatEntryName(const char *filename, size_t entrynum) { - if (!FioCheckFileExists(filename, BASESET_DIR)) return NULL; + if (!FioCheckFileExists(filename, BASESET_DIR)) return nullptr; FioOpenFile(CONFIG_SLOT, filename, BASESET_DIR); uint32 ofs = FioReadDword(); @@ -43,7 +41,7 @@ char *GetMusicCatEntryName(const char *filename, size_t entrynum) name[namelen] = '\0'; return name; } - return NULL; + return nullptr; } /** @@ -52,12 +50,12 @@ char *GetMusicCatEntryName(const char *filename, size_t entrynum) * @param entrynum Index of entry to read * @param[out] entrylen Receives length of data read * @return Pointer to buffer with data read, caller is responsible for freeind memory, - * NULL if entrynum does not exist. + * nullptr if entrynum does not exist. */ byte *GetMusicCatEntryData(const char *filename, size_t entrynum, size_t &entrylen) { entrylen = 0; - if (!FioCheckFileExists(filename, BASESET_DIR)) return NULL; + if (!FioCheckFileExists(filename, BASESET_DIR)) return nullptr; FioOpenFile(CONFIG_SLOT, filename, BASESET_DIR); uint32 ofs = FioReadDword(); @@ -72,7 +70,7 @@ byte *GetMusicCatEntryData(const char *filename, size_t entrynum, size_t &entryl FioReadBlock(data, entrylen); return data; } - return NULL; + return nullptr; } INSTANTIATE_BASE_MEDIA_METHODS(BaseMedia, MusicSet) @@ -99,13 +97,13 @@ template template /* static */ bool BaseMedia::DetermineBestSet() { - if (BaseMedia::used_set != NULL) return true; + if (BaseMedia::used_set != nullptr) return true; - const Tbase_set *best = NULL; - for (const Tbase_set *c = BaseMedia::available_sets; c != NULL; c = c->next) { + const Tbase_set *best = nullptr; + for (const Tbase_set *c = BaseMedia::available_sets; c != nullptr; c = c->next) { if (c->GetNumMissing() != 0) continue; - if (best == NULL || + if (best == nullptr || (best->fallback && !c->fallback) || best->valid_files < c->valid_files || (best->valid_files == c->valid_files && @@ -115,7 +113,7 @@ template } BaseMedia::used_set = best; - return BaseMedia::used_set != NULL; + return BaseMedia::used_set != nullptr; } bool MusicSet::FillSetDetails(IniFile *ini, const char *path, const char *full_filename) @@ -129,7 +127,7 @@ bool MusicSet::FillSetDetails(IniFile *ini, const char *path, const char *full_f uint tracknr = 1; for (uint i = 0; i < lengthof(this->songinfo); i++) { const char *filename = this->files[i].filename; - if (names == NULL || StrEmpty(filename) || this->files[i].check_result == MD5File::CR_NO_FILE) { + if (names == nullptr || StrEmpty(filename) || this->files[i].check_result == MD5File::CR_NO_FILE) { this->songinfo[i].songname[0] = '\0'; continue; } @@ -137,12 +135,12 @@ bool MusicSet::FillSetDetails(IniFile *ini, const char *path, const char *full_f this->songinfo[i].filename = filename; // non-owned pointer IniItem *item = catindex->GetItem(_music_file_names[i], false); - if (item != NULL && !StrEmpty(item->value)) { + if (item != nullptr && !StrEmpty(item->value)) { /* Song has a CAT file index, assume it's MPS MIDI format */ this->songinfo[i].filetype = MTT_MPSMIDI; this->songinfo[i].cat_index = atoi(item->value); char *songname = GetMusicCatEntryName(filename, this->songinfo[i].cat_index); - if (songname == NULL) { + if (songname == nullptr) { DEBUG(grf, 0, "Base music set song missing from CAT file: %s/%d", filename, this->songinfo[i].cat_index); this->songinfo[i].songname[0] = '\0'; continue; @@ -157,17 +155,17 @@ bool MusicSet::FillSetDetails(IniFile *ini, const char *path, const char *full_f /* As we possibly add a path to the filename and we compare * on the filename with the path as in the .obm, we need to * keep stripping path elements until we find a match. */ - for (; trimmed_filename != NULL; trimmed_filename = strchr(trimmed_filename, PATHSEPCHAR)) { + for (; trimmed_filename != nullptr; trimmed_filename = strchr(trimmed_filename, PATHSEPCHAR)) { /* Remove possible double path separator characters from * the beginning, so we don't start reading e.g. root. */ while (*trimmed_filename == PATHSEPCHAR) trimmed_filename++; item = names->GetItem(trimmed_filename, false); - if (item != NULL && !StrEmpty(item->value)) break; + if (item != nullptr && !StrEmpty(item->value)) break; } if (this->songinfo[i].filetype == MTT_STANDARDMIDI) { - if (item != NULL && !StrEmpty(item->value)) { + if (item != nullptr && !StrEmpty(item->value)) { strecpy(this->songinfo[i].songname, item->value, lastof(this->songinfo[i].songname)); } else { DEBUG(grf, 0, "Base music set song name missing: %s", filename); @@ -184,9 +182,9 @@ bool MusicSet::FillSetDetails(IniFile *ini, const char *path, const char *full_f } item = timingtrim->GetItem(trimmed_filename, false); - if (item != NULL && !StrEmpty(item->value)) { + if (item != nullptr && !StrEmpty(item->value)) { const char *endpos = strchr(item->value, ':'); - if (endpos != NULL) { + if (endpos != nullptr) { this->songinfo[i].override_start = atoi(item->value); this->songinfo[i].override_end = atoi(endpos + 1); } diff --git a/src/music/allegro_m.cpp b/src/music/allegro_m.cpp index 906aec84fc..4f90bce061 100644 --- a/src/music/allegro_m.cpp +++ b/src/music/allegro_m.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. @@ -20,7 +18,7 @@ #include "../safeguards.h" static FMusicDriver_Allegro iFMusicDriver_Allegro; -static MIDI *_midi = NULL; +static MIDI *_midi = nullptr; /** * There are multiple modules that might be using Allegro and @@ -30,14 +28,14 @@ extern int _allegro_instance_count; const char *MusicDriver_Allegro::Start(const char * const *param) { - if (_allegro_instance_count == 0 && install_allegro(SYSTEM_AUTODETECT, &errno, NULL)) { + if (_allegro_instance_count == 0 && install_allegro(SYSTEM_AUTODETECT, &errno, nullptr)) { DEBUG(driver, 0, "allegro: install_allegro failed '%s'", allegro_error); return "Failed to set up Allegro"; } _allegro_instance_count++; /* Initialise the sound */ - if (install_sound(DIGI_AUTODETECT, MIDI_AUTODETECT, NULL) != 0) { + if (install_sound(DIGI_AUTODETECT, MIDI_AUTODETECT, nullptr) != 0) { DEBUG(driver, 0, "allegro: install_sound failed '%s'", allegro_error); return "Failed to set up Allegro sound"; } @@ -48,13 +46,13 @@ const char *MusicDriver_Allegro::Start(const char * const *param) return "No sound card found"; } - return NULL; + return nullptr; } void MusicDriver_Allegro::Stop() { - if (_midi != NULL) destroy_midi(_midi); - _midi = NULL; + if (_midi != nullptr) destroy_midi(_midi); + _midi = nullptr; if (--_allegro_instance_count == 0) allegro_exit(); } @@ -63,12 +61,12 @@ void MusicDriver_Allegro::PlaySong(const MusicSongInfo &song) { std::string filename = MidiFile::GetSMFFile(song); - if (_midi != NULL) destroy_midi(_midi); + if (_midi != nullptr) destroy_midi(_midi); if (!filename.empty()) { _midi = load_midi(filename.c_str()); play_midi(_midi, false); } else { - _midi = NULL; + _midi = nullptr; } } diff --git a/src/music/allegro_m.h b/src/music/allegro_m.h index 65d8ab811d..1965626ca2 100644 --- a/src/music/allegro_m.h +++ b/src/music/allegro_m.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. @@ -17,18 +15,18 @@ /** Allegro's music player. */ class MusicDriver_Allegro : public MusicDriver { public: - /* virtual */ const char *Start(const char * const *param); + const char *Start(const char * const *param) override; - /* virtual */ void Stop(); + void Stop() override; - /* virtual */ void PlaySong(const MusicSongInfo &song); + void PlaySong(const MusicSongInfo &song) override; - /* virtual */ void StopSong(); + void StopSong() override; - /* virtual */ bool IsSongPlaying(); + bool IsSongPlaying() override; - /* virtual */ void SetVolume(byte vol); - /* virtual */ const char *GetName() const { return "allegro"; } + void SetVolume(byte vol) override; + const char *GetName() const override { return "allegro"; } }; /** Factory for allegro's music player. */ @@ -43,7 +41,7 @@ public: static const int PRIORITY = 2; #endif FMusicDriver_Allegro() : DriverFactoryBase(Driver::DT_MUSIC, PRIORITY, "allegro", "Allegro MIDI Driver") {} - /* virtual */ Driver *CreateInstance() const { return new MusicDriver_Allegro(); } + Driver *CreateInstance() const override { return new MusicDriver_Allegro(); } }; #endif /* MUSIC_ALLEGRO_H */ diff --git a/src/music/bemidi.cpp b/src/music/bemidi.cpp index ff56d787f1..c3ea152dae 100644 --- a/src/music/bemidi.cpp +++ b/src/music/bemidi.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. @@ -28,7 +26,7 @@ static FMusicDriver_BeMidi iFMusicDriver_BeMidi; const char *MusicDriver_BeMidi::Start(const char * const *parm) { - return NULL; + return nullptr; } void MusicDriver_BeMidi::Stop() diff --git a/src/music/bemidi.h b/src/music/bemidi.h index 7c546525d2..a524069db0 100644 --- a/src/music/bemidi.h +++ b/src/music/bemidi.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. @@ -17,25 +15,25 @@ /** The midi player for BeOS. */ class MusicDriver_BeMidi : public MusicDriver { public: - /* virtual */ const char *Start(const char * const *param); + const char *Start(const char * const *param) override; - /* virtual */ void Stop(); + void Stop() override; - /* virtual */ void PlaySong(const MusicSongInfo &song); + void PlaySong(const MusicSongInfo &song) override; - /* virtual */ void StopSong(); + void StopSong() override; - /* virtual */ bool IsSongPlaying(); + bool IsSongPlaying() override; - /* virtual */ void SetVolume(byte vol); - /* virtual */ const char *GetName() const { return "bemidi"; } + void SetVolume(byte vol) override; + const char *GetName() const override { return "bemidi"; } }; /** Factory for the BeOS midi player. */ class FMusicDriver_BeMidi : public DriverFactoryBase { public: FMusicDriver_BeMidi() : DriverFactoryBase(Driver::DT_MUSIC, 10, "bemidi", "BeOS MIDI Driver") {} - /* virtual */ Driver *CreateInstance() const { return new MusicDriver_BeMidi(); } + Driver *CreateInstance() const override { return new MusicDriver_BeMidi(); } }; #endif /* MUSIC_BEMIDI_H */ diff --git a/src/music/cocoa_m.cpp b/src/music/cocoa_m.cpp index 2416cade0f..f9b8969fdf 100644 --- a/src/music/cocoa_m.cpp +++ b/src/music/cocoa_m.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. @@ -35,8 +33,8 @@ static FMusicDriver_Cocoa iFMusicDriver_Cocoa; -static MusicPlayer _player = NULL; -static MusicSequence _sequence = NULL; +static MusicPlayer _player = nullptr; +static MusicSequence _sequence = nullptr; static MusicTimeStamp _seq_length = 0; static bool _playing = false; static byte _volume = 127; @@ -45,12 +43,12 @@ static byte _volume = 127; /** Set the volume of the current sequence. */ static void DoSetVolume() { - if (_sequence == NULL) return; + if (_sequence == nullptr) return; AUGraph graph; MusicSequenceGetAUGraph(_sequence, &graph); - AudioUnit output_unit = NULL; + AudioUnit output_unit = nullptr; /* Get output audio unit */ UInt32 node_count = 0; @@ -82,7 +80,7 @@ static void DoSetVolume() { #if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) ComponentDescription desc; - AUGraphGetNodeInfo(graph, node, &desc, NULL, NULL, &unit); + AUGraphGetNodeInfo(graph, node, &desc, nullptr, nullptr, &unit); comp_type = desc.componentType; #endif } @@ -92,7 +90,7 @@ static void DoSetVolume() break; } } - if (output_unit == NULL) { + if (output_unit == nullptr) { DEBUG(driver, 1, "cocoa_m: Failed to get output node to set volume"); return; } @@ -109,12 +107,12 @@ const char *MusicDriver_Cocoa::Start(const char * const *parm) { if (NewMusicPlayer(&_player) != noErr) return "failed to create music player"; - return NULL; + return nullptr; } /** - * Checks wether the player is active. + * Checks whether the player is active. */ bool MusicDriver_Cocoa::IsSongPlaying() { @@ -131,8 +129,8 @@ bool MusicDriver_Cocoa::IsSongPlaying() */ void MusicDriver_Cocoa::Stop() { - if (_player != NULL) DisposeMusicPlayer(_player); - if (_sequence != NULL) DisposeMusicSequence(_sequence); + if (_player != nullptr) DisposeMusicPlayer(_player); + if (_sequence != nullptr) DisposeMusicSequence(_sequence); } @@ -148,9 +146,9 @@ void MusicDriver_Cocoa::PlaySong(const MusicSongInfo &song) DEBUG(driver, 2, "cocoa_m: trying to play '%s'", filename.c_str()); this->StopSong(); - if (_sequence != NULL) { + if (_sequence != nullptr) { DisposeMusicSequence(_sequence); - _sequence = NULL; + _sequence = nullptr; } if (filename.empty()) return; @@ -161,13 +159,12 @@ void MusicDriver_Cocoa::PlaySong(const MusicSongInfo &song) } const char *os_file = OTTD2FS(filename.c_str()); - CFURLRef url = CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8*)os_file, strlen(os_file), false); + CFAutoRelease url(CFURLCreateFromFileSystemRepresentation(kCFAllocatorDefault, (const UInt8*)os_file, strlen(os_file), false)); #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) if (MacOSVersionIsAtLeast(10, 5, 0)) { - if (MusicSequenceFileLoad(_sequence, url, kMusicSequenceFile_AnyType, 0) != noErr) { + if (MusicSequenceFileLoad(_sequence, url.get(), kMusicSequenceFile_AnyType, 0) != noErr) { DEBUG(driver, 0, "cocoa_m: Failed to load MIDI file"); - CFRelease(url); return; } } else @@ -175,22 +172,19 @@ void MusicDriver_Cocoa::PlaySong(const MusicSongInfo &song) { #if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) FSRef ref_file; - if (!CFURLGetFSRef(url, &ref_file)) { + if (!CFURLGetFSRef(url.get(), &ref_file)) { DEBUG(driver, 0, "cocoa_m: Failed to make FSRef"); - CFRelease(url); return; } if (MusicSequenceLoadSMFWithFlags(_sequence, &ref_file, 0) != noErr) { DEBUG(driver, 0, "cocoa_m: Failed to load MIDI file old style"); - CFRelease(url); return; } #endif } - CFRelease(url); /* Construct audio graph */ - AUGraph graph = NULL; + AUGraph graph = nullptr; MusicSequenceGetAUGraph(_sequence, &graph); AUGraphOpen(graph); @@ -204,7 +198,7 @@ void MusicDriver_Cocoa::PlaySong(const MusicSongInfo &song) MusicSequenceGetTrackCount(_sequence, &num_tracks); _seq_length = 0; for (UInt32 i = 0; i < num_tracks; i++) { - MusicTrack track = NULL; + MusicTrack track = nullptr; MusicTimeStamp track_length = 0; UInt32 prop_size = sizeof(MusicTimeStamp); MusicSequenceGetIndTrack(_sequence, i, &track); @@ -230,7 +224,7 @@ void MusicDriver_Cocoa::PlaySong(const MusicSongInfo &song) void MusicDriver_Cocoa::StopSong() { MusicPlayerStop(_player); - MusicPlayerSetSequence(_player, NULL); + MusicPlayerSetSequence(_player, nullptr); _playing = false; } diff --git a/src/music/cocoa_m.h b/src/music/cocoa_m.h index fdb10b84e6..aa477eddaf 100644 --- a/src/music/cocoa_m.h +++ b/src/music/cocoa_m.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. @@ -16,24 +14,24 @@ class MusicDriver_Cocoa : public MusicDriver { public: - /* virtual */ const char *Start(const char * const *param); + const char *Start(const char * const *param) override; - /* virtual */ void Stop(); + void Stop() override; - /* virtual */ void PlaySong(const MusicSongInfo &song); + void PlaySong(const MusicSongInfo &song) override; - /* virtual */ void StopSong(); + void StopSong() override; - /* virtual */ bool IsSongPlaying(); + bool IsSongPlaying() override; - /* virtual */ void SetVolume(byte vol); - /* virtual */ const char *GetName() const { return "cocoa"; } + void SetVolume(byte vol) override; + const char *GetName() const override { return "cocoa"; } }; class FMusicDriver_Cocoa : public DriverFactoryBase { public: FMusicDriver_Cocoa() : DriverFactoryBase(Driver::DT_MUSIC, 10, "cocoa", "Cocoa MIDI Driver") {} - /* virtual */ Driver *CreateInstance() const { return new MusicDriver_Cocoa(); } + Driver *CreateInstance() const override { return new MusicDriver_Cocoa(); } }; #endif /* MUSIC_MACOSX_COCOA_H */ diff --git a/src/music/dmusic.cpp b/src/music/dmusic.cpp index fece709fda..4a7461ee8f 100644 --- a/src/music/dmusic.cpp +++ b/src/music/dmusic.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. @@ -19,7 +17,7 @@ #include "../debug.h" #include "../os/windows/win32.h" #include "../core/mem_func.hpp" -#include "../thread/thread.h" +#include "../thread.h" #include "../fileio_func.h" #include "../base_media_base.h" #include "dmusic.h" @@ -30,6 +28,7 @@ #include #include #include +#include #include "../safeguards.h" @@ -138,18 +137,18 @@ static struct { } _playback; /** Handle to our worker thread. */ -static ThreadObject *_dmusic_thread = NULL; +static std::thread _dmusic_thread; /** Event to signal the thread that it should look at a state change. */ -static HANDLE _thread_event = NULL; +static HANDLE _thread_event = nullptr; /** Lock access to playback data that is not thread-safe. */ -static ThreadMutex *_thread_mutex = NULL; +static std::mutex _thread_mutex; /** The direct music object manages buffers and ports. */ -static IDirectMusic *_music = NULL; +static IDirectMusic *_music = nullptr; /** The port object lets us send MIDI data to the synthesizer. */ -static IDirectMusicPort *_port = NULL; +static IDirectMusicPort *_port = nullptr; /** The buffer object collects the data to sent. */ -static IDirectMusicBuffer *_buffer = NULL; +static IDirectMusicBuffer *_buffer = nullptr; /** List of downloaded DLS instruments. */ static std::vector _dls_downloads; @@ -233,7 +232,7 @@ bool DLSFile::ReadDLSRegion(FILE *f, DWORD list_length, std::vector & break; default: - DEBUG(driver, 7, "DLS: Ignoring unkown chunk %c%c%c%c", (char)(chunk.type & 0xFF), (char)((chunk.type >> 8) & 0xFF), (char)((chunk.type >> 16) & 0xFF), (char)((chunk.type >> 24) & 0xFF)); + DEBUG(driver, 7, "DLS: Ignoring unknown chunk %c%c%c%c", (char)(chunk.type & 0xFF), (char)((chunk.type >> 8) & 0xFF), (char)((chunk.type >> 16) & 0xFF), (char)((chunk.type >> 24) & 0xFF)); fseek(f, chunk.length, SEEK_CUR); break; } @@ -256,7 +255,7 @@ bool DLSFile::ReadDLSRegionList(FILE *f, DWORD list_length, DLSInstrument &instr if (list_type == FOURCC_RGN) { this->ReadDLSRegion(f, chunk.length - sizeof(list_type), instrument.regions); } else { - DEBUG(driver, 7, "DLS: Ignoring unkown list chunk of type %c%c%c%c", (char)(list_type & 0xFF), (char)((list_type >> 8) & 0xFF), (char)((list_type >> 16) & 0xFF), (char)((list_type >> 24) & 0xFF)); + DEBUG(driver, 7, "DLS: Ignoring unknown list chunk of type %c%c%c%c", (char)(list_type & 0xFF), (char)((list_type >> 8) & 0xFF), (char)((list_type >> 16) & 0xFF), (char)((list_type >> 24) & 0xFF)); fseek(f, chunk.length - sizeof(list_type), SEEK_CUR); } } else { @@ -303,7 +302,7 @@ bool DLSFile::ReadDLSInstrument(FILE *f, DWORD list_length) break; default: - DEBUG(driver, 7, "DLS: Ignoring unkown chunk %c%c%c%c", (char)(chunk.type & 0xFF), (char)((chunk.type >> 8) & 0xFF), (char)((chunk.type >> 16) & 0xFF), (char)((chunk.type >> 24) & 0xFF)); + DEBUG(driver, 7, "DLS: Ignoring unknown chunk %c%c%c%c", (char)(chunk.type & 0xFF), (char)((chunk.type >> 8) & 0xFF), (char)((chunk.type >> 16) & 0xFF), (char)((chunk.type >> 24) & 0xFF)); fseek(f, chunk.length, SEEK_CUR); break; } @@ -328,7 +327,7 @@ bool DLSFile::ReadDLSInstrumentList(FILE *f, DWORD list_length) if (!this->ReadDLSInstrument(f, chunk.length - sizeof(list_type))) return false; } else { - DEBUG(driver, 7, "DLS: Ignoring unkown list chunk of type %c%c%c%c", (char)(list_type & 0xFF), (char)((list_type >> 8) & 0xFF), (char)((list_type >> 16) & 0xFF), (char)((list_type >> 24) & 0xFF)); + DEBUG(driver, 7, "DLS: Ignoring unknown list chunk of type %c%c%c%c", (char)(list_type & 0xFF), (char)((list_type >> 8) & 0xFF), (char)((list_type >> 16) & 0xFF), (char)((list_type >> 24) & 0xFF)); fseek(f, chunk.length - sizeof(list_type), SEEK_CUR); } } else { @@ -391,7 +390,7 @@ bool DLSFile::ReadDLSWave(FILE *f, DWORD list_length, long offset) break; default: - DEBUG(driver, 7, "DLS: Ignoring unkown chunk %c%c%c%c", (char)(chunk.type & 0xFF), (char)((chunk.type >> 8) & 0xFF), (char)((chunk.type >> 16) & 0xFF), (char)((chunk.type >> 24) & 0xFF)); + DEBUG(driver, 7, "DLS: Ignoring unknown chunk %c%c%c%c", (char)(chunk.type & 0xFF), (char)((chunk.type >> 8) & 0xFF), (char)((chunk.type >> 16) & 0xFF), (char)((chunk.type >> 24) & 0xFF)); fseek(f, chunk.length, SEEK_CUR); break; } @@ -420,7 +419,7 @@ bool DLSFile::ReadDLSWaveList(FILE *f, DWORD list_length) if (!this->ReadDLSWave(f, chunk.length - sizeof(list_type), chunk_offset - base_offset)) return false; } else { - DEBUG(driver, 7, "DLS: Ignoring unkown list chunk of type %c%c%c%c", (char)(list_type & 0xFF), (char)((list_type >> 8) & 0xFF), (char)((list_type >> 16) & 0xFF), (char)((list_type >> 24) & 0xFF)); + DEBUG(driver, 7, "DLS: Ignoring unknown list chunk of type %c%c%c%c", (char)(list_type & 0xFF), (char)((list_type >> 8) & 0xFF), (char)((list_type >> 16) & 0xFF), (char)((list_type >> 24) & 0xFF)); fseek(f, chunk.length - sizeof(list_type), SEEK_CUR); } } else { @@ -437,7 +436,7 @@ bool DLSFile::LoadFile(const TCHAR *file) DEBUG(driver, 2, "DMusic: Try to load DLS file %s", FS2OTTD(file)); FILE *f = _tfopen(file, _T("rb")); - if (f == NULL) return false; + if (f == nullptr) return false; FileCloser f_scope(f); @@ -499,7 +498,7 @@ bool DLSFile::LoadFile(const TCHAR *file) break; default: - DEBUG(driver, 7, "DLS: Ignoring unkown chunk %c%c%c%c", (char)(chunk.type & 0xFF), (char)((chunk.type >> 8) & 0xFF), (char)((chunk.type >> 16) & 0xFF), (char)((chunk.type >> 24) & 0xFF)); + DEBUG(driver, 7, "DLS: Ignoring unknown chunk %c%c%c%c", (char)(chunk.type & 0xFF), (char)((chunk.type >> 8) & 0xFF), (char)((chunk.type >> 16) & 0xFF), (char)((chunk.type >> 24) & 0xFF)); fseek(f, chunk.length, SEEK_CUR); break; } @@ -538,19 +537,19 @@ static void TransmitChannelMsg(IDirectMusicBuffer *buffer, REFERENCE_TIME rt, by } } -static void TransmitSysex(IDirectMusicBuffer *buffer, REFERENCE_TIME rt, byte *&msg_start, size_t &remaining) +static void TransmitSysex(IDirectMusicBuffer *buffer, REFERENCE_TIME rt, const byte *&msg_start, size_t &remaining) { /* Find end of message. */ - byte *msg_end = msg_start; + const byte *msg_end = msg_start; while (*msg_end != MIDIST_ENDSYSEX) msg_end++; msg_end++; // Also include SysEx end byte. - if (buffer->PackUnstructured(rt, 0, msg_end - msg_start, msg_start) == E_OUTOFMEMORY) { + if (buffer->PackUnstructured(rt, 0, msg_end - msg_start, const_cast(msg_start)) == E_OUTOFMEMORY) { /* Buffer is full, clear it and try again. */ _port->PlayBuffer(buffer); buffer->Flush(); - buffer->PackUnstructured(rt, 0, msg_end - msg_start, msg_start); + buffer->PackUnstructured(rt, 0, msg_end - msg_start, const_cast(msg_start)); } /* Update position in buffer. */ @@ -558,9 +557,11 @@ static void TransmitSysex(IDirectMusicBuffer *buffer, REFERENCE_TIME rt, byte *& msg_start = msg_end; } -static void TransmitSysexConst(IDirectMusicBuffer *buffer, REFERENCE_TIME rt, byte *msg_start, size_t length) +static void TransmitStandardSysex(IDirectMusicBuffer *buffer, REFERENCE_TIME rt, MidiSysexMessage msg) { - TransmitSysex(buffer, rt, msg_start, length); + size_t length = 0; + const byte *data = MidiGetStandardSysexMessage(msg, length); + TransmitSysex(buffer, rt, data, length); } /** Transmit 'Note off' messages to all MIDI channels. */ @@ -571,32 +572,21 @@ static void TransmitNotesOff(IDirectMusicBuffer *buffer, REFERENCE_TIME block_ti TransmitChannelMsg(_buffer, block_time + 10, MIDIST_CONTROLLER | ch, MIDICT_SUSTAINSW, 0); TransmitChannelMsg(_buffer, block_time + 10, MIDIST_CONTROLLER | ch, MIDICT_MODE_RESETALLCTRL, 0); } - /* Explicitly flush buffer to make sure the note off messages are processed - * before we send any additional control messages. */ + + /* Performing a GM reset stops all sound and resets all parameters. */ + TransmitStandardSysex(_buffer, block_time + 20, MidiSysexMessage::ResetGM); + TransmitStandardSysex(_buffer, block_time + 30, MidiSysexMessage::RolandSetReverb); + + /* Explicitly flush buffer to make sure the messages are processed, + * as we want sound to stop immediately. */ _port->PlayBuffer(_buffer); _buffer->Flush(); - /* Some songs change the "Pitch bend range" registered parameter. If - * this doesn't get reset, everything else will start sounding wrong. */ - for (int ch = 0; ch < 16; ch++) { - /* Running status, only need status for first message - * Select RPN 00.00, set value to 02.00, and de-select again */ - TransmitChannelMsg(_buffer, block_time + 10, MIDIST_CONTROLLER | ch, MIDICT_RPN_SELECT_LO, 0x00); - TransmitChannelMsg(_buffer, block_time + 10, MIDICT_RPN_SELECT_HI, 0x00); - TransmitChannelMsg(_buffer, block_time + 10, MIDICT_DATAENTRY, 0x02); - TransmitChannelMsg(_buffer, block_time + 10, MIDICT_DATAENTRY_LO, 0x00); - TransmitChannelMsg(_buffer, block_time + 10, MIDICT_RPN_SELECT_LO, 0x7F); - TransmitChannelMsg(_buffer, block_time + 10, MIDICT_RPN_SELECT_HI, 0x7F); - - _port->PlayBuffer(_buffer); - _buffer->Flush(); - } - /* Wait until message time has passed. */ Sleep(Clamp((block_time - cur_time) / MS_TO_REFTIME, 5, 1000)); } -static void MidiThreadProc(void *) +static void MidiThreadProc() { DEBUG(driver, 2, "DMusic: Entering playback thread"); @@ -616,13 +606,6 @@ static void MidiThreadProc(void *) REFERENCE_TIME cur_time; clock->GetTime(&cur_time); - /* Standard "Enable General MIDI" message */ - static byte gm_enable_sysex[] = { 0xF0, 0x7E, 0x00, 0x09, 0x01, 0xF7 }; - TransmitSysexConst(_buffer, cur_time, &gm_enable_sysex[0], sizeof(gm_enable_sysex)); - /* Roland-specific reverb room control, used by the original game */ - static byte roland_reverb_sysex[] = { 0xF0, 0x41, 0x10, 0x42, 0x12, 0x40, 0x01, 0x30, 0x02, 0x04, 0x00, 0x40, 0x40, 0x00, 0x00, 0x09, 0xF7 }; - TransmitSysexConst(_buffer, cur_time, &roland_reverb_sysex[0], sizeof(roland_reverb_sysex)); - _port->PlayBuffer(_buffer); _buffer->Flush(); @@ -655,7 +638,7 @@ static void MidiThreadProc(void *) DEBUG(driver, 2, "DMusic thread: Starting playback"); { /* New scope to limit the time the mutex is locked. */ - ThreadMutexLocker lock(_thread_mutex); + std::lock_guard lock(_thread_mutex); current_file.MoveFrom(_playback.next_file); std::swap(_playback.next_segment, current_segment); @@ -665,7 +648,7 @@ static void MidiThreadProc(void *) _playback.do_start = false; } - /* Turn all notes off in case we are seeking between music titles. */ + /* Reset playback device between songs. */ clock->GetTime(&cur_time); TransmitNotesOff(_buffer, block_time, cur_time); @@ -686,7 +669,7 @@ static void MidiThreadProc(void *) size_t preload_bytes = 0; for (size_t bl = 0; bl < current_file.blocks.size(); bl++) { MidiFile::DataBlock &block = current_file.blocks[bl]; - preload_bytes += block.data.Length(); + preload_bytes += block.data.size(); if (block.ticktime >= current_segment.start) { if (current_segment.loop) { DEBUG(driver, 2, "DMusic: timer: loop from block %d (ticktime %d, realtime %.3f, bytes %d)", (int)bl, (int)block.ticktime, ((int)block.realtime) / 1000.0, (int)preload_bytes); @@ -751,8 +734,8 @@ static void MidiThreadProc(void *) block_time = playback_start_time + block.realtime * MIDITIME_TO_REFTIME; DEBUG(driver, 9, "DMusic thread: Streaming block " PRINTF_SIZE " (cur=" OTTD_PRINTF64 ", block=" OTTD_PRINTF64 ")", current_block, (long long)(current_time / MS_TO_REFTIME), (long long)(block_time / MS_TO_REFTIME)); - byte *data = block.data.Begin(); - size_t remaining = block.data.Length(); + const byte *data = block.data.data(); + size_t remaining = block.data.size(); byte last_status = 0; while (remaining > 0) { /* MidiFile ought to have converted everything out of running status, @@ -878,13 +861,13 @@ static const char *LoadDefaultDLSFile(const char *user_dls) if ((caps.dwFlags & (DMUS_PC_DLS | DMUS_PC_DLS2)) != 0 && (caps.dwFlags & DMUS_PC_GMINHARDWARE) == 0) { DLSFile dls_file; - if (user_dls == NULL) { + if (user_dls == nullptr) { /* Try loading the default GM DLS file stored in the registry. */ HKEY hkDM; if (SUCCEEDED(RegOpenKeyEx(HKEY_LOCAL_MACHINE, _T("Software\\Microsoft\\DirectMusic"), 0, KEY_READ, &hkDM))) { TCHAR dls_path[MAX_PATH]; DWORD buf_size = sizeof(dls_path); // Buffer size as to be given in bytes! - if (SUCCEEDED(RegQueryValueEx(hkDM, _T("GMFilePath"), NULL, NULL, (LPBYTE)dls_path, &buf_size))) { + if (SUCCEEDED(RegQueryValueEx(hkDM, _T("GMFilePath"), nullptr, nullptr, (LPBYTE)dls_path, &buf_size))) { TCHAR expand_path[MAX_PATH * 2]; ExpandEnvironmentStrings(dls_path, expand_path, lengthof(expand_path)); if (!dls_file.LoadFile(expand_path)) DEBUG(driver, 1, "Failed to load default GM DLS file from registry"); @@ -905,7 +888,7 @@ static const char *LoadDefaultDLSFile(const char *user_dls) } /* Get download port and allocate download IDs. */ - IDirectMusicPortDownload *download_port = NULL; + IDirectMusicPortDownload *download_port = nullptr; if (FAILED(_port->QueryInterface(IID_IDirectMusicPortDownload, (LPVOID *)&download_port))) return "Can't get download port"; DWORD dlid_wave = 0, dlid_inst = 0; @@ -919,7 +902,7 @@ static const char *LoadDefaultDLSFile(const char *user_dls) /* Download wave data. */ for (DWORD i = 0; i < dls_file.waves.size(); i++) { - IDirectMusicDownload *dl_wave = NULL; + IDirectMusicDownload *dl_wave = nullptr; if (FAILED(download_port->AllocateBuffer((DWORD)(sizeof(WAVE_DOWNLOAD) + dwAppend * dls_file.waves[i].fmt.wf.nBlockAlign + dls_file.waves[i].data.size()), &dl_wave))) { download_port->Release(); return "Can't allocate wave download buffer"; @@ -983,7 +966,7 @@ static const char *LoadDefaultDLSFile(const char *user_dls) i_size += offsets * sizeof(ULONG); /* Allocate download buffer. */ - IDirectMusicDownload *dl_inst = NULL; + IDirectMusicDownload *dl_inst = nullptr; if (FAILED(download_port->AllocateBuffer((DWORD)i_size, &dl_inst))) { download_port->Release(); return "Can't allocate instrument download buffer"; @@ -1084,19 +1067,19 @@ static const char *LoadDefaultDLSFile(const char *user_dls) download_port->Release(); } - return NULL; + return nullptr; } const char *MusicDriver_DMusic::Start(const char * const *parm) { /* Initialize COM */ - if (FAILED(CoInitializeEx(NULL, COINITBASE_MULTITHREADED))) return "COM initialization failed"; + if (FAILED(CoInitializeEx(nullptr, COINITBASE_MULTITHREADED))) return "COM initialization failed"; /* Create the DirectMusic object */ if (FAILED(CoCreateInstance( CLSID_DirectMusic, - NULL, + nullptr, CLSCTX_INPROC, IID_IDirectMusic, (LPVOID*)&_music @@ -1105,7 +1088,7 @@ const char *MusicDriver_DMusic::Start(const char * const *parm) } /* Assign sound output device. */ - if (FAILED(_music->SetDirectSound(NULL, NULL))) return "Can't set DirectSound interface"; + if (FAILED(_music->SetDirectSound(nullptr, nullptr))) return "Can't set DirectSound interface"; /* MIDI events need to be send to the synth in time before their playback time * has come. By default, we try send any events at least 50 ms before playback. */ @@ -1148,7 +1131,7 @@ const char *MusicDriver_DMusic::Start(const char * const *parm) params.dwSize = sizeof(DMUS_PORTPARAMS); params.dwValidParams = DMUS_PORTPARAMS_CHANNELGROUPS; params.dwChannelGroups = 1; - if (FAILED(_music->CreatePort(guidPort, ¶ms, &_port, NULL))) return "Failed to create port"; + if (FAILED(_music->CreatePort(guidPort, ¶ms, &_port, nullptr))) return "Failed to create port"; /* Activate port. */ if (FAILED(_port->Activate(TRUE))) return "Failed to activate port"; @@ -1158,21 +1141,19 @@ const char *MusicDriver_DMusic::Start(const char * const *parm) desc.dwSize = sizeof(DMUS_BUFFERDESC); desc.guidBufferFormat = KSDATAFORMAT_SUBTYPE_DIRECTMUSIC; desc.cbBuffer = 1024; - if (FAILED(_music->CreateMusicBuffer(&desc, &_buffer, NULL))) return "Failed to create music buffer"; + if (FAILED(_music->CreateMusicBuffer(&desc, &_buffer, nullptr))) return "Failed to create music buffer"; /* On soft-synths (e.g. the default DirectMusic one), we might need to load a wavetable set to get music. */ const char *dls = LoadDefaultDLSFile(GetDriverParam(parm, "dls")); - if (dls != NULL) return dls; + if (dls != nullptr) return dls; /* Create playback thread and synchronization primitives. */ - _thread_event = CreateEvent(NULL, FALSE, FALSE, NULL); - if (_thread_event == NULL) return "Can't create thread shutdown event"; - _thread_mutex = ThreadMutex::New(); - if (_thread_mutex == NULL) return "Can't create thread mutex"; + _thread_event = CreateEvent(nullptr, FALSE, FALSE, nullptr); + if (_thread_event == nullptr) return "Can't create thread shutdown event"; - if (!ThreadObject::New(&MidiThreadProc, this, &_dmusic_thread, "ottd:dmusic")) return "Can't create MIDI output thread"; + if (!StartNewThread(&_dmusic_thread, "ottd:dmusic", &MidiThreadProc)) return "Can't create MIDI output thread"; - return NULL; + return nullptr; } @@ -1184,46 +1165,45 @@ MusicDriver_DMusic::~MusicDriver_DMusic() void MusicDriver_DMusic::Stop() { - if (_dmusic_thread != NULL) { + if (_dmusic_thread.joinable()) { _playback.shutdown = true; SetEvent(_thread_event); - _dmusic_thread->Join(); + _dmusic_thread.join(); } /* Unloaded any instruments we loaded. */ if (_dls_downloads.size() > 0) { - IDirectMusicPortDownload *download_port = NULL; + IDirectMusicPortDownload *download_port = nullptr; _port->QueryInterface(IID_IDirectMusicPortDownload, (LPVOID *)&download_port); /* Instruments refer to waves. As the waves are at the beginning of the download list, * do the unload from the back so that references are cleared properly. */ - for (std::vector::reverse_iterator i = _dls_downloads.rbegin(); download_port != NULL && i != _dls_downloads.rend(); i++) { + for (std::vector::reverse_iterator i = _dls_downloads.rbegin(); download_port != nullptr && i != _dls_downloads.rend(); i++) { download_port->Unload(*i); (*i)->Release(); } _dls_downloads.clear(); - if (download_port != NULL) download_port->Release(); + if (download_port != nullptr) download_port->Release(); } - if (_buffer != NULL) { + if (_buffer != nullptr) { _buffer->Release(); - _buffer = NULL; + _buffer = nullptr; } - if (_port != NULL) { + if (_port != nullptr) { _port->Activate(FALSE); _port->Release(); - _port = NULL; + _port = nullptr; } - if (_music != NULL) { + if (_music != nullptr) { _music->Release(); - _music = NULL; + _music = nullptr; } CloseHandle(_thread_event); - delete _thread_mutex; CoUninitialize(); } @@ -1231,7 +1211,7 @@ void MusicDriver_DMusic::Stop() void MusicDriver_DMusic::PlaySong(const MusicSongInfo &song) { - ThreadMutexLocker lock(_thread_mutex); + std::lock_guard lock(_thread_mutex); if (!_playback.next_file.LoadSong(song)) return; diff --git a/src/music/dmusic.h b/src/music/dmusic.h index 527e064e49..bfbb07f16d 100644 --- a/src/music/dmusic.h +++ b/src/music/dmusic.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. @@ -19,25 +17,25 @@ class MusicDriver_DMusic : public MusicDriver { public: virtual ~MusicDriver_DMusic(); - /* virtual */ const char *Start(const char * const *param); + const char *Start(const char * const *param) override; - /* virtual */ void Stop(); + void Stop() override; - /* virtual */ void PlaySong(const MusicSongInfo &song); + void PlaySong(const MusicSongInfo &song) override; - /* virtual */ void StopSong(); + void StopSong() override; - /* virtual */ bool IsSongPlaying(); + bool IsSongPlaying() override; - /* virtual */ void SetVolume(byte vol); - /* virtual */ const char *GetName() const { return "dmusic"; } + void SetVolume(byte vol) override; + const char *GetName() const override { return "dmusic"; } }; /** Factory for the DirectX music player. */ class FMusicDriver_DMusic : public DriverFactoryBase { public: FMusicDriver_DMusic() : DriverFactoryBase(Driver::DT_MUSIC, 10, "dmusic", "DirectMusic MIDI Driver") {} - /* virtual */ Driver *CreateInstance() const { return new MusicDriver_DMusic(); } + Driver *CreateInstance() const override { return new MusicDriver_DMusic(); } }; #endif /* MUSIC_DMUSIC_H */ diff --git a/src/music/extmidi.cpp b/src/music/extmidi.cpp index 9d07761b73..b7e7e63b90 100644 --- a/src/music/extmidi.cpp +++ b/src/music/extmidi.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. @@ -18,6 +16,7 @@ #include "../gfx_func.h" #include "extmidi.h" #include "../base_media_base.h" +#include "../thread.h" #include "midifile.hpp" #include #include @@ -51,7 +50,7 @@ const char *MusicDriver_ExtMidi::Start(const char * const * parm) if (StrEmpty(command)) command = EXTERNAL_PLAYER " " MIDI_ARG; #endif - /* Count number of arguments, but include 3 extra slots: 1st for command, 2nd for song title, and 3rd for terminating NULL. */ + /* Count number of arguments, but include 3 extra slots: 1st for command, 2nd for song title, and 3rd for terminating nullptr. */ uint num_args = 3; for (const char *t = command; *t != '\0'; t++) if (*t == ' ') num_args++; @@ -62,7 +61,7 @@ const char *MusicDriver_ExtMidi::Start(const char * const * parm) uint p = 1; while (true) { this->params[p] = strchr(this->params[p - 1], ' '); - if (this->params[p] == NULL) break; + if (this->params[p] == nullptr) break; this->params[p][0] = '\0'; this->params[p]++; @@ -74,7 +73,7 @@ const char *MusicDriver_ExtMidi::Start(const char * const * parm) this->song[0] = '\0'; this->pid = -1; - return NULL; + return nullptr; } void MusicDriver_ExtMidi::Stop() @@ -102,7 +101,7 @@ void MusicDriver_ExtMidi::StopSong() bool MusicDriver_ExtMidi::IsSongPlaying() { - if (this->pid != -1 && waitpid(this->pid, NULL, WNOHANG) == this->pid) { + if (this->pid != -1 && waitpid(this->pid, nullptr, WNOHANG) == this->pid) { this->pid = -1; } if (this->pid == -1 && this->song[0] != '\0') this->DoPlay(); @@ -145,7 +144,7 @@ void MusicDriver_ExtMidi::DoStop() * 5 seconds = 5000 milliseconds, 10 ms per cycle => 500 cycles. */ for (int i = 0; i < 500; i++) { kill(this->pid, SIGTERM); - if (waitpid(this->pid, NULL, WNOHANG) == this->pid) { + if (waitpid(this->pid, nullptr, WNOHANG) == this->pid) { /* It has shut down, so we are done */ this->pid = -1; return; @@ -158,6 +157,6 @@ void MusicDriver_ExtMidi::DoStop() /* Gracefully stopping failed. Do it the hard way * and wait till the process finally died. */ kill(this->pid, SIGKILL); - waitpid(this->pid, NULL, 0); + waitpid(this->pid, nullptr, 0); this->pid = -1; } diff --git a/src/music/extmidi.h b/src/music/extmidi.h index e174dc9b08..495e9a72cf 100644 --- a/src/music/extmidi.h +++ b/src/music/extmidi.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. @@ -24,24 +22,24 @@ private: void DoStop(); public: - /* virtual */ const char *Start(const char * const *param); + const char *Start(const char * const *param) override; - /* virtual */ void Stop(); + void Stop() override; - /* virtual */ void PlaySong(const MusicSongInfo &song); + void PlaySong(const MusicSongInfo &song) override; - /* virtual */ void StopSong(); + void StopSong() override; - /* virtual */ bool IsSongPlaying(); + bool IsSongPlaying() override; - /* virtual */ void SetVolume(byte vol); - /* virtual */ const char *GetName() const { return "extmidi"; } + void SetVolume(byte vol) override; + const char *GetName() const override { return "extmidi"; } }; class FMusicDriver_ExtMidi : public DriverFactoryBase { public: FMusicDriver_ExtMidi() : DriverFactoryBase(Driver::DT_MUSIC, 3, "extmidi", "External MIDI Driver") {} - /* virtual */ Driver *CreateInstance() const { return new MusicDriver_ExtMidi(); } + Driver *CreateInstance() const override { return new MusicDriver_ExtMidi(); } }; #endif /* MUSIC_EXTERNAL_H */ diff --git a/src/music/fluidsynth.cpp b/src/music/fluidsynth.cpp index 6baeb899bc..64abe0e538 100644 --- a/src/music/fluidsynth.cpp +++ b/src/music/fluidsynth.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. @@ -17,11 +15,13 @@ #include "midifile.hpp" #include #include "../mixer.h" +#include static struct { fluid_settings_t* settings; ///< FluidSynth settings handle fluid_synth_t* synth; ///< FluidSynth synthesizer handle fluid_player_t* player; ///< FluidSynth MIDI player handle + std::mutex synth_mutex; ///< Guard mutex for synth access } _midi; ///< Metadata about the midi we're playing. /** Factory for the FluidSynth driver. */ @@ -39,17 +39,21 @@ static const char *default_sf[] = { "/usr/share/sounds/sf2/TimGM6mb.sf2", "/usr/share/sounds/sf2/FluidR3_GS.sf2", - NULL + nullptr }; static void RenderMusicStream(int16 *buffer, size_t samples) { - if (!_midi.synth || !_midi.player) return; + std::unique_lock lock{ _midi.synth_mutex, std::try_to_lock }; + + if (!lock.owns_lock() || !_midi.synth || !_midi.player) return; fluid_synth_write_s16(_midi.synth, samples, buffer, 0, 2, buffer, 1, 2); } const char *MusicDriver_FluidSynth::Start(const char * const *param) { + std::lock_guard lock{ _midi.synth_mutex }; + const char *sfont_name = GetDriverParam(param, "soundfont"); int sfont_id; @@ -58,6 +62,13 @@ const char *MusicDriver_FluidSynth::Start(const char * const *param) /* Create the settings. */ _midi.settings = new_fluid_settings(); if (!_midi.settings) return "Could not create midi settings"; + /* Don't try to lock sample data in memory, OTTD usually does not run with privileges allowing that */ + fluid_settings_setint(_midi.settings, "synth.lock-memory", 0); + + /* Install the music render routine and set up the samplerate */ + uint32 samplerate = MxSetMusicSource(RenderMusicStream); + fluid_settings_setnum(_midi.settings, "synth.sample-rate", samplerate); + DEBUG(driver, 1, "Fluidsynth: samplerate %.0f", (float)samplerate); /* Create the synthesizer. */ _midi.synth = new_fluid_synth(_midi.settings); @@ -79,21 +90,25 @@ const char *MusicDriver_FluidSynth::Start(const char * const *param) if (sfont_id == FLUID_FAILED) return "Could not open sound font"; } - _midi.player = NULL; + _midi.player = nullptr; - uint32 samplerate = MxSetMusicSource(RenderMusicStream); - fluid_synth_set_sample_rate(_midi.synth, samplerate); - DEBUG(driver, 1, "Fluidsynth: samplerate %.0f", (float)samplerate); - - return NULL; + return nullptr; } void MusicDriver_FluidSynth::Stop() { - MxSetMusicSource(NULL); - this->StopSong(); - delete_fluid_synth(_midi.synth); - delete_fluid_settings(_midi.settings); + MxSetMusicSource(nullptr); + + std::lock_guard lock{ _midi.synth_mutex }; + + if (_midi.player != nullptr) delete_fluid_player(_midi.player); + _midi.player = nullptr; + + if (_midi.synth != nullptr) delete_fluid_synth(_midi.synth); + _midi.synth = nullptr; + + if (_midi.settings != nullptr) delete_fluid_settings(_midi.settings); + _midi.settings = nullptr; } void MusicDriver_FluidSynth::PlaySong(const MusicSongInfo &song) @@ -106,6 +121,8 @@ void MusicDriver_FluidSynth::PlaySong(const MusicSongInfo &song) return; } + std::lock_guard lock{ _midi.synth_mutex }; + _midi.player = new_fluid_player(_midi.synth); if (!_midi.player) { DEBUG(driver, 0, "Could not create midi player"); @@ -115,19 +132,21 @@ void MusicDriver_FluidSynth::PlaySong(const MusicSongInfo &song) if (fluid_player_add(_midi.player, filename.c_str()) != FLUID_OK) { DEBUG(driver, 0, "Could not open music file"); delete_fluid_player(_midi.player); - _midi.player = NULL; + _midi.player = nullptr; return; } if (fluid_player_play(_midi.player) != FLUID_OK) { DEBUG(driver, 0, "Could not start midi player"); delete_fluid_player(_midi.player); - _midi.player = NULL; + _midi.player = nullptr; return; } } void MusicDriver_FluidSynth::StopSong() { + std::lock_guard lock{ _midi.synth_mutex }; + if (!_midi.player) return; fluid_player_stop(_midi.player); @@ -136,11 +155,13 @@ void MusicDriver_FluidSynth::StopSong() } delete_fluid_player(_midi.player); fluid_synth_system_reset(_midi.synth); - _midi.player = NULL; + fluid_synth_all_sounds_off(_midi.synth, -1); + _midi.player = nullptr; } bool MusicDriver_FluidSynth::IsSongPlaying() { + std::lock_guard lock{ _midi.synth_mutex }; if (!_midi.player) return false; return fluid_player_get_status(_midi.player) == FLUID_PLAYER_PLAYING; @@ -148,12 +169,15 @@ bool MusicDriver_FluidSynth::IsSongPlaying() void MusicDriver_FluidSynth::SetVolume(byte vol) { + std::lock_guard lock{ _midi.synth_mutex }; + if (_midi.settings == nullptr) return; + /* Allowed range of synth.gain is 0.0 to 10.0 */ /* fluidsynth's default gain is 0.2, so use this as "full * volume". Set gain using OpenTTD's volume, as a number between 0 * and 0.2. */ double gain = (1.0 * vol) / (128.0 * 5.0); - if (fluid_settings_setnum(_midi.settings, "synth.gain", gain) != 1) { + if (fluid_settings_setnum(_midi.settings, "synth.gain", gain) != FLUID_OK) { DEBUG(driver, 0, "Could not set volume"); } } diff --git a/src/music/fluidsynth.h b/src/music/fluidsynth.h index 171128a8e9..71d43fec4c 100644 --- a/src/music/fluidsynth.h +++ b/src/music/fluidsynth.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. @@ -17,25 +15,25 @@ /** Music driver making use of FluidSynth. */ class MusicDriver_FluidSynth : public MusicDriver { public: - /* virtual */ const char *Start(const char * const *param); + const char *Start(const char * const *param) override; - /* virtual */ void Stop(); + void Stop() override; - /* virtual */ void PlaySong(const MusicSongInfo &song); + void PlaySong(const MusicSongInfo &song) override; - /* virtual */ void StopSong(); + void StopSong() override; - /* virtual */ bool IsSongPlaying(); + bool IsSongPlaying() override; - /* virtual */ void SetVolume(byte vol); - /* virtual */ const char *GetName() const { return "fluidsynth"; } + void SetVolume(byte vol) override; + const char *GetName() const override { return "fluidsynth"; } }; /** Factory for the fluidsynth driver. */ class FMusicDriver_FluidSynth : public DriverFactoryBase { public: FMusicDriver_FluidSynth() : DriverFactoryBase(Driver::DT_MUSIC, 5, "fluidsynth", "FluidSynth MIDI Driver") {} - /* virtual */ Driver *CreateInstance() const { return new MusicDriver_FluidSynth(); } + Driver *CreateInstance() const override { return new MusicDriver_FluidSynth(); } }; #endif /* MUSIC_FLUIDSYNTH_H */ diff --git a/src/music/midi.h b/src/music/midi.h index 473f7f18bb..6de8b856c9 100644 --- a/src/music/midi.h +++ b/src/music/midi.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. @@ -141,4 +139,19 @@ enum MidiController { MIDICT_MODE_POLY = 127, }; + +/** Well-known MIDI system exclusive message values for use with the MidiGetStandardSysexMessage function. */ +enum class MidiSysexMessage { + /** Reset device to General MIDI defaults */ + ResetGM, + /** Reset device to (Roland) General Standard defaults */ + ResetGS, + /** Reset device to (Yamaha) XG defaults */ + ResetXG, + /** Set up Roland SoundCanvas reverb room as TTD does */ + RolandSetReverb, +}; + +const byte *MidiGetStandardSysexMessage(MidiSysexMessage msg, size_t &length); + #endif /* MUSIC_MIDI_H */ diff --git a/src/music/midifile.cpp b/src/music/midifile.cpp index 91f83c529d..197be14a14 100644 --- a/src/music/midifile.cpp +++ b/src/music/midifile.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. @@ -21,11 +19,41 @@ #include "../console_func.h" #include "../console_internal.h" - /* SMF reader based on description at: http://www.somascape.org/midi/tech/mfile.html */ -static MidiFile *_midifile_instance = NULL; +static MidiFile *_midifile_instance = nullptr; + +/** + * Retrieve a well-known MIDI system exclusive message. + * @param msg Which sysex message to retrieve + * @param[out] length Receives the length of the returned buffer + * @return Pointer to byte buffer with sysex message + */ +const byte *MidiGetStandardSysexMessage(MidiSysexMessage msg, size_t &length) +{ + static byte reset_gm_sysex[] = { 0xF0, 0x7E, 0x7F, 0x09, 0x01, 0xF7 }; + static byte reset_gs_sysex[] = { 0xF0, 0x41, 0x10, 0x42, 0x12, 0x40, 0x00, 0x7F, 0x00, 0x41, 0xF7 }; + static byte reset_xg_sysex[] = { 0xF0, 0x43, 0x10, 0x4C, 0x00, 0x00, 0x7E, 0x00, 0xF7 }; + static byte roland_reverb_sysex[] = { 0xF0, 0x41, 0x10, 0x42, 0x12, 0x40, 0x01, 0x30, 0x02, 0x04, 0x00, 0x40, 0x40, 0x00, 0x00, 0x09, 0xF7 }; + + switch (msg) { + case MidiSysexMessage::ResetGM: + length = lengthof(reset_gm_sysex); + return reset_gm_sysex; + case MidiSysexMessage::ResetGS: + length = lengthof(reset_gs_sysex); + return reset_gs_sysex; + case MidiSysexMessage::ResetXG: + length = lengthof(reset_xg_sysex); + return reset_xg_sysex; + case MidiSysexMessage::RolandSetReverb: + length = lengthof(roland_reverb_sysex); + return roland_reverb_sysex; + default: + NOT_REACHED(); + } +} /** * Owning byte buffer readable as a stream. @@ -114,7 +142,7 @@ public: /** * Read bytes into a buffer. - * @param[out] dest buffer to copy info + * @param[out] dest buffer to copy into * @param length number of bytes to read * @return true if the requested number of bytes were available */ @@ -127,6 +155,21 @@ public: return true; } + /** + * Read bytes into a MidiFile::DataBlock. + * @param[out] dest DataBlock to copy into + * @param length number of bytes to read + * @return true if the requested number of bytes were available + */ + bool ReadDataBlock(MidiFile::DataBlock *dest, size_t length) + { + if (this->IsEnd()) return false; + if (this->buflen - this->pos < length) return false; + dest->data.insert(dest->data.end(), this->buf + this->pos, this->buf + this->pos + length); + this->pos += length; + return true; + } + /** * Skip over a number of bytes in the buffer. * @param count number of bytes to skip over @@ -209,7 +252,6 @@ static bool ReadTrackChunk(FILE *file, MidiFile &target) /* Regular channel message */ last_status = status; running_status: - byte *data; switch (status & 0xF0) { case MIDIST_NOTEOFF: case MIDIST_NOTEON: @@ -217,20 +259,19 @@ static bool ReadTrackChunk(FILE *file, MidiFile &target) case MIDIST_CONTROLLER: case MIDIST_PITCHBEND: /* 3 byte messages */ - data = block->data.Append(3); - data[0] = status; - if (!chunk.ReadBuffer(&data[1], 2)) { + block->data.push_back(status); + if (!chunk.ReadDataBlock(block, 2)) { return false; } break; case MIDIST_PROGCHG: case MIDIST_CHANPRESS: /* 2 byte messages */ - data = block->data.Append(2); - data[0] = status; - if (!chunk.ReadByte(data[1])) { + block->data.push_back(status); + if (!chunk.ReadByte(buf[0])) { return false; } + block->data.push_back(buf[0]); break; default: NOT_REACHED(); @@ -267,15 +308,14 @@ static bool ReadTrackChunk(FILE *file, MidiFile &target) if (!chunk.ReadVariableLength(length)) { return false; } - byte *data = block->data.Append(length + 1); - data[0] = 0xF0; - if (!chunk.ReadBuffer(data + 1, length)) { + block->data.push_back(0xF0); + if (!chunk.ReadDataBlock(block, length)) { return false; } - if (data[length] != 0xF7) { + if (block->data.back() != 0xF7) { /* Engage Casio weirdo mode - convert to normal sysex */ running_sysex = true; - *block->data.Append() = 0xF7; + block->data.push_back(0xF7); } else { running_sysex = false; } @@ -285,8 +325,7 @@ static bool ReadTrackChunk(FILE *file, MidiFile &target) if (!chunk.ReadVariableLength(length)) { return false; } - byte *data = block->data.Append(length); - if (!chunk.ReadBuffer(data, length)) { + if (!chunk.ReadDataBlock(block, length)) { return false; } } else { @@ -330,14 +369,13 @@ static bool FixupMidiData(MidiFile &target) uint32 last_ticktime = 0; for (size_t i = 0; i < target.blocks.size(); i++) { MidiFile::DataBlock &block = target.blocks[i]; - if (block.data.Length() == 0) { + if (block.data.size() == 0) { continue; } else if (block.ticktime > last_ticktime || merged_blocks.size() == 0) { merged_blocks.push_back(block); last_ticktime = block.ticktime; } else { - byte *datadest = merged_blocks.back().data.Append(block.data.Length()); - memcpy(datadest, block.data.Begin(), block.data.Length()); + merged_blocks.back().data.insert(merged_blocks.back().data.end(), block.data.begin(), block.data.end()); } } std::swap(merged_blocks, target.blocks); @@ -427,7 +465,7 @@ bool MidiFile::LoadFile(const char *filename) bool success = false; FILE *file = FioFOpenFile(filename, "rb", Subdirectory::BASESET_DIR); - if (file == NULL) return false; + if (file == nullptr) return false; SMFHeader header; if (!ReadSMFHeader(file, header)) goto cleanup; @@ -508,14 +546,14 @@ struct MpsMachine { static void AddMidiData(MidiFile::DataBlock &block, byte b1, byte b2) { - *block.data.Append() = b1; - *block.data.Append() = b2; + block.data.push_back(b1); + block.data.push_back(b2); } static void AddMidiData(MidiFile::DataBlock &block, byte b1, byte b2, byte b3) { - *block.data.Append() = b1; - *block.data.Append() = b2; - *block.data.Append() = b3; + block.data.push_back(b1); + block.data.push_back(b2); + block.data.push_back(b3); } /** @@ -816,7 +854,7 @@ bool MidiFile::LoadSong(const MusicSongInfo &song) { size_t songdatalen = 0; byte *songdata = GetMusicCatEntryData(song.filename, song.cat_index, songdatalen); - if (songdata != NULL) { + if (songdata != nullptr) { bool result = this->LoadMpsData(songdata, songdatalen); free(songdata); return result; @@ -941,8 +979,8 @@ bool MidiFile::WriteSMF(const char *filename) } /* Write each block data command */ - byte *dp = block.data.Begin(); - while (dp < block.data.End()) { + byte *dp = block.data.data(); + while (dp < block.data.data() + block.data.size()) { /* Always zero delta time inside blocks */ if (needtime) { fputc(0, f); @@ -1025,7 +1063,7 @@ std::string MidiFile::GetSMFFile(const MusicSongInfo &song) char basename[MAX_PATH]; { const char *fnstart = strrchr(song.filename, PATHSEPCHAR); - if (fnstart == NULL) { + if (fnstart == nullptr) { fnstart = song.filename; } else { fnstart++; @@ -1055,7 +1093,7 @@ std::string MidiFile::GetSMFFile(const MusicSongInfo &song) byte *data; size_t datalen; data = GetMusicCatEntryData(song.filename, song.cat_index, datalen); - if (data == NULL) return std::string(); + if (data == nullptr) return std::string(); MidiFile midifile; if (!midifile.LoadMpsData(data, datalen)) { @@ -1083,7 +1121,7 @@ static bool CmdDumpSMF(byte argc, char *argv[]) return false; } - if (_midifile_instance == NULL) { + if (_midifile_instance == nullptr) { IConsolePrint(CC_ERROR, "There is no MIDI file loaded currently, make sure music is playing, and you're using a driver that works with raw MIDI."); return false; } @@ -1121,7 +1159,7 @@ MidiFile::MidiFile() MidiFile::~MidiFile() { if (_midifile_instance == this) { - _midifile_instance = NULL; + _midifile_instance = nullptr; } } diff --git a/src/music/midifile.hpp b/src/music/midifile.hpp index 0016be86ca..d786bf0078 100644 --- a/src/music/midifile.hpp +++ b/src/music/midifile.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. @@ -22,9 +20,9 @@ struct MusicSongInfo; struct MidiFile { struct DataBlock { - uint32 ticktime; ///< tick number since start of file this block should be triggered at - uint32 realtime; ///< real-time (microseconds) since start of file this block should be triggered at - SmallVector data; ///< raw midi data contained in block + uint32 ticktime; ///< tick number since start of file this block should be triggered at + uint32 realtime; ///< real-time (microseconds) since start of file this block should be triggered at + std::vector data; ///< raw midi data contained in block DataBlock(uint32 _ticktime = 0) : ticktime(_ticktime) { } }; struct TempoChange { diff --git a/src/music/music_driver.hpp b/src/music/music_driver.hpp index f4d3d7dd36..601cc6d475 100644 --- a/src/music/music_driver.hpp +++ b/src/music/music_driver.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/music/null_m.cpp b/src/music/null_m.cpp index 90d08d04a1..c9c8bc84f0 100644 --- a/src/music/null_m.cpp +++ b/src/music/null_m.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. diff --git a/src/music/null_m.h b/src/music/null_m.h index 51e1a06656..09f84e35ce 100644 --- a/src/music/null_m.h +++ b/src/music/null_m.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. @@ -17,25 +15,25 @@ /** The music player that does nothing. */ class MusicDriver_Null : public MusicDriver { public: - /* virtual */ const char *Start(const char * const *param) { return NULL; } + const char *Start(const char * const *param) override { return nullptr; } - /* virtual */ void Stop() { } + void Stop() override { } - /* virtual */ void PlaySong(const MusicSongInfo &song) { } + void PlaySong(const MusicSongInfo &song) override { } - /* virtual */ void StopSong() { } + void StopSong() override { } - /* virtual */ bool IsSongPlaying() { return true; } + bool IsSongPlaying() override { return true; } - /* virtual */ void SetVolume(byte vol) { } - /* virtual */ const char *GetName() const { return "null"; } + void SetVolume(byte vol) override { } + const char *GetName() const override { return "null"; } }; /** Factory for the null music player. */ class FMusicDriver_Null : public DriverFactoryBase { public: FMusicDriver_Null() : DriverFactoryBase(Driver::DT_MUSIC, 1, "null", "Null Music Driver") {} - /* virtual */ Driver *CreateInstance() const { return new MusicDriver_Null(); } + Driver *CreateInstance() const override { return new MusicDriver_Null(); } }; #endif /* MUSIC_NULL_H */ diff --git a/src/music/os2_m.cpp b/src/music/os2_m.cpp index 1689f00a64..f66c2bd9e8 100644 --- a/src/music/os2_m.cpp +++ b/src/music/os2_m.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. @@ -45,7 +43,7 @@ static long CDECL MidiSendCommand(const char *cmd, ...) va_start(va, cmd); vseprintf(buf, lastof(buf), cmd, va); va_end(va); - return mciSendString(buf, NULL, 0, NULL, 0); + return mciSendString(buf, nullptr, 0, nullptr, 0); } /** OS/2's music player's factory. */ @@ -78,7 +76,7 @@ void MusicDriver_OS2::SetVolume(byte vol) bool MusicDriver_OS2::IsSongPlaying() { char buf[16]; - mciSendString("status song mode", buf, sizeof(buf), NULL, 0); + mciSendString("status song mode", buf, sizeof(buf), nullptr, 0); return strcmp(buf, "playing") == 0 || strcmp(buf, "seeking") == 0; } diff --git a/src/music/os2_m.h b/src/music/os2_m.h index ac7cd03197..d0a4809b2c 100644 --- a/src/music/os2_m.h +++ b/src/music/os2_m.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. @@ -17,25 +15,25 @@ /** OS/2's music player. */ class MusicDriver_OS2 : public MusicDriver { public: - /* virtual */ const char *Start(const char * const *param); + const char *Start(const char * const *param) override; - /* virtual */ void Stop(); + void Stop() override; - /* virtual */ void PlaySong(const MusicSongInfo &song); + void PlaySong(const MusicSongInfo &song) override; - /* virtual */ void StopSong(); + void StopSong() override; - /* virtual */ bool IsSongPlaying(); + bool IsSongPlaying() override; - /* virtual */ void SetVolume(byte vol); - /* virtual */ const char *GetName() const { return "os2"; } + void SetVolume(byte vol) override; + const char *GetName() const override { return "os2"; } }; /** Factory for OS/2's music player. */ class FMusicDriver_OS2 : public DriverFactoryBase { public: FMusicDriver_OS2() : DriverFactoryBase(Driver::DT_MUSIC, 10, "os2", "OS/2 Music Driver") {} - /* virtual */ Driver *CreateInstance() const { return new MusicDriver_OS2(); } + Driver *CreateInstance() const override { return new MusicDriver_OS2(); } }; #endif /* MUSIC_OS2_H */ diff --git a/src/music/qtmidi.cpp b/src/music/qtmidi.cpp index f8ab150e79..eea1e30842 100644 --- a/src/music/qtmidi.cpp +++ b/src/music/qtmidi.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. @@ -34,11 +32,13 @@ #include "../debug.h" #include "../base_media_base.h" -#define Rect OTTDRect -#define Point OTTDPoint +#define Rect OTTD_Rect +#define Point OTTD_Point +#define WindowClass OTTD_WindowClass #include #undef Rect #undef Point +#undef WindowClass #include "../safeguards.h" @@ -60,7 +60,7 @@ static void SetMIDITypeIfNeeded(const FSRef *ref) assert(ref); - if (noErr != FSGetCatalogInfo(ref, kFSCatInfoNodeFlags | kFSCatInfoFinderInfo, &catalogInfo, NULL, NULL, NULL)) return; + if (noErr != FSGetCatalogInfo(ref, kFSCatInfoNodeFlags | kFSCatInfoFinderInfo, &catalogInfo, nullptr, nullptr, nullptr)) return; if (!(catalogInfo.nodeFlags & kFSNodeIsDirectoryMask)) { FileInfo * const info = (FileInfo *) catalogInfo.finderInfo; if (info->fileType != MIDI_TYPE && !(info->finderFlags & kIsAlias)) { @@ -94,8 +94,8 @@ static bool LoadMovieForMIDIFile(const char *path, Movie *moov) short refnum = 0; short resid = 0; - assert(path != NULL); - assert(moov != NULL); + assert(path != nullptr); + assert(moov != nullptr); DEBUG(driver, 2, "qtmidi: start loading '%s'...", path); @@ -116,15 +116,15 @@ static bool LoadMovieForMIDIFile(const char *path, Movie *moov) return false; } - if (noErr != FSPathMakeRef((const UInt8 *) path, &fsref, NULL)) return false; + if (noErr != FSPathMakeRef((const UInt8 *) path, &fsref, nullptr)) return false; SetMIDITypeIfNeeded(&fsref); - if (noErr != FSGetCatalogInfo(&fsref, kFSCatInfoNone, NULL, NULL, &fsspec, NULL)) return false; + if (noErr != FSGetCatalogInfo(&fsref, kFSCatInfoNone, nullptr, nullptr, &fsspec, nullptr)) return false; if (OpenMovieFile(&fsspec, &refnum, fsRdPerm) != noErr) return false; DEBUG(driver, 3, "qtmidi: '%s' successfully opened", path); - if (noErr != NewMovieFromFile(moov, refnum, &resid, NULL, - newMovieActive | newMovieDontAskUnresolvedDataRefs, NULL)) { + if (noErr != NewMovieFromFile(moov, refnum, &resid, nullptr, + newMovieActive | newMovieDontAskUnresolvedDataRefs, nullptr)) { CloseMovieFile(refnum); return false; } @@ -154,7 +154,7 @@ static void InitQuickTimeIfNeeded() if (_quicktime_started) return; DEBUG(driver, 2, "qtmidi: initializing Quicktime"); - /* Be polite: check wether QuickTime is available and initialize it. */ + /* Be polite: check whether QuickTime is available and initialize it. */ _quicktime_started = (noErr == Gestalt(gestaltQuickTime, &dummy)) && (noErr == EnterMovies()); @@ -191,7 +191,7 @@ static int _quicktime_state = QT_STATE_IDLE; ///< Current player state. const char *MusicDriver_QtMidi::Start(const char * const *parm) { InitQuickTimeIfNeeded(); - return (_quicktime_started) ? NULL : "can't initialize QuickTime"; + return (_quicktime_started) ? nullptr : "can't initialize QuickTime"; } @@ -213,9 +213,9 @@ bool MusicDriver_QtMidi::IsSongPlaying() case QT_STATE_PLAY: MoviesTask(_quicktime_movie, 0); - /* Check wether movie ended. */ + /* Check whether movie ended. */ if (IsMovieDone(_quicktime_movie) || - (GetMovieTime(_quicktime_movie, NULL) >= + (GetMovieTime(_quicktime_movie, nullptr) >= GetMovieDuration(_quicktime_movie))) { _quicktime_state = QT_STATE_STOP; } diff --git a/src/music/qtmidi.h b/src/music/qtmidi.h index 32163db939..d6ed5304a0 100644 --- a/src/music/qtmidi.h +++ b/src/music/qtmidi.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. @@ -16,24 +14,24 @@ class MusicDriver_QtMidi : public MusicDriver { public: - /* virtual */ const char *Start(const char * const *param); + const char *Start(const char * const *param) override; - /* virtual */ void Stop(); + void Stop() override; - /* virtual */ void PlaySong(const MusicSongInfo &song); + void PlaySong(const MusicSongInfo &song) override; - /* virtual */ void StopSong(); + void StopSong() override; - /* virtual */ bool IsSongPlaying(); + bool IsSongPlaying() override; - /* virtual */ void SetVolume(byte vol); - /* virtual */ const char *GetName() const { return "qt"; } + void SetVolume(byte vol) override; + const char *GetName() const override { return "qt"; } }; class FMusicDriver_QtMidi : public DriverFactoryBase { public: FMusicDriver_QtMidi() : DriverFactoryBase(Driver::DT_MUSIC, 5, "qt", "QuickTime MIDI Driver") {} - /* virtual */ Driver *CreateInstance() const { return new MusicDriver_QtMidi(); } + Driver *CreateInstance() const override { return new MusicDriver_QtMidi(); } }; #endif /* MUSIC_MACOSX_QUICKTIME_H */ diff --git a/src/music/win32_m.cpp b/src/music/win32_m.cpp index a32318db12..b4f656b141 100644 --- a/src/music/win32_m.cpp +++ b/src/music/win32_m.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. @@ -19,6 +17,7 @@ #include "midifile.hpp" #include "midi.h" #include "../base_media_base.h" +#include #include "../safeguards.h" @@ -29,13 +28,13 @@ struct PlaybackSegment { }; static struct { - UINT time_period; ///< obtained timer precision value - HMIDIOUT midi_out; ///< handle to open midiOut - UINT timer_id; ///< ID of active multimedia timer - CRITICAL_SECTION lock; ///< synchronization for playback status fields + UINT time_period; ///< obtained timer precision value + HMIDIOUT midi_out; ///< handle to open midiOut + UINT timer_id; ///< ID of active multimedia timer + std::mutex lock; ///< synchronization for playback status fields bool playing; ///< flag indicating that playback is active - bool do_start; ///< flag for starting playback of next_file at next opportunity + int do_start; ///< flag for starting playback of next_file at next opportunity bool do_stop; ///< flag for stopping playback at next opportunity byte current_volume; ///< current effective volume setting byte new_volume; ///< volume setting to change to @@ -73,16 +72,16 @@ static void TransmitChannelMsg(byte status, byte p1, byte p2 = 0) midiOutShortMsg(_midi.midi_out, status | (p1 << 8) | (p2 << 16)); } -static void TransmitSysex(byte *&msg_start, size_t &remaining) +static void TransmitSysex(const byte *&msg_start, size_t &remaining) { /* find end of message */ - byte *msg_end = msg_start; + const byte *msg_end = msg_start; while (*msg_end != MIDIST_ENDSYSEX) msg_end++; msg_end++; /* also include sysex end byte */ /* prepare header */ MIDIHDR *hdr = CallocT(1); - hdr->lpData = (LPSTR)msg_start; + hdr->lpData = reinterpret_cast(const_cast(msg_start)); hdr->dwBufferLength = msg_end - msg_start; if (midiOutPrepareHeader(_midi.midi_out, hdr, sizeof(*hdr)) == MMSYSERR_NOERROR) { /* transmit - just point directly into the data buffer */ @@ -97,9 +96,11 @@ static void TransmitSysex(byte *&msg_start, size_t &remaining) msg_start = msg_end; } -static void TransmitSysexConst(byte *msg_start, size_t length) +static void TransmitStandardSysex(MidiSysexMessage msg) { - TransmitSysex(msg_start, length); + size_t length = 0; + const byte *data = MidiGetStandardSysexMessage(msg, length); + TransmitSysex(data, length); } /** @@ -108,86 +109,93 @@ static void TransmitSysexConst(byte *msg_start, size_t length) */ void CALLBACK TimerCallback(UINT uTimerID, UINT, DWORD_PTR dwUser, DWORD_PTR, DWORD_PTR) { - /* Try to check playback status changes. - * If _midi is already locked, skip checking for this cycle and try again - * next cycle, instead of waiting for locks in the realtime callback. */ - if (TryEnterCriticalSection(&_midi.lock)) { - /* check for stop */ - if (_midi.do_stop) { - DEBUG(driver, 2, "Win32-MIDI: timer: do_stop is set"); - midiOutReset(_midi.midi_out); - _midi.playing = false; - _midi.do_stop = false; - LeaveCriticalSection(&_midi.lock); + /* Ensure only one timer callback is running at once, and prevent races on status flags */ + std::unique_lock mutex_lock(_midi.lock, std::defer_lock); + if (!mutex_lock.try_lock()) return; + + /* check for stop */ + if (_midi.do_stop) { + DEBUG(driver, 2, "Win32-MIDI: timer: do_stop is set"); + midiOutReset(_midi.midi_out); + _midi.playing = false; + _midi.do_stop = false; + return; + } + + /* check for start/restart/change song */ + if (_midi.do_start != 0) { + /* Have a delay between playback start steps, prevents jumbled-together notes at the start of song */ + if (timeGetTime() - _midi.playback_start_time < 50) { return; } + DEBUG(driver, 2, "Win32-MIDI: timer: do_start step %d", _midi.do_start); - /* check for start/restart/change song */ - if (_midi.do_start) { - DEBUG(driver, 2, "Win32-MIDI: timer: do_start is set"); - if (_midi.playing) { - midiOutReset(_midi.midi_out); - /* Some songs change the "Pitch bend range" registered - * parameter. If this doesn't get reset, everything else - * will start sounding wrong. */ - for (int ch = 0; ch < 16; ch++) { - /* Running status, only need status for first message */ - /* Select RPN 00.00, set value to 02.00, and unselect again */ - TransmitChannelMsg(MIDIST_CONTROLLER | ch, MIDICT_RPN_SELECT_LO, 0x00); - TransmitChannelMsg(MIDICT_RPN_SELECT_HI, 0x00); - TransmitChannelMsg(MIDICT_DATAENTRY, 0x02); - TransmitChannelMsg(MIDICT_DATAENTRY_LO, 0x00); - TransmitChannelMsg(MIDICT_RPN_SELECT_LO, 0x7F); - TransmitChannelMsg(MIDICT_RPN_SELECT_HI, 0x7F); - } - } + if (_midi.do_start == 1) { + /* Send "all notes off" */ + midiOutReset(_midi.midi_out); + _midi.playback_start_time = timeGetTime(); + _midi.do_start = 2; + + return; + } else if (_midi.do_start == 2) { + /* Reset the device to General MIDI defaults */ + TransmitStandardSysex(MidiSysexMessage::ResetGM); + _midi.playback_start_time = timeGetTime(); + _midi.do_start = 3; + + return; + } else if (_midi.do_start == 3) { + /* Set up device-specific effects */ + TransmitStandardSysex(MidiSysexMessage::RolandSetReverb); + _midi.playback_start_time = timeGetTime(); + _midi.do_start = 4; + + return; + } else if (_midi.do_start == 4) { + /* Load the new file */ _midi.current_file.MoveFrom(_midi.next_file); std::swap(_midi.next_segment, _midi.current_segment); _midi.current_segment.start_block = 0; _midi.playback_start_time = timeGetTime(); _midi.playing = true; - _midi.do_start = false; + _midi.do_start = 0; _midi.current_block = 0; MemSetT(_midi.channel_volumes, 127, lengthof(_midi.channel_volumes)); - } else if (!_midi.playing) { - /* not playing, stop the timer */ - DEBUG(driver, 2, "Win32-MIDI: timer: not playing, stopping timer"); - timeKillEvent(uTimerID); - _midi.timer_id = 0; - LeaveCriticalSection(&_midi.lock); - return; } + } else if (!_midi.playing) { + /* not playing, stop the timer */ + DEBUG(driver, 2, "Win32-MIDI: timer: not playing, stopping timer"); + timeKillEvent(uTimerID); + _midi.timer_id = 0; + return; + } - /* check for volume change */ - static int volume_throttle = 0; - if (_midi.current_volume != _midi.new_volume) { - if (volume_throttle == 0) { - DEBUG(driver, 2, "Win32-MIDI: timer: volume change"); - _midi.current_volume = _midi.new_volume; - volume_throttle = 20 / _midi.time_period; - for (int ch = 0; ch < 16; ch++) { - int vol = ScaleVolume(_midi.channel_volumes[ch], _midi.current_volume); - TransmitChannelMsg(MIDIST_CONTROLLER | ch, MIDICT_CHANVOLUME, vol); - } - } - else { - volume_throttle--; + /* check for volume change */ + static int volume_throttle = 0; + if (_midi.current_volume != _midi.new_volume) { + if (volume_throttle == 0) { + DEBUG(driver, 2, "Win32-MIDI: timer: volume change"); + _midi.current_volume = _midi.new_volume; + volume_throttle = 20 / _midi.time_period; + for (int ch = 0; ch < 16; ch++) { + byte vol = ScaleVolume(_midi.channel_volumes[ch], _midi.current_volume); + TransmitChannelMsg(MIDIST_CONTROLLER | ch, MIDICT_CHANVOLUME, vol); } + } else { + volume_throttle--; } - - LeaveCriticalSection(&_midi.lock); } /* skip beginning of file? */ if (_midi.current_segment.start > 0 && _midi.current_block == 0 && _midi.current_segment.start_block == 0) { /* find first block after start time and pretend playback started earlier - * this is to allow all blocks prior to the actual start to still affect playback, - * as they may contain important controller and program changes */ - uint preload_bytes = 0; + * this is to allow all blocks prior to the actual start to still affect playback, + * as they may contain important controller and program changes */ + size_t preload_bytes = 0; for (size_t bl = 0; bl < _midi.current_file.blocks.size(); bl++) { MidiFile::DataBlock &block = _midi.current_file.blocks[bl]; - preload_bytes += block.data.Length(); + preload_bytes += block.data.size(); if (block.ticktime >= _midi.current_segment.start) { if (_midi.current_segment.loop) { DEBUG(driver, 2, "Win32-MIDI: timer: loop from block %d (ticktime %d, realtime %.3f, bytes %d)", (int)bl, (int)block.ticktime, ((int)block.realtime)/1000.0, (int)preload_bytes); @@ -200,7 +208,7 @@ void CALLBACK TimerCallback(UINT uTimerID, UINT, DWORD_PTR dwUser, DWORD_PTR, DW * The delay compensation is needed to avoid time-compression of following messages. */ DEBUG(driver, 2, "Win32-MIDI: timer: start from block %d (ticktime %d, realtime %.3f, bytes %d)", (int)bl, (int)block.ticktime, ((int)block.realtime) / 1000.0, (int)preload_bytes); - _midi.playback_start_time -= block.realtime / 1000 - preload_bytes * 1000 / 3125; + _midi.playback_start_time -= block.realtime / 1000 - (DWORD)(preload_bytes * 1000 / 3125); break; } } @@ -229,8 +237,8 @@ void CALLBACK TimerCallback(UINT uTimerID, UINT, DWORD_PTR dwUser, DWORD_PTR, DW break; } - byte *data = block.data.Begin(); - size_t remaining = block.data.Length(); + const byte *data = block.data.data(); + size_t remaining = block.data.size(); byte last_status = 0; while (remaining > 0) { /* MidiFile ought to have converted everything out of running status, @@ -313,61 +321,76 @@ void CALLBACK TimerCallback(UINT uTimerID, UINT, DWORD_PTR dwUser, DWORD_PTR, DW void MusicDriver_Win32::PlaySong(const MusicSongInfo &song) { DEBUG(driver, 2, "Win32-MIDI: PlaySong: entry"); - EnterCriticalSection(&_midi.lock); - if (!_midi.next_file.LoadSong(song)) { - LeaveCriticalSection(&_midi.lock); - return; - } + MidiFile new_song; + if (!new_song.LoadSong(song)) return; + DEBUG(driver, 2, "Win32-MIDI: PlaySong: Loaded song"); + std::lock_guard mutex_lock(_midi.lock); + + _midi.next_file.MoveFrom(new_song); _midi.next_segment.start = song.override_start; _midi.next_segment.end = song.override_end; _midi.next_segment.loop = song.loop; DEBUG(driver, 2, "Win32-MIDI: PlaySong: setting flag"); _midi.do_stop = _midi.playing; - _midi.do_start = true; + _midi.do_start = 1; if (_midi.timer_id == 0) { DEBUG(driver, 2, "Win32-MIDI: PlaySong: starting timer"); _midi.timer_id = timeSetEvent(_midi.time_period, _midi.time_period, TimerCallback, (DWORD_PTR)this, TIME_PERIODIC | TIME_CALLBACK_FUNCTION); } - - LeaveCriticalSection(&_midi.lock); } void MusicDriver_Win32::StopSong() { DEBUG(driver, 2, "Win32-MIDI: StopSong: entry"); - EnterCriticalSection(&_midi.lock); + std::lock_guard mutex_lock(_midi.lock); DEBUG(driver, 2, "Win32-MIDI: StopSong: setting flag"); _midi.do_stop = true; - LeaveCriticalSection(&_midi.lock); } bool MusicDriver_Win32::IsSongPlaying() { - return _midi.playing || _midi.do_start; + return _midi.playing || (_midi.do_start != 0); } void MusicDriver_Win32::SetVolume(byte vol) { - EnterCriticalSection(&_midi.lock); + std::lock_guard mutex_lock(_midi.lock); _midi.new_volume = vol; - LeaveCriticalSection(&_midi.lock); } const char *MusicDriver_Win32::Start(const char * const *parm) { DEBUG(driver, 2, "Win32-MIDI: Start: initializing"); - InitializeCriticalSection(&_midi.lock); - int resolution = GetDriverParamInt(parm, "resolution", 5); - int port = GetDriverParamInt(parm, "port", -1); + uint port = (uint)GetDriverParamInt(parm, "port", UINT_MAX); + const char *portname = GetDriverParam(parm, "portname"); + + /* Enumerate ports either for selecting port by name, or for debug output */ + if (portname != nullptr || _debug_driver_level > 0) { + uint numports = midiOutGetNumDevs(); + DEBUG(driver, 1, "Win32-MIDI: Found %d output devices:", numports); + for (uint tryport = 0; tryport < numports; tryport++) { + MIDIOUTCAPS moc{}; + if (midiOutGetDevCaps(tryport, &moc, sizeof(moc)) == MMSYSERR_NOERROR) { + char tryportname[128]; + convert_from_fs(moc.szPname, tryportname, lengthof(tryportname)); + + /* Compare requested and detected port name. + * If multiple ports have the same name, this will select the last matching port, and the debug output will be confusing. */ + if (portname != nullptr && strncmp(tryportname, portname, lengthof(tryportname)) == 0) port = tryport; + + DEBUG(driver, 1, "MIDI port %2d: %s%s", tryport, tryportname, (tryport == port) ? " [selected]" : ""); + } + } + } UINT devid; - if (port < 0) { + if (port == UINT_MAX) { devid = MIDI_MAPPER; } else { devid = (UINT)port; @@ -381,14 +404,6 @@ const char *MusicDriver_Win32::Start(const char * const *parm) midiOutReset(_midi.midi_out); - /* Standard "Enable General MIDI" message */ - static byte gm_enable_sysex[] = { 0xF0, 0x7E, 0x00, 0x09, 0x01, 0xF7 }; - TransmitSysexConst(&gm_enable_sysex[0], sizeof(gm_enable_sysex)); - - /* Roland-specific reverb room control, used by the original game */ - static byte roland_reverb_sysex[] = { 0xF0, 0x41, 0x10, 0x42, 0x12, 0x40, 0x01, 0x30, 0x02, 0x04, 0x00, 0x40, 0x40, 0x00, 0x00, 0x09, 0xF7 }; - TransmitSysexConst(&roland_reverb_sysex[0], sizeof(roland_reverb_sysex)); - /* prepare multimedia timer */ TIMECAPS timecaps; if (timeGetDevCaps(&timecaps, sizeof(timecaps)) == MMSYSERR_NOERROR) { @@ -396,7 +411,7 @@ const char *MusicDriver_Win32::Start(const char * const *parm) if (timeBeginPeriod(_midi.time_period) == MMSYSERR_NOERROR) { /* success */ DEBUG(driver, 2, "Win32-MIDI: Start: timer resolution is %d", (int)_midi.time_period); - return NULL; + return nullptr; } } midiOutClose(_midi.midi_out); @@ -405,7 +420,7 @@ const char *MusicDriver_Win32::Start(const char * const *parm) void MusicDriver_Win32::Stop() { - EnterCriticalSection(&_midi.lock); + std::lock_guard mutex_lock(_midi.lock); if (_midi.timer_id) { timeKillEvent(_midi.timer_id); @@ -415,7 +430,4 @@ void MusicDriver_Win32::Stop() timeEndPeriod(_midi.time_period); midiOutReset(_midi.midi_out); midiOutClose(_midi.midi_out); - - LeaveCriticalSection(&_midi.lock); - DeleteCriticalSection(&_midi.lock); } diff --git a/src/music/win32_m.h b/src/music/win32_m.h index 1ac8ae69e4..394c3d9909 100644 --- a/src/music/win32_m.h +++ b/src/music/win32_m.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. @@ -17,25 +15,25 @@ /** The Windows music player. */ class MusicDriver_Win32 : public MusicDriver { public: - /* virtual */ const char *Start(const char * const *param); + const char *Start(const char * const *param) override; - /* virtual */ void Stop(); + void Stop() override; - /* virtual */ void PlaySong(const MusicSongInfo &song); + void PlaySong(const MusicSongInfo &song) override; - /* virtual */ void StopSong(); + void StopSong() override; - /* virtual */ bool IsSongPlaying(); + bool IsSongPlaying() override; - /* virtual */ void SetVolume(byte vol); - /* virtual */ const char *GetName() const { return "win32"; } + void SetVolume(byte vol) override; + const char *GetName() const override { return "win32"; } }; /** Factory for Windows' music player. */ class FMusicDriver_Win32 : public DriverFactoryBase { public: FMusicDriver_Win32() : DriverFactoryBase(Driver::DT_MUSIC, 5, "win32", "Win32 Music Driver") {} - /* virtual */ Driver *CreateInstance() const { return new MusicDriver_Win32(); } + Driver *CreateInstance() const override { return new MusicDriver_Win32(); } }; #endif /* MUSIC_WIN32_H */ diff --git a/src/music_gui.cpp b/src/music_gui.cpp index 626dc44bdb..a52be14dea 100644 --- a/src/music_gui.cpp +++ b/src/music_gui.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. @@ -478,7 +476,7 @@ struct MusicTrackSelectionWindow : public Window { this->right_sb->SetCount(GetNumberOfTracksOfTracklist()); } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { switch (widget) { case WID_MTS_PLAYLIST: @@ -495,7 +493,7 @@ struct MusicTrackSelectionWindow : public Window { * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; for (int i = 0; i < 6; i++) { @@ -506,7 +504,7 @@ struct MusicTrackSelectionWindow : public Window { this->SetDirty(); } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_MTS_PLAYLIST: { @@ -541,7 +539,7 @@ struct MusicTrackSelectionWindow : public Window { } } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { switch (widget) { case WID_MTS_LIST_LEFT: { @@ -582,7 +580,7 @@ struct MusicTrackSelectionWindow : public Window { } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_MTS_LIST_LEFT: { // add to playlist @@ -599,8 +597,7 @@ struct MusicTrackSelectionWindow : public Window { case WID_MTS_MUSICSET: { int selected = 0; - DropDownList *dropdown = BuildMusicSetDropDownList(&selected); - ShowDropDownList(this, dropdown, selected, widget, 0, true, false); + ShowDropDownList(this, BuildMusicSetDropDownList(&selected), selected, widget, 0, true, false); break; } @@ -615,7 +612,7 @@ struct MusicTrackSelectionWindow : public Window { } } - virtual void OnDropdownSelect(int widget, int index) + void OnDropdownSelect(int widget, int index) override { switch (widget) { case WID_MTS_MUSICSET: @@ -712,7 +709,7 @@ struct MusicWindow : public Window { ); } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { /* Make sure that WID_M_SHUFFLE and WID_M_PROGRAMME have the same size. @@ -754,7 +751,7 @@ struct MusicWindow : public Window { } } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { switch (widget) { case WID_M_TRACK_NR: { @@ -775,23 +772,35 @@ struct MusicWindow : public Window { case WID_M_TRACK_NAME: { GfxFillRect(r.left, r.top + 1, r.right - 1, r.bottom, PC_BLACK); StringID str = STR_MUSIC_TITLE_NONE; + MusicSystem::PlaylistEntry entry(_music.GetCurrentSong()); if (BaseMusic::GetUsedSet()->num_available == 0) { str = STR_MUSIC_TITLE_NOMUSIC; } else if (_music.IsPlaying()) { str = STR_MUSIC_TITLE_NAME; - SetDParamStr(0, _music.GetCurrentSong().songname); + SetDParamStr(0, entry.songname); } DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, Center(r.top, r.bottom - r.top, FONT_HEIGHT_SMALL), str, TC_FROMSTRING, SA_HOR_CENTER); break; } case WID_M_MUSIC_VOL: case WID_M_EFFECT_VOL: { - int sw = ScaleGUITrad(slider_width); - int hsw = sw / 2; - DrawFrameRect(r.left + hsw, r.top + 2, r.right - hsw, r.bottom - 2, COLOUR_GREY, FR_LOWERED); + /* Draw a wedge indicating low to high volume level. */ + const int ha = (r.bottom - r.top) / 5; + int wx1 = r.left, wx2 = r.right; + 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); + /* Draw a slider handle indicating current volume level. */ + const int sw = ScaleGUITrad(slider_width); byte volume = (widget == WID_M_MUSIC_VOL) ? _settings_client.music.music_vol : _settings_client.music.effect_vol; if (_current_text_dir == TD_RTL) volume = 127 - volume; - int x = r.left + (volume * (r.right - r.left - sw) / 127); + const int x = r.left + (volume * (r.right - r.left - sw) / 127); DrawFrameRect(x, r.top, x + sw, r.bottom, COLOUR_GREY, FR_NONE); break; } @@ -803,7 +812,7 @@ struct MusicWindow : public Window { * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; for (int i = 0; i < 6; i++) { @@ -815,7 +824,7 @@ struct MusicWindow : public Window { this->SetDirty(); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_M_PREV: // skip to prev @@ -896,32 +905,14 @@ static const NWidgetPart _nested_music_window_widgets[] = { NWidget(WWT_PANEL, COLOUR_GREY, -1), SetFill(1, 1), EndContainer(), EndContainer(), NWidget(WWT_PANEL, COLOUR_GREY, WID_M_SLIDERS), - NWidget(NWID_HORIZONTAL), SetPIP(20, 20, 20), + NWidget(NWID_HORIZONTAL), SetPIP(4, 0, 4), NWidget(NWID_VERTICAL), NWidget(WWT_LABEL, COLOUR_GREY, -1), SetFill(1, 0), SetDataTip(STR_MUSIC_MUSIC_VOLUME, STR_NULL), - NWidget(WWT_EMPTY, COLOUR_GREY, WID_M_MUSIC_VOL), SetMinimalSize(67, 0), SetMinimalTextLines(1, 0), SetFill(1, 0), SetDataTip(0x0, STR_MUSIC_TOOLTIP_DRAG_SLIDERS_TO_SET_MUSIC), - NWidget(NWID_HORIZONTAL), - NWidget(WWT_LABEL, COLOUR_GREY, -1), SetDataTip(STR_MUSIC_RULER_MIN, STR_NULL), - NWidget(WWT_LABEL, COLOUR_GREY, -1), SetDataTip(STR_MUSIC_RULER_MARKER, STR_NULL), SetFill(1, 0), - NWidget(WWT_LABEL, COLOUR_GREY, -1), SetDataTip(STR_MUSIC_RULER_MARKER, STR_NULL), SetFill(1, 0), - NWidget(WWT_LABEL, COLOUR_GREY, -1), SetDataTip(STR_MUSIC_RULER_MARKER, STR_NULL), SetFill(1, 0), - NWidget(WWT_LABEL, COLOUR_GREY, -1), SetDataTip(STR_MUSIC_RULER_MARKER, STR_NULL), SetFill(1, 0), - NWidget(WWT_LABEL, COLOUR_GREY, -1), SetDataTip(STR_MUSIC_RULER_MARKER, STR_NULL), SetFill(1, 0), - NWidget(WWT_LABEL, COLOUR_GREY, -1), SetDataTip(STR_MUSIC_RULER_MAX, STR_NULL), - EndContainer(), + NWidget(WWT_EMPTY, COLOUR_GREY, WID_M_MUSIC_VOL), SetMinimalSize(67, 0), SetPadding(2), SetMinimalTextLines(1, 0), SetFill(1, 0), SetDataTip(0x0, STR_MUSIC_TOOLTIP_DRAG_SLIDERS_TO_SET_MUSIC), EndContainer(), NWidget(NWID_VERTICAL), NWidget(WWT_LABEL, COLOUR_GREY, -1), SetFill(1, 0), SetDataTip(STR_MUSIC_EFFECTS_VOLUME, STR_NULL), - NWidget(WWT_EMPTY, COLOUR_GREY, WID_M_EFFECT_VOL), SetMinimalSize(67, 0), SetMinimalTextLines(1, 0), SetFill(1, 0), SetDataTip(0x0, STR_MUSIC_TOOLTIP_DRAG_SLIDERS_TO_SET_MUSIC), - NWidget(NWID_HORIZONTAL), - NWidget(WWT_LABEL, COLOUR_GREY, -1), SetDataTip(STR_MUSIC_RULER_MIN, STR_NULL), - NWidget(WWT_LABEL, COLOUR_GREY, -1), SetDataTip(STR_MUSIC_RULER_MARKER, STR_NULL), SetFill(1, 0), - NWidget(WWT_LABEL, COLOUR_GREY, -1), SetDataTip(STR_MUSIC_RULER_MARKER, STR_NULL), SetFill(1, 0), - NWidget(WWT_LABEL, COLOUR_GREY, -1), SetDataTip(STR_MUSIC_RULER_MARKER, STR_NULL), SetFill(1, 0), - NWidget(WWT_LABEL, COLOUR_GREY, -1), SetDataTip(STR_MUSIC_RULER_MARKER, STR_NULL), SetFill(1, 0), - NWidget(WWT_LABEL, COLOUR_GREY, -1), SetDataTip(STR_MUSIC_RULER_MARKER, STR_NULL), SetFill(1, 0), - NWidget(WWT_LABEL, COLOUR_GREY, -1), SetDataTip(STR_MUSIC_RULER_MAX, STR_NULL), - EndContainer(), + NWidget(WWT_EMPTY, COLOUR_GREY, WID_M_EFFECT_VOL), SetMinimalSize(67, 0), SetPadding(2), SetMinimalTextLines(1, 0), SetFill(1, 0), SetDataTip(0x0, STR_MUSIC_TOOLTIP_DRAG_SLIDERS_TO_SET_MUSIC), EndContainer(), EndContainer(), EndContainer(), diff --git a/src/network/core/address.cpp b/src/network/core/address.cpp index 62af3a40bf..44ba453856 100644 --- a/src/network/core/address.cpp +++ b/src/network/core/address.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. @@ -11,8 +9,6 @@ #include "../../stdafx.h" -#ifdef ENABLE_NETWORK - #include "address.h" #include "../../debug.h" @@ -27,7 +23,7 @@ const char *NetworkAddress::GetHostname() { if (StrEmpty(this->hostname) && this->address.ss_family != AF_UNSPEC) { assert(this->address_length != 0); - getnameinfo((struct sockaddr *)&this->address, this->address_length, this->hostname, sizeof(this->hostname), NULL, 0, NI_NUMERICHOST); + getnameinfo((struct sockaddr *)&this->address, this->address_length, this->hostname, sizeof(this->hostname), nullptr, 0, NI_NUMERICHOST); } return this->hostname; } @@ -133,7 +129,7 @@ const sockaddr_storage *NetworkAddress::GetAddress() * bothered to implement the specifications and allow '0' as value * that means "don't care whether it is SOCK_STREAM or SOCK_DGRAM". */ - this->Resolve(this->address.ss_family, SOCK_STREAM, AI_ADDRCONFIG, NULL, ResolveLoopProc); + this->Resolve(this->address.ss_family, SOCK_STREAM, AI_ADDRCONFIG, nullptr, ResolveLoopProc); this->resolved = true; } return &this->address; @@ -147,7 +143,7 @@ const sockaddr_storage *NetworkAddress::GetAddress() bool NetworkAddress::IsFamily(int family) { if (!this->IsResolved()) { - this->Resolve(family, SOCK_STREAM, AI_ADDRCONFIG, NULL, ResolveLoopProc); + this->Resolve(family, SOCK_STREAM, AI_ADDRCONFIG, nullptr, ResolveLoopProc); } return this->address.ss_family == family; } @@ -158,7 +154,7 @@ bool NetworkAddress::IsFamily(int family) * @note netmask without /n assumes all bits need to match. * @return true if this IP is within the netmask. */ -bool NetworkAddress::IsInNetmask(char *netmask) +bool NetworkAddress::IsInNetmask(const char *netmask) { /* Resolve it if we didn't do it already */ if (!this->IsResolved()) this->GetAddress(); @@ -168,17 +164,16 @@ bool NetworkAddress::IsInNetmask(char *netmask) NetworkAddress mask_address; /* Check for CIDR separator */ - char *chr_cidr = strchr(netmask, '/'); - if (chr_cidr != NULL) { + const char *chr_cidr = strchr(netmask, '/'); + if (chr_cidr != nullptr) { int tmp_cidr = atoi(chr_cidr + 1); /* Invalid CIDR, treat as single host */ if (tmp_cidr > 0 || tmp_cidr < cidr) cidr = tmp_cidr; - /* Remove and then replace the / so that NetworkAddress works on the IP portion */ - *chr_cidr = '\0'; - mask_address = NetworkAddress(netmask, 0, this->address.ss_family); - *chr_cidr = '/'; + /* Remove the / so that NetworkAddress works on the IP portion */ + std::string ip_str(netmask, chr_cidr - netmask); + mask_address = NetworkAddress(ip_str.c_str(), 0, this->address.ss_family); } else { mask_address = NetworkAddress(netmask, 0, this->address.ss_family); } @@ -235,7 +230,7 @@ SOCKET NetworkAddress::Resolve(int family, int socktype, int flags, SocketList * seprintf(port_name, lastof(port_name), "%u", this->GetPort()); bool reset_hostname = false; - /* Setting both hostname to NULL and port to 0 is not allowed. + /* Setting both hostname to nullptr and port to 0 is not allowed. * As port 0 means bind to any port, the other must mean that * we want to bind to 'all' IPs. */ if (StrEmpty(this->hostname) && this->address_length == 0 && this->GetPort() == 0) { @@ -245,7 +240,7 @@ SOCKET NetworkAddress::Resolve(int family, int socktype, int flags, SocketList * strecpy(this->hostname, fam == AF_INET ? "0.0.0.0" : "::", lastof(this->hostname)); } - int e = getaddrinfo(StrEmpty(this->hostname) ? NULL : this->hostname, port_name, &hints, &ai); + int e = getaddrinfo(StrEmpty(this->hostname) ? nullptr : this->hostname, port_name, &hints, &ai); if (reset_hostname) strecpy(this->hostname, "", lastof(this->hostname)); @@ -258,18 +253,18 @@ SOCKET NetworkAddress::Resolve(int family, int socktype, int flags, SocketList * } SOCKET sock = INVALID_SOCKET; - for (struct addrinfo *runp = ai; runp != NULL; runp = runp->ai_next) { + for (struct addrinfo *runp = ai; runp != nullptr; runp = runp->ai_next) { /* When we are binding to multiple sockets, make sure we do not * connect to one with exactly the same address twice. That's * of course totally unneeded ;) */ - if (sockets != NULL) { + if (sockets != nullptr) { NetworkAddress address(runp->ai_addr, (int)runp->ai_addrlen); if (sockets->Contains(address)) continue; } sock = func(runp); if (sock == INVALID_SOCKET) continue; - if (sockets == NULL) { + if (sockets == nullptr) { this->address_length = (int)runp->ai_addrlen; assert(sizeof(this->address) >= runp->ai_addrlen); memcpy(&this->address, runp->ai_addr, runp->ai_addrlen); @@ -326,7 +321,7 @@ SOCKET NetworkAddress::Connect() { DEBUG(net, 1, "Connecting to %s", this->GetAddressAsString()); - return this->Resolve(AF_UNSPEC, SOCK_STREAM, AI_ADDRCONFIG, NULL, ConnectLoopProc); + return this->Resolve(AF_UNSPEC, SOCK_STREAM, AI_ADDRCONFIG, nullptr, ConnectLoopProc); } /** @@ -389,9 +384,9 @@ static SOCKET ListenLoopProc(addrinfo *runp) */ void NetworkAddress::Listen(int socktype, SocketList *sockets) { - assert(sockets != NULL); + assert(sockets != nullptr); - /* Setting both hostname to NULL and port to 0 is not allowed. + /* Setting both hostname to nullptr and port to 0 is not allowed. * As port 0 means bind to any port, the other must mean that * we want to bind to 'all' IPs. */ if (this->address_length == 0 && this->address.ss_family == AF_UNSPEC && @@ -433,5 +428,3 @@ void NetworkAddress::Listen(int socktype, SocketList *sockets) default: return "unsupported"; } } - -#endif /* ENABLE_NETWORK */ diff --git a/src/network/core/address.h b/src/network/core/address.h index 9fd40eaeef..980d7227df 100644 --- a/src/network/core/address.h +++ b/src/network/core/address.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. @@ -17,11 +15,9 @@ #include "../../string_func.h" #include "../../core/smallmap_type.hpp" -#ifdef ENABLE_NETWORK - class NetworkAddress; -typedef SmallVector NetworkAddressList; ///< Type for a list of addresses. -typedef SmallMap SocketList; ///< Type for a mapping between address and socket. +typedef std::vector NetworkAddressList; ///< Type for a list of addresses. +typedef SmallMap SocketList; ///< Type for a mapping between address and socket. /** * Wrapper for (un)resolved network addresses; there's no reason to transform @@ -86,22 +82,13 @@ public: if (*hostname == '[') hostname++; strecpy(this->hostname, StrEmpty(hostname) ? "" : hostname, lastof(this->hostname)); char *tmp = strrchr(this->hostname, ']'); - if (tmp != NULL) *tmp = '\0'; + if (tmp != nullptr) *tmp = '\0'; memset(&this->address, 0, sizeof(this->address)); this->address.ss_family = family; this->SetPort(port); } - /** - * Make a clone of another address - * @param address the address to clone - */ - NetworkAddress(const NetworkAddress &address) - { - memcpy(this, &address, sizeof(*this)); - } - const char *GetHostname(); void GetAddressAsString(char *buffer, const char *last, bool with_family = true); const char *GetAddressAsString(bool with_family = true); @@ -131,7 +118,7 @@ public: } bool IsFamily(int family); - bool IsInNetmask(char *netmask); + bool IsInNetmask(const char *netmask); /** * Compare the address of this class with the address of another. @@ -192,5 +179,4 @@ public: static const char *AddressFamilyAsString(int family); }; -#endif /* ENABLE_NETWORK */ #endif /* NETWORK_CORE_ADDRESS_H */ diff --git a/src/network/core/config.h b/src/network/core/config.h index f6823b1a93..3488b1ff28 100644 --- a/src/network/core/config.h +++ b/src/network/core/config.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/network/core/core.cpp b/src/network/core/core.cpp index c8db860dd5..0aeb9c65ce 100644 --- a/src/network/core/core.cpp +++ b/src/network/core/core.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. @@ -11,8 +9,6 @@ * @file core.cpp Functions used to initialize/shut down the core network */ -#ifdef ENABLE_NETWORK - #include "../../stdafx.h" #include "../../debug.h" #include "os_abstraction.h" @@ -21,48 +17,12 @@ #include "../../safeguards.h" -#ifdef __MORPHOS__ -/* the library base is required here */ -struct Library *SocketBase = NULL; -#endif - /** * Initializes the network core (as that is needed for some platforms * @return true if the core has been initialized, false otherwise */ bool NetworkCoreInitialize() { -#if defined(__MORPHOS__) || defined(__AMIGA__) - /* - * IMPORTANT NOTE: SocketBase needs to be initialized before we use _any_ - * network related function, else: crash. - */ - DEBUG(net, 3, "[core] loading bsd socket library"); - SocketBase = OpenLibrary("bsdsocket.library", 4); - if (SocketBase == NULL) { - DEBUG(net, 0, "[core] can't open bsdsocket.library version 4, network unavailable"); - return false; - } - -#if defined(__AMIGA__) - /* for usleep() implementation (only required for legacy AmigaOS builds) */ - TimerPort = CreateMsgPort(); - if (TimerPort != NULL) { - TimerRequest = (struct timerequest*)CreateIORequest(TimerPort, sizeof(struct timerequest); - if (TimerRequest != NULL) { - if (OpenDevice("timer.device", UNIT_MICROHZ, (struct IORequest*)TimerRequest, 0) == 0) { - TimerBase = TimerRequest->tr_node.io_Device; - if (TimerBase == NULL) { - /* free resources... */ - DEBUG(net, 0, "[core] can't initialize timer, network unavailable"); - return false; - } - } - } - } -#endif /* __AMIGA__ */ -#endif /* __MORPHOS__ / __AMIGA__ */ - /* Let's load the network in windows */ #ifdef _WIN32 { @@ -83,17 +43,6 @@ bool NetworkCoreInitialize() */ void NetworkCoreShutdown() { -#if defined(__MORPHOS__) || defined(__AMIGA__) - /* free allocated resources */ -#if defined(__AMIGA__) - if (TimerBase != NULL) CloseDevice((struct IORequest*)TimerRequest); // XXX This smells wrong - if (TimerRequest != NULL) DeleteIORequest(TimerRequest); - if (TimerPort != NULL) DeleteMsgPort(TimerPort); -#endif - - if (SocketBase != NULL) CloseLibrary(SocketBase); -#endif - #if defined(_WIN32) WSACleanup(); #endif @@ -127,5 +76,3 @@ void NetworkSocketHandler::ReceiveGRFIdentifier(Packet *p, GRFIdentifier *grf) grf->md5sum[j] = p->Recv_uint8(); } } - -#endif /* ENABLE_NETWORK */ diff --git a/src/network/core/core.h b/src/network/core/core.h index a250dbb081..bf83adc72c 100644 --- a/src/network/core/core.h +++ b/src/network/core/core.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. @@ -17,8 +15,6 @@ #include "../../newgrf_config.h" #include "config.h" -#ifdef ENABLE_NETWORK - bool NetworkCoreInitialize(); void NetworkCoreShutdown(); @@ -80,6 +76,4 @@ public: void SendCompanyInformation(Packet *p, const struct Company *c, const struct NetworkCompanyStats *stats, uint max_len = NETWORK_COMPANY_NAME_LENGTH); }; -#endif /* ENABLE_NETWORK */ - #endif /* NETWORK_CORE_CORE_H */ diff --git a/src/network/core/game.h b/src/network/core/game.h index a9da29118e..151ebef284 100644 --- a/src/network/core/game.h +++ b/src/network/core/game.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. @@ -19,8 +17,6 @@ #include "../../newgrf_config.h" #include "../../date_type.h" -#ifdef ENABLE_NETWORK - /** * The game information that is not generated on-the-fly and has to * be sent to the clients. @@ -58,6 +54,4 @@ struct NetworkGameInfo : NetworkServerGameInfo { const char * GetNetworkRevisionString(); -#endif /* ENABLE_NETWORK */ - #endif /* NETWORK_CORE_GAME_H */ diff --git a/src/network/core/host.cpp b/src/network/core/host.cpp index 216839032b..bcb048e474 100644 --- a/src/network/core/host.cpp +++ b/src/network/core/host.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. @@ -9,8 +7,6 @@ /** @file host.cpp Functions related to getting host specific data (IPs). */ -#ifdef ENABLE_NETWORK - #include "../../stdafx.h" #include "../../debug.h" #include "address.h" @@ -24,7 +20,7 @@ */ static void NetworkFindBroadcastIPsInternal(NetworkAddressList *broadcast); -#if defined(BEOS_NET_SERVER) || defined(__HAIKU__) /* doesn't have neither getifaddrs or net/if.h */ +#if defined(__HAIKU__) /* doesn't have neither getifaddrs or net/if.h */ /* Based on Andrew Bachmann's netstat+.c. Big thanks to him! */ extern "C" int _netstat(int fd, char **output, int verbose); @@ -47,7 +43,7 @@ static void NetworkFindBroadcastIPsInternal(NetworkAddressList *broadcast) // BE return; } - char *output_pointer = NULL; + char *output_pointer = nullptr; int output_length = _netstat(sock, &output_pointer, 1); if (output_length < 0) { DEBUG(net, 0, "[core] error running _netstat"); @@ -78,7 +74,7 @@ static void NetworkFindBroadcastIPsInternal(NetworkAddressList *broadcast) // BE memset(&address, 0, sizeof(address)); ((sockaddr_in*)&address)->sin_addr.s_addr = htonl(ip | ~netmask); NetworkAddress addr(address, sizeof(sockaddr)); - if (!broadcast->Contains(addr)) *broadcast->Append() = addr; + if (std::none_of(broadcast->begin(), broadcast->end(), [&addr](NetworkAddress const& elem) -> bool { return elem == addr; })) broadcast->push_back(addr); } if (read < 0) { break; @@ -96,13 +92,13 @@ static void NetworkFindBroadcastIPsInternal(NetworkAddressList *broadcast) // GE if (getifaddrs(&ifap) != 0) return; - for (ifa = ifap; ifa != NULL; ifa = ifa->ifa_next) { + for (ifa = ifap; ifa != nullptr; ifa = ifa->ifa_next) { if (!(ifa->ifa_flags & IFF_BROADCAST)) continue; - if (ifa->ifa_broadaddr == NULL) continue; + if (ifa->ifa_broadaddr == nullptr) continue; if (ifa->ifa_broadaddr->sa_family != AF_INET) continue; NetworkAddress addr(ifa->ifa_broadaddr, sizeof(sockaddr)); - if (!broadcast->Contains(addr)) *broadcast->Append() = addr; + if (std::none_of(broadcast->begin(), broadcast->end(), [&addr](NetworkAddress const& elem) -> bool { return elem == addr; })) broadcast->push_back(addr); } freeifaddrs(ifap); } @@ -118,7 +114,7 @@ static void NetworkFindBroadcastIPsInternal(NetworkAddressList *broadcast) // Wi INTERFACE_INFO *ifo = CallocT(num); for (;;) { - if (WSAIoctl(sock, SIO_GET_INTERFACE_LIST, NULL, 0, ifo, num * sizeof(*ifo), &len, NULL, NULL) == 0) break; + if (WSAIoctl(sock, SIO_GET_INTERFACE_LIST, nullptr, 0, ifo, num * sizeof(*ifo), &len, nullptr, nullptr) == 0) break; free(ifo); if (WSAGetLastError() != WSAEFAULT) { closesocket(sock); @@ -138,7 +134,7 @@ static void NetworkFindBroadcastIPsInternal(NetworkAddressList *broadcast) // Wi memcpy(&address, &ifo[j].iiAddress.Address, sizeof(sockaddr)); ((sockaddr_in*)&address)->sin_addr.s_addr = ifo[j].iiAddress.AddressIn.sin_addr.s_addr | ~ifo[j].iiNetmask.AddressIn.sin_addr.s_addr; NetworkAddress addr(address, sizeof(sockaddr)); - if (!broadcast->Contains(addr)) *broadcast->Append() = addr; + if (std::none_of(broadcast->begin(), broadcast->end(), [&addr](NetworkAddress const& elem) -> bool { return elem == addr; })) broadcast->push_back(addr); } free(ifo); @@ -176,7 +172,7 @@ static void NetworkFindBroadcastIPsInternal(NetworkAddressList *broadcast) // !G (r.ifr_flags & IFF_BROADCAST) && ioctl(sock, SIOCGIFBRDADDR, &r) != -1) { NetworkAddress addr(&r.ifr_broadaddr, sizeof(sockaddr)); - if (!broadcast->Contains(addr)) *broadcast->Append() = addr; + if (std::none_of(broadcast->begin(), broadcast->end(), [&addr](NetworkAddress const& elem) -> bool { return elem == addr; })) broadcast->push_back(addr); } } @@ -202,10 +198,8 @@ void NetworkFindBroadcastIPs(NetworkAddressList *broadcast) /* Now display to the debug all the detected ips */ DEBUG(net, 3, "Detected broadcast addresses:"); int i = 0; - for (NetworkAddress *addr = broadcast->Begin(); addr != broadcast->End(); addr++) { - addr->SetPort(NETWORK_DEFAULT_PORT); - DEBUG(net, 3, "%d) %s", i++, addr->GetHostname()); + for (NetworkAddress &addr : *broadcast) { + addr.SetPort(NETWORK_DEFAULT_PORT); + DEBUG(net, 3, "%d) %s", i++, addr.GetHostname()); } } - -#endif /* ENABLE_NETWORK */ diff --git a/src/network/core/host.h b/src/network/core/host.h index 46bfa4e1fa..345b352193 100644 --- a/src/network/core/host.h +++ b/src/network/core/host.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/network/core/os_abstraction.h b/src/network/core/os_abstraction.h index f9e66e6637..0950d88219 100644 --- a/src/network/core/os_abstraction.h +++ b/src/network/core/os_abstraction.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. @@ -18,8 +16,6 @@ /* Include standard stuff per OS */ -#ifdef ENABLE_NETWORK - /* Windows stuff */ #if defined(_WIN32) #include @@ -33,6 +29,11 @@ /* Windows has some different names for some types */ typedef unsigned long in_addr_t; +/* Handle cross-compilation with --build=*-*-cygwin --host=*-*-mingw32 */ +#if defined(__MINGW32__) && !defined(AI_ADDRCONFIG) +# define AI_ADDRCONFIG 0x00000400 +#endif + #if !(defined(__MINGW32__) || defined(__CYGWIN__)) /* Windows has some different names for some types */ typedef SSIZE_T ssize_t; @@ -48,50 +49,34 @@ typedef unsigned long in_addr_t; # endif # define SOCKET int # define INVALID_SOCKET -1 -# if !defined(__MORPHOS__) && !defined(__AMIGA__) -# define ioctlsocket ioctl -# if !defined(BEOS_NET_SERVER) -# define closesocket close -# endif -# define GET_LAST_ERROR() (errno) -# endif +# define ioctlsocket ioctl +# define closesocket close +# define GET_LAST_ERROR() (errno) /* Need this for FIONREAD on solaris */ # define BSD_COMP /* Includes needed for UNIX-like systems */ # include # include -# if defined(__BEOS__) && defined(BEOS_NET_SERVER) -# include -# include /* snooze() */ -# include - typedef unsigned long in_addr_t; -# define INADDR_NONE INADDR_BROADCAST -# else -# include -# include -# include -# include -# include +# include +# include +# include +# include +# include /* According to glibc/NEWS, appeared in glibc-2.3. */ -# if !defined(__sgi__) && !defined(SUNOS) && !defined(__MORPHOS__) && !defined(__BEOS__) && !defined(__HAIKU__) && !defined(__INNOTEK_LIBC__) \ - && !(defined(__GLIBC__) && (__GLIBC__ <= 2) && (__GLIBC_MINOR__ <= 2)) && !defined(__dietlibc__) && !defined(HPUX) && !defined(__ANDROID__) +# if !defined(__sgi__) && !defined(SUNOS) && !defined(__INNOTEK_LIBC__) \ + && !(defined(__GLIBC__) && (__GLIBC__ <= 2) && (__GLIBC_MINOR__ <= 2)) && !defined(__dietlibc__) && !defined(HPUX) && !defined(__ANDROID__) /* If for any reason ifaddrs.h does not exist on your system, comment out * the following two lines and an alternative way will be used to fetch * the list of IPs from the system. */ -# include -# define HAVE_GETIFADDRS -# endif -# if !defined(INADDR_NONE) -# define INADDR_NONE 0xffffffff -# endif -# if defined(__BEOS__) && !defined(BEOS_NET_SERVER) - /* needed on Zeta */ -# include -# endif -# endif /* BEOS_NET_SERVER */ +# include +# define HAVE_GETIFADDRS +# endif +# if !defined(INADDR_NONE) +# define INADDR_NONE 0xffffffff +# endif -# if !defined(__BEOS__) && defined(__GLIBC__) && (__GLIBC__ <= 2) && (__GLIBC_MINOR__ <= 1) +# if defined(__GLIBC__) && (__GLIBC__ <= 2) && (__GLIBC_MINOR__ <= 1) typedef uint32_t in_addr_t; # endif @@ -100,14 +85,6 @@ typedef unsigned long in_addr_t; # include #endif /* UNIX */ -#ifdef __BEOS__ - typedef int socklen_t; -#endif - -#ifdef __HAIKU__ - #define IPV6_V6ONLY 27 -#endif - /* OS/2 stuff */ #if defined(__OS2__) # define SOCKET int @@ -164,39 +141,6 @@ typedef unsigned long in_addr_t; #endif /* OS/2 */ -/* MorphOS and Amiga stuff */ -#if defined(__MORPHOS__) || defined(__AMIGA__) -# include -# include /* required for Open/CloseLibrary() */ - /* MorphOS defines his network functions with UBYTE arrays while we - * use char arrays. This gives tons of unneeded warnings */ -# define UBYTE char -# if defined(__MORPHOS__) -# include /* FIO* defines */ -# include /* SIO* defines */ -# include -# else /* __AMIGA__ */ -# include -# endif - -/* Make the names compatible */ -# define closesocket(s) CloseSocket(s) -# define GET_LAST_ERROR() Errno() -# define ioctlsocket(s, request, status) IoctlSocket((LONG)s, (ULONG)request, (char*)status) -# define ioctl ioctlsocket - - typedef unsigned int in_addr_t; - typedef long socklen_t; - extern struct Library *SocketBase; - -# ifdef __AMIGA__ - /* for usleep() implementation */ - extern struct Device *TimerBase; - extern struct MsgPort *TimerPort; - extern struct timerequest *TimerRequest; -# endif -#endif /* __MORPHOS__ || __AMIGA__ */ - /** * Try to set the socket into non-blocking mode. * @param d The socket to set the non-blocking more for. @@ -209,11 +153,7 @@ static inline bool SetNonBlocking(SOCKET d) #else int nonblocking = 1; #endif -#if (defined(__BEOS__) && defined(BEOS_NET_SERVER)) - return setsockopt(d, SOL_SOCKET, SO_NONBLOCK, &nonblocking, sizeof(nonblocking)) == 0; -#else return ioctlsocket(d, FIONBIO, &nonblocking) == 0; -#endif } /** @@ -224,19 +164,13 @@ static inline bool SetNonBlocking(SOCKET d) static inline bool SetNoDelay(SOCKET d) { /* XXX should this be done at all? */ -#if !defined(BEOS_NET_SERVER) /* not implemented on BeOS net_server */ int b = 1; /* The (const char*) cast is needed for windows */ return setsockopt(d, IPPROTO_TCP, TCP_NODELAY, (const char*)&b, sizeof(b)) == 0; -#else - return true; -#endif } /* Make sure these structures have the size we expect them to be */ assert_compile(sizeof(in_addr) == 4); ///< IPv4 addresses should be 4 bytes. assert_compile(sizeof(in6_addr) == 16); ///< IPv6 addresses should be 16 bytes. -#endif /* ENABLE_NETWORK */ - #endif /* NETWORK_CORE_OS_ABSTRACTION_H */ diff --git a/src/network/core/packet.cpp b/src/network/core/packet.cpp index 7548132e0b..94ffcc5584 100644 --- a/src/network/core/packet.cpp +++ b/src/network/core/packet.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. @@ -11,8 +9,6 @@ * @file packet.cpp Basic functions to create, fill and read packets. */ -#ifdef ENABLE_NETWORK - #include "../../stdafx.h" #include "../../string_func.h" @@ -26,10 +22,10 @@ */ Packet::Packet(NetworkSocketHandler *cs) { - assert(cs != NULL); + assert(cs != nullptr); this->cs = cs; - this->next = NULL; + this->next = nullptr; this->pos = 0; // We start reading from here this->size = 0; this->buffer = MallocT(SEND_MTU); @@ -41,8 +37,8 @@ Packet::Packet(NetworkSocketHandler *cs) */ Packet::Packet(PacketType type) { - this->cs = NULL; - this->next = NULL; + this->cs = nullptr; + this->next = nullptr; /* Skip the size so we can write that in before sending the packet */ this->pos = 0; @@ -64,7 +60,7 @@ Packet::~Packet() */ void Packet::PrepareToSend() { - assert(this->cs == NULL && this->next == NULL); + assert(this->cs == nullptr && this->next == nullptr); this->buffer[0] = GB(this->size, 0, 8); this->buffer[1] = GB(this->size, 8, 8); @@ -151,7 +147,7 @@ void Packet::Send_uint64(uint64 data) */ void Packet::Send_string(const char *data) { - assert(data != NULL); + assert(data != nullptr); /* The <= *is* valid due to the fact that we are comparing sizes and not the index. */ assert(this->size + strlen(data) + 1 <= SEND_MTU); while ((this->buffer[this->size++] = *data++) != '\0') {} @@ -189,7 +185,7 @@ bool Packet::CanReadFromPacket(uint bytes_to_read) */ void Packet::ReadRawPacketSize() { - assert(this->cs != NULL && this->next == NULL); + assert(this->cs != nullptr && this->next == nullptr); this->size = (PacketSize)this->buffer[0]; this->size += (PacketSize)this->buffer[1] << 8; } @@ -310,5 +306,3 @@ void Packet::Recv_string(char *buffer, size_t size, StringValidationSettings set str_validate(bufp, last, settings); } - -#endif /* ENABLE_NETWORK */ diff --git a/src/network/core/packet.h b/src/network/core/packet.h index 7f344d0179..c9be4eeb53 100644 --- a/src/network/core/packet.h +++ b/src/network/core/packet.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. @@ -18,8 +16,6 @@ #include "core.h" #include "../../string_type.h" -#ifdef ENABLE_NETWORK - typedef uint16 PacketSize; ///< Size of the whole packet. typedef uint8 PacketType; ///< Identifier for the packet @@ -87,6 +83,4 @@ public: void Recv_string(char *buffer, size_t size, StringValidationSettings settings = SVS_REPLACE_WITH_QUESTION_MARK); }; -#endif /* ENABLE_NETWORK */ - #endif /* NETWORK_CORE_PACKET_H */ diff --git a/src/network/core/tcp.cpp b/src/network/core/tcp.cpp index 790941fc01..a51913d843 100644 --- a/src/network/core/tcp.cpp +++ b/src/network/core/tcp.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. @@ -11,8 +9,6 @@ * @file tcp.cpp Basic functions to receive and send TCP packets. */ -#ifdef ENABLE_NETWORK - #include "../../stdafx.h" #include "../../debug.h" @@ -26,7 +22,7 @@ */ NetworkTCPSocketHandler::NetworkTCPSocketHandler(SOCKET s) : NetworkSocketHandler(), - packet_queue(NULL), packet_recv(NULL), + packet_queue(nullptr), packet_recv(nullptr), sock(s), writable(false) { } @@ -45,13 +41,13 @@ NetworkRecvStatus NetworkTCPSocketHandler::CloseConnection(bool error) NetworkSocketHandler::CloseConnection(error); /* Free all pending and partially received packets */ - while (this->packet_queue != NULL) { + while (this->packet_queue != nullptr) { Packet *p = this->packet_queue->next; delete this->packet_queue; this->packet_queue = p; } delete this->packet_recv; - this->packet_recv = NULL; + this->packet_recv = nullptr; return NETWORK_RECV_STATUS_OKAY; } @@ -65,7 +61,7 @@ NetworkRecvStatus NetworkTCPSocketHandler::CloseConnection(bool error) void NetworkTCPSocketHandler::SendPacket(Packet *packet) { Packet *p; - assert(packet != NULL); + assert(packet != nullptr); packet->PrepareToSend(); @@ -76,12 +72,12 @@ void NetworkTCPSocketHandler::SendPacket(Packet *packet) /* Locate last packet buffered for the client */ p = this->packet_queue; - if (p == NULL) { + if (p == nullptr) { /* No packets yet */ this->packet_queue = packet; } else { /* Skip to the last packet */ - while (p->next != NULL) p = p->next; + while (p->next != nullptr) p = p->next; p->next = packet; } } @@ -106,7 +102,7 @@ SendPacketsState NetworkTCPSocketHandler::SendPackets(bool closing_down) if (!this->IsConnected()) return SPS_CLOSED; p = this->packet_queue; - while (p != NULL) { + while (p != nullptr) { res = send(this->sock, (const char*)p->buffer + p->pos, p->size - p->pos, 0); if (res == -1) { int err = GET_LAST_ERROR(); @@ -144,15 +140,15 @@ SendPacketsState NetworkTCPSocketHandler::SendPackets(bool closing_down) /** * Receives a packet for the given client - * @return The received packet (or NULL when it didn't receive one) + * @return The received packet (or nullptr when it didn't receive one) */ Packet *NetworkTCPSocketHandler::ReceivePacket() { ssize_t res; - if (!this->IsConnected()) return NULL; + if (!this->IsConnected()) return nullptr; - if (this->packet_recv == NULL) { + if (this->packet_recv == nullptr) { this->packet_recv = new Packet(this); } @@ -169,15 +165,15 @@ Packet *NetworkTCPSocketHandler::ReceivePacket() /* Something went wrong... (104 is connection reset by peer) */ if (err != 104) DEBUG(net, 0, "recv failed with error %d", err); this->CloseConnection(); - return NULL; + return nullptr; } /* Connection would block, so stop for now */ - return NULL; + return nullptr; } if (res == 0) { /* Client/server has left */ this->CloseConnection(); - return NULL; + return nullptr; } p->pos += res; } @@ -187,7 +183,7 @@ Packet *NetworkTCPSocketHandler::ReceivePacket() if (p->size > SEND_MTU) { this->CloseConnection(); - return NULL; + return nullptr; } } @@ -200,22 +196,22 @@ Packet *NetworkTCPSocketHandler::ReceivePacket() /* Something went wrong... (104 is connection reset by peer) */ if (err != 104) DEBUG(net, 0, "recv failed with error %d", err); this->CloseConnection(); - return NULL; + return nullptr; } /* Connection would block */ - return NULL; + return nullptr; } if (res == 0) { /* Client/server has left */ this->CloseConnection(); - return NULL; + return nullptr; } p->pos += res; } /* Prepare for receiving a new packet */ - this->packet_recv = NULL; + this->packet_recv = nullptr; p->PrepareToRead(); return p; @@ -238,14 +234,8 @@ bool NetworkTCPSocketHandler::CanSendReceive() FD_SET(this->sock, &write_fd); tv.tv_sec = tv.tv_usec = 0; // don't block at all. -#if !defined(__MORPHOS__) && !defined(__AMIGA__) - if (select(FD_SETSIZE, &read_fd, &write_fd, NULL, &tv) < 0) return false; -#else - if (WaitSelect(FD_SETSIZE, &read_fd, &write_fd, NULL, &tv, NULL) < 0) return false; -#endif + if (select(FD_SETSIZE, &read_fd, &write_fd, nullptr, &tv) < 0) return false; this->writable = !!FD_ISSET(this->sock, &write_fd); return FD_ISSET(this->sock, &read_fd) != 0; } - -#endif /* ENABLE_NETWORK */ diff --git a/src/network/core/tcp.h b/src/network/core/tcp.h index b736189b4e..08a09ca1a2 100644 --- a/src/network/core/tcp.h +++ b/src/network/core/tcp.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. @@ -17,8 +15,6 @@ #include "address.h" #include "packet.h" -#ifdef ENABLE_NETWORK - /** The states of sending the packets. */ enum SendPacketsState { SPS_CLOSED, ///< The connection got closed. @@ -42,7 +38,7 @@ public: */ bool IsConnected() const { return this->sock != INVALID_SOCKET; } - virtual NetworkRecvStatus CloseConnection(bool error = true); + NetworkRecvStatus CloseConnection(bool error = true) override; virtual void SendPacket(Packet *packet); SendPacketsState SendPackets(bool closing_down = false); @@ -54,7 +50,7 @@ public: * Whether there is something pending in the send queue. * @return true when something is pending in the send queue. */ - bool HasSendQueue() { return this->packet_queue != NULL; } + bool HasSendQueue() { return this->packet_queue != nullptr; } NetworkTCPSocketHandler(SOCKET s = INVALID_SOCKET); ~NetworkTCPSocketHandler(); @@ -65,7 +61,6 @@ public: */ class TCPConnecter { private: - class ThreadObject *thread; ///< Thread used to create the TCP connection bool connected; ///< Whether we succeeded in making the connection bool aborted; ///< Whether we bailed out (i.e. connection making failed) bool killed; ///< Whether we got killed @@ -73,7 +68,7 @@ private: void Connect(); - static void ThreadEntry(void *param); + static void ThreadEntry(TCPConnecter *param); protected: /** Address we're connecting to */ @@ -99,6 +94,4 @@ public: static void KillAll(); }; -#endif /* ENABLE_NETWORK */ - #endif /* NETWORK_CORE_TCP_H */ diff --git a/src/network/core/tcp_admin.cpp b/src/network/core/tcp_admin.cpp index 284ceda9b1..fdeb3d829b 100644 --- a/src/network/core/tcp_admin.cpp +++ b/src/network/core/tcp_admin.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. @@ -11,8 +9,6 @@ * @file tcp_admin.cpp Basic functions to receive and send TCP packets to and from the admin network. */ -#ifdef ENABLE_NETWORK - #include "../../stdafx.h" #include "../network_internal.h" @@ -117,7 +113,7 @@ NetworkRecvStatus NetworkAdminSocketHandler::HandlePacket(Packet *p) NetworkRecvStatus NetworkAdminSocketHandler::ReceivePackets() { Packet *p; - while ((p = this->ReceivePacket()) != NULL) { + while ((p = this->ReceivePacket()) != nullptr) { NetworkRecvStatus res = this->HandlePacket(p); if (res != NETWORK_RECV_STATUS_OKAY) return res; } @@ -172,5 +168,3 @@ NetworkRecvStatus NetworkAdminSocketHandler::Receive_SERVER_CMD_NAMES(Packet *p) NetworkRecvStatus NetworkAdminSocketHandler::Receive_SERVER_CMD_LOGGING(Packet *p) { return this->ReceiveInvalidPacket(ADMIN_PACKET_SERVER_CMD_LOGGING); } NetworkRecvStatus NetworkAdminSocketHandler::Receive_SERVER_RCON_END(Packet *p) { return this->ReceiveInvalidPacket(ADMIN_PACKET_SERVER_RCON_END); } NetworkRecvStatus NetworkAdminSocketHandler::Receive_SERVER_PONG(Packet *p) { return this->ReceiveInvalidPacket(ADMIN_PACKET_SERVER_PONG); } - -#endif /* ENABLE_NETWORK */ diff --git a/src/network/core/tcp_admin.h b/src/network/core/tcp_admin.h index e141a191a8..979e5963f0 100644 --- a/src/network/core/tcp_admin.h +++ b/src/network/core/tcp_admin.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. @@ -19,8 +17,6 @@ #include "../network_type.h" #include "../../core/pool_type.hpp" -#ifdef ENABLE_NETWORK - /** * Enum with types of TCP packets specific to the admin network. * This protocol may only be extended to ensure stability. @@ -483,7 +479,7 @@ protected: NetworkRecvStatus HandlePacket(Packet *p); public: - NetworkRecvStatus CloseConnection(bool error = true); + NetworkRecvStatus CloseConnection(bool error = true) override; NetworkAdminSocketHandler(SOCKET s); ~NetworkAdminSocketHandler(); @@ -500,6 +496,4 @@ public: } }; -#endif /* ENABLE_NETWORK */ - #endif /* NETWORK_CORE_TCP_ADMIN_H */ diff --git a/src/network/core/tcp_connect.cpp b/src/network/core/tcp_connect.cpp index 2dc7898824..9448acb830 100644 --- a/src/network/core/tcp_connect.cpp +++ b/src/network/core/tcp_connect.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. @@ -11,17 +9,15 @@ * @file tcp_connect.cpp Basic functions to create connections without blocking. */ -#ifdef ENABLE_NETWORK - #include "../../stdafx.h" -#include "../../thread/thread.h" +#include "../../thread.h" #include "tcp.h" #include "../../safeguards.h" /** List of connections that are currently being created */ -static SmallVector _tcp_connecters; +static std::vector _tcp_connecters; /** * Create a new connecter for the given address @@ -34,8 +30,8 @@ TCPConnecter::TCPConnecter(const NetworkAddress &address) : sock(INVALID_SOCKET), address(address) { - *_tcp_connecters.Append() = this; - if (!ThreadObject::New(TCPConnecter::ThreadEntry, this, &this->thread, "ottd:tcp")) { + _tcp_connecters.push_back(this); + if (!StartNewThread(nullptr, "ottd:tcp", &TCPConnecter::ThreadEntry, this)) { this->Connect(); } } @@ -55,9 +51,9 @@ void TCPConnecter::Connect() * Entry point for the new threads. * @param param the TCPConnecter instance to call Connect on. */ -/* static */ void TCPConnecter::ThreadEntry(void *param) +/* static */ void TCPConnecter::ThreadEntry(TCPConnecter *param) { - static_cast(param)->Connect(); + param->Connect(); } /** @@ -68,22 +64,22 @@ void TCPConnecter::Connect() */ /* static */ void TCPConnecter::CheckCallbacks() { - for (TCPConnecter **iter = _tcp_connecters.Begin(); iter < _tcp_connecters.End(); /* nothing */) { + for (auto iter = _tcp_connecters.begin(); iter < _tcp_connecters.end(); /* nothing */) { TCPConnecter *cur = *iter; if ((cur->connected || cur->aborted) && cur->killed) { - _tcp_connecters.Erase(iter); + iter = _tcp_connecters.erase(iter); if (cur->sock != INVALID_SOCKET) closesocket(cur->sock); delete cur; continue; } if (cur->connected) { - _tcp_connecters.Erase(iter); + iter = _tcp_connecters.erase(iter); cur->OnConnect(cur->sock); delete cur; continue; } if (cur->aborted) { - _tcp_connecters.Erase(iter); + iter = _tcp_connecters.erase(iter); cur->OnFailure(); delete cur; continue; @@ -95,7 +91,5 @@ void TCPConnecter::Connect() /** Kill all connection attempts. */ /* static */ void TCPConnecter::KillAll() { - for (TCPConnecter **iter = _tcp_connecters.Begin(); iter != _tcp_connecters.End(); iter++) (*iter)->killed = true; + for (TCPConnecter *conn : _tcp_connecters) conn->killed = true; } - -#endif /* ENABLE_NETWORK */ diff --git a/src/network/core/tcp_content.cpp b/src/network/core/tcp_content.cpp index fc22c4491f..989fbefaf4 100644 --- a/src/network/core/tcp_content.cpp +++ b/src/network/core/tcp_content.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. @@ -11,8 +9,6 @@ * @file tcp_content.cpp Basic functions to receive and send Content packets. */ -#ifdef ENABLE_NETWORK - #include "../../stdafx.h" #ifndef OPENTTD_MSU #include "../../textfile_gui.h" @@ -49,8 +45,8 @@ void ContentInfo::TransferFrom(ContentInfo *other) free(this->dependencies); free(this->tags); memcpy(this, other, sizeof(ContentInfo)); - other->dependencies = NULL; - other->tags = NULL; + other->dependencies = nullptr; + other->tags = nullptr; } } @@ -100,11 +96,11 @@ bool ContentInfo::IsValid() const /** * Search a textfile file next to this file in the content list. * @param type The type of the textfile to search for. - * @return The filename for the textfile, \c NULL otherwise. + * @return The filename for the textfile, \c nullptr otherwise. */ const char *ContentInfo::GetTextfile(TextfileType type) const { - if (this->state == INVALID) return NULL; + if (this->state == INVALID) return nullptr; const char *tmp; switch (this->type) { default: NOT_REACHED(); @@ -122,7 +118,7 @@ const char *ContentInfo::GetTextfile(TextfileType type) const break; case CONTENT_TYPE_NEWGRF: { const GRFConfig *gc = FindGRFConfig(BSWAP32(this->unique_id), FGCM_EXACT, this->md5sum); - tmp = gc != NULL ? gc->filename : NULL; + tmp = gc != nullptr ? gc->filename : nullptr; break; } case CONTENT_TYPE_BASE_GRAPHICS: @@ -140,7 +136,7 @@ const char *ContentInfo::GetTextfile(TextfileType type) const tmp = FindScenario(this, true); break; } - if (tmp == NULL) return NULL; + if (tmp == nullptr) return nullptr; return ::GetTextfile(type, GetContentInfoSubDir(this->type), tmp); } #endif /* OPENTTD_MSU */ @@ -211,7 +207,7 @@ bool NetworkContentSocketHandler::ReceivePackets() Packet *p; static const int MAX_PACKETS_TO_RECEIVE = 42; int i = MAX_PACKETS_TO_RECEIVE; - while (--i != 0 && (p = this->ReceivePacket()) != NULL) { + while (--i != 0 && (p = this->ReceivePacket()) != nullptr) { bool cont = this->HandlePacket(p); delete p; if (!cont) return true; @@ -266,5 +262,3 @@ Subdirectory GetContentInfoSubDir(ContentType type) } } #endif /* OPENTTD_MSU */ - -#endif /* ENABLE_NETWORK */ diff --git a/src/network/core/tcp_content.h b/src/network/core/tcp_content.h index a506439da9..be1cc6e77e 100644 --- a/src/network/core/tcp_content.h +++ b/src/network/core/tcp_content.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. @@ -19,8 +17,6 @@ #include "packet.h" #include "../../debug.h" -#ifdef ENABLE_NETWORK - /** The values in the enum are important; they are used as database 'keys' */ enum ContentType { CONTENT_TYPE_BEGIN = 1, ///< Helper to mark the begin of the types @@ -100,7 +96,7 @@ struct ContentInfo { class NetworkContentSocketHandler : public NetworkTCPSocketHandler { protected: NetworkAddress client_addr; ///< The address we're connected to. - virtual void Close(); + void Close() override; bool ReceiveInvalidPacket(PacketContentType type); @@ -213,6 +209,4 @@ public: Subdirectory GetContentInfoSubDir(ContentType type); #endif /* OPENTTD_MSU */ -#endif /* ENABLE_NETWORK */ - #endif /* NETWORK_CORE_TCP_CONTENT_H */ diff --git a/src/network/core/tcp_game.cpp b/src/network/core/tcp_game.cpp index caa378fc4c..e0835771ed 100644 --- a/src/network/core/tcp_game.cpp +++ b/src/network/core/tcp_game.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. @@ -11,8 +9,6 @@ * @file tcp_game.cpp Basic functions to receive and send TCP packets for game purposes. */ -#ifdef ENABLE_NETWORK - #include "../../stdafx.h" #include "../network.h" @@ -28,7 +24,7 @@ * Create a new socket for the game connection. * @param s The socket to connect with. */ -NetworkGameSocketHandler::NetworkGameSocketHandler(SOCKET s) : info(NULL), client_id(INVALID_CLIENT_ID), +NetworkGameSocketHandler::NetworkGameSocketHandler(SOCKET s) : info(nullptr), client_id(INVALID_CLIENT_ID), last_frame(_frame_counter), last_frame_server(_frame_counter), last_packet(_realtime_tick) { this->sock = s; @@ -136,7 +132,7 @@ NetworkRecvStatus NetworkGameSocketHandler::HandlePacket(Packet *p) NetworkRecvStatus NetworkGameSocketHandler::ReceivePackets() { Packet *p; - while ((p = this->ReceivePacket()) != NULL) { + while ((p = this->ReceivePacket()) != nullptr) { NetworkRecvStatus res = HandlePacket(p); delete p; if (res != NETWORK_RECV_STATUS_OKAY) return res; @@ -199,5 +195,3 @@ NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_MOVE(Packet *p) { ret NetworkRecvStatus NetworkGameSocketHandler::Receive_CLIENT_MOVE(Packet *p) { return this->ReceiveInvalidPacket(PACKET_CLIENT_MOVE); } NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_COMPANY_UPDATE(Packet *p) { return this->ReceiveInvalidPacket(PACKET_SERVER_COMPANY_UPDATE); } NetworkRecvStatus NetworkGameSocketHandler::Receive_SERVER_CONFIG_UPDATE(Packet *p) { return this->ReceiveInvalidPacket(PACKET_SERVER_CONFIG_UPDATE); } - -#endif /* ENABLE_NETWORK */ diff --git a/src/network/core/tcp_game.h b/src/network/core/tcp_game.h index 5c6cb5c34d..9e3dcf197c 100644 --- a/src/network/core/tcp_game.h +++ b/src/network/core/tcp_game.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. @@ -19,8 +17,6 @@ #include "../network_type.h" #include "../../core/pool_type.hpp" -#ifdef ENABLE_NETWORK - /** * Enum with all types of TCP packets. * For the exact meaning, look at #NetworkGameSocketHandler. @@ -132,12 +128,12 @@ struct CommandPacket; /** A queue of CommandPackets. */ class CommandQueue { CommandPacket *first; ///< The first packet in the queue. - CommandPacket *last; ///< The last packet in the queue; only valid when first != NULL. + CommandPacket *last; ///< The last packet in the queue; only valid when first != nullptr. uint count; ///< The number of items in the queue. public: /** Initialise the command queue. */ - CommandQueue() : first(NULL), last(NULL), count(0) {} + CommandQueue() : first(nullptr), last(nullptr), count(0) {} /** Clear the command queue. */ ~CommandQueue() { this->Free(); } void Append(CommandPacket *p); @@ -524,7 +520,7 @@ public: CommandQueue incoming_queue; ///< The command-queue awaiting handling uint last_packet; ///< Time we received the last frame. - NetworkRecvStatus CloseConnection(bool error = true); + NetworkRecvStatus CloseConnection(bool error = true) override; /** * Close the network connection due to the given status. @@ -539,7 +535,7 @@ public: */ inline void SetInfo(NetworkClientInfo *info) { - assert(info != NULL && this->info == NULL); + assert(info != nullptr && this->info == nullptr); this->info = info; } @@ -558,6 +554,4 @@ public: void SendCommand(Packet *p, const CommandPacket *cp); }; -#endif /* ENABLE_NETWORK */ - #endif /* NETWORK_CORE_TCP_GAME_H */ diff --git a/src/network/core/tcp_http.cpp b/src/network/core/tcp_http.cpp index aec198bf55..b2a6b0c040 100644 --- a/src/network/core/tcp_http.cpp +++ b/src/network/core/tcp_http.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. @@ -11,8 +9,6 @@ * @file tcp_http.cpp Basic functions to receive and send HTTP TCP packets. */ -#ifdef ENABLE_NETWORK - #include "../../stdafx.h" #include "../../debug.h" #include "../../rev.h" @@ -23,7 +19,7 @@ #include "../../safeguards.h" /** List of open HTTP connections. */ -static SmallVector _http_connections; +static std::vector _http_connections; /** * Start the querying @@ -45,11 +41,11 @@ NetworkHTTPSocketHandler::NetworkHTTPSocketHandler(SOCKET s, redirect_depth(depth), sock(s) { - size_t bufferSize = strlen(url) + strlen(host) + strlen(GetNetworkRevisionString()) + (data == NULL ? 0 : strlen(data)) + 128; + size_t bufferSize = strlen(url) + strlen(host) + strlen(GetNetworkRevisionString()) + (data == nullptr ? 0 : strlen(data)) + 128; char *buffer = AllocaM(char, bufferSize); DEBUG(net, 7, "[tcp/http] requesting %s%s", host, url); - if (data != NULL) { + if (data != nullptr) { seprintf(buffer, buffer + bufferSize - 1, "POST %s HTTP/1.0\r\nHost: %s\r\nUser-Agent: OpenTTD/%s\r\nContent-Type: text/plain\r\nContent-Length: %d\r\n\r\n%s\r\n", url, host, GetNetworkRevisionString(), (int)strlen(data), data); } else { seprintf(buffer, buffer + bufferSize - 1, "GET %s HTTP/1.0\r\nHost: %s\r\nUser-Agent: OpenTTD/%s\r\n\r\n", url, host, GetNetworkRevisionString()); @@ -65,7 +61,7 @@ NetworkHTTPSocketHandler::NetworkHTTPSocketHandler(SOCKET s, return; } - *_http_connections.Append() = this; + _http_connections.push_back(this); } /** Free whatever needs to be freed. */ @@ -110,7 +106,7 @@ static const char * const LOCATION = "Location: "; ///< Header for l int NetworkHTTPSocketHandler::HandleHeader() { assert(strlen(HTTP_1_0) == strlen(HTTP_1_1)); - assert(strstr(this->recv_buffer, END_OF_HEADER) != NULL); + 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 && @@ -124,7 +120,7 @@ int NetworkHTTPSocketHandler::HandleHeader() /* Get the length of the document to receive */ char *length = strcasestr(this->recv_buffer, CONTENT_LENGTH); - if (length == NULL) return_error("[tcp/http] missing 'content-length' header"); + if (length == nullptr) return_error("[tcp/http] missing 'content-length' header"); /* Skip the header */ length += strlen(CONTENT_LENGTH); @@ -165,7 +161,7 @@ int NetworkHTTPSocketHandler::HandleHeader() /* Redirect to other URL */ char *uri = strcasestr(this->recv_buffer, LOCATION); - if (uri == NULL) return_error("[tcp/http] missing 'location' header for redirect"); + if (uri == nullptr) return_error("[tcp/http] missing 'location' header for redirect"); uri += strlen(LOCATION); @@ -180,7 +176,7 @@ int NetworkHTTPSocketHandler::HandleHeader() if (ret != 0) return ret; /* We've relinquished control of data now. */ - this->data = NULL; + this->data = nullptr; /* Restore the header. */ *end_of_line = '\r'; @@ -197,22 +193,22 @@ int NetworkHTTPSocketHandler::HandleHeader() /* static */ int NetworkHTTPSocketHandler::Connect(char *uri, HTTPCallback *callback, const char *data, int depth) { char *hname = strstr(uri, "://"); - if (hname == NULL) return_error("[tcp/http] invalid location"); + if (hname == nullptr) return_error("[tcp/http] invalid location"); hname += 3; char *url = strchr(hname, '/'); - if (url == NULL) return_error("[tcp/http] invalid location"); + if (url == nullptr) return_error("[tcp/http] invalid location"); *url = '\0'; /* Fetch the hostname, and possible port number. */ - const char *company = NULL; - const char *port = NULL; + const char *company = nullptr; + const char *port = nullptr; ParseConnectionString(&company, &port, hname); - if (company != NULL) return_error("[tcp/http] invalid hostname"); + if (company != nullptr) return_error("[tcp/http] invalid hostname"); - NetworkAddress address(hname, port == NULL ? 80 : atoi(port)); + NetworkAddress address(hname, port == nullptr ? 80 : atoi(port)); /* Restore the URL. */ *url = '/'; @@ -248,7 +244,7 @@ int NetworkHTTPSocketHandler::Receive() if (res == 0) { if (this->recv_length != 0) return -1; - this->callback->OnReceiveData(NULL, 0); + this->callback->OnReceiveData(nullptr, 0); return 0; } @@ -263,7 +259,7 @@ int NetworkHTTPSocketHandler::Receive() char *end_of_header = strstr(this->recv_buffer, END_OF_HEADER); this->recv_buffer[end] = prev; - if (end_of_header == NULL) { + if (end_of_header == nullptr) { if (read == lengthof(this->recv_buffer)) { DEBUG(net, 0, "[tcp/http] header too big"); return -1; @@ -299,25 +295,21 @@ int NetworkHTTPSocketHandler::Receive() /* static */ void NetworkHTTPSocketHandler::HTTPReceive() { /* No connections, just bail out. */ - if (_http_connections.Length() == 0) return; + if (_http_connections.size() == 0) return; fd_set read_fd; struct timeval tv; FD_ZERO(&read_fd); - for (NetworkHTTPSocketHandler **iter = _http_connections.Begin(); iter < _http_connections.End(); iter++) { - FD_SET((*iter)->sock, &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. -#if !defined(__MORPHOS__) && !defined(__AMIGA__) - int n = select(FD_SETSIZE, &read_fd, NULL, NULL, &tv); -#else - int n = WaitSelect(FD_SETSIZE, &read_fd, NULL, NULL, &tv, NULL); -#endif + int n = select(FD_SETSIZE, &read_fd, nullptr, nullptr, &tv); if (n == -1) return; - for (NetworkHTTPSocketHandler **iter = _http_connections.Begin(); iter < _http_connections.End(); /* nothing */) { + for (auto iter = _http_connections.begin(); iter < _http_connections.end(); /* nothing */) { NetworkHTTPSocketHandler *cur = *iter; if (FD_ISSET(cur->sock, &read_fd)) { @@ -327,7 +319,7 @@ int NetworkHTTPSocketHandler::Receive() if (ret <= 0) { /* Then... the connection can be closed */ cur->CloseConnection(); - _http_connections.Erase(iter); + iter = _http_connections.erase(iter); delete cur; continue; } @@ -335,5 +327,3 @@ int NetworkHTTPSocketHandler::Receive() iter++; } } - -#endif /* ENABLE_NETWORK */ diff --git a/src/network/core/tcp_http.h b/src/network/core/tcp_http.h index 36520f1364..1a1edaf87a 100644 --- a/src/network/core/tcp_http.h +++ b/src/network/core/tcp_http.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. @@ -16,8 +14,6 @@ #include "tcp.h" -#ifdef ENABLE_NETWORK - /** Callback for when the HTTP handler has something to tell us. */ struct HTTPCallback { /** @@ -28,9 +24,9 @@ struct HTTPCallback { /** * We're receiving data. - * @param data the received data, NULL when all data has been received. + * @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 NULL is sent the HTTP socket handler is closed/freed. + * @note When nullptr is sent the HTTP socket handler is closed/freed. */ virtual void OnReceiveData(const char *data, size_t length) = 0; @@ -62,7 +58,7 @@ public: return this->sock != INVALID_SOCKET; } - virtual NetworkRecvStatus CloseConnection(bool error = true); + NetworkRecvStatus CloseConnection(bool error = true) override; NetworkHTTPSocketHandler(SOCKET sock, HTTPCallback *callback, const char *host, const char *url, const char *data, int depth); @@ -70,7 +66,7 @@ public: ~NetworkHTTPSocketHandler(); static int Connect(char *uri, HTTPCallback *callback, - const char *data = NULL, int depth = 0); + const char *data = nullptr, int depth = 0); static void HTTPReceive(); }; @@ -93,7 +89,7 @@ public: */ NetworkHTTPContentConnecter(const NetworkAddress &address, HTTPCallback *callback, const char *url, - const char *data = NULL, int depth = 0) : + const char *data = nullptr, int depth = 0) : TCPConnecter(address), callback(callback), url(stredup(url)), @@ -108,20 +104,18 @@ public: free(this->url); } - virtual void OnFailure() + void OnFailure() override { this->callback->OnFailure(); free(this->data); } - virtual void OnConnect(SOCKET s) + void OnConnect(SOCKET s) override { new NetworkHTTPSocketHandler(s, this->callback, this->address.GetHostname(), this->url, this->data, this->depth); /* We've relinquished control of data now. */ - this->data = NULL; + this->data = nullptr; } }; -#endif /* ENABLE_NETWORK */ - #endif /* NETWORK_CORE_TCP_HTTP_H */ diff --git a/src/network/core/tcp_listen.h b/src/network/core/tcp_listen.h index e6b5893324..d2982363e6 100644 --- a/src/network/core/tcp_listen.h +++ b/src/network/core/tcp_listen.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. @@ -20,8 +18,6 @@ #include "../../debug.h" #include "table/strings.h" -#ifdef ENABLE_NETWORK - /** * Template for TCP listeners. * @param Tsocket The class we create sockets for. @@ -56,13 +52,13 @@ public: /* Check if the client is banned */ bool banned = false; - for (char **iter = _network_ban_list.Begin(); iter != _network_ban_list.End(); iter++) { - banned = address.IsInNetmask(*iter); + for (const auto &entry : _network_ban_list) { + banned = address.IsInNetmask(entry.c_str()); if (banned) { Packet p(Tban_packet); p.PrepareToSend(); - DEBUG(net, 1, "[%s] Banned ip tried to join (%s), refused", Tsocket::GetName(), *iter); + DEBUG(net, 1, "[%s] Banned ip tried to join (%s), refused", Tsocket::GetName(), entry.c_str()); if (send(s, (const char*)p.buffer, p.size, 0) < 0) { DEBUG(net, 0, "send failed with error %d", GET_LAST_ERROR()); @@ -106,31 +102,26 @@ public: FD_ZERO(&write_fd); - Tsocket *cs; - FOR_ALL_ITEMS_FROM(Tsocket, idx, cs, 0) { + for (Tsocket *cs : Tsocket::Iterate()) { FD_SET(cs->sock, &read_fd); FD_SET(cs->sock, &write_fd); } /* take care of listener port */ - for (SocketList::iterator s = sockets.Begin(); s != sockets.End(); s++) { - FD_SET(s->second, &read_fd); + for (auto &s : sockets) { + FD_SET(s.second, &read_fd); } tv.tv_sec = tv.tv_usec = 0; // don't block at all. -#if !defined(__MORPHOS__) && !defined(__AMIGA__) - if (select(FD_SETSIZE, &read_fd, &write_fd, NULL, &tv) < 0) return false; -#else - if (WaitSelect(FD_SETSIZE, &read_fd, &write_fd, NULL, &tv, NULL) < 0) return false; -#endif + if (select(FD_SETSIZE, &read_fd, &write_fd, nullptr, &tv) < 0) return false; /* accept clients.. */ - for (SocketList::iterator s = sockets.Begin(); s != sockets.End(); s++) { - if (FD_ISSET(s->second, &read_fd)) AcceptClient(s->second); + for (auto &s : sockets) { + if (FD_ISSET(s.second, &read_fd)) AcceptClient(s.second); } /* read stuff from clients */ - FOR_ALL_ITEMS_FROM(Tsocket, idx, cs, 0) { + for (Tsocket *cs : Tsocket::Iterate()) { cs->writable = !!FD_ISSET(cs->sock, &write_fd); if (FD_ISSET(cs->sock, &read_fd)) { cs->ReceivePackets(); @@ -146,16 +137,16 @@ public: */ static bool Listen(uint16 port) { - assert(sockets.Length() == 0); + assert(sockets.size() == 0); NetworkAddressList addresses; GetBindAddresses(&addresses, port); - for (NetworkAddress *address = addresses.Begin(); address != addresses.End(); address++) { - address->Listen(SOCK_STREAM, &sockets); + for (NetworkAddress &address : addresses) { + address.Listen(SOCK_STREAM, &sockets); } - if (sockets.Length() == 0) { + if (sockets.size() == 0) { DEBUG(net, 0, "[server] could not start network: could not create listening socket"); NetworkError(STR_NETWORK_ERROR_SERVER_START); return false; @@ -167,16 +158,14 @@ public: /** Close the sockets we're listening on. */ static void CloseListeners() { - for (SocketList::iterator s = sockets.Begin(); s != sockets.End(); s++) { - closesocket(s->second); + for (auto &s : sockets) { + closesocket(s.second); } - sockets.Clear(); + sockets.clear(); DEBUG(net, 1, "[%s] closed listeners", Tsocket::GetName()); } }; template SocketList TCPListenHandler::sockets; -#endif /* ENABLE_NETWORK */ - #endif /* NETWORK_CORE_TCP_LISTEN_H */ diff --git a/src/network/core/udp.cpp b/src/network/core/udp.cpp index d2dc15d427..1236838732 100644 --- a/src/network/core/udp.cpp +++ b/src/network/core/udp.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. @@ -11,8 +9,6 @@ * @file core/udp.cpp Basic functions to receive and send UDP packets. */ -#ifdef ENABLE_NETWORK - #include "../../stdafx.h" #include "../../date_func.h" #include "../../debug.h" @@ -26,16 +22,16 @@ */ NetworkUDPSocketHandler::NetworkUDPSocketHandler(NetworkAddressList *bind) { - if (bind != NULL) { - for (NetworkAddress *addr = bind->Begin(); addr != bind->End(); addr++) { - *this->bind.Append() = *addr; + if (bind != nullptr) { + for (NetworkAddress &addr : *bind) { + this->bind.push_back(addr); } } else { - /* As hostname NULL and port 0/NULL don't go well when + /* As hostname nullptr and port 0/nullptr don't go well when * resolving it we need to add an address for each of * the address families we support. */ - *this->bind.Append() = NetworkAddress(NULL, 0, AF_INET); - *this->bind.Append() = NetworkAddress(NULL, 0, AF_INET6); + this->bind.emplace_back(nullptr, 0, AF_INET); + this->bind.emplace_back(nullptr, 0, AF_INET6); } } @@ -49,11 +45,11 @@ bool NetworkUDPSocketHandler::Listen() /* Make sure socket is closed */ this->Close(); - for (NetworkAddress *addr = this->bind.Begin(); addr != this->bind.End(); addr++) { - addr->Listen(SOCK_DGRAM, &this->sockets); + for (NetworkAddress &addr : this->bind) { + addr.Listen(SOCK_DGRAM, &this->sockets); } - return this->sockets.Length() != 0; + return this->sockets.size() != 0; } /** @@ -61,10 +57,10 @@ bool NetworkUDPSocketHandler::Listen() */ void NetworkUDPSocketHandler::Close() { - for (SocketList::iterator s = this->sockets.Begin(); s != this->sockets.End(); s++) { - closesocket(s->second); + for (auto &s : this->sockets) { + closesocket(s.second); } - this->sockets.Clear(); + this->sockets.clear(); } NetworkRecvStatus NetworkUDPSocketHandler::CloseConnection(bool error) @@ -82,30 +78,28 @@ NetworkRecvStatus NetworkUDPSocketHandler::CloseConnection(bool error) */ void NetworkUDPSocketHandler::SendPacket(Packet *p, NetworkAddress *recv, bool all, bool broadcast) { - if (this->sockets.Length() == 0) this->Listen(); + if (this->sockets.size() == 0) this->Listen(); - for (SocketList::iterator s = this->sockets.Begin(); s != this->sockets.End(); s++) { + for (auto &s : this->sockets) { /* Make a local copy because if we resolve it we cannot * easily unresolve it so we can resolve it later again. */ NetworkAddress send(*recv); /* Not the same type */ - if (!send.IsFamily(s->first.GetAddress()->ss_family)) continue; + if (!send.IsFamily(s.first.GetAddress()->ss_family)) continue; p->PrepareToSend(); -#ifndef BEOS_NET_SERVER /* will work around this, some day; maybe. */ if (broadcast) { /* Enable broadcast */ unsigned long val = 1; - if (setsockopt(s->second, SOL_SOCKET, SO_BROADCAST, (char *) &val, sizeof(val)) < 0) { + if (setsockopt(s.second, SOL_SOCKET, SO_BROADCAST, (char *) &val, sizeof(val)) < 0) { DEBUG(net, 1, "[udp] setting broadcast failed with: %i", GET_LAST_ERROR()); } } -#endif /* Send the buffer */ - int res = sendto(s->second, (const char*)p->buffer, p->size, 0, (const struct sockaddr *)send.GetAddress(), send.GetAddressLength()); + int res = sendto(s.second, (const char*)p->buffer, p->size, 0, (const struct sockaddr *)send.GetAddress(), send.GetAddressLength()); DEBUG(net, 7, "[udp] sendto(%s)", send.GetAddressAsString()); /* Check for any errors, but ignore it otherwise */ @@ -120,7 +114,7 @@ void NetworkUDPSocketHandler::SendPacket(Packet *p, NetworkAddress *recv, bool a */ void NetworkUDPSocketHandler::ReceivePackets() { - for (SocketList::iterator s = this->sockets.Begin(); s != this->sockets.End(); s++) { + for (auto &s : this->sockets) { for (int i = 0; i < 1000; i++) { // Do not infinitely loop when DoSing with UDP struct sockaddr_storage client_addr; memset(&client_addr, 0, sizeof(client_addr)); @@ -129,8 +123,8 @@ void NetworkUDPSocketHandler::ReceivePackets() socklen_t client_len = sizeof(client_addr); /* Try to receive anything */ - SetNonBlocking(s->second); // Some OSes seem to lose the non-blocking status of the socket - int nbytes = recvfrom(s->second, (char*)p.buffer, SEND_MTU, 0, (struct sockaddr *)&client_addr, &client_len); + SetNonBlocking(s.second); // Some OSes seem to lose the non-blocking status of the socket + int nbytes = recvfrom(s.second, (char*)p.buffer, SEND_MTU, 0, (struct sockaddr *)&client_addr, &client_len); /* Did we get the bytes for the base header of the packet? */ if (nbytes <= 0) break; // No data, i.e. no packet @@ -180,13 +174,13 @@ void NetworkUDPSocketHandler::SendNetworkGameInfo(Packet *p, const NetworkGameIn uint count = 0; /* Count number of GRFs to send information about */ - for (c = info->grfconfig; c != NULL; c = c->next) { + for (c = info->grfconfig; c != nullptr; c = c->next) { if (!HasBit(c->flags, GCF_STATIC)) count++; } p->Send_uint8 (count); // Send number of GRFs /* Send actual GRF Identifications */ - for (c = info->grfconfig; c != NULL; c = c->next) { + for (c = info->grfconfig; c != nullptr; c = c->next) { if (!HasBit(c->flags, GCF_STATIC)) this->SendGRFIdentifier(p, &c->ident); } } @@ -349,5 +343,3 @@ void NetworkUDPSocketHandler::Receive_SERVER_UNREGISTER(Packet *p, NetworkAddres void NetworkUDPSocketHandler::Receive_CLIENT_GET_NEWGRFS(Packet *p, NetworkAddress *client_addr) { this->ReceiveInvalidPacket(PACKET_UDP_CLIENT_GET_NEWGRFS, client_addr); } void NetworkUDPSocketHandler::Receive_SERVER_NEWGRFS(Packet *p, NetworkAddress *client_addr) { this->ReceiveInvalidPacket(PACKET_UDP_SERVER_NEWGRFS, client_addr); } void NetworkUDPSocketHandler::Receive_MASTER_SESSION_KEY(Packet *p, NetworkAddress *client_addr) { this->ReceiveInvalidPacket(PACKET_UDP_MASTER_SESSION_KEY, client_addr); } - -#endif /* ENABLE_NETWORK */ diff --git a/src/network/core/udp.h b/src/network/core/udp.h index 9aa0c9dc49..ddbbd4515f 100644 --- a/src/network/core/udp.h +++ b/src/network/core/udp.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. @@ -18,8 +16,6 @@ #include "game.h" #include "packet.h" -#ifdef ENABLE_NETWORK - /** Enum with all types of UDP packets. The order MUST not be changed **/ enum PacketUDPType { PACKET_UDP_CLIENT_FIND_SERVER, ///< Queries a game server for game information @@ -54,7 +50,7 @@ protected: /** The opened sockets. */ SocketList sockets; - NetworkRecvStatus CloseConnection(bool error = true); + NetworkRecvStatus CloseConnection(bool error = true) override; void ReceiveInvalidPacket(PacketUDPType, NetworkAddress *client_addr); @@ -231,13 +227,13 @@ protected: */ virtual void HandleIncomingNetworkGameInfoGRFConfig(GRFConfig *config) { NOT_REACHED(); } public: - NetworkUDPSocketHandler(NetworkAddressList *bind = NULL); + NetworkUDPSocketHandler(NetworkAddressList *bind = nullptr); /** On destructing of this class, the socket needs to be closed */ virtual ~NetworkUDPSocketHandler() { this->Close(); } bool Listen(); - void Close(); + void Close() override; void SendPacket(Packet *p, NetworkAddress *recv, bool all = false, bool broadcast = false); void ReceivePackets(); @@ -246,6 +242,4 @@ public: void ReceiveNetworkGameInfo(Packet *p, NetworkGameInfo *info); }; -#endif /* ENABLE_NETWORK */ - #endif /* NETWORK_CORE_UDP_H */ diff --git a/src/network/network.cpp b/src/network/network.cpp index 4727e33443..e8c99c89bb 100644 --- a/src/network/network.cpp +++ b/src/network/network.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. @@ -11,8 +9,6 @@ #include "../stdafx.h" -#ifdef ENABLE_NETWORK - #include "../strings_func.h" #include "../command_func.h" #include "../date_func.h" @@ -59,7 +55,7 @@ bool _network_available; ///< is network mode available? bool _network_dedicated; ///< are we a dedicated server? bool _is_network_server; ///< Does this client wants to be a network-server? NetworkServerGameInfo _network_game_info; ///< Information about our game. -NetworkCompanyState *_network_company_states = NULL; ///< Statistics about some companies. +NetworkCompanyState *_network_company_states = nullptr; ///< Statistics about some companies. ClientID _network_own_client_id; ///< Our client identifier. ClientID _redirect_console_to_client; ///< If not invalid, redirect the console output to a client. bool _network_need_advertise; ///< Whether we need to advertise. @@ -103,10 +99,7 @@ extern void StateGameLoop(); */ bool HasClients() { - NetworkClientSocket *cs; - FOR_ALL_CLIENT_SOCKETS(cs) return true; - - return false; + return !NetworkClientSocket::Iterate().empty(); } /** @@ -121,41 +114,36 @@ NetworkClientInfo::~NetworkClientInfo() /** * Return the CI given it's client-identifier * @param client_id the ClientID to search for - * @return return a pointer to the corresponding NetworkClientInfo struct or NULL when not found + * @return return a pointer to the corresponding NetworkClientInfo struct or nullptr when not found */ /* static */ NetworkClientInfo *NetworkClientInfo::GetByClientID(ClientID client_id) { - NetworkClientInfo *ci; - - FOR_ALL_CLIENT_INFOS(ci) { + for (NetworkClientInfo *ci : NetworkClientInfo::Iterate()) { if (ci->client_id == client_id) return ci; } - return NULL; + return nullptr; } /** * Return the client state given it's client-identifier * @param client_id the ClientID to search for - * @return return a pointer to the corresponding NetworkClientSocket struct or NULL when not found + * @return return a pointer to the corresponding NetworkClientSocket struct or nullptr when not found */ /* static */ ServerNetworkGameSocketHandler *ServerNetworkGameSocketHandler::GetByClientID(ClientID client_id) { - NetworkClientSocket *cs; - - FOR_ALL_CLIENT_SOCKETS(cs) { + for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) { if (cs->client_id == client_id) return cs; } - return NULL; + return nullptr; } byte NetworkSpectatorCount() { - const NetworkClientInfo *ci; byte count = 0; - FOR_ALL_CLIENT_INFOS(ci) { + for (const NetworkClientInfo *ci : NetworkClientInfo::Iterate()) { if (ci->client_playas == COMPANY_SPECTATOR) count++; } @@ -260,6 +248,7 @@ void NetworkTextMessage(NetworkAction action, TextColour colour, bool self_send, case NETWORK_ACTION_GIVE_MONEY: strid = self_send ? STR_NETWORK_MESSAGE_GAVE_MONEY_AWAY : STR_NETWORK_MESSAGE_GIVE_MONEY; break; case NETWORK_ACTION_CHAT_COMPANY: strid = self_send ? STR_NETWORK_CHAT_TO_COMPANY : STR_NETWORK_CHAT_COMPANY; break; case NETWORK_ACTION_CHAT_CLIENT: strid = self_send ? STR_NETWORK_CHAT_TO_CLIENT : STR_NETWORK_CHAT_CLIENT; break; + case NETWORK_ACTION_KICKED: strid = STR_NETWORK_MESSAGE_KICKED; break; default: strid = STR_NETWORK_CHAT_ALL; break; } @@ -380,7 +369,7 @@ void NetworkHandlePauseChange(PauseMode prev_mode, PauseMode changed_mode) char buffer[DRAW_STRING_BUFFER]; GetString(buffer, str, lastof(buffer)); - NetworkTextMessage(NETWORK_ACTION_SERVER_MESSAGE, CC_DEFAULT, false, NULL, buffer); + NetworkTextMessage(NETWORK_ACTION_SERVER_MESSAGE, CC_DEFAULT, false, nullptr, buffer); break; } @@ -412,10 +401,9 @@ static void CheckPauseHelper(bool pause, PauseMode pm) */ static uint NetworkCountActiveClients() { - const NetworkClientSocket *cs; uint count = 0; - FOR_ALL_CLIENT_SOCKETS(cs) { + for (const NetworkClientSocket *cs : NetworkClientSocket::Iterate()) { if (cs->status != NetworkClientSocket::STATUS_ACTIVE) continue; if (!Company::IsValidID(cs->GetInfo()->client_playas)) continue; count++; @@ -443,8 +431,7 @@ static void CheckMinActiveClients() */ static bool NetworkHasJoiningClient() { - const NetworkClientSocket *cs; - FOR_ALL_CLIENT_SOCKETS(cs) { + for (const NetworkClientSocket *cs : NetworkClientSocket::Iterate()) { if (cs->status >= NetworkClientSocket::STATUS_AUTHORIZED && cs->status < NetworkClientSocket::STATUS_ACTIVE) return true; } @@ -531,19 +518,17 @@ void NetworkClose(bool close_admins) { if (_network_server) { if (close_admins) { - ServerNetworkAdminSocketHandler *as; - FOR_ALL_ADMIN_SOCKETS(as) { + for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::Iterate()) { as->CloseConnection(true); } } - NetworkClientSocket *cs; - FOR_ALL_CLIENT_SOCKETS(cs) { + for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) { cs->CloseConnection(NETWORK_RECV_STATUS_CONN_LOST); } ServerNetworkGameSocketHandler::CloseListeners(); ServerNetworkAdminSocketHandler::CloseListeners(); - } else if (MyClient::my_client != NULL) { + } else if (MyClient::my_client != nullptr) { MyClient::SendQuit(); MyClient::my_client->CloseConnection(NETWORK_RECV_STATUS_CONN_LOST); } @@ -556,7 +541,7 @@ void NetworkClose(bool close_admins) NetworkFreeLocalCommandQueue(); free(_network_company_states); - _network_company_states = NULL; + _network_company_states = nullptr; InitializeNetworkPools(close_admins); } @@ -578,12 +563,12 @@ class TCPQueryConnecter : TCPConnecter { public: TCPQueryConnecter(const NetworkAddress &address) : TCPConnecter(address) {} - virtual void OnFailure() + void OnFailure() override { NetworkDisconnect(); } - virtual void OnConnect(SOCKET s) + void OnConnect(SOCKET s) override { _networking = true; new ClientNetworkGameSocketHandler(s); @@ -610,8 +595,8 @@ void NetworkTCPQueryServer(NetworkAddress address) void NetworkAddServer(const char *b) { if (*b != '\0') { - const char *port = NULL; - const char *company = NULL; + const char *port = nullptr; + const char *company = nullptr; char host[NETWORK_HOSTNAME_LENGTH]; uint16 rport; @@ -621,7 +606,7 @@ void NetworkAddServer(const char *b) rport = NETWORK_DEFAULT_PORT; ParseConnectionString(&company, &port, host); - if (port != NULL) rport = atoi(port); + if (port != nullptr) rport = atoi(port); NetworkUDPQueryServer(NetworkAddress(host, rport), true); } @@ -634,13 +619,13 @@ void NetworkAddServer(const char *b) */ void GetBindAddresses(NetworkAddressList *addresses, uint16 port) { - for (char **iter = _network_bind_list.Begin(); iter != _network_bind_list.End(); iter++) { - *addresses->Append() = NetworkAddress(*iter, port); + for (const auto &iter : _network_bind_list) { + addresses->emplace_back(iter.c_str(), port); } /* No address, so bind to everything. */ - if (addresses->Length() == 0) { - *addresses->Append() = NetworkAddress("", port); + if (addresses->size() == 0) { + addresses->emplace_back("", port); } } @@ -649,10 +634,10 @@ void GetBindAddresses(NetworkAddressList *addresses, uint16 port) * by the function that generates the config file. */ void NetworkRebuildHostList() { - _network_host_list.Clear(); + _network_host_list.clear(); - for (NetworkGameList *item = _network_game_list; item != NULL; item = item->next) { - if (item->manually) *_network_host_list.Append() = stredup(item->address.GetAddressAsString(false)); + for (NetworkGameList *item = _network_game_list; item != nullptr; item = item->next) { + if (item->manually) _network_host_list.emplace_back(item->address.GetAddressAsString(false)); } } @@ -661,12 +646,12 @@ class TCPClientConnecter : TCPConnecter { public: TCPClientConnecter(const NetworkAddress &address) : TCPConnecter(address) {} - virtual void OnFailure() + void OnFailure() override { NetworkError(STR_NETWORK_ERROR_NOCONNECTION); } - virtual void OnConnect(SOCKET s) + void OnConnect(SOCKET s) override { _networking = true; new ClientNetworkGameSocketHandler(s); @@ -772,14 +757,12 @@ bool NetworkServerStart() void NetworkReboot() { if (_network_server) { - NetworkClientSocket *cs; - FOR_ALL_CLIENT_SOCKETS(cs) { + for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) { cs->SendNewGame(); cs->SendPackets(); } - ServerNetworkAdminSocketHandler *as; - FOR_ALL_ACTIVE_ADMIN_SOCKETS(as) { + for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::IterateActive()) { as->SendNewGame(); as->SendPackets(); } @@ -798,15 +781,13 @@ void NetworkReboot() void NetworkDisconnect(bool blocking, bool close_admins) { if (_network_server) { - NetworkClientSocket *cs; - FOR_ALL_CLIENT_SOCKETS(cs) { + for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) { cs->SendShutdown(); cs->SendPackets(); } if (close_admins) { - ServerNetworkAdminSocketHandler *as; - FOR_ALL_ACTIVE_ADMIN_SOCKETS(as) { + for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::IterateActive()) { as->SendShutdown(); as->SendPackets(); } @@ -886,21 +867,21 @@ void NetworkGameLoop() static FILE *f = FioFOpenFile("commands.log", "rb", SAVE_DIR); static Date next_date = 0; static uint32 next_date_fract; - static CommandPacket *cp = NULL; + static CommandPacket *cp = nullptr; static bool check_sync_state = false; static uint32 sync_state[2]; - if (f == NULL && next_date == 0) { + if (f == nullptr && next_date == 0) { DEBUG(net, 0, "Cannot open commands.log"); next_date = 1; } - while (f != NULL && !feof(f)) { + while (f != nullptr && !feof(f)) { if (_date == next_date && _date_fract == next_date_fract) { - if (cp != NULL) { - NetworkSendCommand(cp->tile, cp->p1, cp->p2, cp->cmd & ~CMD_FLAGS_MASK, NULL, cp->text, cp->company); + if (cp != nullptr) { + NetworkSendCommand(cp->tile, cp->p1, cp->p2, cp->cmd & ~CMD_FLAGS_MASK, nullptr, cp->text, cp->company); DEBUG(net, 0, "injecting: %08x; %02x; %02x; %06x; %08x; %08x; %08x; \"%s\" (%s)", _date, _date_fract, (int)_current_company, cp->tile, cp->p1, cp->p2, cp->cmd, cp->text, GetCommandName(cp->cmd)); free(cp); - cp = NULL; + cp = nullptr; } if (check_sync_state) { if (sync_state[0] == _random.state[0] && sync_state[1] == _random.state[1]) { @@ -914,16 +895,16 @@ void NetworkGameLoop() } } - if (cp != NULL || check_sync_state) break; + if (cp != nullptr || check_sync_state) break; char buff[4096]; - if (fgets(buff, lengthof(buff), f) == NULL) break; + if (fgets(buff, lengthof(buff), f) == nullptr) break; char *p = buff; /* Ignore the "[date time] " part of the message */ if (*p == '[') { p = strchr(p, ']'); - if (p == NULL) break; + if (p == nullptr) break; p += 2; } @@ -970,10 +951,10 @@ void NetworkGameLoop() NOT_REACHED(); } } - if (f != NULL && feof(f)) { + if (f != nullptr && feof(f)) { DEBUG(net, 0, "End of commands.log"); fclose(f); - f = NULL; + f = nullptr; } #endif /* DEBUG_DUMP_COMMANDS */ if (_frame_counter >= _frame_counter_max) { @@ -1172,5 +1153,3 @@ bool IsNetworkCompatibleVersion(const char *other) const char *hash2 = ExtractNetworkRevisionHash(other); return hash1 && hash2 && (strncmp(hash1, hash2, GITHASH_SUFFIX_LEN) == 0); } - -#endif /* ENABLE_NETWORK */ diff --git a/src/network/network.h b/src/network/network.h index 26f94482ec..1de0da3a8b 100644 --- a/src/network/network.h +++ b/src/network/network.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. @@ -12,9 +10,6 @@ #ifndef NETWORK_H #define NETWORK_H - -#ifdef ENABLE_NETWORK - void NetworkStartUp(); void NetworkShutDown(); void NetworkDrawChatMessage(); @@ -26,19 +21,4 @@ extern bool _network_available; ///< is network mode available? extern bool _network_dedicated; ///< are we a dedicated server? extern bool _is_network_server; ///< Does this client wants to be a network-server? -#else /* ENABLE_NETWORK */ -/* Network function stubs when networking is disabled */ - -static inline void NetworkStartUp() {} -static inline void NetworkShutDown() {} -static inline void NetworkDrawChatMessage() {} -static inline bool HasClients() { return false; } - -#define _networking 0 -#define _network_server 0 -#define _network_available 0 -#define _network_dedicated 0 -#define _is_network_server 0 - -#endif /* ENABLE_NETWORK */ #endif /* NETWORK_H */ diff --git a/src/network/network_admin.cpp b/src/network/network_admin.cpp index f70f3d1a51..f304740a6a 100644 --- a/src/network/network_admin.cpp +++ b/src/network/network_admin.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. @@ -9,8 +7,6 @@ /** @file network_admin.cpp Server part of the admin network protocol. */ -#ifdef ENABLE_NETWORK - #include "../stdafx.h" #include "../strings_func.h" #include "../date_func.h" @@ -98,8 +94,7 @@ ServerNetworkAdminSocketHandler::~ServerNetworkAdminSocketHandler() /** Send the packets for the server sockets. */ /* static */ void ServerNetworkAdminSocketHandler::Send() { - ServerNetworkAdminSocketHandler *as; - FOR_ALL_ADMIN_SOCKETS(as) { + for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::Iterate()) { if (as->status == ADMIN_STATUS_INACTIVE && as->realtime_connect + ADMIN_AUTHORISATION_TIMEOUT < _realtime_tick) { DEBUG(net, 1, "[admin] Admin did not send its authorisation within %d seconds", ADMIN_AUTHORISATION_TIMEOUT / 1000); as->CloseConnection(true); @@ -236,12 +231,12 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendClientJoin(ClientID clien NetworkRecvStatus ServerNetworkAdminSocketHandler::SendClientInfo(const NetworkClientSocket *cs, const NetworkClientInfo *ci) { /* Only send data when we're a proper client, not just someone trying to query the server. */ - if (ci == NULL) return NETWORK_RECV_STATUS_OKAY; + if (ci == nullptr) return NETWORK_RECV_STATUS_OKAY; Packet *p = new Packet(ADMIN_PACKET_SERVER_CLIENT_INFO); p->Send_uint32(ci->client_id); - p->Send_string(cs == NULL ? "" : const_cast(cs->client_address).GetHostname()); + p->Send_string(cs == nullptr ? "" : const_cast(cs->client_address).GetHostname()); p->Send_string(ci->client_name); p->Send_uint8 (ci->client_lang); p->Send_uint32(ci->join_date); @@ -403,8 +398,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyRemove(CompanyID c /** Send economic information of all companies. */ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyEconomy() { - const Company *company; - FOR_ALL_COMPANIES(company) { + for (const Company *company : Company::Iterate()) { /* Get the income. */ Money income = 0; for (uint i = 0; i < lengthof(company->yearly_expenses[0]); i++) { @@ -442,10 +436,8 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::SendCompanyStats() NetworkCompanyStats company_stats[MAX_COMPANIES]; NetworkPopulateCompanyStats(company_stats); - const Company *company; - /* Go through all the companies. */ - FOR_ALL_COMPANIES(company) { + for (const Company *company : Company::Iterate()) { Packet *p = new Packet(ADMIN_PACKET_SERVER_COMPANY_STATS); /* Send the information. */ @@ -734,32 +726,30 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_POLL(Packet *p) case ADMIN_UPDATE_CLIENT_INFO: /* The admin is requesting client info. */ - const NetworkClientSocket *cs; if (d1 == UINT32_MAX) { - this->SendClientInfo(NULL, NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER)); - FOR_ALL_CLIENT_SOCKETS(cs) { + this->SendClientInfo(nullptr, NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER)); + for (const NetworkClientSocket *cs : NetworkClientSocket::Iterate()) { this->SendClientInfo(cs, cs->GetInfo()); } } else { if (d1 == CLIENT_ID_SERVER) { - this->SendClientInfo(NULL, NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER)); + this->SendClientInfo(nullptr, NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER)); } else { - cs = NetworkClientSocket::GetByClientID((ClientID)d1); - if (cs != NULL) this->SendClientInfo(cs, cs->GetInfo()); + const NetworkClientSocket *cs = NetworkClientSocket::GetByClientID((ClientID)d1); + if (cs != nullptr) this->SendClientInfo(cs, cs->GetInfo()); } } break; case ADMIN_UPDATE_COMPANY_INFO: /* The admin is asking for company info. */ - const Company *company; if (d1 == UINT32_MAX) { - FOR_ALL_COMPANIES(company) { + for (const Company *company : Company::Iterate()) { this->SendCompanyInfo(company); } } else { - company = Company::GetIfValid(d1); - if (company != NULL) this->SendCompanyInfo(company); + const Company *company = Company::GetIfValid(d1); + if (company != nullptr) this->SendCompanyInfo(company); } break; @@ -825,8 +815,7 @@ NetworkRecvStatus ServerNetworkAdminSocketHandler::Receive_ADMIN_CHAT(Packet *p) */ void NetworkAdminClientInfo(const NetworkClientSocket *cs, bool new_client) { - ServerNetworkAdminSocketHandler *as; - FOR_ALL_ACTIVE_ADMIN_SOCKETS(as) { + for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::IterateActive()) { if (as->update_frequency[ADMIN_UPDATE_CLIENT_INFO] & ADMIN_FREQUENCY_AUTOMATIC) { as->SendClientInfo(cs, cs->GetInfo()); if (new_client) { @@ -842,8 +831,7 @@ void NetworkAdminClientInfo(const NetworkClientSocket *cs, bool new_client) */ void NetworkAdminClientUpdate(const NetworkClientInfo *ci) { - ServerNetworkAdminSocketHandler *as; - FOR_ALL_ACTIVE_ADMIN_SOCKETS(as) { + for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::IterateActive()) { if (as->update_frequency[ADMIN_UPDATE_CLIENT_INFO] & ADMIN_FREQUENCY_AUTOMATIC) { as->SendClientUpdate(ci); } @@ -856,8 +844,7 @@ void NetworkAdminClientUpdate(const NetworkClientInfo *ci) */ void NetworkAdminClientQuit(ClientID client_id) { - ServerNetworkAdminSocketHandler *as; - FOR_ALL_ACTIVE_ADMIN_SOCKETS(as) { + for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::IterateActive()) { if (as->update_frequency[ADMIN_UPDATE_CLIENT_INFO] & ADMIN_FREQUENCY_AUTOMATIC) { as->SendClientQuit(client_id); } @@ -871,8 +858,7 @@ void NetworkAdminClientQuit(ClientID client_id) */ void NetworkAdminClientError(ClientID client_id, NetworkErrorCode error_code) { - ServerNetworkAdminSocketHandler *as; - FOR_ALL_ACTIVE_ADMIN_SOCKETS(as) { + for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::IterateActive()) { if (as->update_frequency[ADMIN_UPDATE_CLIENT_INFO] & ADMIN_FREQUENCY_AUTOMATIC) { as->SendClientError(client_id, error_code); } @@ -886,13 +872,12 @@ void NetworkAdminClientError(ClientID client_id, NetworkErrorCode error_code) */ void NetworkAdminCompanyInfo(const Company *company, bool new_company) { - if (company == NULL) { + if (company == nullptr) { DEBUG(net, 1, "[admin] Empty company given for update"); return; } - ServerNetworkAdminSocketHandler *as; - FOR_ALL_ACTIVE_ADMIN_SOCKETS(as) { + for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::IterateActive()) { if (as->update_frequency[ADMIN_UPDATE_COMPANY_INFO] != ADMIN_FREQUENCY_AUTOMATIC) continue; as->SendCompanyInfo(company); @@ -908,10 +893,9 @@ void NetworkAdminCompanyInfo(const Company *company, bool new_company) */ void NetworkAdminCompanyUpdate(const Company *company) { - if (company == NULL) return; + if (company == nullptr) return; - ServerNetworkAdminSocketHandler *as; - FOR_ALL_ACTIVE_ADMIN_SOCKETS(as) { + for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::IterateActive()) { if (as->update_frequency[ADMIN_UPDATE_COMPANY_INFO] != ADMIN_FREQUENCY_AUTOMATIC) continue; as->SendCompanyUpdate(company); @@ -925,8 +909,7 @@ void NetworkAdminCompanyUpdate(const Company *company) */ void NetworkAdminCompanyRemove(CompanyID company_id, AdminCompanyRemoveReason bcrr) { - ServerNetworkAdminSocketHandler *as; - FOR_ALL_ACTIVE_ADMIN_SOCKETS(as) { + for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::IterateActive()) { as->SendCompanyRemove(company_id, bcrr); } } @@ -939,8 +922,7 @@ void NetworkAdminChat(NetworkAction action, DestType desttype, ClientID client_i { if (from_admin) return; - ServerNetworkAdminSocketHandler *as; - FOR_ALL_ACTIVE_ADMIN_SOCKETS(as) { + for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::IterateActive()) { if (as->update_frequency[ADMIN_UPDATE_CHAT] & ADMIN_FREQUENCY_AUTOMATIC) { as->SendChat(action, desttype, client_id, msg, data); } @@ -965,8 +947,7 @@ void NetworkServerSendAdminRcon(AdminIndex admin_index, TextColour colour_code, */ void NetworkAdminConsole(const char *origin, const char *string) { - ServerNetworkAdminSocketHandler *as; - FOR_ALL_ACTIVE_ADMIN_SOCKETS(as) { + for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::IterateActive()) { if (as->update_frequency[ADMIN_UPDATE_CONSOLE] & ADMIN_FREQUENCY_AUTOMATIC) { as->SendConsole(origin, string); } @@ -979,8 +960,7 @@ void NetworkAdminConsole(const char *origin, const char *string) */ void NetworkAdminGameScript(const char *json) { - ServerNetworkAdminSocketHandler *as; - FOR_ALL_ACTIVE_ADMIN_SOCKETS(as) { + for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::IterateActive()) { if (as->update_frequency[ADMIN_UPDATE_GAMESCRIPT] & ADMIN_FREQUENCY_AUTOMATIC) { as->SendGameScript(json); } @@ -994,10 +974,9 @@ void NetworkAdminGameScript(const char *json) */ void NetworkAdminCmdLogging(const NetworkClientSocket *owner, const CommandPacket *cp) { - ClientID client_id = owner == NULL ? _network_own_client_id : owner->client_id; + ClientID client_id = owner == nullptr ? _network_own_client_id : owner->client_id; - ServerNetworkAdminSocketHandler *as; - FOR_ALL_ACTIVE_ADMIN_SOCKETS(as) { + for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::IterateActive()) { if (as->update_frequency[ADMIN_UPDATE_CMD_LOGGING] & ADMIN_FREQUENCY_AUTOMATIC) { as->SendCmdLogging(client_id, cp); } @@ -1009,8 +988,7 @@ void NetworkAdminCmdLogging(const NetworkClientSocket *owner, const CommandPacke */ void ServerNetworkAdminSocketHandler::WelcomeAll() { - ServerNetworkAdminSocketHandler *as; - FOR_ALL_ACTIVE_ADMIN_SOCKETS(as) { + for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::IterateActive()) { as->SendWelcome(); } } @@ -1021,8 +999,7 @@ void ServerNetworkAdminSocketHandler::WelcomeAll() */ void NetworkAdminUpdate(AdminUpdateFrequency freq) { - ServerNetworkAdminSocketHandler *as; - FOR_ALL_ACTIVE_ADMIN_SOCKETS(as) { + for (ServerNetworkAdminSocketHandler *as : ServerNetworkAdminSocketHandler::IterateActive()) { for (int i = 0; i < ADMIN_UPDATE_END; i++) { if (as->update_frequency[i] & freq) { /* Update the admin for the required details */ @@ -1045,5 +1022,3 @@ void NetworkAdminUpdate(AdminUpdateFrequency freq) } } } - -#endif /* ENABLE_NETWORK */ diff --git a/src/network/network_admin.h b/src/network/network_admin.h index cb478fc7e7..16bd57a4d6 100644 --- a/src/network/network_admin.h +++ b/src/network/network_admin.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. @@ -12,8 +10,6 @@ #ifndef NETWORK_ADMIN_H #define NETWORK_ADMIN_H -#ifdef ENABLE_NETWORK - #include "network_internal.h" #include "core/tcp_listen.h" #include "core/tcp_admin.h" @@ -28,14 +24,14 @@ extern NetworkAdminSocketPool _networkadminsocket_pool; /** Class for handling the server side of the game connection. */ class ServerNetworkAdminSocketHandler : public NetworkAdminSocketPool::PoolItem<&_networkadminsocket_pool>, public NetworkAdminSocketHandler, public TCPListenHandler { protected: - virtual NetworkRecvStatus Receive_ADMIN_JOIN(Packet *p); - virtual NetworkRecvStatus Receive_ADMIN_QUIT(Packet *p); - virtual NetworkRecvStatus Receive_ADMIN_UPDATE_FREQUENCY(Packet *p); - virtual NetworkRecvStatus Receive_ADMIN_POLL(Packet *p); - virtual NetworkRecvStatus Receive_ADMIN_CHAT(Packet *p); - virtual NetworkRecvStatus Receive_ADMIN_RCON(Packet *p); - virtual NetworkRecvStatus Receive_ADMIN_GAMESCRIPT(Packet *p); - virtual NetworkRecvStatus Receive_ADMIN_PING(Packet *p); + NetworkRecvStatus Receive_ADMIN_JOIN(Packet *p) override; + NetworkRecvStatus Receive_ADMIN_QUIT(Packet *p) override; + NetworkRecvStatus Receive_ADMIN_UPDATE_FREQUENCY(Packet *p) override; + NetworkRecvStatus Receive_ADMIN_POLL(Packet *p) override; + NetworkRecvStatus Receive_ADMIN_CHAT(Packet *p) override; + NetworkRecvStatus Receive_ADMIN_RCON(Packet *p) override; + NetworkRecvStatus Receive_ADMIN_GAMESCRIPT(Packet *p) override; + NetworkRecvStatus Receive_ADMIN_PING(Packet *p) override; NetworkRecvStatus SendProtocol(); NetworkRecvStatus SendPong(uint32 d1); @@ -86,29 +82,22 @@ public: { return "admin"; } + + struct ServerNetworkAdminSocketHandlerFilter { + bool operator() (size_t index) { return ServerNetworkAdminSocketHandler::Get(index)->GetAdminStatus() == ADMIN_STATUS_ACTIVE; } + }; + + /** + * Returns an iterable ensemble of all active admin sockets + * @param from index of the first socket to consider + * @return an iterable ensemble of all active admin sockets + */ + static Pool::IterateWrapperFiltered IterateActive(size_t from = 0) + { + return Pool::IterateWrapperFiltered(from, ServerNetworkAdminSocketHandlerFilter{}); + } }; -/** - * Iterate over all the sockets from a given starting point. - * @param var The variable to iterate with. - * @param start The start of the iteration. - */ -#define FOR_ALL_ADMIN_SOCKETS_FROM(var, start) FOR_ALL_ITEMS_FROM(ServerNetworkAdminSocketHandler, adminsocket_index, var, start) - -/** - * Iterate over all the sockets. - * @param var The variable to iterate with. - */ -#define FOR_ALL_ADMIN_SOCKETS(var) FOR_ALL_ADMIN_SOCKETS_FROM(var, 0) - -/** - * Iterate over all the active sockets. - * @param var The variable to iterate with. - */ -#define FOR_ALL_ACTIVE_ADMIN_SOCKETS(var) \ - FOR_ALL_ADMIN_SOCKETS(var) \ - if (var->GetAdminStatus() == ADMIN_STATUS_ACTIVE) - void NetworkAdminClientInfo(const NetworkClientSocket *cs, bool new_client = false); void NetworkAdminClientUpdate(const NetworkClientInfo *ci); void NetworkAdminClientQuit(ClientID client_id); @@ -124,5 +113,4 @@ void NetworkAdminConsole(const char *origin, const char *string); void NetworkAdminGameScript(const char *json); void NetworkAdminCmdLogging(const NetworkClientSocket *owner, const CommandPacket *cp); -#endif /* ENABLE_NETWORK */ #endif /* NETWORK_ADMIN_H */ diff --git a/src/network/network_base.h b/src/network/network_base.h index 1644b3558a..cbb7e88f2c 100644 --- a/src/network/network_base.h +++ b/src/network/network_base.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. @@ -12,8 +10,6 @@ #ifndef NETWORK_BASE_H #define NETWORK_BASE_H -#ifdef ENABLE_NETWORK - #include "network_type.h" #include "core/address.h" #include "../core/pool_type.hpp" @@ -41,18 +37,4 @@ struct NetworkClientInfo : NetworkClientInfoPool::PoolItem<&_networkclientinfo_p static NetworkClientInfo *GetByClientID(ClientID client_id); }; -/** - * Iterate over all the clients from a given index. - * @param var The variable to iterate with. - * @param start The location to start the iteration from. - */ -#define FOR_ALL_CLIENT_INFOS_FROM(var, start) FOR_ALL_ITEMS_FROM(NetworkClientInfo, clientinfo_index, var, start) - -/** - * Iterate over all the clients. - * @param var The variable to iterate with. - */ -#define FOR_ALL_CLIENT_INFOS(var) FOR_ALL_CLIENT_INFOS_FROM(var, 0) - -#endif /* ENABLE_NETWORK */ #endif /* NETWORK_BASE_H */ diff --git a/src/network/network_chat_gui.cpp b/src/network/network_chat_gui.cpp index 45c2aa90b3..6dbae0de46 100644 --- a/src/network/network_chat_gui.cpp +++ b/src/network/network_chat_gui.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. @@ -11,8 +9,6 @@ #include /* va_list */ -#ifdef ENABLE_NETWORK - #include "../stdafx.h" #include "../strings_func.h" #include "../blitter/factory.hpp" @@ -48,7 +44,7 @@ struct ChatMessage { }; /* used for chat window */ -static ChatMessage *_chatmsg_list = NULL; ///< The actual chat message list. +static ChatMessage *_chatmsg_list = nullptr; ///< The actual chat message list. static bool _chatmessage_dirty = false; ///< Does the chat message need repainting? static bool _chatmessage_visible = false; ///< Is a chat message visible. static bool _chat_tab_completion_active; ///< Whether tab completion is active. @@ -59,7 +55,7 @@ static uint MAX_CHAT_MESSAGES = 0; ///< The limit of chat messages to sho * the left and pixels from the bottom. The height is the maximum height. */ static PointDimension _chatmsg_box; -static uint8 *_chatmessage_backup = NULL; ///< Backup in case text is moved. +static uint8 *_chatmessage_backup = nullptr; ///< Backup in case text is moved. /** * Count the chat messages. @@ -322,7 +318,7 @@ struct NetworkChatWindow : public Window { InvalidateWindowData(WC_NEWS_WINDOW, 0, 0); } - virtual void FindWindowPlacementAndResize(int def_width, int def_height) + void FindWindowPlacementAndResize(int def_width, int def_height) override { Window::FindWindowPlacementAndResize(_toolbar_width, def_height); } @@ -340,8 +336,7 @@ struct NetworkChatWindow : public Window { /* First, try clients */ if (*item < MAX_CLIENT_SLOTS) { /* Skip inactive clients */ - NetworkClientInfo *ci; - FOR_ALL_CLIENT_INFOS_FROM(ci, *item) { + for (NetworkClientInfo *ci : NetworkClientInfo::Iterate(*item)) { *item = ci->index; return ci->client_name; } @@ -352,9 +347,7 @@ struct NetworkChatWindow : public Window { * Not that the following assumes all town indices are adjacent, ie no * towns have been deleted. */ if (*item < (uint)MAX_CLIENT_SLOTS + Town::GetPoolSize()) { - const Town *t; - - FOR_ALL_TOWNS_FROM(t, *item - MAX_CLIENT_SLOTS) { + for (const Town *t : Town::Iterate(*item - MAX_CLIENT_SLOTS)) { /* Get the town-name via the string-system */ SetDParam(0, t->index); GetString(chat_tab_temp_buffer, STR_TOWN_NAME, lastof(chat_tab_temp_buffer)); @@ -362,7 +355,7 @@ struct NetworkChatWindow : public Window { } } - return NULL; + return nullptr; } /** @@ -373,7 +366,7 @@ struct NetworkChatWindow : public Window { static char *ChatTabCompletionFindText(char *buf) { char *p = strrchr(buf, ' '); - if (p == NULL) return buf; + if (p == nullptr) return buf; *p = '\0'; return p + 1; @@ -402,7 +395,7 @@ struct NetworkChatWindow : public Window { tb_buf = ChatTabCompletionFindText(pre_buf); tb_len = strlen(tb_buf); - while ((cur_name = ChatTabCompletionNextItem(&item)) != NULL) { + while ((cur_name = ChatTabCompletionNextItem(&item)) != nullptr) { item++; if (_chat_tab_completion_active) { @@ -460,13 +453,13 @@ struct NetworkChatWindow : public Window { free(pre_buf); } - virtual Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number) + Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number) override { Point pt = { (int)GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL) * 2, _screen.height - sm_height - FindWindowById(WC_STATUS_BAR, 0)->height }; return pt; } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { if (widget != WID_NC_DESTINATION) return; @@ -479,7 +472,7 @@ struct NetworkChatWindow : public Window { *size = maxdim(*size, d); } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { if (widget != WID_NC_DESTINATION) return; @@ -489,7 +482,7 @@ struct NetworkChatWindow : public Window { DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, Center(r.top, r.bottom - r.top), this->dest_string, TC_BLACK, SA_RIGHT); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_NC_SENDBUTTON: /* Send */ @@ -502,7 +495,7 @@ struct NetworkChatWindow : public Window { } } - virtual EventState OnKeyPress(WChar key, uint16 keycode) + EventState OnKeyPress(WChar key, uint16 keycode) override { EventState state = ES_NOT_HANDLED; if (keycode == WKC_TAB) { @@ -512,7 +505,7 @@ struct NetworkChatWindow : public Window { return state; } - virtual void OnEditboxChanged(int wid) + void OnEditboxChanged(int wid) override { _chat_tab_completion_active = false; } @@ -522,7 +515,7 @@ struct NetworkChatWindow : public Window { * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (data == this->dest) delete this; } @@ -545,7 +538,7 @@ static const NWidgetPart _nested_chat_window_widgets[] = { /** The description of the chat window. */ static WindowDesc _chat_window_desc( - WDP_MANUAL, NULL, 0, 0, + WDP_MANUAL, nullptr, 0, 0, WC_SEND_NETWORK_MSG, WC_NONE, 0, _nested_chat_window_widgets, lengthof(_nested_chat_window_widgets) @@ -562,5 +555,3 @@ void ShowNetworkChatQueryWindow(DestType type, int dest) DeleteWindowByClass(WC_SEND_NETWORK_MSG); new NetworkChatWindow(&_chat_window_desc, type, dest); } - -#endif /* ENABLE_NETWORK */ diff --git a/src/network/network_client.cpp b/src/network/network_client.cpp index 62db6a5552..74b802f919 100644 --- a/src/network/network_client.cpp +++ b/src/network/network_client.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. @@ -9,8 +7,6 @@ /** @file network_client.cpp Client part of the network protocol. */ -#ifdef ENABLE_NETWORK - #include "../stdafx.h" #include "network_gui.h" #include "../saveload/saveload.h" @@ -31,6 +27,7 @@ #include "network_base.h" #include "network_client.h" #include "../core/backup_type.hpp" +#include "../thread.h" #include "table/strings.h" @@ -43,7 +40,7 @@ struct PacketReader : LoadFilter { static const size_t CHUNK = 32 * 1024; ///< 32 KiB chunks of memory. - AutoFreeSmallVector blocks; ///< Buffer with blocks of allocated memory. + std::vector blocks; ///< Buffer with blocks of allocated memory. byte *buf; ///< Buffer we're going to write to/read from. byte *bufe; ///< End of the buffer we write to/read from. byte **block; ///< The block we're reading from/writing to. @@ -51,10 +48,17 @@ struct PacketReader : LoadFilter { size_t read_bytes; ///< The total number of read bytes. /** Initialise everything. */ - PacketReader() : LoadFilter(NULL), buf(NULL), bufe(NULL), block(NULL), written_bytes(0), read_bytes(0) + PacketReader() : LoadFilter(nullptr), buf(nullptr), bufe(nullptr), block(nullptr), written_bytes(0), read_bytes(0) { } + ~PacketReader() override + { + for (auto p : this->blocks) { + free(p); + } + } + /** * Add a packet to this buffer. * @param p The packet to add. @@ -79,14 +83,14 @@ struct PacketReader : LoadFilter { /* Allocate a new chunk and add the remaining data. */ pbuf += to_write; to_write = in_packet - to_write; - this->buf = *this->blocks.Append() = CallocT(CHUNK); + this->blocks.push_back(this->buf = CallocT(CHUNK)); this->bufe = this->buf + CHUNK; memcpy(this->buf, pbuf, to_write); this->buf += to_write; } - /* virtual */ size_t Read(byte *rbuf, size_t size) + size_t Read(byte *rbuf, size_t size) override { /* Limit the amount to read to whatever we still have. */ size_t ret_size = size = min(this->written_bytes - this->read_bytes, size); @@ -108,11 +112,11 @@ struct PacketReader : LoadFilter { return ret_size; } - /* virtual */ void Reset() + void Reset() override { this->read_bytes = 0; - this->block = this->blocks.Begin(); + this->block = this->blocks.data(); this->buf = *this->block++; this->bufe = this->buf + CHUNK; } @@ -137,9 +141,9 @@ void ClientNetworkEmergencySave() * Create a new socket for the client side of the game connection. * @param s The socket to connect with. */ -ClientNetworkGameSocketHandler::ClientNetworkGameSocketHandler(SOCKET s) : NetworkGameSocketHandler(s), savegame(NULL), status(STATUS_INACTIVE) +ClientNetworkGameSocketHandler::ClientNetworkGameSocketHandler(SOCKET s) : NetworkGameSocketHandler(s), savegame(nullptr), status(STATUS_INACTIVE) { - assert(ClientNetworkGameSocketHandler::my_client == NULL); + assert(ClientNetworkGameSocketHandler::my_client == nullptr); ClientNetworkGameSocketHandler::my_client = this; } @@ -147,7 +151,7 @@ ClientNetworkGameSocketHandler::ClientNetworkGameSocketHandler(SOCKET s) : Netwo ClientNetworkGameSocketHandler::~ClientNetworkGameSocketHandler() { assert(ClientNetworkGameSocketHandler::my_client == this); - ClientNetworkGameSocketHandler::my_client = NULL; + ClientNetworkGameSocketHandler::my_client = nullptr; delete this->savegame; } @@ -295,7 +299,7 @@ void ClientNetworkGameSocketHandler::ClientError(NetworkRecvStatus res) /** Our client's connection. */ -ClientNetworkGameSocketHandler * ClientNetworkGameSocketHandler::my_client = NULL; +ClientNetworkGameSocketHandler * ClientNetworkGameSocketHandler::my_client = nullptr; /** Last frame we performed an ack. */ static uint32 last_ack_frame; @@ -314,9 +318,9 @@ static uint8 _network_server_max_spectators; CompanyID _network_join_as; /** Login password from -p argument */ -const char *_network_join_server_password = NULL; +const char *_network_join_server_password = nullptr; /** Company password from -P argument */ -const char *_network_join_company_password = NULL; +const char *_network_join_company_password = nullptr; /** Make sure the server ID length is the same as a md5 hash. */ assert_compile(NETWORK_SERVER_ID_LENGTH == 16 * 2 + 1); @@ -527,7 +531,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::SendMove(CompanyID company, co */ bool ClientNetworkGameSocketHandler::IsConnected() { - return my_client != NULL && my_client->status == STATUS_ACTIVE; + return my_client != nullptr && my_client->status == STATUS_ACTIVE; } @@ -536,7 +540,7 @@ bool ClientNetworkGameSocketHandler::IsConnected() * DEF_CLIENT_RECEIVE_COMMAND has parameter: Packet *p ************/ -extern bool SafeLoad(const char *filename, SaveLoadOperation fop, DetailedFileType dft, GameMode newgm, Subdirectory subdir, struct LoadFilter *lf = NULL); +extern bool SafeLoad(const char *filename, SaveLoadOperation fop, DetailedFileType dft, GameMode newgm, Subdirectory subdir, struct LoadFilter *lf = nullptr); NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_FULL(Packet *p) { @@ -570,7 +574,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_COMPANY_INFO(Pa if (current >= MAX_COMPANIES) return NETWORK_RECV_STATUS_CLOSE_QUERY; NetworkCompanyInfo *company_info = GetLobbyCompanyInfo(current); - if (company_info == NULL) return NETWORK_RECV_STATUS_CLOSE_QUERY; + if (company_info == nullptr) return NETWORK_RECV_STATUS_CLOSE_QUERY; p->Recv_string(company_info->company_name, sizeof(company_info->company_name)); company_info->inaugurated_year = p->Recv_uint32(); @@ -613,7 +617,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CLIENT_INFO(Pac if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CONN_LOST; ci = NetworkClientInfo::GetByClientID(client_id); - if (ci != NULL) { + if (ci != nullptr) { if (playas == ci->client_playas && strcmp(name, ci->client_name) != 0) { /* Client name changed, display the change */ NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, name); @@ -683,8 +687,15 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_ERROR(Packet *p StringID err = STR_NETWORK_ERROR_LOSTCONNECTION; if (error < (ptrdiff_t)lengthof(network_error_strings)) err = network_error_strings[error]; - - ShowErrorMessage(err, INVALID_STRING_ID, WL_CRITICAL); + /* In case of kicking a client, we assume there is a kick message in the packet if we can read one byte */ + if (error == NETWORK_ERROR_KICKED && p->CanReadFromPacket(1)) { + char kick_msg[255]; + p->Recv_string(kick_msg, sizeof(kick_msg)); + SetDParamStr(0, kick_msg); + ShowErrorMessage(err, STR_NETWORK_ERROR_KICK_MESSAGE, WL_CRITICAL); + } else { + ShowErrorMessage(err, INVALID_STRING_ID, WL_CRITICAL); + } /* Perform an emergency save if we had already entered the game */ if (this->status == STATUS_ACTIVE) ClientNetworkEmergencySave(); @@ -708,7 +719,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CHECK_NEWGRFS(P /* Check whether we know this GRF */ const GRFConfig *f = FindGRFConfig(c.grfid, FGCM_EXACT, c.md5sum); - if (f == NULL) { + if (f == nullptr) { /* We do not know this GRF, bail out of initialization */ char buf[sizeof(c.md5sum) * 2 + 1]; md5sumToString(buf, lastof(buf), c.md5sum); @@ -794,7 +805,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_MAP_BEGIN(Packe if (this->status < STATUS_AUTHORIZED || this->status >= STATUS_MAP) return NETWORK_RECV_STATUS_MALFORMED_PACKET; this->status = STATUS_MAP; - if (this->savegame != NULL) return NETWORK_RECV_STATUS_MALFORMED_PACKET; + if (this->savegame != nullptr) return NETWORK_RECV_STATUS_MALFORMED_PACKET; this->savegame = new PacketReader(); @@ -812,7 +823,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_MAP_BEGIN(Packe NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_MAP_SIZE(Packet *p) { if (this->status != STATUS_MAP) return NETWORK_RECV_STATUS_MALFORMED_PACKET; - if (this->savegame == NULL) return NETWORK_RECV_STATUS_MALFORMED_PACKET; + if (this->savegame == nullptr) return NETWORK_RECV_STATUS_MALFORMED_PACKET; _network_join_bytes_total = p->Recv_uint32(); SetWindowDirty(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN); @@ -823,7 +834,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_MAP_SIZE(Packet NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_MAP_DATA(Packet *p) { if (this->status != STATUS_MAP) return NETWORK_RECV_STATUS_MALFORMED_PACKET; - if (this->savegame == NULL) return NETWORK_RECV_STATUS_MALFORMED_PACKET; + if (this->savegame == nullptr) return NETWORK_RECV_STATUS_MALFORMED_PACKET; /* We are still receiving data, put it to the file */ this->savegame->AddPacket(p); @@ -837,7 +848,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_MAP_DATA(Packet NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_MAP_DONE(Packet *p) { if (this->status != STATUS_MAP) return NETWORK_RECV_STATUS_MALFORMED_PACKET; - if (this->savegame == NULL) return NETWORK_RECV_STATUS_MALFORMED_PACKET; + if (this->savegame == nullptr) return NETWORK_RECV_STATUS_MALFORMED_PACKET; _network_join_status = NETWORK_JOIN_STATUS_PROCESSING; SetWindowDirty(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN); @@ -850,12 +861,12 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_MAP_DONE(Packet * game, which would cause us to free this->savegame twice. */ LoadFilter *lf = this->savegame; - this->savegame = NULL; + this->savegame = nullptr; lf->Reset(); /* The map is done downloading, load it */ ClearErrorMessages(); - bool load_success = SafeLoad(NULL, SLO_LOAD, DFT_GAME_FILE, GM_NORMAL, NO_DIRECTORY, lf); + bool load_success = SafeLoad(nullptr, SLO_LOAD, DFT_GAME_FILE, GM_NORMAL, NO_DIRECTORY, lf); /* Long savegame loads shouldn't affect the lag calculation! */ this->last_packet = _realtime_tick; @@ -881,7 +892,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_MAP_DONE(Packet * the server will give us a client-id and let us in */ _network_join_status = NETWORK_JOIN_STATUS_REGISTERING; ShowJoinStatusWindow(); - NetworkSendCommand(0, CCA_NEW, 0, CMD_COMPANY_CTRL, NULL, NULL, _local_company); + NetworkSendCommand(0, CCA_NEW, 0, CMD_COMPANY_CTRL, nullptr, nullptr, _local_company); } } else { /* take control over an existing company */ @@ -946,7 +957,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_COMMAND(Packet cp.frame = p->Recv_uint32(); cp.my_cmd = p->Recv_bool(); - if (err != NULL) { + if (err != nullptr) { IConsolePrintF(CC_ERROR, "WARNING: %s from server, dropping...", err); return NETWORK_RECV_STATUS_MALFORMED_PACKET; } @@ -961,7 +972,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CHAT(Packet *p) if (this->status != STATUS_ACTIVE) return NETWORK_RECV_STATUS_MALFORMED_PACKET; char name[NETWORK_NAME_LENGTH], msg[NETWORK_CHAT_LENGTH]; - const NetworkClientInfo *ci = NULL, *ci_to; + const NetworkClientInfo *ci = nullptr, *ci_to; NetworkAction action = (NetworkAction)p->Recv_uint8(); ClientID client_id = (ClientID)p->Recv_uint32(); @@ -970,7 +981,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CHAT(Packet *p) int64 data = p->Recv_uint64(); ci_to = NetworkClientInfo::GetByClientID(client_id); - if (ci_to == NULL) return NETWORK_RECV_STATUS_OKAY; + if (ci_to == nullptr) return NETWORK_RECV_STATUS_OKAY; /* Did we initiate the action locally? */ if (self_send) { @@ -1003,7 +1014,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_CHAT(Packet *p) ci = ci_to; } - if (ci != NULL) { + if (ci != nullptr) { NetworkTextMessage(action, GetDrawStringCompanyColour(ci->client_playas), self_send, name, msg, data); } return NETWORK_RECV_STATUS_OKAY; @@ -1016,8 +1027,8 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_ERROR_QUIT(Pack ClientID client_id = (ClientID)p->Recv_uint32(); NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id); - if (ci != NULL) { - NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, ci->client_name, NULL, GetNetworkErrorMsg((NetworkErrorCode)p->Recv_uint8())); + if (ci != nullptr) { + NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, ci->client_name, nullptr, GetNetworkErrorMsg((NetworkErrorCode)p->Recv_uint8())); delete ci; } @@ -1033,8 +1044,8 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_QUIT(Packet *p) ClientID client_id = (ClientID)p->Recv_uint32(); NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id); - if (ci != NULL) { - NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, ci->client_name, NULL, STR_NETWORK_MESSAGE_CLIENT_LEAVING); + if (ci != nullptr) { + NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, ci->client_name, nullptr, STR_NETWORK_MESSAGE_CLIENT_LEAVING); delete ci; } else { DEBUG(net, 0, "Unknown client (%d) is leaving the game", client_id); @@ -1053,7 +1064,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_JOIN(Packet *p) ClientID client_id = (ClientID)p->Recv_uint32(); NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id); - if (ci != NULL) { + if (ci != nullptr) { NetworkTextMessage(NETWORK_ACTION_JOIN, CC_DEFAULT, false, ci->client_name); } @@ -1123,7 +1134,7 @@ NetworkRecvStatus ClientNetworkGameSocketHandler::Receive_SERVER_MOVE(Packet *p) const NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id); /* Just make sure we do not try to use a client_index that does not exist */ - if (ci == NULL) return NETWORK_RECV_STATUS_OKAY; + if (ci == nullptr) return NETWORK_RECV_STATUS_OKAY; /* if not valid player, force spectator, else check player exists */ if (!Company::IsValidID(company_id)) company_id = COMPANY_SPECTATOR; @@ -1226,12 +1237,11 @@ void NetworkClientRequestMove(CompanyID company_id, const char *pass) */ void NetworkClientsToSpectators(CompanyID cid) { - Backup cur_company(_current_company, FILE_LINE); + Backup cur_company(_current_company, FILE_LINE); /* If our company is changing owner, go to spectators */ if (cid == _local_company) SetLocalCompany(COMPANY_SPECTATOR); - NetworkClientInfo *ci; - FOR_ALL_CLIENT_INFOS(ci) { + for (NetworkClientInfo *ci : NetworkClientInfo::Iterate()) { if (ci->client_playas != cid) continue; NetworkTextMessage(NETWORK_ACTION_COMPANY_SPECTATOR, CC_DEFAULT, false, ci->client_name); ci->client_playas = COMPANY_SPECTATOR; @@ -1247,7 +1257,7 @@ void NetworkUpdateClientName() { NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(_network_own_client_id); - if (ci == NULL) return; + if (ci == nullptr) return; /* Don't change the name if it is the same as the old name */ if (strcmp(ci->client_name, _settings_client.network.client_name) != 0) { @@ -1295,8 +1305,7 @@ bool NetworkClientPreferTeamChat(const NetworkClientInfo *cio) /* Only companies actually playing can speak to team. Eg spectators cannot */ if (!_settings_client.gui.prefer_teamchat || !Company::IsValidID(cio->client_playas)) return false; - const NetworkClientInfo *ci; - FOR_ALL_CLIENT_INFOS(ci) { + for (const NetworkClientInfo *ci : NetworkClientInfo::Iterate()) { if (ci->client_playas == cio->client_playas && ci != cio) return true; } @@ -1320,5 +1329,3 @@ bool NetworkMaxSpectatorsReached() { return NetworkSpectatorCount() >= (_network_server ? _settings_client.network.max_spectators : _network_server_max_spectators); } - -#endif /* ENABLE_NETWORK */ diff --git a/src/network/network_client.h b/src/network/network_client.h index 23878b5067..d1ffe1c1d1 100644 --- a/src/network/network_client.h +++ b/src/network/network_client.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. @@ -12,8 +10,6 @@ #ifndef NETWORK_CLIENT_H #define NETWORK_CLIENT_H -#ifdef ENABLE_NETWORK - #include "network_internal.h" /** Class for handling the client side of the game connection. */ @@ -44,33 +40,33 @@ protected: friend void NetworkClose(bool close_admins); static ClientNetworkGameSocketHandler *my_client; ///< This is us! - virtual NetworkRecvStatus Receive_SERVER_FULL(Packet *p); - virtual NetworkRecvStatus Receive_SERVER_BANNED(Packet *p); - virtual NetworkRecvStatus Receive_SERVER_ERROR(Packet *p); - virtual NetworkRecvStatus Receive_SERVER_COMPANY_INFO(Packet *p); - virtual NetworkRecvStatus Receive_SERVER_CLIENT_INFO(Packet *p); - virtual NetworkRecvStatus Receive_SERVER_NEED_GAME_PASSWORD(Packet *p); - virtual NetworkRecvStatus Receive_SERVER_NEED_COMPANY_PASSWORD(Packet *p); - virtual NetworkRecvStatus Receive_SERVER_WELCOME(Packet *p); - virtual NetworkRecvStatus Receive_SERVER_WAIT(Packet *p); - virtual NetworkRecvStatus Receive_SERVER_MAP_BEGIN(Packet *p); - virtual NetworkRecvStatus Receive_SERVER_MAP_SIZE(Packet *p); - virtual NetworkRecvStatus Receive_SERVER_MAP_DATA(Packet *p); - virtual NetworkRecvStatus Receive_SERVER_MAP_DONE(Packet *p); - virtual NetworkRecvStatus Receive_SERVER_JOIN(Packet *p); - virtual NetworkRecvStatus Receive_SERVER_FRAME(Packet *p); - virtual NetworkRecvStatus Receive_SERVER_SYNC(Packet *p); - virtual NetworkRecvStatus Receive_SERVER_COMMAND(Packet *p); - virtual NetworkRecvStatus Receive_SERVER_CHAT(Packet *p); - virtual NetworkRecvStatus Receive_SERVER_QUIT(Packet *p); - virtual NetworkRecvStatus Receive_SERVER_ERROR_QUIT(Packet *p); - virtual NetworkRecvStatus Receive_SERVER_SHUTDOWN(Packet *p); - virtual NetworkRecvStatus Receive_SERVER_NEWGAME(Packet *p); - virtual NetworkRecvStatus Receive_SERVER_RCON(Packet *p); - virtual NetworkRecvStatus Receive_SERVER_CHECK_NEWGRFS(Packet *p); - virtual NetworkRecvStatus Receive_SERVER_MOVE(Packet *p); - virtual NetworkRecvStatus Receive_SERVER_COMPANY_UPDATE(Packet *p); - virtual NetworkRecvStatus Receive_SERVER_CONFIG_UPDATE(Packet *p); + NetworkRecvStatus Receive_SERVER_FULL(Packet *p) override; + NetworkRecvStatus Receive_SERVER_BANNED(Packet *p) override; + NetworkRecvStatus Receive_SERVER_ERROR(Packet *p) override; + NetworkRecvStatus Receive_SERVER_COMPANY_INFO(Packet *p) override; + NetworkRecvStatus Receive_SERVER_CLIENT_INFO(Packet *p) override; + NetworkRecvStatus Receive_SERVER_NEED_GAME_PASSWORD(Packet *p) override; + NetworkRecvStatus Receive_SERVER_NEED_COMPANY_PASSWORD(Packet *p) override; + NetworkRecvStatus Receive_SERVER_WELCOME(Packet *p) override; + NetworkRecvStatus Receive_SERVER_WAIT(Packet *p) override; + NetworkRecvStatus Receive_SERVER_MAP_BEGIN(Packet *p) override; + NetworkRecvStatus Receive_SERVER_MAP_SIZE(Packet *p) override; + NetworkRecvStatus Receive_SERVER_MAP_DATA(Packet *p) override; + NetworkRecvStatus Receive_SERVER_MAP_DONE(Packet *p) override; + NetworkRecvStatus Receive_SERVER_JOIN(Packet *p) override; + NetworkRecvStatus Receive_SERVER_FRAME(Packet *p) override; + NetworkRecvStatus Receive_SERVER_SYNC(Packet *p) override; + NetworkRecvStatus Receive_SERVER_COMMAND(Packet *p) override; + NetworkRecvStatus Receive_SERVER_CHAT(Packet *p) override; + NetworkRecvStatus Receive_SERVER_QUIT(Packet *p) override; + NetworkRecvStatus Receive_SERVER_ERROR_QUIT(Packet *p) override; + NetworkRecvStatus Receive_SERVER_SHUTDOWN(Packet *p) override; + NetworkRecvStatus Receive_SERVER_NEWGAME(Packet *p) override; + NetworkRecvStatus Receive_SERVER_RCON(Packet *p) override; + NetworkRecvStatus Receive_SERVER_CHECK_NEWGRFS(Packet *p) override; + NetworkRecvStatus Receive_SERVER_MOVE(Packet *p) override; + NetworkRecvStatus Receive_SERVER_COMPANY_UPDATE(Packet *p) override; + NetworkRecvStatus Receive_SERVER_CONFIG_UPDATE(Packet *p) override; static NetworkRecvStatus SendNewGRFsOk(); static NetworkRecvStatus SendGetMap(); @@ -80,7 +76,7 @@ public: ClientNetworkGameSocketHandler(SOCKET s); ~ClientNetworkGameSocketHandler(); - NetworkRecvStatus CloseConnection(NetworkRecvStatus status); + NetworkRecvStatus CloseConnection(NetworkRecvStatus status) override; void ClientError(NetworkRecvStatus res); static NetworkRecvStatus SendCompanyInformationQuery(); @@ -118,6 +114,4 @@ extern CompanyID _network_join_as; extern const char *_network_join_server_password; extern const char *_network_join_company_password; -#endif /* ENABLE_NETWORK */ - #endif /* NETWORK_CLIENT_H */ diff --git a/src/network/network_command.cpp b/src/network/network_command.cpp index bc08bc5f14..5d36a39b96 100644 --- a/src/network/network_command.cpp +++ b/src/network/network_command.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. @@ -9,8 +7,6 @@ /** @file network_command.cpp Command handling over network connections. */ -#ifdef ENABLE_NETWORK - #include "../stdafx.h" #include "network_admin.h" #include "network_client.h" @@ -23,7 +19,7 @@ /** Table with all the callbacks we'll use for conversion*/ static CommandCallback * const _callback_table[] = { - /* 0x00 */ NULL, + /* 0x00 */ nullptr, /* 0x01 */ CcBuildPrimaryVehicle, /* 0x02 */ CcBuildAirport, /* 0x03 */ CcBuildBridge, @@ -62,8 +58,8 @@ void CommandQueue::Append(CommandPacket *p) { CommandPacket *add = MallocT(1); *add = *p; - add->next = NULL; - if (this->first == NULL) { + add->next = nullptr; + if (this->first == nullptr) { this->first = add; } else { this->last->next = add; @@ -81,15 +77,15 @@ CommandPacket *CommandQueue::Pop(bool ignore_paused) { CommandPacket **prev = &this->first; CommandPacket *ret = this->first; - CommandPacket *prev_item = NULL; + CommandPacket *prev_item = nullptr; if (ignore_paused && _pause_mode != PM_UNPAUSED) { - while (ret != NULL && !IsCommandAllowedWhilePaused(ret->cmd)) { + while (ret != nullptr && !IsCommandAllowedWhilePaused(ret->cmd)) { prev_item = ret; prev = &ret->next; ret = ret->next; } } - if (ret != NULL) { + if (ret != nullptr) { if (ret == this->last) this->last = prev_item; *prev = ret->next; this->count--; @@ -106,17 +102,17 @@ CommandPacket *CommandQueue::Peek(bool ignore_paused) { if (!ignore_paused || _pause_mode == PM_UNPAUSED) return this->first; - for (CommandPacket *p = this->first; p != NULL; p = p->next) { + for (CommandPacket *p = this->first; p != nullptr; p = p->next) { if (IsCommandAllowedWhilePaused(p->cmd)) return p; } - return NULL; + return nullptr; } /** Free everything that is in the queue. */ void CommandQueue::Free() { CommandPacket *cp; - while ((cp = this->Pop()) != NULL) { + while ((cp = this->Pop()) != nullptr) { free(cp); } assert(this->count == 0); @@ -149,7 +145,7 @@ void NetworkSendCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, Comman c.cmd = cmd; c.callback = callback; - strecpy(c.text, (text != NULL) ? text : "", lastof(c.text)); + strecpy(c.text, (text != nullptr) ? text : "", lastof(c.text)); if (_network_server) { /* If we are the server, we queue the command in our 'special' queue. @@ -182,7 +178,7 @@ void NetworkSendCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd, Comman */ void NetworkSyncCommandQueue(NetworkClientSocket *cs) { - for (CommandPacket *p = _local_execution_queue.Peek(); p != NULL; p = p->next) { + for (CommandPacket *p = _local_execution_queue.Peek(); p != nullptr; p = p->next) { CommandPacket c = *p; c.callback = 0; cs->outgoing_queue.Append(&c); @@ -199,7 +195,7 @@ void NetworkExecuteLocalCommandQueue() CommandQueue &queue = (_network_server ? _local_execution_queue : ClientNetworkGameSocketHandler::my_client->incoming_queue); CommandPacket *cp; - while ((cp = queue.Peek()) != NULL) { + while ((cp = queue.Peek()) != nullptr) { /* The queue is always in order, which means * that the first element will be executed first. */ if (_frame_counter < cp->frame) break; @@ -242,19 +238,18 @@ static void DistributeCommandPacket(CommandPacket &cp, const NetworkClientSocket CommandCallback *callback = cp.callback; cp.frame = _frame_counter_max + 1; - NetworkClientSocket *cs; - FOR_ALL_CLIENT_SOCKETS(cs) { + for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) { if (cs->status >= NetworkClientSocket::STATUS_MAP) { /* Callbacks are only send back to the client who sent them in the * first place. This filters that out. */ - cp.callback = (cs != owner) ? NULL : callback; + cp.callback = (cs != owner) ? nullptr : callback; cp.my_cmd = (cs == owner); cs->outgoing_queue.Append(&cp); } } - cp.callback = (cs != owner) ? NULL : callback; - cp.my_cmd = (cs == owner); + cp.callback = (nullptr != owner) ? nullptr : callback; + cp.my_cmd = (nullptr == owner); _local_execution_queue.Append(&cp); } @@ -273,7 +268,7 @@ static void DistributeQueue(CommandQueue *queue, const NetworkClientSocket *owne #endif CommandPacket *cp; - while (--to_go >= 0 && (cp = queue->Pop(true)) != NULL) { + while (--to_go >= 0 && (cp = queue->Pop(true)) != nullptr) { DistributeCommandPacket(*cp, owner); NetworkAdminCmdLogging(owner, cp); free(cp); @@ -284,11 +279,10 @@ static void DistributeQueue(CommandQueue *queue, const NetworkClientSocket *owne void NetworkDistributeCommands() { /* First send the server's commands. */ - DistributeQueue(&_local_wait_queue, NULL); + DistributeQueue(&_local_wait_queue, nullptr); /* Then send the queues of the others. */ - NetworkClientSocket *cs; - FOR_ALL_CLIENT_SOCKETS(cs) { + for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) { DistributeQueue(&cs->incoming_queue, cs); } } @@ -297,7 +291,7 @@ void NetworkDistributeCommands() * Receives a command from the network. * @param p the packet to read from. * @param cp the struct to write the data to. - * @return an error message. When NULL there has been no error. + * @return an error message. When nullptr there has been no error. */ const char *NetworkGameSocketHandler::ReceiveCommand(Packet *p, CommandPacket *cp) { @@ -316,7 +310,7 @@ const char *NetworkGameSocketHandler::ReceiveCommand(Packet *p, CommandPacket *c if (callback >= lengthof(_callback_table)) return "invalid callback"; cp->callback = _callback_table[callback]; - return NULL; + return nullptr; } /** @@ -340,9 +334,7 @@ void NetworkGameSocketHandler::SendCommand(Packet *p, const CommandPacket *cp) if (callback == lengthof(_callback_table)) { DEBUG(net, 0, "Unknown callback. (Pointer: %p) No callback sent", cp->callback); - callback = 0; // _callback_table[0] == NULL + callback = 0; // _callback_table[0] == nullptr } p->Send_uint8 (callback); } - -#endif /* ENABLE_NETWORK */ diff --git a/src/network/network_content.cpp b/src/network/network_content.cpp index 551abb4420..5e401d3e92 100644 --- a/src/network/network_content.cpp +++ b/src/network/network_content.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. @@ -9,8 +7,6 @@ /** @file network_content.cpp Content sending/receiving part of the network protocol. */ -#if defined(ENABLE_NETWORK) - #include "../stdafx.h" #include "../rev.h" #include "../ai/ai.hpp" @@ -37,7 +33,7 @@ ClientNetworkContentSocketHandler _network_content_client; /** Wrapper function for the HasProc */ static bool HasGRFConfig(const ContentInfo *ci, bool md5sum) { - return FindGRFConfig(BSWAP32(ci->unique_id), md5sum ? FGCM_EXACT : FGCM_ANY, md5sum ? ci->md5sum : NULL) != NULL; + return FindGRFConfig(BSWAP32(ci->unique_id), md5sum ? FGCM_EXACT : FGCM_ANY, md5sum ? ci->md5sum : nullptr) != nullptr; } /** @@ -81,7 +77,7 @@ bool ClientNetworkContentSocketHandler::Receive_SERVER_INFO(Packet *p) } /* Find the appropriate check function */ - HasProc proc = NULL; + HasProc proc = nullptr; switch (ci->type) { case CONTENT_TYPE_NEWGRF: proc = HasGRFConfig; @@ -124,7 +120,7 @@ bool ClientNetworkContentSocketHandler::Receive_SERVER_INFO(Packet *p) break; } - if (proc != NULL) { + if (proc != nullptr) { if (proc(ci, true)) { ci->state = ContentInfo::ALREADY_HERE; } else { @@ -135,12 +131,11 @@ bool ClientNetworkContentSocketHandler::Receive_SERVER_INFO(Packet *p) ci->state = ContentInfo::UNSELECTED; } - /* Something we don't have and has filesize 0 does not exist in te system */ + /* Something we don't have and has filesize 0 does not exist in the system */ if (ci->state == ContentInfo::UNSELECTED && ci->filesize == 0) ci->state = ContentInfo::DOES_NOT_EXIST; /* Do we already have a stub for this? */ - for (ContentIterator iter = this->infos.Begin(); iter != this->infos.End(); iter++) { - ContentInfo *ici = *iter; + for (ContentInfo *ici : this->infos) { if (ici->type == ci->type && ici->unique_id == ci->unique_id && memcmp(ci->md5sum, ici->md5sum, sizeof(ci->md5sum)) == 0) { /* Preserve the name if possible */ @@ -167,11 +162,11 @@ bool ClientNetworkContentSocketHandler::Receive_SERVER_INFO(Packet *p) return true; } - *this->infos.Append() = ci; + this->infos.push_back(ci); /* Incoming data means that we might need to reconsider dependencies */ - for (ContentIterator iter = this->infos.Begin(); iter != this->infos.End(); iter++) { - this->CheckDependencyState(*iter); + for (ContentInfo *ici : this->infos) { + this->CheckDependencyState(ici); } this->OnReceiveContentInfo(ci); @@ -244,19 +239,18 @@ void ClientNetworkContentSocketHandler::RequestContentList(uint count, const Con */ void ClientNetworkContentSocketHandler::RequestContentList(ContentVector *cv, bool send_md5sum) { - if (cv == NULL) return; + if (cv == nullptr) return; this->Connect(); - assert(cv->Length() < 255); - assert(cv->Length() < (SEND_MTU - sizeof(PacketSize) - sizeof(byte) - sizeof(uint8)) / + assert(cv->size() < 255); + assert(cv->size() < (SEND_MTU - sizeof(PacketSize) - sizeof(byte) - sizeof(uint8)) / (sizeof(uint8) + sizeof(uint32) + (send_md5sum ? /*sizeof(ContentInfo::md5sum)*/16 : 0))); Packet *p = new Packet(send_md5sum ? PACKET_CONTENT_CLIENT_INFO_EXTID_MD5 : PACKET_CONTENT_CLIENT_INFO_EXTID); - p->Send_uint8(cv->Length()); + p->Send_uint8((uint8)cv->size()); - for (ContentIterator iter = cv->Begin(); iter != cv->End(); iter++) { - const ContentInfo *ci = *iter; + for (const ContentInfo *ci : *cv) { p->Send_uint8((byte)ci->type); p->Send_uint32(ci->unique_id); if (!send_md5sum) continue; @@ -268,11 +262,9 @@ void ClientNetworkContentSocketHandler::RequestContentList(ContentVector *cv, bo this->SendPacket(p); - for (ContentIterator iter = cv->Begin(); iter != cv->End(); iter++) { - ContentInfo *ci = *iter; + for (ContentInfo *ci : *cv) { bool found = false; - for (ContentIterator iter2 = this->infos.Begin(); iter2 != this->infos.End(); iter2++) { - ContentInfo *ci2 = *iter2; + for (ContentInfo *ci2 : this->infos) { if (ci->type == ci2->type && ci->unique_id == ci2->unique_id && (!send_md5sum || memcmp(ci->md5sum, ci2->md5sum, sizeof(ci->md5sum)) == 0)) { found = true; @@ -280,7 +272,7 @@ void ClientNetworkContentSocketHandler::RequestContentList(ContentVector *cv, bo } } if (!found) { - *this->infos.Append() = ci; + this->infos.push_back(ci); } else { delete ci; } @@ -298,15 +290,14 @@ void ClientNetworkContentSocketHandler::DownloadSelectedContent(uint &files, uin bytes = 0; ContentIDList content; - for (ContentIterator iter = this->infos.Begin(); iter != this->infos.End(); iter++) { - const ContentInfo *ci = *iter; + for (const ContentInfo *ci : this->infos) { if (!ci->IsSelected() || ci->state == ContentInfo::ALREADY_HERE) continue; - *content.Append() = ci->id; + content.push_back(ci->id); bytes += ci->filesize; } - files = content.Length(); + files = (uint)content.size(); /* If there's nothing to download, do nothing. */ if (files == 0) return; @@ -324,7 +315,7 @@ void ClientNetworkContentSocketHandler::DownloadSelectedContent(uint &files, uin */ void ClientNetworkContentSocketHandler::DownloadSelectedContentHTTP(const ContentIDList &content) { - uint count = content.Length(); + uint count = (uint)content.size(); /* Allocate memory for the whole request. * Requests are "id\nid\n..." (as strings), so assume the maximum ID, @@ -335,8 +326,8 @@ void ClientNetworkContentSocketHandler::DownloadSelectedContentHTTP(const Conten const char *lastof = content_request + bytes - 1; char *p = content_request; - for (const ContentID *id = content.Begin(); id != content.End(); id++) { - p += seprintf(p, lastof, "%d\n", *id); + for (const ContentID &id : content) { + p += seprintf(p, lastof, "%d\n", id); } this->http_response_index = -1; @@ -352,8 +343,8 @@ void ClientNetworkContentSocketHandler::DownloadSelectedContentHTTP(const Conten */ void ClientNetworkContentSocketHandler::DownloadSelectedContentFallback(const ContentIDList &content) { - uint count = content.Length(); - const ContentID *content_ids = content.Begin(); + uint count = (uint)content.size(); + const ContentID *content_ids = content.data(); this->Connect(); while (count > 0) { @@ -381,12 +372,12 @@ void ClientNetworkContentSocketHandler::DownloadSelectedContentFallback(const Co * @param ci the information to get the filename from * @param compressed should the filename end with .gz? * @return a statically allocated buffer with the filename or - * NULL when no filename could be made. + * nullptr when no filename could be made. */ static char *GetFullFilename(const ContentInfo *ci, bool compressed) { Subdirectory dir = GetContentInfoSubDir(ci->type); - if (dir == NO_DIRECTORY) return NULL; + if (dir == NO_DIRECTORY) return nullptr; static char buf[MAX_PATH]; FioGetFullPath(buf, lastof(buf), SP_AUTODOWNLOAD_DIR, dir, ci->filename); @@ -407,14 +398,14 @@ static bool GunzipFile(const ContentInfo *ci) /* Need to open the file with fopen() to support non-ASCII on Windows. */ FILE *ftmp = fopen(GetFullFilename(ci, true), "rb"); - if (ftmp == NULL) return false; + if (ftmp == nullptr) return false; /* Duplicate the handle, and close the FILE*, to avoid double-closing the handle later. */ gzFile fin = gzdopen(dup(fileno(ftmp)), "rb"); fclose(ftmp); FILE *fout = fopen(GetFullFilename(ci, false), "wb"); - if (fin == NULL || fout == NULL) { + if (fin == nullptr || fout == nullptr) { ret = false; } else { byte buff[8192]; @@ -448,8 +439,8 @@ static bool GunzipFile(const ContentInfo *ci) } } - if (fin != NULL) gzclose(fin); - if (fout != NULL) fclose(fout); + if (fin != nullptr) gzclose(fin); + if (fout != nullptr) fclose(fout); return ret; #else @@ -459,7 +450,7 @@ static bool GunzipFile(const ContentInfo *ci) bool ClientNetworkContentSocketHandler::Receive_SERVER_CONTENT(Packet *p) { - if (this->curFile == NULL) { + if (this->curFile == nullptr) { delete this->curInfo; /* When we haven't opened a file this must be our first packet with metadata. */ this->curInfo = new ContentInfo; @@ -480,7 +471,7 @@ bool ClientNetworkContentSocketHandler::Receive_SERVER_CONTENT(Packet *p) ShowErrorMessage(STR_CONTENT_ERROR_COULD_NOT_DOWNLOAD, STR_CONTENT_ERROR_COULD_NOT_DOWNLOAD_FILE_NOT_WRITABLE, WL_ERROR); this->Close(); fclose(this->curFile); - this->curFile = NULL; + this->curFile = nullptr; return false; } @@ -501,14 +492,14 @@ bool ClientNetworkContentSocketHandler::BeforeDownload() { if (!this->curInfo->IsValid()) { delete this->curInfo; - this->curInfo = NULL; + this->curInfo = nullptr; return false; } if (this->curInfo->filesize != 0) { /* The filesize is > 0, so we are going to download it */ const char *filename = GetFullFilename(this->curInfo, true); - if (filename == NULL || (this->curFile = fopen(filename, "wb")) == NULL) { + if (filename == nullptr || (this->curFile = fopen(filename, "wb")) == nullptr) { /* Unless that fails of course... */ DeleteWindowById(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_CONTENT_DOWNLOAD); ShowErrorMessage(STR_CONTENT_ERROR_COULD_NOT_DOWNLOAD, STR_CONTENT_ERROR_COULD_NOT_DOWNLOAD_FILE_NOT_WRITABLE, WL_ERROR); @@ -527,7 +518,7 @@ void ClientNetworkContentSocketHandler::AfterDownload() /* We read nothing; that's our marker for end-of-stream. * Now gunzip the tar and make it known. */ fclose(this->curFile); - this->curFile = NULL; + this->curFile = nullptr; if (GunzipFile(this->curInfo)) { unlink(GetFullFilename(this->curInfo, true)); @@ -557,41 +548,42 @@ void ClientNetworkContentSocketHandler::OnFailure() uint files, bytes; this->DownloadSelectedContent(files, bytes, true); - this->http_response.Reset(); + this->http_response.clear(); + this->http_response.shrink_to_fit(); this->http_response_index = -2; - if (this->curFile != NULL) { + 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); fclose(this->curFile); - this->curFile = NULL; + this->curFile = nullptr; } } void ClientNetworkContentSocketHandler::OnReceiveData(const char *data, size_t length) { - assert(data == NULL || length != 0); + assert(data == nullptr || length != 0); /* Ignore any latent data coming from a connection we closed. */ if (this->http_response_index == -2) return; if (this->http_response_index == -1) { - if (data != NULL) { + if (data != nullptr) { /* Append the rest of the response. */ - memcpy(this->http_response.Append((uint)length), data, length); + this->http_response.insert(this->http_response.end(), data, data + length); return; } else { /* Make sure the response is properly terminated. */ - *this->http_response.Append() = '\0'; + this->http_response.push_back('\0'); /* And prepare for receiving the rest of the data. */ this->http_response_index = 0; } } - if (data != NULL) { + if (data != nullptr) { /* We have data, so write it to the file. */ if (fwrite(data, 1, length, this->curFile) != length) { /* Writing failed somehow, let try via the old method. */ @@ -604,12 +596,12 @@ void ClientNetworkContentSocketHandler::OnReceiveData(const char *data, size_t l return; } - if (this->curFile != NULL) { + if (this->curFile != nullptr) { /* We've finished downloading a file. */ this->AfterDownload(); } - if ((uint)this->http_response_index >= this->http_response.Length()) { + if ((uint)this->http_response_index >= this->http_response.size()) { /* It's not a real failure, but if there's * nothing more to download it helps with * cleaning up the stuff we allocated. */ @@ -622,12 +614,12 @@ void ClientNetworkContentSocketHandler::OnReceiveData(const char *data, size_t l this->curInfo = new ContentInfo; /** Check p for not being null and return calling OnFailure if that's not the case. */ -#define check_not_null(p) { if ((p) == NULL) { this->OnFailure(); return; } } +#define check_not_null(p) { if ((p) == nullptr) { this->OnFailure(); return; } } /** Check p for not being null and then terminate, or return calling OnFailure. */ #define check_and_terminate(p) { check_not_null(p); *(p) = '\0'; } for (;;) { - char *str = this->http_response.Begin() + this->http_response_index; + char *str = this->http_response.data() + this->http_response_index; char *p = strchr(str, '\n'); check_and_terminate(p); @@ -655,7 +647,7 @@ void ClientNetworkContentSocketHandler::OnReceiveData(const char *data, size_t l str = p + 1; /* Is it a fallback URL? If so, just continue with the next one. */ if (strncmp(str, "ottd", 4) == 0) { - if ((uint)this->http_response_index >= this->http_response.Length()) { + if ((uint)this->http_response_index >= this->http_response.size()) { /* Have we gone through all lines? */ this->OnFailure(); return; @@ -701,8 +693,8 @@ void ClientNetworkContentSocketHandler::OnReceiveData(const char *data, size_t l ClientNetworkContentSocketHandler::ClientNetworkContentSocketHandler() : NetworkContentSocketHandler(), http_response_index(-2), - curFile(NULL), - curInfo(NULL), + curFile(nullptr), + curInfo(nullptr), isConnecting(false), lastActivity(_realtime_tick) { @@ -712,9 +704,9 @@ ClientNetworkContentSocketHandler::ClientNetworkContentSocketHandler() : ClientNetworkContentSocketHandler::~ClientNetworkContentSocketHandler() { delete this->curInfo; - if (this->curFile != NULL) fclose(this->curFile); + if (this->curFile != nullptr) fclose(this->curFile); - for (ContentIterator iter = this->infos.Begin(); iter != this->infos.End(); iter++) delete *iter; + for (ContentInfo *ci : this->infos) delete ci; } /** Connect to the content server. */ @@ -726,13 +718,13 @@ public: */ NetworkContentConnecter(const NetworkAddress &address) : TCPConnecter(address) {} - virtual void OnFailure() + void OnFailure() override { _network_content_client.isConnecting = false; _network_content_client.OnConnect(false); } - virtual void OnConnect(SOCKET s) + void OnConnect(SOCKET s) override { assert(_network_content_client.sock == INVALID_SOCKET); _network_content_client.isConnecting = false; @@ -780,7 +772,7 @@ void ClientNetworkContentSocketHandler::SendReceive() if (this->CanSendReceive()) { if (this->ReceivePackets()) { - /* Only update activity once a packet is received, instead of everytime we try it. */ + /* Only update activity once a packet is received, instead of every time we try it. */ this->lastActivity = _realtime_tick; } } @@ -795,25 +787,23 @@ void ClientNetworkContentSocketHandler::SendReceive() void ClientNetworkContentSocketHandler::DownloadContentInfo(ContentID cid) { /* When we tried to download it already, don't try again */ - if (this->requested.Contains(cid)) return; + if (std::find(this->requested.begin(), this->requested.end(), cid) != this->requested.end()) return; - *this->requested.Append() = cid; - assert(this->requested.Contains(cid)); + this->requested.push_back(cid); this->RequestContentList(1, &cid); } /** * Get the content info based on a ContentID * @param cid the ContentID to search for - * @return the ContentInfo or NULL if not found + * @return the ContentInfo or nullptr if not found */ ContentInfo *ClientNetworkContentSocketHandler::GetContent(ContentID cid) { - for (ContentIterator iter = this->infos.Begin(); iter != this->infos.End(); iter++) { - ContentInfo *ci = *iter; + for (ContentInfo *ci : this->infos) { if (ci->id == cid) return ci; } - return NULL; + return nullptr; } @@ -824,7 +814,7 @@ ContentInfo *ClientNetworkContentSocketHandler::GetContent(ContentID cid) void ClientNetworkContentSocketHandler::Select(ContentID cid) { ContentInfo *ci = this->GetContent(cid); - if (ci == NULL || ci->state != ContentInfo::UNSELECTED) return; + if (ci == nullptr || ci->state != ContentInfo::UNSELECTED) return; ci->state = ContentInfo::SELECTED; this->CheckDependencyState(ci); @@ -837,7 +827,7 @@ void ClientNetworkContentSocketHandler::Select(ContentID cid) void ClientNetworkContentSocketHandler::Unselect(ContentID cid) { ContentInfo *ci = this->GetContent(cid); - if (ci == NULL || !ci->IsSelected()) return; + if (ci == nullptr || !ci->IsSelected()) return; ci->state = ContentInfo::UNSELECTED; this->CheckDependencyState(ci); @@ -846,8 +836,7 @@ void ClientNetworkContentSocketHandler::Unselect(ContentID cid) /** Select everything we can select */ void ClientNetworkContentSocketHandler::SelectAll() { - for (ContentIterator iter = this->infos.Begin(); iter != this->infos.End(); iter++) { - ContentInfo *ci = *iter; + for (ContentInfo *ci : this->infos) { if (ci->state == ContentInfo::UNSELECTED) { ci->state = ContentInfo::SELECTED; this->CheckDependencyState(ci); @@ -858,8 +847,7 @@ void ClientNetworkContentSocketHandler::SelectAll() /** Select everything that's an update for something we've got */ void ClientNetworkContentSocketHandler::SelectUpgrade() { - for (ContentIterator iter = this->infos.Begin(); iter != this->infos.End(); iter++) { - ContentInfo *ci = *iter; + for (ContentInfo *ci : this->infos) { if (ci->state == ContentInfo::UNSELECTED && ci->upgrade) { ci->state = ContentInfo::SELECTED; this->CheckDependencyState(ci); @@ -870,8 +858,7 @@ void ClientNetworkContentSocketHandler::SelectUpgrade() /** Unselect everything that we've not downloaded so far. */ void ClientNetworkContentSocketHandler::UnselectAll() { - for (ContentIterator iter = this->infos.Begin(); iter != this->infos.End(); iter++) { - ContentInfo *ci = *iter; + for (ContentInfo *ci : this->infos) { if (ci->IsSelected() && ci->state != ContentInfo::ALREADY_HERE) ci->state = ContentInfo::UNSELECTED; } } @@ -901,13 +888,12 @@ void ClientNetworkContentSocketHandler::ToggleSelectedState(const ContentInfo *c */ void ClientNetworkContentSocketHandler::ReverseLookupDependency(ConstContentVector &parents, const ContentInfo *child) const { - for (ConstContentIterator iter = this->infos.Begin(); iter != this->infos.End(); iter++) { - const ContentInfo *ci = *iter; + for (const ContentInfo * const &ci : this->infos) { if (ci == child) continue; for (uint i = 0; i < ci->dependency_count; i++) { if (ci->dependencies[i] == child->id) { - *parents.Append() = ci; + parents.push_back(ci); break; } } @@ -921,18 +907,18 @@ void ClientNetworkContentSocketHandler::ReverseLookupDependency(ConstContentVect */ void ClientNetworkContentSocketHandler::ReverseLookupTreeDependency(ConstContentVector &tree, const ContentInfo *child) const { - *tree.Append() = child; + tree.push_back(child); /* First find all direct parents. We can't use the "normal" iterator as * we are including stuff into the vector and as such the vector's data * store can be reallocated (and thus move), which means out iterating * pointer gets invalid. So fall back to the indices. */ - for (uint i = 0; i < tree.Length(); i++) { + for (uint i = 0; i < tree.size(); i++) { ConstContentVector parents; this->ReverseLookupDependency(parents, tree[i]); - for (ConstContentIterator piter = parents.Begin(); piter != parents.End(); piter++) { - tree.Include(*piter); + for (const ContentInfo *ci : parents) { + include(tree, ci); } } } @@ -949,7 +935,7 @@ void ClientNetworkContentSocketHandler::CheckDependencyState(ContentInfo *ci) * selected and thus can unselect when a dependency is removed. */ for (uint i = 0; i < ci->dependency_count; i++) { ContentInfo *c = this->GetContent(ci->dependencies[i]); - if (c == NULL) { + if (c == nullptr) { this->DownloadContentInfo(ci->dependencies[i]); } else if (c->state == ContentInfo::UNSELECTED) { c->state = ContentInfo::AUTOSELECTED; @@ -967,8 +953,7 @@ void ClientNetworkContentSocketHandler::CheckDependencyState(ContentInfo *ci) * we automatically selected them. */ ConstContentVector parents; this->ReverseLookupDependency(parents, ci); - for (ConstContentIterator iter = parents.Begin(); iter != parents.End(); iter++) { - const ContentInfo *c = *iter; + for (const ContentInfo *c : parents) { if (!c->IsSelected()) continue; this->Unselect(c->id); @@ -976,22 +961,22 @@ void ClientNetworkContentSocketHandler::CheckDependencyState(ContentInfo *ci) for (uint i = 0; i < ci->dependency_count; i++) { const ContentInfo *c = this->GetContent(ci->dependencies[i]); - if (c == NULL) { + if (c == nullptr) { DownloadContentInfo(ci->dependencies[i]); continue; } if (c->state != ContentInfo::AUTOSELECTED) continue; /* Only unselect when WE are the only parent. */ - parents.Clear(); + parents.clear(); this->ReverseLookupDependency(parents, c); /* First check whether anything depends on us */ int sel_count = 0; bool force_selection = false; - for (ConstContentIterator iter = parents.Begin(); iter != parents.End(); iter++) { - if ((*iter)->IsSelected()) sel_count++; - if ((*iter)->state == ContentInfo::SELECTED) force_selection = true; + for (const ContentInfo *ci : parents) { + if (ci->IsSelected()) sel_count++; + if (ci->state == ContentInfo::SELECTED) force_selection = true; } if (sel_count == 0) { /* Nothing depends on us */ @@ -1002,12 +987,12 @@ void ClientNetworkContentSocketHandler::CheckDependencyState(ContentInfo *ci) if (force_selection) continue; /* "Flood" search to find all items in the dependency graph*/ - parents.Clear(); + parents.clear(); this->ReverseLookupTreeDependency(parents, c); /* Is there anything that is "force" selected?, if so... we're done. */ - for (ConstContentIterator iter = parents.Begin(); iter != parents.End(); iter++) { - if ((*iter)->state != ContentInfo::SELECTED) continue; + for (const ContentInfo *ci : parents) { + if (ci->state != ContentInfo::SELECTED) continue; force_selection = true; break; @@ -1020,12 +1005,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 (ConstContentIterator iter = parents.Begin(); iter != parents.End(); iter++) { - const ContentInfo *c = *iter; + for (const ContentInfo *c : parents) { if (c->state == ContentInfo::AUTOSELECTED) this->Unselect(c->id); } - for (ConstContentIterator iter = parents.Begin(); iter != parents.End(); iter++) { - this->CheckDependencyState(this->GetContent((*iter)->id)); + for (const ContentInfo *c : parents) { + this->CheckDependencyState(this->GetContent(c->id)); } } } @@ -1033,62 +1017,63 @@ void ClientNetworkContentSocketHandler::CheckDependencyState(ContentInfo *ci) /** Clear all downloaded content information. */ void ClientNetworkContentSocketHandler::Clear() { - for (ContentIterator iter = this->infos.Begin(); iter != this->infos.End(); iter++) delete *iter; + for (ContentInfo *c : this->infos) delete c; - this->infos.Clear(); - this->requested.Clear(); + this->infos.clear(); + this->requested.clear(); } /*** CALLBACK ***/ void ClientNetworkContentSocketHandler::OnConnect(bool success) { - for (ContentCallback **iter = this->callbacks.Begin(); iter != this->callbacks.End(); /* nothing */) { - ContentCallback *cb = *iter; + for (size_t i = 0; i < this->callbacks.size(); /* nothing */) { + ContentCallback *cb = this->callbacks[i]; + /* the callback may remove itself from this->callbacks */ cb->OnConnect(success); - if (iter != this->callbacks.End() && *iter == cb) iter++; + if (i != this->callbacks.size() && this->callbacks[i] == cb) i++; } } void ClientNetworkContentSocketHandler::OnDisconnect() { - for (ContentCallback **iter = this->callbacks.Begin(); iter != this->callbacks.End(); /* nothing */) { - ContentCallback *cb = *iter; + for (size_t i = 0; i < this->callbacks.size(); /* nothing */) { + ContentCallback *cb = this->callbacks[i]; cb->OnDisconnect(); - if (iter != this->callbacks.End() && *iter == cb) iter++; + if (i != this->callbacks.size() && this->callbacks[i] == cb) i++; } } void ClientNetworkContentSocketHandler::OnReceiveContentInfo(const ContentInfo *ci) { - for (ContentCallback **iter = this->callbacks.Begin(); iter != this->callbacks.End(); /* nothing */) { - ContentCallback *cb = *iter; + for (size_t i = 0; i < this->callbacks.size(); /* nothing */) { + ContentCallback *cb = this->callbacks[i]; + /* the callback may add items and/or remove itself from this->callbacks */ cb->OnReceiveContentInfo(ci); - if (iter != this->callbacks.End() && *iter == cb) iter++; + if (i != this->callbacks.size() && this->callbacks[i] == cb) i++; } } void ClientNetworkContentSocketHandler::OnDownloadProgress(const ContentInfo *ci, int bytes) { - for (ContentCallback **iter = this->callbacks.Begin(); iter != this->callbacks.End(); /* nothing */) { - ContentCallback *cb = *iter; + for (size_t i = 0; i < this->callbacks.size(); /* nothing */) { + ContentCallback *cb = this->callbacks[i]; cb->OnDownloadProgress(ci, bytes); - if (iter != this->callbacks.End() && *iter == cb) iter++; + if (i != this->callbacks.size() && this->callbacks[i] == cb) i++; } } void ClientNetworkContentSocketHandler::OnDownloadComplete(ContentID cid) { ContentInfo *ci = this->GetContent(cid); - if (ci != NULL) { + if (ci != nullptr) { ci->state = ContentInfo::ALREADY_HERE; } - for (ContentCallback **iter = this->callbacks.Begin(); iter != this->callbacks.End(); /* nothing */) { - ContentCallback *cb = *iter; + for (size_t i = 0; i < this->callbacks.size(); /* nothing */) { + ContentCallback *cb = this->callbacks[i]; + /* the callback may remove itself from this->callbacks */ cb->OnDownloadComplete(cid); - if (iter != this->callbacks.End() && *iter == cb) iter++; + if (i != this->callbacks.size() && this->callbacks[i] == cb) i++; } } - -#endif /* ENABLE_NETWORK */ diff --git a/src/network/network_content.h b/src/network/network_content.h index 25788065fd..fc33e72a14 100644 --- a/src/network/network_content.h +++ b/src/network/network_content.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. @@ -15,12 +13,10 @@ #include "core/tcp_content.h" #include "core/tcp_http.h" -#if defined(ENABLE_NETWORK) - /** Vector with content info */ -typedef SmallVector ContentVector; +typedef std::vector ContentVector; /** Vector with constant content info */ -typedef SmallVector ConstContentVector; +typedef std::vector ConstContentVector; /** Iterator for the content vector */ typedef ContentInfo **ContentIterator; @@ -68,12 +64,12 @@ struct ContentCallback { */ class ClientNetworkContentSocketHandler : public NetworkContentSocketHandler, ContentCallback, HTTPCallback { protected: - typedef SmallVector ContentIDList; ///< List of content IDs to (possibly) select. - SmallVector callbacks; ///< Callbacks to notify "the world" - ContentIDList requested; ///< ContentIDs we already requested (so we don't do it again) - ContentVector infos; ///< All content info we received - SmallVector http_response; ///< The HTTP response to the requests we've been doing - int http_response_index; ///< Where we are, in the response, with handling it + typedef std::vector ContentIDList; ///< List of content IDs to (possibly) select. + std::vector callbacks; ///< Callbacks to notify "the world" + ContentIDList requested; ///< ContentIDs we already requested (so we don't do it again) + ContentVector infos; ///< All content info we received + std::vector http_response; ///< The HTTP response to the requests we've been doing + int http_response_index; ///< Where we are, in the response, with handling it FILE *curFile; ///< Currently downloaded file ContentInfo *curInfo; ///< Information about the currently downloaded file @@ -82,20 +78,20 @@ protected: friend class NetworkContentConnecter; - virtual bool Receive_SERVER_INFO(Packet *p); - virtual bool Receive_SERVER_CONTENT(Packet *p); + bool Receive_SERVER_INFO(Packet *p) override; + bool Receive_SERVER_CONTENT(Packet *p) override; ContentInfo *GetContent(ContentID cid); void DownloadContentInfo(ContentID cid); - void OnConnect(bool success); - void OnDisconnect(); - void OnReceiveContentInfo(const ContentInfo *ci); - void OnDownloadProgress(const ContentInfo *ci, int bytes); - void OnDownloadComplete(ContentID cid); + void OnConnect(bool success) override; + void OnDisconnect() override; + void OnReceiveContentInfo(const ContentInfo *ci) override; + void OnDownloadProgress(const ContentInfo *ci, int bytes) override; + void OnDownloadComplete(ContentID cid) override; - void OnFailure(); - void OnReceiveData(const char *data, size_t length); + void OnFailure() override; + void OnReceiveData(const char *data, size_t length) override; bool BeforeDownload(); void AfterDownload(); @@ -111,7 +107,7 @@ public: void Connect(); void SendReceive(); - void Close(); + void Close() override; void RequestContentList(ContentType type); void RequestContentList(uint count, const ContentID *content_ids); @@ -131,30 +127,26 @@ public: void CheckDependencyState(ContentInfo *ci); /** Get the number of content items we know locally. */ - uint Length() const { return this->infos.Length(); } + uint Length() const { return (uint)this->infos.size(); } /** Get the begin of the content inf iterator. */ - ConstContentIterator Begin() const { return this->infos.Begin(); } + ConstContentIterator Begin() const { return this->infos.data(); } /** Get the nth position of the content inf iterator. */ - ConstContentIterator Get(uint32 index) const { return this->infos.Get(index); } + ConstContentIterator Get(uint32 index) const { return this->infos.data() + index; } /** Get the end of the content inf iterator. */ - ConstContentIterator End() const { return this->infos.End(); } + ConstContentIterator End() const { return this->Begin() + this->Length(); } void Clear(); /** Add a callback to this class */ - void AddCallback(ContentCallback *cb) { this->callbacks.Include(cb); } + void AddCallback(ContentCallback *cb) { include(this->callbacks, cb); } /** Remove a callback */ - void RemoveCallback(ContentCallback *cb) { this->callbacks.Erase(this->callbacks.Find(cb)); } + void RemoveCallback(ContentCallback *cb) { this->callbacks.erase(std::find(this->callbacks.begin(), this->callbacks.end(), cb)); } }; extern ClientNetworkContentSocketHandler _network_content_client; -void ShowNetworkContentListWindow(ContentVector *cv = NULL, ContentType type1 = CONTENT_TYPE_END, ContentType type2 = CONTENT_TYPE_END); +void ShowNetworkContentListWindow(ContentVector *cv = nullptr, ContentType type1 = CONTENT_TYPE_END, ContentType type2 = CONTENT_TYPE_END); void ShowMissingContentWindow(const struct GRFConfig *list); -#else -static inline void ShowNetworkContentListWindow() {} -#endif /* ENABLE_NETWORK */ - #endif /* NETWORK_CONTENT_H */ diff --git a/src/network/network_content_gui.cpp b/src/network/network_content_gui.cpp index 306bf9e39f..3ebfe03d78 100644 --- a/src/network/network_content_gui.cpp +++ b/src/network/network_content_gui.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. @@ -9,7 +7,6 @@ /** @file network_content_gui.cpp Implementation of the Network Content related GUIs. */ -#if defined(ENABLE_NETWORK) #include "../stdafx.h" #include "../strings_func.h" #include "../gfx_func.h" @@ -67,7 +64,7 @@ struct ContentTextfileWindow : public TextfileWindow { } } - /* virtual */ void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { if (widget == WID_TF_CAPTION) { SetDParam(0, this->GetTypeString()); @@ -98,7 +95,7 @@ static const NWidgetPart _nested_network_content_download_status_window_widgets[ /** Window description for the download window */ static WindowDesc _network_content_download_status_window_desc( - WDP_CENTER, NULL, 0, 0, + WDP_CENTER, nullptr, 0, 0, WC_NETWORK_STATUS_WINDOW, WC_NONE, WDF_MODAL, _nested_network_content_download_status_window_widgets, lengthof(_nested_network_content_download_status_window_widgets) @@ -118,7 +115,7 @@ BaseNetworkContentDownloadStatusWindow::~BaseNetworkContentDownloadStatusWindow( _network_content_client.RemoveCallback(this); } -/* virtual */ void BaseNetworkContentDownloadStatusWindow::DrawWidget(const Rect &r, int widget) const +void BaseNetworkContentDownloadStatusWindow::DrawWidget(const Rect &r, int widget) const { if (widget != WID_NCDS_BACKGROUND) return; @@ -147,7 +144,7 @@ BaseNetworkContentDownloadStatusWindow::~BaseNetworkContentDownloadStatusWindow( DrawStringMultiLine(r.left + 2, r.right - 2, y, y + FONT_HEIGHT_NORMAL * 2, str, TC_FROMSTRING, SA_CENTER); } -/* virtual */ void BaseNetworkContentDownloadStatusWindow::OnDownloadProgress(const ContentInfo *ci, int bytes) +void BaseNetworkContentDownloadStatusWindow::OnDownloadProgress(const ContentInfo *ci, int bytes) { if (ci->id != this->cur_id) { strecpy(this->name, ci->filename, lastof(this->name)); @@ -163,7 +160,7 @@ BaseNetworkContentDownloadStatusWindow::~BaseNetworkContentDownloadStatusWindow( /** Window for showing the download status of content */ struct NetworkContentDownloadStatusWindow : public BaseNetworkContentDownloadStatusWindow { private: - SmallVector receivedTypes; ///< Types we received so we can update their cache + std::vector receivedTypes; ///< Types we received so we can update their cache public: /** @@ -179,8 +176,8 @@ public: ~NetworkContentDownloadStatusWindow() { TarScanner::Mode mode = TarScanner::NONE; - for (ContentType *iter = this->receivedTypes.Begin(); iter != this->receivedTypes.End(); iter++) { - switch (*iter) { + for (auto ctype : this->receivedTypes) { + switch (ctype) { case CONTENT_TYPE_AI: case CONTENT_TYPE_AI_LIBRARY: /* AI::Rescan calls the scanner. */ @@ -213,8 +210,8 @@ public: TarScanner::DoScan(mode); /* Tell all the backends about what we've downloaded */ - for (ContentType *iter = this->receivedTypes.Begin(); iter != this->receivedTypes.End(); iter++) { - switch (*iter) { + for (auto ctype : this->receivedTypes) { + switch (ctype) { case CONTENT_TYPE_AI: case CONTENT_TYPE_AI_LIBRARY: AI::Rescan(); @@ -241,7 +238,7 @@ public: break; case CONTENT_TYPE_NEWGRF: - ScanNewGRFFiles(NULL); + ScanNewGRFFiles(nullptr); break; case CONTENT_TYPE_SCENARIO: @@ -260,7 +257,7 @@ public: InvalidateWindowData(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_CONTENT_LIST, 2); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { if (widget == WID_NCDS_CANCELOK) { if (this->downloaded_bytes != this->total_bytes) { @@ -274,10 +271,10 @@ public: } } - virtual void OnDownloadProgress(const ContentInfo *ci, int bytes) + void OnDownloadProgress(const ContentInfo *ci, int bytes) override { BaseNetworkContentDownloadStatusWindow::OnDownloadProgress(ci, bytes); - this->receivedTypes.Include(ci->type); + include(this->receivedTypes, ci->type); /* When downloading is finished change cancel in ok */ if (this->downloaded_bytes == this->total_bytes) { @@ -292,7 +289,7 @@ struct ContentListFilterData { std::bitset types; ///< Content types displayed }; -/** Filter criterias for NetworkContentListWindow. */ +/** Filter criteria for NetworkContentListWindow. */ enum ContentListFilterCriteria { CONTENT_FILTER_TEXT = 0, ///< Filter by query sting CONTENT_FILTER_TYPE_OR_SELECTED,///< Filter by being of displayed type or selected for download @@ -336,8 +333,7 @@ class NetworkContentListWindow : public Window, ContentCallback { pos = strecpy(pos, "do=searchgrfid&q=", last); bool first = true; - for (ConstContentIterator iter = this->content.Begin(); iter != this->content.End(); iter++) { - const ContentInfo *ci = *iter; + for (const ContentInfo *ci : this->content) { if (ci->state != ContentInfo::DOES_NOT_EXIST) continue; if (!first) pos = strecpy(pos, ",", last); @@ -388,49 +384,49 @@ class NetworkContentListWindow : public Window, ContentCallback { if (!this->content.NeedRebuild()) return; /* Create temporary array of games to use for listing */ - this->content.Clear(); + this->content.clear(); bool all_available = true; for (ConstContentIterator iter = _network_content_client.Begin(); iter != _network_content_client.End(); iter++) { if ((*iter)->state == ContentInfo::DOES_NOT_EXIST) all_available = false; - *this->content.Append() = *iter; + this->content.push_back(*iter); } this->SetWidgetDisabledState(WID_NCL_SEARCH_EXTERNAL, this->auto_select && all_available); this->FilterContentList(); - this->content.Compact(); + this->content.shrink_to_fit(); this->content.RebuildDone(); this->SortContentList(); - this->vscroll->SetCount(this->content.Length()); // Update the scrollbar + this->vscroll->SetCount((int)this->content.size()); // Update the scrollbar this->ScrollToSelected(); } /** Sort content by name. */ - static int CDECL NameSorter(const ContentInfo * const *a, const ContentInfo * const *b) + static bool NameSorter(const ContentInfo * const &a, const ContentInfo * const &b) { - return strnatcmp((*a)->name, (*b)->name, true); // Sort by name (natural sorting). + return strnatcmp(a->name, b->name, true) < 0; // Sort by name (natural sorting). } /** Sort content by type. */ - static int CDECL TypeSorter(const ContentInfo * const *a, const ContentInfo * const *b) + static bool TypeSorter(const ContentInfo * const &a, const ContentInfo * const &b) { int r = 0; - if ((*a)->type != (*b)->type) { - r = strnatcmp(content_type_strs[(*a)->type], content_type_strs[(*b)->type]); + if (a->type != b->type) { + r = strnatcmp(content_type_strs[a->type], content_type_strs[b->type]); } - if (r == 0) r = NameSorter(a, b); - return r; + if (r == 0) return NameSorter(a, b); + return r < 0; } /** Sort content by state. */ - static int CDECL StateSorter(const ContentInfo * const *a, const ContentInfo * const *b) + static bool StateSorter(const ContentInfo * const &a, const ContentInfo * const &b) { - int r = (*a)->state - (*b)->state; - if (r == 0) r = TypeSorter(a, b); - return r; + int r = a->state - b->state; + if (r == 0) return TypeSorter(a, b); + return r < 0; } /** Sort the content list */ @@ -438,12 +434,8 @@ class NetworkContentListWindow : public Window, ContentCallback { { if (!this->content.Sort()) return; - for (ConstContentIterator iter = this->content.Begin(); iter != this->content.End(); iter++) { - if (*iter == this->selected) { - this->list_pos = iter - this->content.Begin(); - break; - } - } + int idx = find_index(this->content, this->selected); + if (idx >= 0) this->list_pos = idx; } /** Filter content by tags/name */ @@ -481,15 +473,14 @@ class NetworkContentListWindow : public Window, ContentCallback { if (!changed) return; /* update list position */ - for (ConstContentIterator iter = this->content.Begin(); iter != this->content.End(); iter++) { - if (*iter == this->selected) { - this->list_pos = iter - this->content.Begin(); - return; - } + int idx = find_index(this->content, this->selected); + if (idx >= 0) { + this->list_pos = idx; + return; } /* previously selected item not in list anymore */ - this->selected = NULL; + this->selected = nullptr; this->list_pos = 0; } @@ -510,7 +501,7 @@ class NetworkContentListWindow : public Window, ContentCallback { /** Make sure that the currently selected content info is within the visible part of the matrix */ void ScrollToSelected() { - if (this->selected == NULL) return; + if (this->selected == nullptr) return; this->vscroll->ScrollTowards(this->list_pos); } @@ -530,7 +521,7 @@ public: Window(desc), auto_select(select_all), filter_editbox(EDITBOX_MAX_SIZE), - selected(NULL), + selected(nullptr), list_pos(0) { this->checkbox_size = maxdim(maxdim(GetSpriteSize(SPR_BOX_EMPTY), GetSpriteSize(SPR_BOX_CHECKED)), GetSpriteSize(SPR_BLOT)); @@ -565,7 +556,7 @@ public: _network_content_client.RemoveCallback(this); } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_NCL_FILTER_CAPT: @@ -593,7 +584,7 @@ public: } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { switch (widget) { case WID_NCL_FILTER_CAPT: @@ -610,7 +601,7 @@ public: } } - virtual void OnPaint() + void OnPaint() override { const SortButtonState arrow = this->content.IsDescSortOrder() ? SBS_DOWN : SBS_UP; @@ -643,8 +634,12 @@ public: int sprite_y_offset = WD_MATRIX_TOP + (line_height - this->checkbox_size.height) / 2 - 1 + (this->resize.step_height - line_height) / 2; int text_y_offset = WD_MATRIX_TOP + (line_height - FONT_HEIGHT_NORMAL) / 2 + (this->resize.step_height - line_height) / 2; uint y = r.top; - int cnt = 0; - for (ConstContentIterator iter = this->content.Get(this->vscroll->GetPosition()); iter != this->content.End() && cnt < this->vscroll->GetCapacity(); iter++, cnt++) { + + 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(); + + for (/**/; iter != end; iter++) { const ContentInfo *ci = *iter; if (ci == this->selected) GfxFillRect(r.left + 1, y + WD_FRAMERECT_TOP, r.right - 1, y + this->resize.step_height - WD_FRAMERECT_BOTTOM, PC_GREY); @@ -690,7 +685,7 @@ public: 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); - if (this->selected == NULL) return; + 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); @@ -769,8 +764,7 @@ public: char buf[DRAW_STRING_BUFFER] = ""; char *p = buf; - for (ConstContentIterator iter = tree.Begin(); iter != tree.End(); iter++) { - const ContentInfo *ci = *iter; + for (const ContentInfo *ci : tree) { if (ci == this->selected || ci->state != ContentInfo::SELECTED) continue; p += seprintf(p, lastof(buf), buf == p ? "%s" : ", %s", ci->name); @@ -782,10 +776,10 @@ public: } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { if (widget >= WID_NCL_TEXTFILE && widget < WID_NCL_TEXTFILE + TFT_END) { - if (this->selected == NULL || this->selected->state != ContentInfo::ALREADY_HERE) return; + if (this->selected == nullptr || this->selected->state != ContentInfo::ALREADY_HERE) return; ShowContentTextfileWindow((TextfileType)(widget - WID_NCL_TEXTFILE), this->selected); return; @@ -794,9 +788,9 @@ public: switch (widget) { case WID_NCL_MATRIX: { uint id_v = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_NCL_MATRIX); - if (id_v >= this->content.Length()) return; // click out of bounds + if (id_v >= this->content.size()) return; // click out of bounds - this->selected = *this->content.Get(id_v); + this->selected = this->content[id_v]; this->list_pos = id_v; const NWidgetBase *checkbox = this->GetWidget(WID_NCL_CHECKBOX); @@ -818,7 +812,7 @@ public: case WID_NCL_NAME: if (this->content.SortType() == widget - WID_NCL_CHECKBOX) { this->content.ToggleSortOrder(); - if (this->content.Length() > 0) this->list_pos = this->content.Length() - this->list_pos - 1; + if (this->content.size() > 0) this->list_pos = (int)this->content.size() - this->list_pos - 1; } else { this->content.SetSortType(widget - WID_NCL_CHECKBOX); this->content.ForceResort(); @@ -848,14 +842,14 @@ public: break; case WID_NCL_OPEN_URL: - if (this->selected != NULL) { + if (this->selected != nullptr) { extern void OpenBrowser(const char *url); OpenBrowser(this->selected->url); } break; case WID_NCL_DOWNLOAD: - if (BringWindowToFrontById(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_CONTENT_DOWNLOAD) == NULL) new NetworkContentDownloadStatusWindow(); + if (BringWindowToFrontById(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_CONTENT_DOWNLOAD) == nullptr) new NetworkContentDownloadStatusWindow(); break; case WID_NCL_SEARCH_EXTERNAL: @@ -868,7 +862,7 @@ public: } } - virtual EventState OnKeyPress(WChar key, uint16 keycode) + EventState OnKeyPress(WChar key, uint16 keycode) override { switch (keycode) { case WKC_UP: @@ -877,7 +871,7 @@ public: break; case WKC_DOWN: /* scroll down by one */ - if (this->list_pos < (int)this->content.Length() - 1) this->list_pos++; + if (this->list_pos < (int)this->content.size() - 1) this->list_pos++; break; case WKC_PAGEUP: /* scroll up a page */ @@ -885,7 +879,7 @@ public: break; case WKC_PAGEDOWN: /* scroll down a page */ - this->list_pos = min(this->list_pos + this->vscroll->GetCapacity(), (int)this->content.Length() - 1); + this->list_pos = min(this->list_pos + this->vscroll->GetCapacity(), (int)this->content.size() - 1); break; case WKC_HOME: /* jump to beginning */ @@ -893,13 +887,13 @@ public: break; case WKC_END: /* jump to end */ - this->list_pos = this->content.Length() - 1; + this->list_pos = (int)this->content.size() - 1; break; case WKC_SPACE: case WKC_RETURN: if (keycode == WKC_RETURN || !IsWidgetFocused(WID_NCL_FILTER)) { - if (this->selected != NULL) { + if (this->selected != nullptr) { _network_content_client.ToggleSelectedState(this->selected); this->content.ForceResort(); this->InvalidateData(); @@ -917,7 +911,7 @@ public: return ES_NOT_HANDLED; } - if (this->content.Length() == 0) { + if (this->content.size() == 0) { this->list_pos = 0; // above stuff may result in "-1". if (this->UpdateFilterState()) { this->content.ForceRebuild(); @@ -926,7 +920,7 @@ public: return ES_HANDLED; } - this->selected = *this->content.Get(this->list_pos); + this->selected = this->content[this->list_pos]; if (this->UpdateFilterState()) { this->content.ForceRebuild(); @@ -940,7 +934,7 @@ public: return ES_HANDLED; } - virtual void OnEditboxChanged(int wid) + void OnEditboxChanged(int wid) override { if (wid == WID_NCL_FILTER) { this->filter_data.string_filter.SetFilterTerm(this->filter_editbox.text.buf); @@ -950,25 +944,25 @@ public: } } - virtual void OnResize() + void OnResize() override { this->vscroll->SetCapacityFromWidget(this, WID_NCL_MATRIX); } - virtual void OnReceiveContentInfo(const ContentInfo *rci) + void OnReceiveContentInfo(const ContentInfo *rci) override { if (this->auto_select && !rci->IsSelected()) _network_content_client.ToggleSelectedState(rci); this->content.ForceRebuild(); this->InvalidateData(); } - virtual void OnDownloadComplete(ContentID cid) + void OnDownloadComplete(ContentID cid) override { this->content.ForceResort(); this->InvalidateData(); } - virtual void OnConnect(bool success) + void OnConnect(bool success) override { if (!success) { ShowErrorMessage(STR_CONTENT_ERROR_COULD_NOT_CONNECT, INVALID_STRING_ID, WL_ERROR); @@ -984,7 +978,7 @@ public: * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; if (this->content.NeedRebuild()) this->BuildContentList(); @@ -993,8 +987,7 @@ public: this->filesize_sum = 0; bool show_select_all = false; bool show_select_upgrade = false; - for (ConstContentIterator iter = this->content.Begin(); iter != this->content.End(); iter++) { - const ContentInfo *ci = *iter; + for (const ContentInfo *ci : this->content) { switch (ci->state) { case ContentInfo::SELECTED: case ContentInfo::AUTOSELECTED: @@ -1012,13 +1005,13 @@ public: } /* If data == 2 then the status window caused this OnInvalidate */ - this->SetWidgetDisabledState(WID_NCL_DOWNLOAD, this->filesize_sum == 0 || (FindWindowById(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_CONTENT_DOWNLOAD) != NULL && data != 2)); + this->SetWidgetDisabledState(WID_NCL_DOWNLOAD, this->filesize_sum == 0 || (FindWindowById(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_CONTENT_DOWNLOAD) != nullptr && data != 2)); this->SetWidgetDisabledState(WID_NCL_UNSELECT, this->filesize_sum == 0); this->SetWidgetDisabledState(WID_NCL_SELECT_ALL, !show_select_all); this->SetWidgetDisabledState(WID_NCL_SELECT_UPDATE, !show_select_upgrade); - this->SetWidgetDisabledState(WID_NCL_OPEN_URL, this->selected == NULL || StrEmpty(this->selected->url)); + this->SetWidgetDisabledState(WID_NCL_OPEN_URL, this->selected == nullptr || StrEmpty(this->selected->url)); for (TextfileType tft = TFT_BEGIN; tft < TFT_END; tft++) { - this->SetWidgetDisabledState(WID_NCL_TEXTFILE + tft, this->selected == NULL || this->selected->state != ContentInfo::ALREADY_HERE || this->selected->GetTextfile(tft) == NULL); + this->SetWidgetDisabledState(WID_NCL_TEXTFILE + tft, this->selected == nullptr || this->selected->state != ContentInfo::ALREADY_HERE || this->selected->GetTextfile(tft) == nullptr); } this->GetWidget(WID_NCL_CANCEL)->widget_data = this->filesize_sum == 0 ? STR_AI_SETTINGS_CLOSE : STR_AI_LIST_CANCEL; @@ -1138,7 +1131,7 @@ static WindowDesc _network_content_list_desc( /** * Show the content list window with a given set of content - * @param cv the content to show, or NULL when it has to search for itself + * @param cv the content to show, or nullptr when it has to search for itself * @param type1 the first type to (only) show or #CONTENT_TYPE_END to show all. * @param type2 the second type to (only) show in addition to type1. If type2 is != #CONTENT_TYPE_END, then also type1 should be != #CONTENT_TYPE_END. * If type2 != #CONTENT_TYPE_END, then type1 != type2 must be true. @@ -1148,7 +1141,7 @@ void ShowNetworkContentListWindow(ContentVector *cv, ContentType type1, ContentT #if defined(WITH_ZLIB) std::bitset types; _network_content_client.Clear(); - if (cv == NULL) { + if (cv == nullptr) { assert(type1 != CONTENT_TYPE_END || type2 == CONTENT_TYPE_END); assert(type1 == CONTENT_TYPE_END || type1 != type2); _network_content_client.RequestContentList(type1); @@ -1161,14 +1154,12 @@ void ShowNetworkContentListWindow(ContentVector *cv, ContentType type1, ContentT } DeleteWindowById(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_CONTENT_LIST); - new NetworkContentListWindow(&_network_content_list_desc, cv != NULL, types); + new NetworkContentListWindow(&_network_content_list_desc, cv != nullptr, types); #else ShowErrorMessage(STR_CONTENT_NO_ZLIB, STR_CONTENT_NO_ZLIB_SUB, WL_ERROR); /* Connection failed... clean up the mess */ - if (cv != NULL) { - for (ContentIterator iter = cv->Begin(); iter != cv->End(); iter++) delete *iter; + if (cv != nullptr) { + for (ContentInfo *ci : *cv) delete ci; } #endif /* WITH_ZLIB */ } - -#endif /* ENABLE_NETWORK */ diff --git a/src/network/network_content_gui.h b/src/network/network_content_gui.h index 1397010019..4853101bbf 100644 --- a/src/network/network_content_gui.h +++ b/src/network/network_content_gui.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. @@ -39,8 +37,8 @@ public: */ ~BaseNetworkContentDownloadStatusWindow(); - virtual void DrawWidget(const Rect &r, int widget) const; - virtual void OnDownloadProgress(const ContentInfo *ci, int bytes); + void DrawWidget(const Rect &r, int widget) const override; + void OnDownloadProgress(const ContentInfo *ci, int bytes) override; }; void BuildContentTypeStringList(); diff --git a/src/network/network_func.h b/src/network/network_func.h index 4f1525b5a4..cbb89820cf 100644 --- a/src/network/network_func.h +++ b/src/network/network_func.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. @@ -26,8 +24,6 @@ #include "../openttd.h" #include "../company_type.h" -#ifdef ENABLE_NETWORK - extern NetworkServerGameInfo _network_game_info; extern NetworkCompanyState *_network_company_states; @@ -53,7 +49,7 @@ void NetworkPopulateCompanyStats(NetworkCompanyStats *stats); void NetworkUpdateClientInfo(ClientID client_id); void NetworkClientsToSpectators(CompanyID cid); -void NetworkClientConnectGame(NetworkAddress address, CompanyID join_as, const char *join_server_password = NULL, const char *join_company_password = NULL); +void NetworkClientConnectGame(NetworkAddress address, CompanyID join_as, const char *join_server_password = nullptr, const char *join_company_password = nullptr); void NetworkClientRequestMove(CompanyID company, const char *pass = ""); void NetworkClientSendRcon(const char *password, const char *command); void NetworkClientSendChat(NetworkAction action, DestType type, int dest, const char *msg, int64 data = 0); @@ -79,9 +75,9 @@ void NetworkServerDoMove(ClientID client_id, CompanyID company_id); void NetworkServerSendRcon(ClientID client_id, TextColour colour_code, const char *string); void NetworkServerSendChat(NetworkAction action, DestType type, int dest, const char *msg, ClientID from_id, int64 data = 0, bool from_admin = false); -void NetworkServerKickClient(ClientID client_id); -uint NetworkServerKickOrBanIP(ClientID client_id, bool ban); -uint NetworkServerKickOrBanIP(const char *ip, bool ban); +void NetworkServerKickClient(ClientID client_id, const char *reason); +uint NetworkServerKickOrBanIP(ClientID client_id, bool ban, const char *reason); +uint NetworkServerKickOrBanIP(const char *ip, bool ban, const char *reason); void NetworkInitChatMessage(); void CDECL NetworkAddChatMessage(TextColour colour, uint duration, const char *message, ...) WARN_FORMAT(3, 4); @@ -90,5 +86,4 @@ void NetworkChatMessageLoop(); void NetworkAfterNewGRFScan(); -#endif /* ENABLE_NETWORK */ #endif /* NETWORK_FUNC_H */ diff --git a/src/network/network_gamelist.cpp b/src/network/network_gamelist.cpp index e5d80630e1..ff744e8757 100644 --- a/src/network/network_gamelist.cpp +++ b/src/network/network_gamelist.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. @@ -12,24 +10,20 @@ * Also, it handles the request to a server for data about the server */ -#ifdef ENABLE_NETWORK - #include "../stdafx.h" #include "../debug.h" #include "../window_func.h" -#include "../thread/thread.h" #include "network_internal.h" #include "network_udp.h" #include "network_gamelist.h" +#include #include "../safeguards.h" -NetworkGameList *_network_game_list = NULL; +NetworkGameList *_network_game_list = nullptr; -/** Mutex for handling delayed insertion/querying of servers. */ -static ThreadMutex *_network_game_list_mutex = ThreadMutex::New(); /** The games to insert when the GUI thread has time for us. */ -static NetworkGameList *_network_game_delayed_insertion_list = NULL; +static std::atomic _network_game_delayed_insertion_list(nullptr); /** * Add a new item to the linked gamelist, but do it delayed in the next tick @@ -38,23 +32,21 @@ static NetworkGameList *_network_game_delayed_insertion_list = NULL; */ void NetworkGameListAddItemDelayed(NetworkGameList *item) { - _network_game_list_mutex->BeginCritical(); - item->next = _network_game_delayed_insertion_list; - _network_game_delayed_insertion_list = item; - _network_game_list_mutex->EndCritical(); + item->next = _network_game_delayed_insertion_list.load(std::memory_order_relaxed); + while (!_network_game_delayed_insertion_list.compare_exchange_weak(item->next, item, std::memory_order_acq_rel)) {} } /** Perform the delayed (thread safe) insertion into the game list */ static void NetworkGameListHandleDelayedInsert() { - _network_game_list_mutex->BeginCritical(); - while (_network_game_delayed_insertion_list != NULL) { - NetworkGameList *ins_item = _network_game_delayed_insertion_list; - _network_game_delayed_insertion_list = ins_item->next; + while (true) { + NetworkGameList *ins_item = _network_game_delayed_insertion_list.load(std::memory_order_relaxed); + while (ins_item != nullptr && !_network_game_delayed_insertion_list.compare_exchange_weak(ins_item, ins_item->next, std::memory_order_acq_rel)) {} + if (ins_item == nullptr) break; // No item left. NetworkGameList *item = NetworkGameListAddItem(ins_item->address); - if (item != NULL) { + if (item != nullptr) { if (StrEmpty(item->info.server_name)) { ClearGRFConfigList(&item->info.grfconfig); memset(&item->info, 0, sizeof(item->info)); @@ -68,7 +60,6 @@ static void NetworkGameListHandleDelayedInsert() } free(ins_item); } - _network_game_list_mutex->EndCritical(); } /** @@ -85,22 +76,22 @@ NetworkGameList *NetworkGameListAddItem(NetworkAddress address) if (StrEmpty(hostname) || strcmp(hostname, "0.0.0.0") == 0 || strcmp(hostname, "::") == 0) { - return NULL; + return nullptr; } NetworkGameList *item, *prev_item; - prev_item = NULL; - for (item = _network_game_list; item != NULL; item = item->next) { + prev_item = nullptr; + for (item = _network_game_list; item != nullptr; item = item->next) { if (item->address == address) return item; prev_item = item; } item = CallocT(1); - item->next = NULL; + item->next = nullptr; item->address = address; - if (prev_item == NULL) { + if (prev_item == nullptr) { _network_game_list = item; } else { prev_item->next = item; @@ -118,10 +109,10 @@ NetworkGameList *NetworkGameListAddItem(NetworkAddress address) */ void NetworkGameListRemoveItem(NetworkGameList *remove) { - NetworkGameList *prev_item = NULL; - for (NetworkGameList *item = _network_game_list; item != NULL; item = item->next) { + NetworkGameList *prev_item = nullptr; + for (NetworkGameList *item = _network_game_list; item != nullptr; item = item->next) { if (remove == item) { - if (prev_item == NULL) { + if (prev_item == nullptr) { _network_game_list = remove->next; } else { prev_item->next = remove->next; @@ -130,7 +121,7 @@ void NetworkGameListRemoveItem(NetworkGameList *remove) /* Remove GRFConfig information */ ClearGRFConfigList(&remove->info.grfconfig); free(remove); - remove = NULL; + remove = nullptr; DEBUG(net, 4, "[gamelist] removed server from list"); NetworkRebuildHostList(); @@ -155,7 +146,7 @@ void NetworkGameListRequery() if (++requery_cnt < REQUERY_EVERY_X_GAMELOOPS) return; requery_cnt = 0; - for (NetworkGameList *item = _network_game_list; item != NULL; item = item->next) { + for (NetworkGameList *item = _network_game_list; item != nullptr; item = item->next) { item->retries++; if (item->retries < REFRESH_GAMEINFO_X_REQUERIES && (item->online || item->retries >= MAX_GAME_LIST_REQUERY_COUNT)) continue; @@ -172,15 +163,15 @@ void NetworkGameListRequery() */ void NetworkAfterNewGRFScan() { - for (NetworkGameList *item = _network_game_list; item != NULL; item = item->next) { + for (NetworkGameList *item = _network_game_list; item != nullptr; item = item->next) { /* Reset compatibility state */ item->info.compatible = item->info.version_compatible; - for (GRFConfig *c = item->info.grfconfig; c != NULL; c = c->next) { + for (GRFConfig *c = item->info.grfconfig; c != nullptr; c = c->next) { assert(HasBit(c->flags, GCF_COPY)); const GRFConfig *f = FindGRFConfig(c->ident.grfid, FGCM_EXACT, c->ident.md5sum); - if (f == NULL) { + if (f == nullptr) { /* Don't know the GRF, so mark game incompatible and the (possibly) * already resolved name for this GRF (another server has sent the * name of the GRF already. */ @@ -206,5 +197,3 @@ void NetworkAfterNewGRFScan() InvalidateWindowClassesData(WC_NETWORK_WINDOW); } - -#endif /* ENABLE_NETWORK */ diff --git a/src/network/network_gamelist.h b/src/network/network_gamelist.h index c77c6719e0..8e61f3a93b 100644 --- a/src/network/network_gamelist.h +++ b/src/network/network_gamelist.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/network/network_gui.cpp b/src/network/network_gui.cpp index ce41e187da..e3a687ce0a 100644 --- a/src/network/network_gui.cpp +++ b/src/network/network_gui.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. @@ -9,7 +7,6 @@ /** @file network_gui.cpp Implementation of the Network related GUIs. */ -#ifdef ENABLE_NETWORK #include "../stdafx.h" #include "../strings_func.h" #include "../date_func.h" @@ -65,18 +62,18 @@ static const StringID _lan_internet_types_dropdown[] = { INVALID_STRING_ID }; -static StringID _language_dropdown[NETLANG_COUNT + 1] = {STR_NULL}; +static std::vector _language_dropdown; void SortNetworkLanguages() { /* Init the strings */ - if (_language_dropdown[0] == STR_NULL) { - for (int i = 0; i < NETLANG_COUNT; i++) _language_dropdown[i] = STR_NETWORK_LANG_ANY + i; - _language_dropdown[NETLANG_COUNT] = INVALID_STRING_ID; + if (_language_dropdown.empty()) { + for (int i = 0; i < NETLANG_COUNT; i++) _language_dropdown.emplace_back(STR_NETWORK_LANG_ANY + i); + _language_dropdown.emplace_back(INVALID_STRING_ID); } /* Sort the strings (we don't move 'any' and the 'invalid' one) */ - QSortT(_language_dropdown + 1, NETLANG_COUNT - 1, &StringIDSorter); + std::sort(_language_dropdown.begin() + 1, _language_dropdown.end() - 1, StringIDSorter); } /** @@ -119,7 +116,7 @@ public: *lastof(this->visible) = true; } - void SetupSmallestSize(Window *w, bool init_array) + void SetupSmallestSize(Window *w, bool init_array) override { /* Oh yeah, we ought to be findable! */ w->nested_array[WID_NG_HEADER] = this; @@ -131,13 +128,13 @@ public: this->resize_y = 0; // We never resize in this direction /* First initialise some variables... */ - for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) { + for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { child_wid->SetupSmallestSize(w, init_array); this->smallest_y = max(this->smallest_y, child_wid->smallest_y + child_wid->padding_top + child_wid->padding_bottom); } /* ... then in a second pass make sure the 'current' sizes are set. Won't change for most widgets. */ - for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) { + for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { child_wid->current_x = child_wid->smallest_x; child_wid->current_y = this->smallest_y; } @@ -145,7 +142,7 @@ public: this->smallest_x = this->head->smallest_x + this->tail->smallest_x; // First and last are always shown, rest not } - void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl) + void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl) override { assert(given_width >= this->smallest_x && given_height >= this->smallest_y); @@ -174,7 +171,7 @@ public: uint position = 0; // Place to put next child relative to origin of the container. uint i = rtl ? lengthof(this->visible) - 1 : 0; child_wid = rtl ? this->tail : this->head; - while (child_wid != NULL) { + while (child_wid != nullptr) { if (this->visible[i]) { child_wid->AssignSizePosition(sizing, x + position, y, child_wid->current_x, this->current_y, rtl); position += child_wid->current_x; @@ -185,27 +182,27 @@ public: } } - /* virtual */ void Draw(const Window *w) + void Draw(const Window *w) override { int i = 0; - for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) { + for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { if (!this->visible[i++]) continue; child_wid->Draw(w); } } - /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y) + NWidgetCore *GetWidgetFromPos(int x, int y) override { - if (!IsInsideBS(x, this->pos_x, this->current_x) || !IsInsideBS(y, this->pos_y, this->current_y)) return NULL; + if (!IsInsideBS(x, this->pos_x, this->current_x) || !IsInsideBS(y, this->pos_y, this->current_y)) return nullptr; int i = 0; - for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) { + for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { if (!this->visible[i++]) continue; NWidgetCore *nwid = child_wid->GetWidgetFromPos(x, y); - if (nwid != NULL) return nwid; + if (nwid != nullptr) return nwid; } - return NULL; + return nullptr; } /** @@ -240,7 +237,7 @@ protected: int lock_offset; ///< Left offset for lock icon. int blot_offset; ///< Left offset for green/yellow/red compatibility icon. - int flag_offset; ///< Left offset for langauge flag icon. + int flag_offset; ///< Left offset for language flag icon. /** * (Re)build the GUI network game list (a.k.a. this->servers) as some @@ -252,10 +249,10 @@ protected: if (!this->servers.NeedRebuild()) return; /* Create temporary array of games to use for listing */ - this->servers.Clear(); + this->servers.clear(); - for (NetworkGameList *ngl = _network_game_list; ngl != NULL; ngl = ngl->next) { - *this->servers.Append() = ngl; + for (NetworkGameList *ngl = _network_game_list; ngl != nullptr; ngl = ngl->next) { + this->servers.push_back(ngl); } /* Apply the filter condition immediately, if a search string has been provided. */ @@ -269,9 +266,9 @@ protected: this->servers.SetFilterState(false); } - this->servers.Compact(); + this->servers.shrink_to_fit(); this->servers.RebuildDone(); - this->vscroll->SetCount(this->servers.Length()); + this->vscroll->SetCount((int)this->servers.size()); /* Sort the list of network games as requested. */ this->servers.Sort(); @@ -279,10 +276,10 @@ protected: } /** Sort servers by name. */ - static int CDECL NGameNameSorter(NetworkGameList * const *a, NetworkGameList * const *b) + static bool NGameNameSorter(NetworkGameList * const &a, NetworkGameList * const &b) { - int r = strnatcmp((*a)->info.server_name, (*b)->info.server_name, true); // Sort by name (natural sorting). - return r == 0 ? (*a)->address.CompareTo((*b)->address) : r; + int r = strnatcmp(a->info.server_name, b->info.server_name, true); // Sort by name (natural sorting). + return r == 0 ? a->address.CompareTo(b->address) < 0: r < 0; } /** @@ -290,60 +287,60 @@ protected: * server. If the two servers have the same amount, the one with the * higher maximum is preferred. */ - static int CDECL NGameClientSorter(NetworkGameList * const *a, NetworkGameList * const *b) + static bool NGameClientSorter(NetworkGameList * const &a, NetworkGameList * const &b) { /* Reverse as per default we are interested in most-clients first */ - int r = (*a)->info.clients_on - (*b)->info.clients_on; + int r = a->info.clients_on - b->info.clients_on; - if (r == 0) r = (*a)->info.clients_max - (*b)->info.clients_max; - if (r == 0) r = NGameNameSorter(a, b); + if (r == 0) r = a->info.clients_max - b->info.clients_max; + if (r == 0) return NGameNameSorter(a, b); - return r; + return r < 0; } /** Sort servers by map size */ - static int CDECL NGameMapSizeSorter(NetworkGameList * const *a, NetworkGameList * const *b) + static bool NGameMapSizeSorter(NetworkGameList * const &a, NetworkGameList * const &b) { /* Sort by the area of the map. */ - int r = ((*a)->info.map_height) * ((*a)->info.map_width) - ((*b)->info.map_height) * ((*b)->info.map_width); + int r = (a->info.map_height) * (a->info.map_width) - (b->info.map_height) * (b->info.map_width); - if (r == 0) r = (*a)->info.map_width - (*b)->info.map_width; - return (r != 0) ? r : NGameClientSorter(a, b); + if (r == 0) r = a->info.map_width - b->info.map_width; + return (r != 0) ? r < 0 : NGameClientSorter(a, b); } /** Sort servers by current date */ - static int CDECL NGameDateSorter(NetworkGameList * const *a, NetworkGameList * const *b) + static bool NGameDateSorter(NetworkGameList * const &a, NetworkGameList * const &b) { - int r = (*a)->info.game_date - (*b)->info.game_date; - return (r != 0) ? r : NGameClientSorter(a, b); + int r = a->info.game_date - b->info.game_date; + return (r != 0) ? r < 0 : NGameClientSorter(a, b); } /** Sort servers by the number of days the game is running */ - static int CDECL NGameYearsSorter(NetworkGameList * const *a, NetworkGameList * const *b) + static bool NGameYearsSorter(NetworkGameList * const &a, NetworkGameList * const &b) { - int r = (*a)->info.game_date - (*a)->info.start_date - (*b)->info.game_date + (*b)->info.start_date; - return (r != 0) ? r : NGameDateSorter(a, b); + int r = a->info.game_date - a->info.start_date - b->info.game_date + b->info.start_date; + return (r != 0) ? r < 0: NGameDateSorter(a, b); } /** * Sort servers by joinability. If both servers are the * same, prefer the non-passworded server first. */ - static int CDECL NGameAllowedSorter(NetworkGameList * const *a, NetworkGameList * const *b) + static bool NGameAllowedSorter(NetworkGameList * const &a, NetworkGameList * const &b) { /* The servers we do not know anything about (the ones that did not reply) should be at the bottom) */ - int r = StrEmpty((*a)->info.server_revision) - StrEmpty((*b)->info.server_revision); + int r = StrEmpty(a->info.server_revision) - StrEmpty(b->info.server_revision); /* Reverse default as we are interested in version-compatible clients first */ - if (r == 0) r = (*b)->info.version_compatible - (*a)->info.version_compatible; + if (r == 0) r = b->info.version_compatible - a->info.version_compatible; /* The version-compatible ones are then sorted with NewGRF compatible first, incompatible last */ - if (r == 0) r = (*b)->info.compatible - (*a)->info.compatible; + if (r == 0) r = b->info.compatible - a->info.compatible; /* Passworded servers should be below unpassworded servers */ - if (r == 0) r = (*a)->info.use_password - (*b)->info.use_password; + if (r == 0) r = a->info.use_password - b->info.use_password; /* Finally sort on the number of clients of the server */ - if (r == 0) r = -NGameClientSorter(a, b); + if (r == 0) return NGameClientSorter(a, b); - return r; + return r < 0; } /** Sort the server list */ @@ -356,7 +353,7 @@ protected: void UpdateListPos() { this->list_pos = SLP_INVALID; - for (uint i = 0; i != this->servers.Length(); i++) { + for (uint i = 0; i != this->servers.size(); i++) { if (this->servers[i] == this->server) { this->list_pos = i; break; @@ -366,8 +363,8 @@ protected: static bool CDECL NGameSearchFilter(NetworkGameList * const *item, StringFilter &sf) { - assert(item != NULL); - assert((*item) != NULL); + assert(item != nullptr); + assert((*item) != nullptr); sf.ResetState(); sf.AddLine((*item)->info.server_name); @@ -462,7 +459,7 @@ public: NetworkGameWindow(WindowDesc *desc) : Window(desc), name_editbox(NETWORK_CLIENT_NAME_LENGTH), filter_editbox(120) { this->list_pos = SLP_INVALID; - this->server = NULL; + this->server = nullptr; this->lock_offset = 5; this->blot_offset = this->lock_offset + 3 + GetSpriteSize(SPR_LOCK).width; @@ -481,7 +478,7 @@ public: this->last_joined = NetworkGameListAddItem(NetworkAddress(_settings_client.network.last_host, _settings_client.network.last_port)); this->server = this->last_joined; - if (this->last_joined != NULL) NetworkUDPQueryServer(this->last_joined->address); + if (this->last_joined != nullptr) NetworkUDPQueryServer(this->last_joined->address); this->requery_timer.SetInterval(MILLISECONDS_PER_TICK); @@ -496,7 +493,7 @@ public: this->last_sorting = this->servers.GetListing(); } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { switch (widget) { case WID_NG_CONN_BTN: @@ -505,7 +502,7 @@ public: } } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_NG_CONN_BTN: @@ -560,13 +557,13 @@ public: } } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { switch (widget) { case WID_NG_MATRIX: { uint16 y = r.top; - const int max = min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), (int)this->servers.Length()); + const int max = min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), (int)this->servers.size()); for (int i = this->vscroll->GetPosition(); i < max; ++i) { const NetworkGameList *ngl = this->servers[i]; @@ -578,7 +575,7 @@ public: case WID_NG_LASTJOINED: /* Draw the last joined server, if any */ - if (this->last_joined != NULL) this->DrawServerLine(this->last_joined, r.top, this->last_joined == this->server); + if (this->last_joined != nullptr) this->DrawServerLine(this->last_joined, r.top, this->last_joined == this->server); break; case WID_NG_DETAILS: @@ -597,7 +594,7 @@ public: } - virtual void OnPaint() + void OnPaint() override { if (this->servers.NeedRebuild()) { this->BuildGUINetworkGameList(); @@ -608,16 +605,16 @@ public: NetworkGameList *sel = this->server; /* 'Refresh' button invisible if no server selected */ - this->SetWidgetDisabledState(WID_NG_REFRESH, sel == NULL); + this->SetWidgetDisabledState(WID_NG_REFRESH, sel == nullptr); /* 'Join' button disabling conditions */ - this->SetWidgetDisabledState(WID_NG_JOIN, sel == NULL || // no Selected Server + this->SetWidgetDisabledState(WID_NG_JOIN, sel == nullptr || // no Selected Server !sel->online || // Server offline sel->info.clients_on >= sel->info.clients_max || // Server full !sel->info.compatible); // Revision mismatch /* 'NewGRF Settings' button invisible if no NewGRF is used */ - this->GetWidget(WID_NG_NEWGRF_SEL)->SetDisplayedPlane(sel == NULL || !sel->online || sel->info.grfconfig == NULL); - this->GetWidget(WID_NG_NEWGRF_MISSING_SEL)->SetDisplayedPlane(sel == NULL || !sel->online || sel->info.grfconfig == NULL || !sel->info.version_compatible || sel->info.compatible); + this->GetWidget(WID_NG_NEWGRF_SEL)->SetDisplayedPlane(sel == nullptr || !sel->online || sel->info.grfconfig == nullptr); + this->GetWidget(WID_NG_NEWGRF_MISSING_SEL)->SetDisplayedPlane(sel == nullptr || !sel->online || sel->info.grfconfig == nullptr || !sel->info.version_compatible || sel->info.compatible); this->DrawWidgets(); } @@ -630,7 +627,7 @@ public: /* Draw the right menu */ GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.top + detail_height - 1, PC_DARK_BLUE); - if (sel == NULL) { + 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); } else if (!sel->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 @@ -693,7 +690,7 @@ public: } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_NG_CANCEL: // Cancel button @@ -712,7 +709,7 @@ public: case WID_NG_INFO: // Connectivity (green dot) if (this->servers.SortType() == widget - WID_NG_NAME) { this->servers.ToggleSortOrder(); - if (this->list_pos != SLP_INVALID) this->list_pos = this->servers.Length() - this->list_pos - 1; + if (this->list_pos != SLP_INVALID) this->list_pos = (ServerListPosition)this->servers.size() - this->list_pos - 1; } else { this->servers.SetSortType(widget - WID_NG_NAME); this->servers.ForceResort(); @@ -724,8 +721,8 @@ public: case WID_NG_MATRIX: { // Show available network games uint id_v = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_NG_MATRIX); - this->server = (id_v < this->servers.Length()) ? this->servers[id_v] : NULL; - this->list_pos = (server == NULL) ? SLP_INVALID : id_v; + this->server = (id_v < this->servers.size()) ? this->servers[id_v] : nullptr; + this->list_pos = (server == nullptr) ? SLP_INVALID : id_v; this->SetDirty(); /* FIXME the disabling should go into some InvalidateData, which is called instead of the SetDirty */ @@ -734,7 +731,7 @@ public: } case WID_NG_LASTJOINED: { - if (this->last_joined != NULL) { + if (this->last_joined != nullptr) { this->server = this->last_joined; /* search the position of the newly selected server */ @@ -769,7 +766,7 @@ public: break; case WID_NG_JOIN: // Join Game - if (this->server != NULL) { + if (this->server != nullptr) { seprintf(_settings_client.network.last_host, lastof(_settings_client.network.last_host), "%s", this->server->address.GetHostname()); _settings_client.network.last_port = this->server->address.GetPort(); ShowNetworkLobbyWindow(this->server); @@ -777,20 +774,20 @@ public: break; case WID_NG_REFRESH: // Refresh - if (this->server != NULL) NetworkUDPQueryServer(this->server->address); + if (this->server != nullptr) NetworkUDPQueryServer(this->server->address); break; case WID_NG_NEWGRF: // NewGRF Settings - if (this->server != NULL) ShowNewGRFSettings(false, false, false, &this->server->info.grfconfig); + if (this->server != nullptr) ShowNewGRFSettings(false, false, false, &this->server->info.grfconfig); break; case WID_NG_NEWGRF_MISSING: // Find missing content online - if (this->server != NULL) ShowMissingContentWindow(this->server->info.grfconfig); + if (this->server != nullptr) ShowMissingContentWindow(this->server->info.grfconfig); break; } } - virtual void OnDropdownSelect(int widget, int index) + void OnDropdownSelect(int widget, int index) override { switch (widget) { case WID_NG_CONN_BTN: @@ -809,19 +806,19 @@ public: * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { this->servers.ForceRebuild(); this->SetDirty(); } - virtual EventState OnKeyPress(WChar key, uint16 keycode) + EventState OnKeyPress(WChar key, uint16 keycode) override { EventState state = ES_NOT_HANDLED; /* handle up, down, pageup, pagedown, home and end */ if (keycode == WKC_UP || keycode == WKC_DOWN || keycode == WKC_PAGEUP || keycode == WKC_PAGEDOWN || keycode == WKC_HOME || keycode == WKC_END) { - if (this->servers.Length() == 0) return ES_HANDLED; + if (this->servers.size() == 0) return ES_HANDLED; switch (keycode) { case WKC_UP: /* scroll up by one */ @@ -831,7 +828,7 @@ public: case WKC_DOWN: /* scroll down by one */ if (this->list_pos == SLP_INVALID) return ES_HANDLED; - if (this->list_pos < this->servers.Length() - 1) this->list_pos++; + if (this->list_pos < this->servers.size() - 1) this->list_pos++; break; case WKC_PAGEUP: /* scroll up a page */ @@ -841,7 +838,7 @@ public: case WKC_PAGEDOWN: /* scroll down a page */ if (this->list_pos == SLP_INVALID) return ES_HANDLED; - this->list_pos = min(this->list_pos + this->vscroll->GetCapacity(), (int)this->servers.Length() - 1); + this->list_pos = min(this->list_pos + this->vscroll->GetCapacity(), (int)this->servers.size() - 1); break; case WKC_HOME: /* jump to beginning */ @@ -849,7 +846,7 @@ public: break; case WKC_END: /* jump to end */ - this->list_pos = this->servers.Length() - 1; + this->list_pos = (ServerListPosition)this->servers.size() - 1; break; default: NOT_REACHED(); } @@ -864,11 +861,11 @@ public: return ES_HANDLED; } - if (this->server != NULL) { + if (this->server != nullptr) { if (keycode == WKC_DELETE) { // Press 'delete' to remove servers NetworkGameListRemoveItem(this->server); - if (this->server == this->last_joined) this->last_joined = NULL; - this->server = NULL; + if (this->server == this->last_joined) this->last_joined = nullptr; + this->server = nullptr; this->list_pos = SLP_INVALID; } } @@ -876,7 +873,7 @@ public: return state; } - virtual void OnEditboxChanged(int wid) + void OnEditboxChanged(int wid) override { switch (wid) { case WID_NG_FILTER: { @@ -898,17 +895,17 @@ public: } } - virtual void OnQueryTextFinished(char *str) + void OnQueryTextFinished(char *str) override { if (!StrEmpty(str)) NetworkAddServer(str); } - virtual void OnResize() + void OnResize() override { this->vscroll->SetCapacityFromWidget(this, WID_NG_MATRIX); } - virtual void OnRealtimeTick(uint delta_ms) + void OnRealtimeTick(uint delta_ms) override { if (!this->requery_timer.Elapsed(delta_ms)) return; this->requery_timer.SetInterval(MILLISECONDS_PER_TICK); @@ -1044,8 +1041,8 @@ void ShowNetworkGameWindow() if (first) { first = false; /* Add all servers from the config file to our list. */ - for (char **iter = _network_host_list.Begin(); iter != _network_host_list.End(); iter++) { - NetworkAddServer(*iter); + for (const auto &iter : _network_host_list) { + NetworkAddServer(iter.c_str()); } } @@ -1066,7 +1063,7 @@ struct NetworkStartServerWindow : public Window { this->SetFocusedWidget(WID_NSS_GAMENAME); } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { switch (widget) { case WID_NSS_CONNTYPE_BTN: @@ -1091,7 +1088,7 @@ struct NetworkStartServerWindow : public Window { } } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_NSS_CONNTYPE_BTN: @@ -1102,7 +1099,7 @@ struct NetworkStartServerWindow : public Window { } } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { switch (widget) { case WID_NSS_SETPWD: @@ -1111,7 +1108,7 @@ struct NetworkStartServerWindow : public Window { } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_NSS_CANCEL: // Cancel button @@ -1171,13 +1168,13 @@ struct NetworkStartServerWindow : public Window { case WID_NSS_LANGUAGE_BTN: { // Language uint sel = 0; - for (uint i = 0; i < lengthof(_language_dropdown) - 1; i++) { + for (uint i = 0; i < _language_dropdown.size() - 1; i++) { if (_language_dropdown[i] == STR_NETWORK_LANG_ANY + _settings_client.network.server_lang) { sel = i; break; } } - ShowDropDownMenu(this, _language_dropdown, sel, WID_NSS_LANGUAGE_BTN, 0, 0); + ShowDropDownMenu(this, _language_dropdown.data(), sel, WID_NSS_LANGUAGE_BTN, 0, 0); break; } @@ -1207,7 +1204,7 @@ struct NetworkStartServerWindow : public Window { } } - virtual void OnDropdownSelect(int widget, int index) + void OnDropdownSelect(int widget, int index) override { switch (widget) { case WID_NSS_CONNTYPE_BTN: @@ -1223,14 +1220,14 @@ struct NetworkStartServerWindow : public Window { this->SetDirty(); } - virtual void OnEditboxChanged(int wid) + void OnEditboxChanged(int wid) override { if (wid == WID_NSS_GAMENAME) { strecpy(_settings_client.network.server_name, this->name_editbox.text.buf, lastof(_settings_client.network.server_name)); } } - virtual void OnTimeout() + void OnTimeout() override { static const int raise_widgets[] = {WID_NSS_CLIENTS_BTND, WID_NSS_CLIENTS_BTNU, WID_NSS_COMPANIES_BTND, WID_NSS_COMPANIES_BTNU, WID_NSS_SPECTATORS_BTND, WID_NSS_SPECTATORS_BTNU, WIDGET_LIST_END}; for (const int *widget = raise_widgets; *widget != WIDGET_LIST_END; widget++) { @@ -1241,9 +1238,9 @@ struct NetworkStartServerWindow : public Window { } } - virtual void OnQueryTextFinished(char *str) + void OnQueryTextFinished(char *str) override { - if (str == NULL) return; + if (str == nullptr) return; if (this->widget_id == WID_NSS_SETPWD) { strecpy(_settings_client.network.server_password, str, lastof(_settings_client.network.server_password)); @@ -1343,7 +1340,7 @@ static const NWidgetPart _nested_network_start_server_window_widgets[] = { }; static WindowDesc _network_start_server_window_desc( - WDP_CENTER, NULL, 0, 0, + WDP_CENTER, nullptr, 0, 0, WC_NETWORK_WINDOW, WC_NONE, 0, _nested_network_start_server_window_widgets, lengthof(_nested_network_start_server_window_widgets) @@ -1383,7 +1380,7 @@ struct NetworkLobbyWindow : public Window { return COMPANY_FIRST; } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_NL_HEADER: @@ -1401,7 +1398,7 @@ struct NetworkLobbyWindow : public Window { } } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { switch (widget) { case WID_NL_TEXT: @@ -1410,7 +1407,7 @@ struct NetworkLobbyWindow : public Window { } } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { switch (widget) { case WID_NL_DETAILS: @@ -1423,7 +1420,7 @@ struct NetworkLobbyWindow : public Window { } } - virtual void OnPaint() + void OnPaint() override { const NetworkGameInfo *gi = &this->server->info; @@ -1545,7 +1542,7 @@ struct NetworkLobbyWindow : public Window { DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_GAME_LOBBY_PLAYERS); // players } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_NL_CANCEL: // Cancel button @@ -1584,7 +1581,7 @@ struct NetworkLobbyWindow : public Window { } } - virtual void OnResize() + void OnResize() override { this->vscroll->SetCapacityFromWidget(this, WID_NL_MATRIX); } @@ -1630,7 +1627,7 @@ static const NWidgetPart _nested_network_lobby_window_widgets[] = { }; static WindowDesc _network_lobby_window_desc( - WDP_CENTER, NULL, 0, 0, + WDP_CENTER, nullptr, 0, 0, WC_NETWORK_WINDOW, WC_NONE, 0, _nested_network_lobby_window_widgets, lengthof(_nested_network_lobby_window_widgets) @@ -1659,7 +1656,7 @@ static void ShowNetworkLobbyWindow(NetworkGameList *ngl) NetworkCompanyInfo *GetLobbyCompanyInfo(CompanyID company) { NetworkLobbyWindow *lobby = dynamic_cast(FindWindowById(WC_NETWORK_WINDOW, WN_NETWORK_WINDOW_LOBBY)); - return (lobby != NULL && company < MAX_COMPANIES) ? &lobby->company_info[company] : NULL; + return (lobby != nullptr && company < MAX_COMPANIES) ? &lobby->company_info[company] : nullptr; } /* The window below gives information about the connected clients @@ -1679,7 +1676,7 @@ static const NWidgetPart _nested_client_list_popup_widgets[] = { }; static WindowDesc _client_list_popup_desc( - WDP_AUTO, NULL, 0, 0, + WDP_AUTO, nullptr, 0, 0, WC_CLIENT_LIST_POPUP, WC_CLIENT_LIST, 0, _nested_client_list_popup_widgets, lengthof(_nested_client_list_popup_widgets) @@ -1688,12 +1685,12 @@ static WindowDesc _client_list_popup_desc( /* Here we start to define the options out of the menu */ static void ClientList_Kick(const NetworkClientInfo *ci) { - NetworkServerKickClient(ci->client_id); + NetworkServerKickClient(ci->client_id, nullptr); } static void ClientList_Ban(const NetworkClientInfo *ci) { - NetworkServerKickOrBanIP(ci->client_id, true); + NetworkServerKickOrBanIP(ci->client_id, true, nullptr); } static void ClientList_GiveMoney(const NetworkClientInfo *ci) @@ -1727,7 +1724,7 @@ struct NetworkClientListPopupWindow : Window { int sel_index; ClientID client_id; Point desired_location; - SmallVector actions; ///< Actions to execute + std::vector actions; ///< Actions to execute /** * Add an action to the list of actions to execute. @@ -1736,9 +1733,7 @@ struct NetworkClientListPopupWindow : Window { */ inline void AddAction(StringID name, ClientList_Action_Proc *proc) { - ClientListAction *action = this->actions.Append(); - action->name = name; - action->proc = proc; + this->actions.push_back({name, proc}); } NetworkClientListPopupWindow(WindowDesc *desc, int x, int y, ClientID client_id) : @@ -1776,31 +1771,31 @@ struct NetworkClientListPopupWindow : Window { CLRBITS(this->flags, WF_WHITE_BORDER); } - virtual Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number) + Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number) override { return this->desired_location; } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { Dimension d = *size; - for (const ClientListAction *action = this->actions.Begin(); action != this->actions.End(); action++) { - d = maxdim(GetStringBoundingBox(action->name), d); + for (const ClientListAction &action : this->actions) { + d = maxdim(GetStringBoundingBox(action.name), d); } d.height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL); - d.height *= this->actions.Length(); + d.height *= (uint)this->actions.size(); d.width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT; d.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM; *size = d; } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { /* Draw the actions */ int sel = this->sel_index; int y = r.top + WD_FRAMERECT_TOP; - for (const ClientListAction *action = this->actions.Begin(); action != this->actions.End(); action++, y += GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL)) { + for (const ClientListAction &action : this->actions) { TextColour colour; if (sel-- == 0) { // Selected item, highlight it GfxFillRect(r.left + 1, y, r.right - 1, y + GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL) - 1, PC_BLACK); @@ -1809,11 +1804,30 @@ struct NetworkClientListPopupWindow : Window { colour = TC_BLACK; } - DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, Center(y, GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL)), action->name, colour); + DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, Center(y, GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL)), action.name, colour); + y += GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL) } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnMouseLoop() override + { + /* We selected an action */ + uint index = (_cursor.pos.y - this->top - WD_FRAMERECT_TOP) / FONT_HEIGHT_NORMAL; + + if (_left_button_down) { + if (index == this->sel_index || index >= this->actions.size()) return; + + this->sel_index = index; + this->SetDirty(); + } else { + if (index < this->actions.size() && _cursor.pos.y >= this->top) { + const NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(this->client_id); + if (ci != nullptr) this->actions[index].proc(ci); + } + } + } + + void OnClick(Point pt, int widget, int click_count) override { int index = (pt.y - WD_FRAMERECT_TOP) / GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL); @@ -1833,7 +1847,7 @@ static void PopupClientList(ClientID client_id, int x, int y) { DeleteWindowByClass(WC_CLIENT_LIST_POPUP); - if (NetworkClientInfo::GetByClientID(client_id) == NULL) return; + if (NetworkClientInfo::GetByClientID(client_id) == nullptr) return; new NetworkClientListPopupWindow(&_client_list_popup_desc, x, y, client_id); } @@ -1880,10 +1894,9 @@ struct NetworkClientListWindow : Window { bool CheckClientListHeight() { int num = 0; - const NetworkClientInfo *ci; /* Should be replaced with a loop through all clients */ - FOR_ALL_CLIENT_INFOS(ci) { + for (const NetworkClientInfo *ci : NetworkClientInfo::Iterate()) { if (ci->client_playas != COMPANY_INACTIVE_CLIENT) num++; } @@ -1902,7 +1915,7 @@ struct NetworkClientListWindow : Window { return true; } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { if (widget != WID_CL_PANEL) return; @@ -1912,15 +1925,14 @@ struct NetworkClientListWindow : Window { this->line_height = GetMinSizing(NWST_STEP, this->line_height); uint width = 100; // Default width - const NetworkClientInfo *ci; - FOR_ALL_CLIENT_INFOS(ci) { + for (const NetworkClientInfo *ci : NetworkClientInfo::Iterate()) { width = max(width, GetStringBoundingBox(ci->client_name).width); } this->line_width = this->server_client_width + this->icon_size.width + WD_FRAMERECT_LEFT + width + WD_FRAMERECT_RIGHT; } - virtual void OnPaint() + void OnPaint() override { /* Check if we need to reset the height */ if (!this->CheckClientListHeight()) return; @@ -1928,7 +1940,7 @@ struct NetworkClientListWindow : Window { this->DrawWidgets(); } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { if (widget != WID_CL_PANEL) return; @@ -1942,8 +1954,7 @@ struct NetworkClientListWindow : Window { uint type_icon_width = this->server_client_width + this->icon_size.width + WD_FRAMERECT_LEFT; int i = 0; - const NetworkClientInfo *ci; - FOR_ALL_CLIENT_INFOS(ci) { + for (const NetworkClientInfo *ci : NetworkClientInfo::Iterate()) { uint type_left = rtl ? right - this->server_client_width : left; uint type_right = rtl ? right : left + this->server_client_width - 1; uint icon_left = rtl ? right - type_icon_width + WD_FRAMERECT_LEFT : left + this->server_client_width; @@ -1984,23 +1995,22 @@ struct NetworkClientListWindow : Window { } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { /* Show the popup with option */ if (this->selected_item != -1) { - NetworkClientInfo *ci; - int client_no = this->selected_item; - FOR_ALL_CLIENT_INFOS(ci) { - if (client_no == 0) break; + for (NetworkClientInfo *ci : NetworkClientInfo::Iterate()) { + if (client_no == 0) { + PopupClientList(ci->client_id, pt.x + this->left, pt.y + this->top); + break; + } client_no--; } - - if (ci != NULL) PopupClientList(ci->client_id, pt.x + this->left, pt.y + this->top); } } - virtual void OnMouseOver(Point pt, int widget) + void OnMouseOver(Point pt, int widget) override { /* -1 means we left the current window */ if (pt.y == -1) { @@ -2044,7 +2054,7 @@ struct NetworkJoinStatusWindow : Window { this->InitNested(WN_NETWORK_STATUS_WINDOW_JOIN); } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { if (widget != WID_NJS_BACKGROUND) return; @@ -2078,7 +2088,7 @@ struct NetworkJoinStatusWindow : Window { DrawFrameRect(r.left + 20, r.top + 5, (int)((this->width - 20) * progress / 100), r.top + 15, COLOUR_MAUVE, FR_NONE); } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { if (widget != WID_NJS_BACKGROUND) return; @@ -2104,7 +2114,7 @@ struct NetworkJoinStatusWindow : Window { size->width = width + WD_FRAMERECT_LEFT + WD_FRAMERECT_BOTTOM + 10; } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { if (widget == WID_NJS_CANCELOK) { // Disconnect button NetworkDisconnect(); @@ -2113,7 +2123,7 @@ struct NetworkJoinStatusWindow : Window { } } - virtual void OnQueryTextFinished(char *str) + void OnQueryTextFinished(char *str) override { if (StrEmpty(str)) { NetworkDisconnect(); @@ -2143,7 +2153,7 @@ static const NWidgetPart _nested_network_join_status_window_widgets[] = { }; static WindowDesc _network_join_status_window_desc( - WDP_CENTER, NULL, 0, 0, + WDP_CENTER, nullptr, 0, 0, WC_NETWORK_STATUS_WINDOW, WC_NONE, WDF_MODAL, _nested_network_join_status_window_widgets, lengthof(_nested_network_join_status_window_widgets) @@ -2158,7 +2168,7 @@ void ShowJoinStatusWindow() void ShowNetworkNeedPassword(NetworkPasswordType npt) { NetworkJoinStatusWindow *w = (NetworkJoinStatusWindow *)FindWindowById(WC_NETWORK_STATUS_WINDOW, WN_NETWORK_STATUS_WINDOW_JOIN); - if (w == NULL) return; + if (w == nullptr) return; w->password_type = npt; StringID caption; @@ -2167,15 +2177,17 @@ void ShowNetworkNeedPassword(NetworkPasswordType npt) case NETWORK_GAME_PASSWORD: caption = STR_NETWORK_NEED_GAME_PASSWORD_CAPTION; break; case NETWORK_COMPANY_PASSWORD: caption = STR_NETWORK_NEED_COMPANY_PASSWORD_CAPTION; break; } - ShowQueryString(STR_EMPTY, caption, NETWORK_PASSWORD_LENGTH, w, CS_ALPHANUMERAL, QSF_NONE); + ShowQueryString(STR_EMPTY, caption, NETWORK_PASSWORD_LENGTH, w, CS_ALPHANUMERAL, QSF_PASSWORD); } struct NetworkCompanyPasswordWindow : public Window { QueryString password_editbox; ///< Password editbox. + Dimension warning_size; ///< How much space to use for the warning text NetworkCompanyPasswordWindow(WindowDesc *desc, Window *parent) : Window(desc), password_editbox(lengthof(_settings_client.network.default_company_pass)) { this->InitNested(0); + this->UpdateWarningStringSize(); this->parent = parent; this->querystrings[WID_NCP_PASSWORD] = &this->password_editbox; @@ -2184,6 +2196,32 @@ struct NetworkCompanyPasswordWindow : public Window { this->SetFocusedWidget(WID_NCP_PASSWORD); } + 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.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->ReInit(); + } + + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override + { + if (widget == WID_NCP_WARNING) { + *size = this->warning_size; + } + } + + void DrawWidget(const Rect &r, int widget) const override + { + 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, + STR_WARNING_PASSWORD_SECURITY, TC_FROMSTRING, SA_CENTER); + } + void OnOk() { if (this->IsWidgetLowered(WID_NCP_SAVE_AS_DEFAULT_PASSWORD)) { @@ -2193,7 +2231,7 @@ struct NetworkCompanyPasswordWindow : public Window { NetworkChangeCompanyPassword(_local_company, this->password_editbox.text.buf); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_NCP_OK: @@ -2230,6 +2268,7 @@ static const NWidgetPart _nested_network_company_password_window_widgets[] = { EndContainer(), EndContainer(), EndContainer(), + NWidget(WWT_PANEL, COLOUR_GREY, WID_NCP_WARNING), EndContainer(), NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_NCP_CANCEL), SetFill(1, 0), SetDataTip(STR_BUTTON_CANCEL, STR_COMPANY_PASSWORD_CANCEL), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_NCP_OK), SetFill(1, 0), SetDataTip(STR_BUTTON_OK, STR_COMPANY_PASSWORD_OK), @@ -2237,7 +2276,7 @@ static const NWidgetPart _nested_network_company_password_window_widgets[] = { }; static WindowDesc _network_company_password_window_desc( - WDP_AUTO, NULL, 0, 0, + WDP_AUTO, nullptr, 0, 0, WC_COMPANY_PASSWORD_WINDOW, WC_NONE, 0, _nested_network_company_password_window_widgets, lengthof(_nested_network_company_password_window_widgets) @@ -2249,5 +2288,3 @@ void ShowNetworkCompanyPasswordWindow(Window *parent) new NetworkCompanyPasswordWindow(&_network_company_password_window_desc, parent); } - -#endif /* ENABLE_NETWORK */ diff --git a/src/network/network_gui.h b/src/network/network_gui.h index a196c75e9f..b9439599b5 100644 --- a/src/network/network_gui.h +++ b/src/network/network_gui.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. @@ -17,8 +15,6 @@ #include "../window_type.h" #include "network_type.h" -#ifdef ENABLE_NETWORK - void ShowNetworkNeedPassword(NetworkPasswordType npt); void ShowNetworkGiveMoneyWindow(CompanyID company); void ShowNetworkChatQueryWindow(DestType type, int dest); @@ -42,14 +38,4 @@ struct NetworkCompanyInfo : NetworkCompanyStats { NetworkCompanyInfo *GetLobbyCompanyInfo(CompanyID company); -#else /* ENABLE_NETWORK */ -/* Network function stubs when networking is disabled */ - -static inline void ShowNetworkChatQueryWindow(byte desttype, int dest) {} -static inline void ShowClientList() {} -static inline void ShowNetworkGameWindow() {} -static inline void ShowNetworkCompanyPasswordWindow(Window *parent) {} - -#endif /* ENABLE_NETWORK */ - #endif /* NETWORK_GUI_H */ diff --git a/src/network/network_internal.h b/src/network/network_internal.h index ed9a8de6f6..8cae502e10 100644 --- a/src/network/network_internal.h +++ b/src/network/network_internal.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. @@ -17,8 +15,6 @@ #include "../command_type.h" -#ifdef ENABLE_NETWORK - #ifdef RANDOM_DEBUG /** * If this line is enable, every frame will have a sync test @@ -151,8 +147,8 @@ bool IsNetworkCompatibleVersion(const char *version); * Everything we need to know about a command to be able to execute it. */ struct CommandPacket : CommandContainer { - /** Make sure the pointer is NULL. */ - CommandPacket() : next(NULL), company(INVALID_COMPANY), frame(0), my_cmd(false) {} + /** Make sure the pointer is nullptr. */ + 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 @@ -171,5 +167,4 @@ StringID GetNetworkErrorMsg(NetworkErrorCode err); bool NetworkFindName(char *new_name, const char *last); const char *GenerateCompanyPasswordHash(const char *password, const char *password_server_id, uint32 password_game_seed); -#endif /* ENABLE_NETWORK */ #endif /* NETWORK_INTERNAL_H */ diff --git a/src/network/network_server.cpp b/src/network/network_server.cpp index 05fb27fc87..36a15d3ae3 100644 --- a/src/network/network_server.cpp +++ b/src/network/network_server.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. @@ -9,8 +7,6 @@ /** @file network_server.cpp Server part of the network protocol. */ -#ifdef ENABLE_NETWORK - #include "../stdafx.h" #include "../strings_func.h" #include "../date_func.h" @@ -32,6 +28,8 @@ #include "../core/pool_func.hpp" #include "../core/random_func.hpp" #include "../rev.h" +#include +#include #include "../safeguards.h" @@ -60,47 +58,40 @@ struct PacketWriter : SaveFilter { Packet *current; ///< The packet we're currently writing to. size_t total_size; ///< Total size of the compressed savegame. Packet *packets; ///< Packet queue of the savegame; send these "slowly" to the client. - ThreadMutex *mutex; ///< Mutex for making threaded saving safe. + std::mutex mutex; ///< Mutex for making threaded saving safe. + std::condition_variable exit_sig; ///< Signal for threaded destruction of this packet writer. /** * Create the packet writer. * @param cs The socket handler we're making the packets for. */ - PacketWriter(ServerNetworkGameSocketHandler *cs) : SaveFilter(NULL), cs(cs), current(NULL), total_size(0), packets(NULL) + PacketWriter(ServerNetworkGameSocketHandler *cs) : SaveFilter(nullptr), cs(cs), current(nullptr), total_size(0), packets(nullptr) { - this->mutex = ThreadMutex::New(); } /** Make sure everything is cleaned up. */ ~PacketWriter() { - if (this->mutex != NULL) this->mutex->BeginCritical(); + std::unique_lock lock(this->mutex); - if (this->cs != NULL && this->mutex != NULL) { - this->mutex->WaitForSignal(); - } + if (this->cs != nullptr) this->exit_sig.wait(lock); /* This must all wait until the Destroy function is called. */ - while (this->packets != NULL) { + while (this->packets != nullptr) { Packet *p = this->packets->next; delete this->packets; this->packets = p; } delete this->current; - - if (this->mutex != NULL) this->mutex->EndCritical(); - - delete this->mutex; - this->mutex = NULL; } /** * Begin the destruction of this packet writer. It can happen in two ways: * in the first case the client disconnected while saving the map. In this * case the saving has not finished and killed this PacketWriter. In that - * case we simply set cs to NULL, triggering the appending to fail due to + * case we simply set cs to nullptr, triggering the appending to fail due to * the connection problem and eventually triggering the destructor. In the * second case the destructor is already called, and it is waiting for our * signal which we will send. Only then the packets will be removed by the @@ -108,13 +99,12 @@ struct PacketWriter : SaveFilter { */ void Destroy() { - if (this->mutex != NULL) this->mutex->BeginCritical(); + std::unique_lock lock(this->mutex); - this->cs = NULL; + this->cs = nullptr; - if (this->mutex != NULL) this->mutex->SendSignal(); - - if (this->mutex != NULL) this->mutex->EndCritical(); + this->exit_sig.notify_all(); + lock.unlock(); /* Make sure the saving is completely cancelled. Yes, * we need to handle the save finish as well as the @@ -132,7 +122,7 @@ struct PacketWriter : SaveFilter { */ bool HasPackets() { - return this->packets != NULL; + return this->packets != nullptr; } /** @@ -140,13 +130,11 @@ struct PacketWriter : SaveFilter { */ Packet *PopPacket() { - if (this->mutex != NULL) this->mutex->BeginCritical(); + std::lock_guard lock(this->mutex); Packet *p = this->packets; this->packets = p->next; - p->next = NULL; - - if (this->mutex != NULL) this->mutex->EndCritical(); + p->next = nullptr; return p; } @@ -154,25 +142,25 @@ struct PacketWriter : SaveFilter { /** Append the current packet to the queue. */ void AppendQueue() { - if (this->current == NULL) return; + if (this->current == nullptr) return; Packet **p = &this->packets; - while (*p != NULL) { + while (*p != nullptr) { p = &(*p)->next; } *p = this->current; - this->current = NULL; + this->current = nullptr; } - /* virtual */ void Write(byte *buf, size_t size) + void Write(byte *buf, size_t size) override { /* We want to abort the saving when the socket is closed. */ - if (this->cs == NULL) SlError(STR_NETWORK_ERROR_LOSTCONNECTION); + if (this->cs == nullptr) SlError(STR_NETWORK_ERROR_LOSTCONNECTION); - if (this->current == NULL) this->current = new Packet(PACKET_SERVER_MAP_DATA); + if (this->current == nullptr) this->current = new Packet(PACKET_SERVER_MAP_DATA); - if (this->mutex != NULL) this->mutex->BeginCritical(); + std::lock_guard lock(this->mutex); byte *bufe = buf + size; while (buf != bufe) { @@ -187,17 +175,15 @@ struct PacketWriter : SaveFilter { } } - if (this->mutex != NULL) this->mutex->EndCritical(); - this->total_size += size; } - /* virtual */ void Finish() + void Finish() override { /* We want to abort the saving when the socket is closed. */ - if (this->cs == NULL) SlError(STR_NETWORK_ERROR_LOSTCONNECTION); + if (this->cs == nullptr) SlError(STR_NETWORK_ERROR_LOSTCONNECTION); - if (this->mutex != NULL) this->mutex->BeginCritical(); + std::lock_guard lock(this->mutex); /* Make sure the last packet is flushed. */ this->AppendQueue(); @@ -210,8 +196,6 @@ struct PacketWriter : SaveFilter { Packet *p = new Packet(PACKET_SERVER_MAP_SIZE); p->Send_uint32((uint32)this->total_size); this->cs->NetworkTCPSocketHandler::SendPacket(p); - - if (this->mutex != NULL) this->mutex->EndCritical(); } }; @@ -240,9 +224,9 @@ ServerNetworkGameSocketHandler::~ServerNetworkGameSocketHandler() if (_redirect_console_to_client == this->client_id) _redirect_console_to_client = INVALID_CLIENT_ID; OrderBackup::ResetUser(this->client_id); - if (this->savegame != NULL) { + if (this->savegame != nullptr) { this->savegame->Destroy(); - this->savegame = NULL; + this->savegame = nullptr; } } @@ -250,12 +234,12 @@ Packet *ServerNetworkGameSocketHandler::ReceivePacket() { /* Only allow receiving when we have some buffer free; this value * can go negative, but eventually it will become positive again. */ - if (this->receive_limit <= 0) return NULL; + if (this->receive_limit <= 0) return nullptr; /* We can receive a packet, so try that and if needed account for * the amount of received data. */ Packet *p = this->NetworkTCPSocketHandler::ReceivePacket(); - if (p != NULL) this->receive_limit -= p->size; + if (p != nullptr) this->receive_limit -= p->size; return p; } @@ -274,14 +258,13 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::CloseConnection(NetworkRecvSta if (status != NETWORK_RECV_STATUS_CONN_LOST && !this->HasClientQuit() && this->status >= STATUS_AUTHORIZED) { /* We did not receive a leave message from this client... */ char client_name[NETWORK_CLIENT_NAME_LENGTH]; - NetworkClientSocket *new_cs; this->GetClientName(client_name, lastof(client_name)); - NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, NULL, STR_NETWORK_ERROR_CLIENT_CONNECTION_LOST); + NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, nullptr, STR_NETWORK_ERROR_CLIENT_CONNECTION_LOST); /* Inform other clients of this... strange leaving ;) */ - FOR_ALL_CLIENT_SOCKETS(new_cs) { + for (NetworkClientSocket *new_cs : NetworkClientSocket::Iterate()) { if (new_cs->status > STATUS_AUTHORIZED && this != new_cs) { new_cs->SendErrorQuit(this->client_id, NETWORK_ERROR_CONNECTION_LOST); } @@ -326,8 +309,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::CloseConnection(NetworkRecvSta /** Send the packets for the server sockets. */ /* static */ void ServerNetworkGameSocketHandler::Send() { - NetworkClientSocket *cs; - FOR_ALL_CLIENT_SOCKETS(cs) { + for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) { if (cs->writable) { if (cs->SendPackets() != SPS_CLOSED && cs->status == STATUS_MAP) { /* This client is in the middle of a map-send, call the function for that */ @@ -370,22 +352,21 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendCompanyInfo() /* Make a list of all clients per company */ char clients[MAX_COMPANIES][NETWORK_CLIENTS_LENGTH]; - NetworkClientSocket *csi; memset(clients, 0, sizeof(clients)); /* Add the local player (if not dedicated) */ const NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER); - if (ci != NULL && Company::IsValidID(ci->client_playas)) { + if (ci != nullptr && Company::IsValidID(ci->client_playas)) { strecpy(clients[ci->client_playas], ci->client_name, lastof(clients[ci->client_playas])); } - FOR_ALL_CLIENT_SOCKETS(csi) { + for (NetworkClientSocket *csi : NetworkClientSocket::Iterate()) { char client_name[NETWORK_CLIENT_NAME_LENGTH]; ((ServerNetworkGameSocketHandler*)csi)->GetClientName(client_name, lastof(client_name)); ci = csi->GetInfo(); - if (ci != NULL && Company::IsValidID(ci->client_playas)) { + if (ci != nullptr && Company::IsValidID(ci->client_playas)) { if (!StrEmpty(clients[ci->client_playas])) { strecat(clients[ci->client_playas], ", ", lastof(clients[ci->client_playas])); } @@ -396,10 +377,9 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendCompanyInfo() /* Now send the data */ - Company *company; Packet *p; - FOR_ALL_COMPANIES(company) { + for (const Company *company : Company::Iterate()) { p = new Packet(PACKET_SERVER_COMPANY_INFO); p->Send_uint8 (NETWORK_COMPANY_INFO_VERSION); @@ -427,13 +407,15 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendCompanyInfo() /** * Send an error to the client, and close its connection. * @param error The error to disconnect for. + * @param reason In case of kicking a client, specifies the reason for kicking the client. */ -NetworkRecvStatus ServerNetworkGameSocketHandler::SendError(NetworkErrorCode error) +NetworkRecvStatus ServerNetworkGameSocketHandler::SendError(NetworkErrorCode error, const char *reason) { char str[100]; Packet *p = new Packet(PACKET_SERVER_ERROR); p->Send_uint8(error); + if (reason != nullptr) p->Send_string(reason); this->SendPacket(p); StringID strid = GetNetworkErrorMsg(error); @@ -441,16 +423,19 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendError(NetworkErrorCode err /* Only send when the current client was in game */ if (this->status > STATUS_AUTHORIZED) { - NetworkClientSocket *new_cs; char client_name[NETWORK_CLIENT_NAME_LENGTH]; this->GetClientName(client_name, lastof(client_name)); DEBUG(net, 1, "'%s' made an error and has been disconnected. Reason: '%s'", client_name, str); - NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, NULL, strid); + if (error == NETWORK_ERROR_KICKED && reason != nullptr) { + NetworkTextMessage(NETWORK_ACTION_KICKED, CC_DEFAULT, false, client_name, reason, strid); + } else { + NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, nullptr, strid); + } - FOR_ALL_CLIENT_SOCKETS(new_cs) { + for (NetworkClientSocket *new_cs : NetworkClientSocket::Iterate()) { if (new_cs->status > STATUS_AUTHORIZED && new_cs != this) { /* Some errors we filter to a more general error. Clients don't have to know the real * reason a joining failed. */ @@ -477,12 +462,12 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendNewGRFCheck() const GRFConfig *c; uint grf_count = 0; - for (c = _grfconfig; c != NULL; c = c->next) { + for (c = _grfconfig; c != nullptr; c = c->next) { if (!HasBit(c->flags, GCF_STATIC)) grf_count++; } p->Send_uint8 (grf_count); - for (c = _grfconfig; c != NULL; c = c->next) { + for (c = _grfconfig; c != nullptr; c = c->next) { if (!HasBit(c->flags, GCF_STATIC)) this->SendGRFIdentifier(p, &c->ident); } @@ -526,7 +511,6 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendNeedCompanyPassword() NetworkRecvStatus ServerNetworkGameSocketHandler::SendWelcome() { Packet *p; - NetworkClientSocket *new_cs; /* Invalid packet when status is AUTH or higher */ if (this->status >= STATUS_AUTHORIZED) return this->CloseConnection(NETWORK_RECV_STATUS_MALFORMED_PACKET); @@ -544,7 +528,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendWelcome() this->SendPacket(p); /* Transmit info about all the active clients */ - FOR_ALL_CLIENT_SOCKETS(new_cs) { + for (NetworkClientSocket *new_cs : NetworkClientSocket::Iterate()) { if (new_cs != this && new_cs->status > STATUS_AUTHORIZED) { this->SendClientInfo(new_cs->GetInfo()); } @@ -557,11 +541,10 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendWelcome() NetworkRecvStatus ServerNetworkGameSocketHandler::SendWait() { int waiting = 0; - NetworkClientSocket *new_cs; Packet *p; /* Count how many clients are waiting in the queue, in front of you! */ - FOR_ALL_CLIENT_SOCKETS(new_cs) { + for (NetworkClientSocket *new_cs : NetworkClientSocket::Iterate()) { if (new_cs->status != STATUS_MAP_WAIT) continue; if (new_cs->GetInfo()->join_date < this->GetInfo()->join_date || (new_cs->GetInfo()->join_date == this->GetInfo()->join_date && new_cs->client_id < this->client_id)) waiting++; } @@ -621,31 +604,30 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::SendMap() if (last_packet) { /* Done reading, make sure saving is done as well */ this->savegame->Destroy(); - this->savegame = NULL; + this->savegame = nullptr; /* Set the status to DONE_MAP, no we will wait for the client * to send it is ready (maybe that happens like never ;)) */ this->status = STATUS_DONE_MAP; /* Find the best candidate for joining, i.e. the first joiner. */ - NetworkClientSocket *new_cs; - NetworkClientSocket *best = NULL; - FOR_ALL_CLIENT_SOCKETS(new_cs) { + NetworkClientSocket *best = nullptr; + for (NetworkClientSocket *new_cs : NetworkClientSocket::Iterate()) { if (new_cs->status == STATUS_MAP_WAIT) { - if (best == NULL || best->GetInfo()->join_date > new_cs->GetInfo()->join_date || (best->GetInfo()->join_date == new_cs->GetInfo()->join_date && best->client_id > new_cs->client_id)) { + if (best == nullptr || best->GetInfo()->join_date > new_cs->GetInfo()->join_date || (best->GetInfo()->join_date == new_cs->GetInfo()->join_date && best->client_id > new_cs->client_id)) { best = new_cs; } } } /* Is there someone else to join? */ - if (best != NULL) { + if (best != nullptr) { /* Let the first start joining. */ best->status = STATUS_AUTHORIZED; best->SendMap(); /* And update the rest. */ - FOR_ALL_CLIENT_SOCKETS(new_cs) { + for (NetworkClientSocket *new_cs : NetworkClientSocket::Iterate()) { if (new_cs->status == STATUS_MAP_WAIT) new_cs->SendWait(); } } @@ -960,9 +942,9 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_JOIN(Packet *p) this->status = STATUS_NEWGRFS_CHECK; - if (_grfconfig == NULL) { + if (_grfconfig == nullptr) { /* Behave as if we received PACKET_CLIENT_NEWGRFS_CHECKED */ - return this->Receive_CLIENT_NEWGRFS_CHECKED(NULL); + return this->Receive_CLIENT_NEWGRFS_CHECKED(nullptr); } return this->SendNewGRFCheck(); @@ -1017,7 +999,6 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_COMPANY_PASSWOR NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_GETMAP(Packet *p) { - NetworkClientSocket *new_cs; /* The client was never joined.. so this is impossible, right? * Ignore the packet, give the client a warning, and close his connection */ if (this->status < STATUS_AUTHORIZED || this->HasClientQuit()) { @@ -1025,7 +1006,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_GETMAP(Packet * } /* Check if someone else is receiving the map */ - FOR_ALL_CLIENT_SOCKETS(new_cs) { + for (NetworkClientSocket *new_cs : NetworkClientSocket::Iterate()) { if (new_cs->status == STATUS_MAP) { /* Tell the new client to wait */ this->status = STATUS_MAP_WAIT; @@ -1042,11 +1023,10 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_MAP_OK(Packet * /* Client has the map, now start syncing */ if (this->status == STATUS_DONE_MAP && !this->HasClientQuit()) { char client_name[NETWORK_CLIENT_NAME_LENGTH]; - NetworkClientSocket *new_cs; this->GetClientName(client_name, lastof(client_name)); - NetworkTextMessage(NETWORK_ACTION_JOIN, CC_DEFAULT, false, client_name, NULL, this->client_id); + NetworkTextMessage(NETWORK_ACTION_JOIN, CC_DEFAULT, false, client_name, nullptr, this->client_id); /* Mark the client as pre-active, and wait for an ACK * so we know he is done loading and in sync with us */ @@ -1060,7 +1040,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_MAP_OK(Packet * this->last_frame = _frame_counter; this->last_frame_server = _frame_counter; - FOR_ALL_CLIENT_SOCKETS(new_cs) { + for (NetworkClientSocket *new_cs : NetworkClientSocket::Iterate()) { if (new_cs->status > STATUS_AUTHORIZED) { new_cs->SendClientInfo(this->GetInfo()); new_cs->SendJoin(this->client_id); @@ -1103,7 +1083,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_COMMAND(Packet NetworkClientInfo *ci = this->GetInfo(); - if (err != NULL) { + if (err != nullptr) { IConsolePrintF(CC_ERROR, "WARNING: %s from client %d (IP: %s).", err, ci->client_id, this->GetClientIP()); return this->SendError(NETWORK_ERROR_NOT_EXPECTED); } @@ -1152,7 +1132,6 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_ERROR(Packet *p { /* This packets means a client noticed an error and is reporting this * to us. Display the error and report it to the other clients */ - NetworkClientSocket *new_cs; char str[100]; char client_name[NETWORK_CLIENT_NAME_LENGTH]; NetworkErrorCode errorno = (NetworkErrorCode)p->Recv_uint8(); @@ -1169,9 +1148,9 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_ERROR(Packet *p DEBUG(net, 2, "'%s' reported an error and is closing its connection (%s)", client_name, str); - NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, NULL, strid); + NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, nullptr, strid); - FOR_ALL_CLIENT_SOCKETS(new_cs) { + for (NetworkClientSocket *new_cs : NetworkClientSocket::Iterate()) { if (new_cs->status > STATUS_AUTHORIZED) { new_cs->SendErrorQuit(this->client_id, errorno); } @@ -1186,7 +1165,6 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_QUIT(Packet *p) { /* The client wants to leave. Display this and report it to the other * clients. */ - NetworkClientSocket *new_cs; char client_name[NETWORK_CLIENT_NAME_LENGTH]; /* The client was never joined.. thank the client for the packet, but ignore it */ @@ -1196,9 +1174,9 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_QUIT(Packet *p) this->GetClientName(client_name, lastof(client_name)); - NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, NULL, STR_NETWORK_MESSAGE_CLIENT_LEAVING); + NetworkTextMessage(NETWORK_ACTION_LEAVE, CC_DEFAULT, false, client_name, nullptr, STR_NETWORK_MESSAGE_CLIENT_LEAVING); - FOR_ALL_CLIENT_SOCKETS(new_cs) { + for (NetworkClientSocket *new_cs : NetworkClientSocket::Iterate()) { if (new_cs->status > STATUS_AUTHORIZED && new_cs != this) { new_cs->SendQuit(this->client_id); } @@ -1220,7 +1198,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_ACK(Packet *p) /* The client is trying to catch up with the server */ if (this->status == STATUS_PRE_ACTIVE) { - /* The client is not yet catched up? */ + /* The client is not yet caught up? */ if (frame + DAY_TICKS < _frame_counter) return NETWORK_RECV_STATUS_OKAY; /* Now he is! Unpause the game */ @@ -1267,7 +1245,6 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_ACK(Packet *p) */ void NetworkServerSendChat(NetworkAction action, DestType desttype, int dest, const char *msg, ClientID from_id, int64 data, bool from_admin) { - NetworkClientSocket *cs; const NetworkClientInfo *ci, *ci_own, *ci_to; switch (desttype) { @@ -1276,7 +1253,7 @@ void NetworkServerSendChat(NetworkAction action, DestType desttype, int dest, co if ((ClientID)dest == CLIENT_ID_SERVER) { ci = NetworkClientInfo::GetByClientID(from_id); /* Display the text locally, and that is it */ - if (ci != NULL) { + if (ci != nullptr) { NetworkTextMessage(action, GetDrawStringCompanyColour(ci->client_playas), false, ci->client_name, msg, data); if (_settings_client.network.server_admin_chat) { @@ -1285,7 +1262,7 @@ void NetworkServerSendChat(NetworkAction action, DestType desttype, int dest, co } } else { /* Else find the client to send the message to */ - FOR_ALL_CLIENT_SOCKETS(cs) { + for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) { if (cs->client_id == (ClientID)dest) { cs->SendChat(action, from_id, false, msg, data); break; @@ -1298,11 +1275,11 @@ void NetworkServerSendChat(NetworkAction action, DestType desttype, int dest, co if (from_id == CLIENT_ID_SERVER) { ci = NetworkClientInfo::GetByClientID(from_id); ci_to = NetworkClientInfo::GetByClientID((ClientID)dest); - if (ci != NULL && ci_to != NULL) { + if (ci != nullptr && ci_to != nullptr) { NetworkTextMessage(action, GetDrawStringCompanyColour(ci->client_playas), true, ci_to->client_name, msg, data); } } else { - FOR_ALL_CLIENT_SOCKETS(cs) { + for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) { if (cs->client_id == from_id) { cs->SendChat(action, (ClientID)dest, true, msg, data); break; @@ -1315,10 +1292,10 @@ void NetworkServerSendChat(NetworkAction action, DestType desttype, int dest, co /* If this is false, the message is already displayed on the client who sent it. */ bool show_local = true; /* Find all clients that belong to this company */ - ci_to = NULL; - FOR_ALL_CLIENT_SOCKETS(cs) { + ci_to = nullptr; + for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) { ci = cs->GetInfo(); - if (ci != NULL && ci->client_playas == (CompanyID)dest) { + if (ci != nullptr && ci->client_playas == (CompanyID)dest) { cs->SendChat(action, from_id, false, msg, data); if (cs->client_id == from_id) show_local = false; ci_to = ci; // Remember a client that is in the company for company-name @@ -1332,17 +1309,17 @@ void NetworkServerSendChat(NetworkAction action, DestType desttype, int dest, co ci = NetworkClientInfo::GetByClientID(from_id); ci_own = NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER); - if (ci != NULL && ci_own != NULL && ci_own->client_playas == dest) { + if (ci != nullptr && ci_own != nullptr && ci_own->client_playas == dest) { NetworkTextMessage(action, GetDrawStringCompanyColour(ci->client_playas), false, ci->client_name, msg, data); if (from_id == CLIENT_ID_SERVER) show_local = false; ci_to = ci_own; } /* There is no such client */ - if (ci_to == NULL) break; + if (ci_to == nullptr) break; /* Display the message locally (so you know you have sent it) */ - if (ci != NULL && show_local) { + if (ci != nullptr && show_local) { if (from_id == CLIENT_ID_SERVER) { char name[NETWORK_NAME_LENGTH]; StringID str = Company::IsValidID(ci_to->client_playas) ? STR_COMPANY_NAME : STR_NETWORK_SPECTATORS; @@ -1350,7 +1327,7 @@ void NetworkServerSendChat(NetworkAction action, DestType desttype, int dest, co GetString(name, str, lastof(name)); NetworkTextMessage(action, GetDrawStringCompanyColour(ci_own->client_playas), true, name, msg, data); } else { - FOR_ALL_CLIENT_SOCKETS(cs) { + for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) { if (cs->client_id == from_id) { cs->SendChat(action, ci_to->client_id, true, msg, data); } @@ -1364,14 +1341,14 @@ void NetworkServerSendChat(NetworkAction action, DestType desttype, int dest, co FALLTHROUGH; case DESTTYPE_BROADCAST: - FOR_ALL_CLIENT_SOCKETS(cs) { + for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) { cs->SendChat(action, from_id, false, msg, data); } NetworkAdminChat(action, desttype, from_id, msg, data, from_admin); ci = NetworkClientInfo::GetByClientID(from_id); - if (ci != NULL) { + if (ci != nullptr) { NetworkTextMessage(action, GetDrawStringCompanyColour(ci->client_playas), false, ci->client_name, msg, data); } break; @@ -1442,7 +1419,7 @@ NetworkRecvStatus ServerNetworkGameSocketHandler::Receive_CLIENT_SET_NAME(Packet if (this->HasClientQuit()) return NETWORK_RECV_STATUS_CONN_LOST; - if (ci != NULL) { + if (ci != nullptr) { /* Display change */ if (NetworkFindName(client_name, lastof(client_name))) { NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, false, ci->client_name, client_name); @@ -1563,13 +1540,10 @@ void NetworkSocketHandler::SendCompanyInformation(Packet *p, const Company *c, c */ void NetworkPopulateCompanyStats(NetworkCompanyStats *stats) { - const Vehicle *v; - const Station *s; - memset(stats, 0, sizeof(*stats) * MAX_COMPANIES); /* Go through all vehicles and count the type of vehicles */ - FOR_ALL_VEHICLES(v) { + for (const Vehicle *v : Vehicle::Iterate()) { if (!Company::IsValidID(v->owner) || !v->IsPrimaryVehicle()) continue; byte type = 0; switch (v->type) { @@ -1583,7 +1557,7 @@ void NetworkPopulateCompanyStats(NetworkCompanyStats *stats) } /* Go through all stations and count the types of stations */ - FOR_ALL_STATIONS(s) { + for (const Station *s : Station::Iterate()) { if (Company::IsValidID(s->owner)) { NetworkCompanyStats *npi = &stats[s->owner]; @@ -1602,14 +1576,13 @@ void NetworkPopulateCompanyStats(NetworkCompanyStats *stats) */ void NetworkUpdateClientInfo(ClientID client_id) { - NetworkClientSocket *cs; NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id); - if (ci == NULL) return; + if (ci == nullptr) return; DEBUG(desync, 1, "client: %08x; %02x; %02x; %04x", _date, _date_fract, (int)ci->client_playas, client_id); - FOR_ALL_CLIENT_SOCKETS(cs) { + for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) { cs->SendClientInfo(ci); } @@ -1622,7 +1595,20 @@ static void NetworkCheckRestartMap() if (_settings_client.network.restart_game_year != 0 && _cur_year >= _settings_client.network.restart_game_year) { DEBUG(net, 0, "Auto-restarting map. Year %d reached", _cur_year); - StartNewGameWithoutGUI(GENERATE_NEW_SEED); + _settings_newgame.game_creation.generation_seed = GENERATE_NEW_SEED; + switch(_file_to_saveload.abstract_ftype) { + case FT_SAVEGAME: + case FT_SCENARIO: + _switch_mode = SM_LOAD_GAME; + break; + + case FT_HEIGHTMAP: + _switch_mode = SM_START_HEIGHTMAP; + break; + + default: + _switch_mode = SM_NEWGAME; + } } } @@ -1634,8 +1620,6 @@ static void NetworkCheckRestartMap() */ static void NetworkAutoCleanCompanies() { - const NetworkClientInfo *ci; - const Company *c; bool clients_in_company[MAX_COMPANIES]; int vehicles_in_company[MAX_COMPANIES]; @@ -1644,27 +1628,26 @@ static void NetworkAutoCleanCompanies() memset(clients_in_company, 0, sizeof(clients_in_company)); /* Detect the active companies */ - FOR_ALL_CLIENT_INFOS(ci) { + for (const NetworkClientInfo *ci : NetworkClientInfo::Iterate()) { if (Company::IsValidID(ci->client_playas)) clients_in_company[ci->client_playas] = true; } if (!_network_dedicated) { - ci = NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER); + const NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER); if (Company::IsValidID(ci->client_playas)) clients_in_company[ci->client_playas] = true; } if (_settings_client.network.autoclean_novehicles != 0) { memset(vehicles_in_company, 0, sizeof(vehicles_in_company)); - const Vehicle *v; - FOR_ALL_VEHICLES(v) { + for (const Vehicle *v : Vehicle::Iterate()) { if (!Company::IsValidID(v->owner) || !v->IsPrimaryVehicle()) continue; vehicles_in_company[v->owner]++; } } /* Go through all the companies */ - FOR_ALL_COMPANIES(c) { + for (const Company *c : Company::Iterate()) { /* Skip the non-active once */ if (c->is_ai) continue; @@ -1675,7 +1658,7 @@ static void NetworkAutoCleanCompanies() /* Is the company empty for autoclean_unprotected-months, and is there no protection? */ if (_settings_client.network.autoclean_unprotected != 0 && _network_company_states[c->index].months_empty > _settings_client.network.autoclean_unprotected && StrEmpty(_network_company_states[c->index].password)) { /* Shut the company down */ - DoCommandP(0, CCA_DELETE | c->index << 16, CRR_AUTOCLEAN, CMD_COMPANY_CTRL); + DoCommandP(0, CCA_DELETE | c->index << 16 | CRR_AUTOCLEAN << 24, 0, CMD_COMPANY_CTRL); IConsolePrintF(CC_DEFAULT, "Auto-cleaned company #%d with no password", c->index + 1); } /* Is the company empty for autoclean_protected-months, and there is a protection? */ @@ -1689,7 +1672,7 @@ static void NetworkAutoCleanCompanies() /* Is the company empty for autoclean_novehicles-months, and has no vehicles? */ if (_settings_client.network.autoclean_novehicles != 0 && _network_company_states[c->index].months_empty > _settings_client.network.autoclean_novehicles && vehicles_in_company[c->index] == 0) { /* Shut the company down */ - DoCommandP(0, CCA_DELETE | c->index << 16, CRR_AUTOCLEAN, CMD_COMPANY_CTRL); + DoCommandP(0, CCA_DELETE | c->index << 16 | CRR_AUTOCLEAN << 24, 0, CMD_COMPANY_CTRL); IConsolePrintF(CC_DEFAULT, "Auto-cleaned company #%d with no vehicles", c->index + 1); } } else { @@ -1714,10 +1697,8 @@ bool NetworkFindName(char *new_name, const char *last) strecpy(original_name, new_name, lastof(original_name)); while (!found_name) { - const NetworkClientInfo *ci; - found_name = true; - FOR_ALL_CLIENT_INFOS(ci) { + for (const NetworkClientInfo *ci : NetworkClientInfo::Iterate()) { if (strcmp(ci->client_name, new_name) == 0) { /* Name already in use */ found_name = false; @@ -1725,8 +1706,8 @@ bool NetworkFindName(char *new_name, const char *last) } } /* Check if it is the same as the server-name */ - ci = NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER); - if (ci != NULL) { + const NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(CLIENT_ID_SERVER); + if (ci != nullptr) { if (strcmp(ci->client_name, new_name) == 0) found_name = false; // name already in use } @@ -1750,14 +1731,13 @@ bool NetworkFindName(char *new_name, const char *last) */ bool NetworkServerChangeClientName(ClientID client_id, const char *new_name) { - NetworkClientInfo *ci; /* Check if the name's already in use */ - FOR_ALL_CLIENT_INFOS(ci) { + for (NetworkClientInfo *ci : NetworkClientInfo::Iterate()) { if (strcmp(ci->client_name, new_name) == 0) return false; } - ci = NetworkClientInfo::GetByClientID(client_id); - if (ci == NULL) return false; + NetworkClientInfo *ci = NetworkClientInfo::GetByClientID(client_id); + if (ci == nullptr) return false; NetworkTextMessage(NETWORK_ACTION_NAME_CHANGE, CC_DEFAULT, true, ci->client_name, new_name); @@ -1792,7 +1772,7 @@ void NetworkServerSetCompanyPassword(CompanyID company_id, const char *password, static void NetworkHandleCommandQueue(NetworkClientSocket *cs) { CommandPacket *cp; - while ((cp = cs->outgoing_queue.Pop()) != NULL) { + while ((cp = cs->outgoing_queue.Pop()) != nullptr) { cs->SendCommand(cp); free(cp); } @@ -1804,7 +1784,6 @@ static void NetworkHandleCommandQueue(NetworkClientSocket *cs) */ void NetworkServer_Tick(bool send_frame) { - NetworkClientSocket *cs; #ifndef ENABLE_NETWORK_SYNC_EVERY_FRAME bool send_sync = false; #endif @@ -1818,7 +1797,7 @@ void NetworkServer_Tick(bool send_frame) /* Now we are done with the frame, inform the clients that they can * do their frame! */ - FOR_ALL_CLIENT_SOCKETS(cs) { + for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) { /* We allow a number of bytes per frame, but only to the burst amount * to be available for packet receiving at any particular time. */ cs->receive_limit = min(cs->receive_limit + _settings_client.network.bytes_per_frame, @@ -1975,10 +1954,9 @@ void NetworkServerShowStatusToConsole() }; assert_compile(lengthof(stat_str) == NetworkClientSocket::STATUS_END); - NetworkClientSocket *cs; - FOR_ALL_CLIENT_SOCKETS(cs) { + for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) { NetworkClientInfo *ci = cs->GetInfo(); - if (ci == NULL) continue; + if (ci == nullptr) continue; uint lag = NetworkCalculateLag(cs); const char *status; @@ -1995,9 +1973,7 @@ void NetworkServerShowStatusToConsole() */ void NetworkServerSendConfigUpdate() { - NetworkClientSocket *cs; - - FOR_ALL_CLIENT_SOCKETS(cs) { + for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) { if (cs->status >= NetworkClientSocket::STATUS_PRE_ACTIVE) cs->SendConfigUpdate(); } } @@ -2014,8 +1990,7 @@ void NetworkServerUpdateCompanyPassworded(CompanyID company_id, bool passworded) SB(_network_company_passworded, company_id, 1, !!passworded); SetWindowClassesDirty(WC_COMPANY); - NetworkClientSocket *cs; - FOR_ALL_CLIENT_SOCKETS(cs) { + for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) { if (cs->status >= NetworkClientSocket::STATUS_PRE_ACTIVE) cs->SendCompanyUpdate(); } @@ -2070,50 +2045,57 @@ void NetworkServerSendRcon(ClientID client_id, TextColour colour_code, const cha /** * Kick a single client. * @param client_id The client to kick. + * @param reason In case of kicking a client, specifies the reason for kicking the client. */ -void NetworkServerKickClient(ClientID client_id) +void NetworkServerKickClient(ClientID client_id, const char *reason) { if (client_id == CLIENT_ID_SERVER) return; - NetworkClientSocket::GetByClientID(client_id)->SendError(NETWORK_ERROR_KICKED); + NetworkClientSocket::GetByClientID(client_id)->SendError(NETWORK_ERROR_KICKED, reason); } /** * Ban, or kick, everyone joined from the given client's IP. * @param client_id The client to check for. * @param ban Whether to ban or kick. + * @param reason In case of kicking a client, specifies the reason for kicking the client. */ -uint NetworkServerKickOrBanIP(ClientID client_id, bool ban) +uint NetworkServerKickOrBanIP(ClientID client_id, bool ban, const char *reason) { - return NetworkServerKickOrBanIP(NetworkClientSocket::GetByClientID(client_id)->GetClientIP(), ban); + return NetworkServerKickOrBanIP(NetworkClientSocket::GetByClientID(client_id)->GetClientIP(), ban, reason); } /** * Kick or ban someone based on an IP address. * @param ip The IP address/range to ban/kick. * @param ban Whether to ban or just kick. + * @param reason In case of kicking a client, specifies the reason for kicking the client. */ -uint NetworkServerKickOrBanIP(const char *ip, bool ban) +uint NetworkServerKickOrBanIP(const char *ip, bool ban, const char *reason) { /* Add address to ban-list */ if (ban) { bool contains = false; - for (char **iter = _network_ban_list.Begin(); iter != _network_ban_list.End(); iter++) { - if (strcmp(*iter, ip) == 0) { + for (const auto &iter : _network_ban_list) { + if (iter == ip) { contains = true; break; } } - if (!contains) *_network_ban_list.Append() = stredup(ip); + if (!contains) _network_ban_list.emplace_back(ip); } uint n = 0; - /* There can be multiple clients with the same IP, kick them all */ - NetworkClientSocket *cs; - FOR_ALL_CLIENT_SOCKETS(cs) { + /* There can be multiple clients with the same IP, kick them all but don't kill the server, + * or the client doing the rcon. The latter can't be kicked because kicking frees closes + * and subsequently free the connection related instances, which we would be reading from + * and writing to after returning. So we would read or write data from freed memory up till + * the segfault triggers. */ + for (NetworkClientSocket *cs : NetworkClientSocket::Iterate()) { if (cs->client_id == CLIENT_ID_SERVER) continue; - if (cs->client_address.IsInNetmask(const_cast(ip))) { - NetworkServerKickClient(cs->client_id); + if (cs->client_id == _redirect_console_to_client) continue; + if (cs->client_address.IsInNetmask(ip)) { + NetworkServerKickClient(cs->client_id, reason); n++; } } @@ -2128,8 +2110,7 @@ uint NetworkServerKickOrBanIP(const char *ip, bool ban) */ bool NetworkCompanyHasClients(CompanyID company) { - const NetworkClientInfo *ci; - FOR_ALL_CLIENT_INFOS(ci) { + for (const NetworkClientInfo *ci : NetworkClientInfo::Iterate()) { if (ci->client_playas == company) return true; } return false; @@ -2145,7 +2126,7 @@ void ServerNetworkGameSocketHandler::GetClientName(char *client_name, const char { const NetworkClientInfo *ci = this->GetInfo(); - if (ci == NULL || StrEmpty(ci->client_name)) { + if (ci == nullptr || StrEmpty(ci->client_name)) { seprintf(client_name, last, "Client #%4d", this->client_id); } else { strecpy(client_name, ci->client_name, last); @@ -2157,8 +2138,7 @@ void ServerNetworkGameSocketHandler::GetClientName(char *client_name, const char */ void NetworkPrintClients() { - NetworkClientInfo *ci; - FOR_ALL_CLIENT_INFOS(ci) { + for (NetworkClientInfo *ci : NetworkClientInfo::Iterate()) { if (_network_server) { IConsolePrintF(CC_INFO, "Client #%1d name: '%s' company: %1d IP: %s", ci->client_id, @@ -2176,12 +2156,12 @@ void NetworkPrintClients() /** * Perform all the server specific administration of a new company. - * @param c The newly created company; can't be NULL. - * @param ci The client information of the client that made the company; can be NULL. + * @param c The newly created company; can't be nullptr. + * @param ci The client information of the client that made the company; can be nullptr. */ void NetworkServerNewCompany(const Company *c, NetworkClientInfo *ci) { - assert(c != NULL); + assert(c != nullptr); if (!_network_server) return; @@ -2189,22 +2169,20 @@ void NetworkServerNewCompany(const Company *c, NetworkClientInfo *ci) _network_company_states[c->index].password[0] = '\0'; NetworkServerUpdateCompanyPassworded(c->index, false); - if (ci != NULL) { - /* ci is NULL when replaying, or for AIs. In neither case there is a client. */ + if (ci != nullptr) { + /* ci is nullptr when replaying, or for AIs. In neither case there is a client. */ ci->client_playas = c->index; NetworkUpdateClientInfo(ci->client_id); - NetworkSendCommand(0, 0, 0, CMD_RENAME_PRESIDENT, NULL, ci->client_name, c->index); + NetworkSendCommand(0, 0, 0, CMD_RENAME_PRESIDENT, nullptr, ci->client_name, c->index); } /* Announce new company on network. */ NetworkAdminCompanyInfo(c, true); - if (ci != NULL) { - /* ci is NULL when replaying, or for AIs. In neither case there is a client. + if (ci != nullptr) { + /* ci is nullptr when replaying, or for AIs. In neither case there is a client. We need to send Admin port update here so that they first know about the new company and then learn about a possibly joining client (see FS#6025) */ NetworkServerSendChat(NETWORK_ACTION_COMPANY_NEW, DESTTYPE_BROADCAST, 0, "", ci->client_id, c->index + 1); } } - -#endif /* ENABLE_NETWORK */ diff --git a/src/network/network_server.h b/src/network/network_server.h index a52b2c9366..3dfcf5594f 100644 --- a/src/network/network_server.h +++ b/src/network/network_server.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. @@ -12,11 +10,8 @@ #ifndef NETWORK_SERVER_H #define NETWORK_SERVER_H -#ifdef ENABLE_NETWORK - #include "network_internal.h" #include "core/tcp_listen.h" -#include "../thread/thread.h" class ServerNetworkGameSocketHandler; /** Make the code look slightly nicer/simpler. */ @@ -28,22 +23,22 @@ extern NetworkClientSocketPool _networkclientsocket_pool; /** Class for handling the server side of the game connection. */ class ServerNetworkGameSocketHandler : public NetworkClientSocketPool::PoolItem<&_networkclientsocket_pool>, public NetworkGameSocketHandler, public TCPListenHandler { protected: - virtual NetworkRecvStatus Receive_CLIENT_JOIN(Packet *p); - virtual NetworkRecvStatus Receive_CLIENT_COMPANY_INFO(Packet *p); - virtual NetworkRecvStatus Receive_CLIENT_GAME_PASSWORD(Packet *p); - virtual NetworkRecvStatus Receive_CLIENT_COMPANY_PASSWORD(Packet *p); - virtual NetworkRecvStatus Receive_CLIENT_GETMAP(Packet *p); - virtual NetworkRecvStatus Receive_CLIENT_MAP_OK(Packet *p); - virtual NetworkRecvStatus Receive_CLIENT_ACK(Packet *p); - virtual NetworkRecvStatus Receive_CLIENT_COMMAND(Packet *p); - virtual NetworkRecvStatus Receive_CLIENT_CHAT(Packet *p); - virtual NetworkRecvStatus Receive_CLIENT_SET_PASSWORD(Packet *p); - virtual NetworkRecvStatus Receive_CLIENT_SET_NAME(Packet *p); - virtual NetworkRecvStatus Receive_CLIENT_QUIT(Packet *p); - virtual NetworkRecvStatus Receive_CLIENT_ERROR(Packet *p); - virtual NetworkRecvStatus Receive_CLIENT_RCON(Packet *p); - virtual NetworkRecvStatus Receive_CLIENT_NEWGRFS_CHECKED(Packet *p); - virtual NetworkRecvStatus Receive_CLIENT_MOVE(Packet *p); + NetworkRecvStatus Receive_CLIENT_JOIN(Packet *p) override; + NetworkRecvStatus Receive_CLIENT_COMPANY_INFO(Packet *p) override; + NetworkRecvStatus Receive_CLIENT_GAME_PASSWORD(Packet *p) override; + NetworkRecvStatus Receive_CLIENT_COMPANY_PASSWORD(Packet *p) override; + NetworkRecvStatus Receive_CLIENT_GETMAP(Packet *p) override; + NetworkRecvStatus Receive_CLIENT_MAP_OK(Packet *p) override; + NetworkRecvStatus Receive_CLIENT_ACK(Packet *p) override; + NetworkRecvStatus Receive_CLIENT_COMMAND(Packet *p) override; + NetworkRecvStatus Receive_CLIENT_CHAT(Packet *p) override; + NetworkRecvStatus Receive_CLIENT_SET_PASSWORD(Packet *p) override; + NetworkRecvStatus Receive_CLIENT_SET_NAME(Packet *p) override; + NetworkRecvStatus Receive_CLIENT_QUIT(Packet *p) override; + NetworkRecvStatus Receive_CLIENT_ERROR(Packet *p) override; + NetworkRecvStatus Receive_CLIENT_RCON(Packet *p) override; + NetworkRecvStatus Receive_CLIENT_NEWGRFS_CHECKED(Packet *p) override; + NetworkRecvStatus Receive_CLIENT_MOVE(Packet *p) override; NetworkRecvStatus SendCompanyInfo(); NetworkRecvStatus SendNewGRFCheck(); @@ -81,8 +76,8 @@ public: ServerNetworkGameSocketHandler(SOCKET s); ~ServerNetworkGameSocketHandler(); - virtual Packet *ReceivePacket(); - NetworkRecvStatus CloseConnection(NetworkRecvStatus status); + virtual Packet *ReceivePacket() override; + NetworkRecvStatus CloseConnection(NetworkRecvStatus status) override; void GetClientName(char *client_name, const char *last) const; NetworkRecvStatus SendMap(); @@ -94,7 +89,7 @@ public: NetworkRecvStatus SendMove(ClientID client_id, CompanyID company_id); NetworkRecvStatus SendClientInfo(NetworkClientInfo *ci); - NetworkRecvStatus SendError(NetworkErrorCode error); + NetworkRecvStatus SendError(NetworkErrorCode error, const char *reason = nullptr); NetworkRecvStatus SendChat(NetworkAction action, ClientID client_id, bool self_send, const char *msg, int64 data); NetworkRecvStatus SendJoin(ClientID client_id); NetworkRecvStatus SendFrame(); @@ -125,25 +120,4 @@ void NetworkServer_Tick(bool send_frame); void NetworkServerSetCompanyPassword(CompanyID company_id, const char *password, bool already_hashed = true); void NetworkServerUpdateCompanyPassworded(CompanyID company_id, bool passworded); -/** - * Iterate over all the sockets from a given starting point. - * @param var The variable to iterate with. - * @param start The start of the iteration. - */ -#define FOR_ALL_CLIENT_SOCKETS_FROM(var, start) FOR_ALL_ITEMS_FROM(NetworkClientSocket, clientsocket_index, var, start) - -/** - * Iterate over all the sockets. - * @param var The variable to iterate with. - */ -#define FOR_ALL_CLIENT_SOCKETS(var) FOR_ALL_CLIENT_SOCKETS_FROM(var, 0) - -#else /* ENABLE_NETWORK */ -/* Network function stubs when networking is disabled */ - -static inline void NetworkServerMonthlyLoop() {} -static inline void NetworkServerYearlyLoop() {} - -#endif /* ENABLE_NETWORK */ - #endif /* NETWORK_SERVER_H */ diff --git a/src/network/network_type.h b/src/network/network_type.h index 3c390c29be..5f796b83d7 100644 --- a/src/network/network_type.h +++ b/src/network/network_type.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. @@ -14,8 +12,6 @@ #include "core/game.h" -#ifdef ENABLE_NETWORK - /** How many clients can we have */ static const uint MAX_CLIENTS = 255; @@ -40,7 +36,7 @@ enum NetworkVehicleType { }; /** 'Unique' identifier to be given to clients */ -enum ClientID { +enum ClientID : uint32 { INVALID_CLIENT_ID = 0, ///< Client is not part of anything CLIENT_ID_SERVER = 1, ///< Servers always have this ID CLIENT_ID_FIRST = 2, ///< The first client ID @@ -89,6 +85,7 @@ enum DestType { enum NetworkAction { NETWORK_ACTION_JOIN, NETWORK_ACTION_LEAVE, + NETWORK_ACTION_KICKED, NETWORK_ACTION_SERVER_MESSAGE, NETWORK_ACTION_CHAT, NETWORK_ACTION_CHAT_COMPANY, @@ -130,5 +127,4 @@ enum NetworkErrorCode { NETWORK_ERROR_END, }; -#endif /* ENABLE_NETWORK */ #endif /* NETWORK_TYPE_H */ diff --git a/src/network/network_udp.cpp b/src/network/network_udp.cpp index 3fd0dd4853..90b99ec44b 100644 --- a/src/network/network_udp.cpp +++ b/src/network/network_udp.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. @@ -14,8 +12,6 @@ * communication before the game is being joined. */ -#ifdef ENABLE_NETWORK - #include "../stdafx.h" #include "../date_func.h" #include "../map_func.h" @@ -26,18 +22,19 @@ #include "network.h" #include "../core/endian_func.hpp" #include "../company_base.h" -#include "../thread/thread.h" +#include "../thread.h" #include "../rev.h" #include "../newgrf_text.h" #include "../strings_func.h" #include "table/strings.h" +#include #include "core/udp.h" #include "../safeguards.h" /** Mutex for all out threaded udp resolution and such. */ -static ThreadMutex *_network_udp_mutex = ThreadMutex::New(); +static std::mutex _network_udp_mutex; /** Session key to register ourselves to the master server */ static uint64 _session_key = 0; @@ -46,25 +43,9 @@ static const uint32 ADVERTISE_NORMAL_INTERVAL = 15 * 60 * 1000; ///< interval be static const uint32 ADVERTISE_RETRY_INTERVAL = 10 * 1000; ///< re-advertise when no response after this many ms (10 seconds) static const uint32 ADVERTISE_RETRY_TIMES = 3; ///< give up re-advertising after this much failed retries -NetworkUDPSocketHandler *_udp_client_socket = NULL; ///< udp client socket -NetworkUDPSocketHandler *_udp_server_socket = NULL; ///< udp server socket -NetworkUDPSocketHandler *_udp_master_socket = NULL; ///< udp master socket - -/** Simpler wrapper struct for NetworkUDPQueryServerThread */ -struct NetworkUDPQueryServerInfo : NetworkAddress { - bool manually; ///< Did we connect manually or not? - - /** - * Create the structure. - * @param address The address of the server to query. - * @param manually Whether the address was entered manually. - */ - NetworkUDPQueryServerInfo(const NetworkAddress &address, bool manually) : - NetworkAddress(address), - manually(manually) - { - } -}; +NetworkUDPSocketHandler *_udp_client_socket = nullptr; ///< udp client socket +NetworkUDPSocketHandler *_udp_server_socket = nullptr; ///< udp server socket +NetworkUDPSocketHandler *_udp_master_socket = nullptr; ///< udp master socket /** * Helper function doing the actual work for querying the server. @@ -72,33 +53,21 @@ struct NetworkUDPQueryServerInfo : NetworkAddress { * @param needs_mutex Whether we need to acquire locks when sending the packet or not. * @param manually Whether the address was entered manually. */ -static void NetworkUDPQueryServer(NetworkAddress *address, bool needs_mutex, bool manually) +static void DoNetworkUDPQueryServer(NetworkAddress &address, bool needs_mutex, bool manually) { /* Clear item in gamelist */ NetworkGameList *item = CallocT(1); - address->GetAddressAsString(item->info.server_name, lastof(item->info.server_name)); - strecpy(item->info.hostname, address->GetHostname(), lastof(item->info.hostname)); - item->address = *address; + address.GetAddressAsString(item->info.server_name, lastof(item->info.server_name)); + strecpy(item->info.hostname, address.GetHostname(), lastof(item->info.hostname)); + item->address = address; item->manually = manually; NetworkGameListAddItemDelayed(item); - if (needs_mutex) _network_udp_mutex->BeginCritical(); + std::unique_lock lock(_network_udp_mutex, std::defer_lock); + if (needs_mutex) lock.lock(); /* Init the packet */ Packet p(PACKET_UDP_CLIENT_FIND_SERVER); - if (_udp_client_socket != NULL) _udp_client_socket->SendPacket(&p, address); - if (needs_mutex) _network_udp_mutex->EndCritical(); -} - -/** - * Threaded part for resolving the IP of a server and querying it. - * @param pntr the NetworkUDPQueryServerInfo. - */ -static void NetworkUDPQueryServerThread(void *pntr) -{ - NetworkUDPQueryServerInfo *info = (NetworkUDPQueryServerInfo*)pntr; - NetworkUDPQueryServer(info, true, info->manually); - - delete info; + if (_udp_client_socket != nullptr) _udp_client_socket->SendPacket(&p, &address); } /** @@ -108,9 +77,8 @@ static void NetworkUDPQueryServerThread(void *pntr) */ void NetworkUDPQueryServer(NetworkAddress address, bool manually) { - NetworkUDPQueryServerInfo *info = new NetworkUDPQueryServerInfo(address, manually); - if (address.IsResolved() || !ThreadObject::New(NetworkUDPQueryServerThread, info, NULL, "ottd:udp-query")) { - NetworkUDPQueryServerThread(info); + if (address.IsResolved() || !StartNewThread(nullptr, "ottd:udp-query", &DoNetworkUDPQueryServer, std::move(address), true, std::move(manually))) { + DoNetworkUDPQueryServer(address, true, manually); } } @@ -119,8 +87,8 @@ void NetworkUDPQueryServer(NetworkAddress address, bool manually) /** Helper class for connecting to the master server. */ class MasterNetworkUDPSocketHandler : public NetworkUDPSocketHandler { protected: - virtual void Receive_MASTER_ACK_REGISTER(Packet *p, NetworkAddress *client_addr); - virtual void Receive_MASTER_SESSION_KEY(Packet *p, NetworkAddress *client_addr); + void Receive_MASTER_ACK_REGISTER(Packet *p, NetworkAddress *client_addr) override; + void Receive_MASTER_SESSION_KEY(Packet *p, NetworkAddress *client_addr) override; public: /** * Create the socket. @@ -150,9 +118,9 @@ void MasterNetworkUDPSocketHandler::Receive_MASTER_SESSION_KEY(Packet *p, Networ /** Helper class for handling all server side communication. */ class ServerNetworkUDPSocketHandler : public NetworkUDPSocketHandler { protected: - virtual void Receive_CLIENT_FIND_SERVER(Packet *p, NetworkAddress *client_addr); - virtual void Receive_CLIENT_DETAIL_INFO(Packet *p, NetworkAddress *client_addr); - virtual void Receive_CLIENT_GET_NEWGRFS(Packet *p, NetworkAddress *client_addr); + void Receive_CLIENT_FIND_SERVER(Packet *p, NetworkAddress *client_addr) override; + void Receive_CLIENT_DETAIL_INFO(Packet *p, NetworkAddress *client_addr) override; + void Receive_CLIENT_GET_NEWGRFS(Packet *p, NetworkAddress *client_addr) override; public: /** * Create the socket. @@ -230,8 +198,7 @@ void ServerNetworkUDPSocketHandler::Receive_CLIENT_DETAIL_INFO(Packet *p, Networ for (;;) { int free = SEND_MTU - packet.size; - Company *company; - FOR_ALL_COMPANIES(company) { + for (const Company *company : Company::Iterate()) { char company_name[NETWORK_COMPANY_NAME_LENGTH]; SetDParam(0, company->index); GetString(company_name, STR_COMPANY_NAME, company_name + max_cname_length - 1); @@ -246,9 +213,8 @@ void ServerNetworkUDPSocketHandler::Receive_CLIENT_DETAIL_INFO(Packet *p, Networ } } - Company *company; /* Go through all the companies */ - FOR_ALL_COMPANIES(company) { + for (const Company *company : Company::Iterate()) { /* Send the information */ this->SendCompanyInformation(&packet, company, &company_stats[company->index], max_cname_length); } @@ -291,7 +257,7 @@ void ServerNetworkUDPSocketHandler::Receive_CLIENT_GET_NEWGRFS(Packet *p, Networ /* Find the matching GRF file */ f = FindGRFConfig(c.grfid, FGCM_EXACT, c.md5sum); - if (f == NULL) continue; // The GRF is unknown to this server + if (f == nullptr) continue; // The GRF is unknown to this server /* If the reply might exceed the size of the packet, only reply * the current list and do not send the other data. @@ -326,10 +292,10 @@ void ServerNetworkUDPSocketHandler::Receive_CLIENT_GET_NEWGRFS(Packet *p, Networ /** Helper class for handling all client side communication. */ class ClientNetworkUDPSocketHandler : public NetworkUDPSocketHandler { protected: - virtual void Receive_SERVER_RESPONSE(Packet *p, NetworkAddress *client_addr); - virtual void Receive_MASTER_RESPONSE_LIST(Packet *p, NetworkAddress *client_addr); - virtual void Receive_SERVER_NEWGRFS(Packet *p, NetworkAddress *client_addr); - virtual void HandleIncomingNetworkGameInfoGRFConfig(GRFConfig *config); + void Receive_SERVER_RESPONSE(Packet *p, NetworkAddress *client_addr) override; + void Receive_MASTER_RESPONSE_LIST(Packet *p, NetworkAddress *client_addr) override; + void Receive_SERVER_NEWGRFS(Packet *p, NetworkAddress *client_addr) override; + void HandleIncomingNetworkGameInfoGRFConfig(GRFConfig *config) override; public: virtual ~ClientNetworkUDPSocketHandler() {} }; @@ -362,7 +328,7 @@ void ClientNetworkUDPSocketHandler::Receive_SERVER_RESPONSE(Packet *p, NetworkAd const GRFConfig *c; uint in_request_count = 0; - for (c = item->info.grfconfig; c != NULL; c = c->next) { + for (c = item->info.grfconfig; c != nullptr; c = c->next) { if (c->status == GCS_NOT_FOUND) item->info.compatible = false; if (c->status != GCS_NOT_FOUND || strcmp(c->GetName(), UNKNOWN_GRF_NAME_PLACEHOLDER) != 0) continue; in_request[in_request_count] = c; @@ -430,7 +396,7 @@ void ClientNetworkUDPSocketHandler::Receive_MASTER_RESPONSE_LIST(Packet *p, Netw /* Somehow we reached the end of the packet */ if (this->HasClientQuit()) return; - NetworkUDPQueryServer(&addr, false, false); + DoNetworkUDPQueryServer(addr, false, false); } } } @@ -461,7 +427,7 @@ void ClientNetworkUDPSocketHandler::Receive_SERVER_NEWGRFS(Packet *p, NetworkAdd * If it exists and not resolved yet, then name of the fake GRF is * overwritten with the name from the reply. */ GRFTextWrapper *unknown_name = FindUnknownGRFName(c.grfid, c.md5sum, false); - if (unknown_name != NULL && strcmp(GetGRFStringFromGRFText(unknown_name->text), UNKNOWN_GRF_NAME_PLACEHOLDER) == 0) { + if (unknown_name != nullptr && strcmp(GetGRFStringFromGRFText(unknown_name->text), UNKNOWN_GRF_NAME_PLACEHOLDER) == 0) { AddGRFTextToList(&unknown_name->text, name); } } @@ -471,7 +437,7 @@ void ClientNetworkUDPSocketHandler::HandleIncomingNetworkGameInfoGRFConfig(GRFCo { /* Find the matching GRF file */ const GRFConfig *f = FindGRFConfig(config->ident.grfid, FGCM_EXACT, config->ident.md5sum); - if (f == NULL) { + if (f == nullptr) { /* Don't know the GRF, so mark game incompatible and the (possibly) * already resolved name for this GRF (another server has sent the * name of the GRF already */ @@ -497,12 +463,12 @@ void ClientNetworkUDPSocketHandler::HandleIncomingNetworkGameInfoGRFConfig(GRFCo /** Broadcast to all ips */ static void NetworkUDPBroadCast(NetworkUDPSocketHandler *socket) { - for (NetworkAddress *addr = _broadcast_list.Begin(); addr != _broadcast_list.End(); addr++) { + for (NetworkAddress &addr : _broadcast_list) { Packet p(PACKET_UDP_CLIENT_FIND_SERVER); - DEBUG(net, 4, "[udp] broadcasting to %s", addr->GetHostname()); + DEBUG(net, 4, "[udp] broadcasting to %s", addr.GetHostname()); - socket->SendPacket(&p, addr, true, true); + socket->SendPacket(&p, &addr, true, true); } } @@ -536,9 +502,8 @@ void NetworkUDPSearchGame() /** * Thread entry point for de-advertising. - * @param pntr unused. */ -static void NetworkUDPRemoveAdvertiseThread(void *pntr) +static void NetworkUDPRemoveAdvertiseThread() { DEBUG(net, 1, "[udp] removing advertise from master server"); @@ -551,9 +516,8 @@ static void NetworkUDPRemoveAdvertiseThread(void *pntr) p.Send_uint8 (NETWORK_MASTER_SERVER_VERSION); p.Send_uint16(_settings_client.network.server_port); - _network_udp_mutex->BeginCritical(); - if (_udp_master_socket != NULL) _udp_master_socket->SendPacket(&p, &out_addr, true); - _network_udp_mutex->EndCritical(); + std::lock_guard lock(_network_udp_mutex); + if (_udp_master_socket != nullptr) _udp_master_socket->SendPacket(&p, &out_addr, true); } /** @@ -565,16 +529,15 @@ void NetworkUDPRemoveAdvertise(bool blocking) /* Check if we are advertising */ if (!_networking || !_network_server || !_network_udp_server) return; - if (blocking || !ThreadObject::New(NetworkUDPRemoveAdvertiseThread, NULL, NULL, "ottd:udp-advert")) { - NetworkUDPRemoveAdvertiseThread(NULL); + if (blocking || !StartNewThread(nullptr, "ottd:udp-advert", &NetworkUDPRemoveAdvertiseThread)) { + NetworkUDPRemoveAdvertiseThread(); } } /** * Thread entry point for advertising. - * @param pntr unused. */ -static void NetworkUDPAdvertiseThread(void *pntr) +static void NetworkUDPAdvertiseThread() { /* Find somewhere to send */ NetworkAddress out_addr(NETWORK_MASTER_SERVER_HOST, NETWORK_MASTER_SERVER_PORT); @@ -605,9 +568,8 @@ static void NetworkUDPAdvertiseThread(void *pntr) p.Send_uint16(_settings_client.network.server_port); p.Send_uint64(_session_key); - _network_udp_mutex->BeginCritical(); - if (_udp_master_socket != NULL) _udp_master_socket->SendPacket(&p, &out_addr, true); - _network_udp_mutex->EndCritical(); + std::lock_guard lock(_network_udp_mutex); + if (_udp_master_socket != nullptr) _udp_master_socket->SendPacket(&p, &out_addr, true); } /** @@ -648,8 +610,8 @@ void NetworkUDPAdvertise() if (_next_advertisement < _last_advertisement) _next_advertisement = UINT32_MAX; if (_next_retry < _last_advertisement) _next_retry = UINT32_MAX; - if (!ThreadObject::New(NetworkUDPAdvertiseThread, NULL, NULL, "ottd:udp-advert")) { - NetworkUDPAdvertiseThread(NULL); + if (!StartNewThread(nullptr, "ottd:udp-advert", &NetworkUDPAdvertiseThread)) { + NetworkUDPAdvertiseThread(); } } @@ -657,12 +619,12 @@ void NetworkUDPAdvertise() void NetworkUDPInitialize() { /* If not closed, then do it. */ - if (_udp_server_socket != NULL) NetworkUDPClose(); + if (_udp_server_socket != nullptr) NetworkUDPClose(); DEBUG(net, 1, "[udp] initializing listeners"); - assert(_udp_client_socket == NULL && _udp_server_socket == NULL && _udp_master_socket == NULL); + assert(_udp_client_socket == nullptr && _udp_server_socket == nullptr && _udp_master_socket == nullptr); - _network_udp_mutex->BeginCritical(); + std::lock_guard lock(_network_udp_mutex); _udp_client_socket = new ClientNetworkUDPSocketHandler(); @@ -670,29 +632,27 @@ void NetworkUDPInitialize() GetBindAddresses(&server, _settings_client.network.server_port); _udp_server_socket = new ServerNetworkUDPSocketHandler(&server); - server.Clear(); + server.clear(); GetBindAddresses(&server, 0); _udp_master_socket = new MasterNetworkUDPSocketHandler(&server); _network_udp_server = false; _network_udp_broadcast = 0; - _network_udp_mutex->EndCritical(); } /** Close all UDP related stuff. */ void NetworkUDPClose() { - _network_udp_mutex->BeginCritical(); + std::lock_guard lock(_network_udp_mutex); _udp_server_socket->Close(); _udp_master_socket->Close(); _udp_client_socket->Close(); delete _udp_client_socket; delete _udp_server_socket; delete _udp_master_socket; - _udp_client_socket = NULL; - _udp_server_socket = NULL; - _udp_master_socket = NULL; - _network_udp_mutex->EndCritical(); + _udp_client_socket = nullptr; + _udp_server_socket = nullptr; + _udp_master_socket = nullptr; _network_udp_server = false; _network_udp_broadcast = 0; @@ -702,7 +662,7 @@ void NetworkUDPClose() /** Receive the UDP packets. */ void NetworkBackgroundUDPLoop() { - _network_udp_mutex->BeginCritical(); + std::lock_guard lock(_network_udp_mutex); if (_network_udp_server) { _udp_server_socket->ReceivePackets(); @@ -711,8 +671,4 @@ void NetworkBackgroundUDPLoop() _udp_client_socket->ReceivePackets(); if (_network_udp_broadcast > 0) _network_udp_broadcast--; } - - _network_udp_mutex->EndCritical(); } - -#endif /* ENABLE_NETWORK */ diff --git a/src/network/network_udp.h b/src/network/network_udp.h index 3dfd076720..c042bea404 100644 --- a/src/network/network_udp.h +++ b/src/network/network_udp.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. @@ -12,8 +10,6 @@ #ifndef NETWORK_UDP_H #define NETWORK_UDP_H -#ifdef ENABLE_NETWORK - #include "core/address.h" void NetworkUDPInitialize(); @@ -25,6 +21,4 @@ void NetworkUDPRemoveAdvertise(bool blocking); void NetworkUDPClose(); void NetworkBackgroundUDPLoop(); -#endif /* ENABLE_NETWORK */ - #endif /* NETWORK_UDP_H */ diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 1741b73295..e622fad071 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.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. @@ -49,6 +47,7 @@ #include "vehicle_func.h" #include "language.h" #include "vehicle_base.h" +#include "road.h" #include "table/strings.h" #include "table/build_industry.h" @@ -65,7 +64,12 @@ * served as subject to the initial testing of this codec. */ /** List of all loaded GRF files */ -static SmallVector _grf_files; +static std::vector _grf_files; + +const std::vector &GetAllGRFFiles() +{ + return _grf_files; +} /** Miscellaneous GRF features, set by Action 0x0D, parameter 0x9E */ byte _misc_grf_features = 0; @@ -103,7 +107,7 @@ public: byte grf_container_ver; ///< Container format of the current GRF file. /* Kind of return values when processing certain actions */ - int skip_sprites; ///< Number of psuedo sprites to skip before processing the next one. (-1 to skip to end of file) + int skip_sprites; ///< Number of pseudo sprites to skip before processing the next one. (-1 to skip to end of file) /* Currently referenceable spritegroups */ SpriteGroup *spritegroups[MAX_SPRITEGROUP + 1]; @@ -309,6 +313,7 @@ struct GRFTempEngineData { uint16 cargo_allowed; uint16 cargo_disallowed; RailTypeLabel railtypelabel; + 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)? @@ -391,11 +396,10 @@ void CDECL grfmsg(int severity, const char *str, ...) */ static GRFFile *GetFileByGRFID(uint32 grfid) { - const GRFFile * const *end = _grf_files.End(); - for (GRFFile * const *file = _grf_files.Begin(); file != end; file++) { - if ((*file)->grfid == grfid) return *file; + for (GRFFile * const file : _grf_files) { + if (file->grfid == grfid) return file; } - return NULL; + return nullptr; } /** @@ -405,35 +409,34 @@ static GRFFile *GetFileByGRFID(uint32 grfid) */ static GRFFile *GetFileByFilename(const char *filename) { - const GRFFile * const *end = _grf_files.End(); - for (GRFFile * const *file = _grf_files.Begin(); file != end; file++) { - if (strcmp((*file)->filename, filename) == 0) return *file; + for (GRFFile * const file : _grf_files) { + if (strcmp(file->filename, filename) == 0) return file; } - return NULL; + return nullptr; } /** 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 != NULL;) { + for (GRFLabel *l = gf->label; l != nullptr;) { GRFLabel *l2 = l->next; free(l); l = l2; } - gf->label = NULL; + gf->label = nullptr; } /** * Disable a GRF * @param message Error message or STR_NULL. - * @param config GRFConfig to disable, NULL for current. + * @param config GRFConfig to disable, nullptr for current. * @return Error message of the GRF for further customisation. */ -static GRFError *DisableGrf(StringID message = STR_NULL, GRFConfig *config = NULL) +static GRFError *DisableGrf(StringID message = STR_NULL, GRFConfig *config = nullptr) { GRFFile *file; - if (config != NULL) { + if (config != nullptr) { file = GetFileByGRFID(config->ident.grfid); } else { config = _cur.grfconfig; @@ -441,7 +444,7 @@ static GRFError *DisableGrf(StringID message = STR_NULL, GRFConfig *config = NUL } config->status = GCS_DISABLED; - if (file != NULL) ClearTemporaryNewGRFData(file); + if (file != nullptr) ClearTemporaryNewGRFData(file); if (config == _cur.grfconfig) _cur.skip_sprites = -1; if (message != STR_NULL) { @@ -461,7 +464,7 @@ struct StringIDMapping { StringID source; ///< Source StringID (GRF local). StringID *target; ///< Destination for mapping result. }; -typedef SmallVector StringIDMappingVector; +typedef std::vector StringIDMappingVector; static StringIDMappingVector _string_to_grf_mapping; /** @@ -472,10 +475,7 @@ static StringIDMappingVector _string_to_grf_mapping; static void AddStringForMapping(StringID source, StringID *target) { *target = STR_UNDEFINED; - StringIDMapping *item = _string_to_grf_mapping.Append(); - item->grfid = _cur.grffile->grfid; - item->source = source; - item->target = target; + _string_to_grf_mapping.push_back({_cur.grffile->grfid, source, target}); } /** @@ -553,7 +553,7 @@ StringID MapGRFStringID(uint32 grfid, StringID str) { if (IsInsideMM(str, 0xD800, 0xE000)) { /* General text provided by NewGRF. - * In the specs this is called the 0xDCxx range (misc presistent texts), + * In the specs this is called the 0xDCxx range (misc persistent texts), * but we meanwhile extended the range to 0xD800-0xDFFF. * Note: We are not involved in the "persistent" business, since we do not store * any NewGRF strings in savegames. */ @@ -594,7 +594,7 @@ static void SetNewGRFOverride(uint32 source_grfid, uint32 target_grfid) * @param file NewGRF that wants to change the engine. * @param type Vehicle type. * @param internal_id Engine ID inside the NewGRF. - * @param static_access If the engine is not present, return NULL instead of allocating a new engine. (Used for static Action 0x04). + * @param static_access If the engine is not present, return nullptr instead of allocating a new engine. (Used for static Action 0x04). * @return The requested engine. */ static Engine *GetNewEngine(const GRFFile *file, VehicleType type, uint16 internal_id, bool static_access = false) @@ -609,7 +609,7 @@ static Engine *GetNewEngine(const GRFFile *file, VehicleType type, uint16 intern if (override != 0) { scope_grfid = override; const GRFFile *grf_match = GetFileByGRFID(override); - if (grf_match == NULL) { + if (grf_match == nullptr) { grfmsg(5, "Tried mapping from GRFID %x to %x but target is not loaded", BSWAP32(file->grfid), BSWAP32(override)); } else { grfmsg(5, "Mapping from GRFID %x to %x", BSWAP32(file->grfid), BSWAP32(override)); @@ -620,7 +620,7 @@ static Engine *GetNewEngine(const GRFFile *file, VehicleType type, uint16 intern EngineID engine = _engine_mngr.GetID(type, internal_id, scope_grfid); if (engine != INVALID_ENGINE) { Engine *e = Engine::Get(engine); - if (e->grf_prop.grffile == NULL) e->grf_prop.grffile = file; + if (e->grf_prop.grffile == nullptr) e->grf_prop.grffile = file; return e; } } @@ -630,25 +630,25 @@ static Engine *GetNewEngine(const GRFFile *file, VehicleType type, uint16 intern if (engine != INVALID_ENGINE) { Engine *e = Engine::Get(engine); - if (e->grf_prop.grffile == NULL) { + if (e->grf_prop.grffile == nullptr) { e->grf_prop.grffile = file; grfmsg(5, "Replaced engine at index %d for GRFID %x, type %d, index %d", e->index, BSWAP32(file->grfid), type, internal_id); } /* Reserve the engine slot */ if (!static_access) { - EngineIDMapping *eid = _engine_mngr.Get(engine); + EngineIDMapping *eid = _engine_mngr.data() + engine; eid->grfid = scope_grfid; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation } return e; } - if (static_access) return NULL; + if (static_access) return nullptr; if (!Engine::CanAllocateItem()) { grfmsg(0, "Can't allocate any more engines"); - return NULL; + return nullptr; } size_t engine_pool_size = Engine::GetPoolSize(); @@ -658,12 +658,13 @@ static Engine *GetNewEngine(const GRFFile *file, VehicleType type, uint16 intern e->grf_prop.grffile = file; /* Reserve the engine slot */ - assert(_engine_mngr.Length() == e->index); - EngineIDMapping *eid = _engine_mngr.Append(); - eid->type = type; - eid->grfid = scope_grfid; // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation - eid->internal_id = internal_id; - eid->substitute_id = min(internal_id, _engine_counts[type]); // substitute_id == _engine_counts[subtype] means "no substitute" + assert(_engine_mngr.size() == e->index); + _engine_mngr.push_back({ + scope_grfid, // Note: this is INVALID_GRFID if dynamic_engines is disabled, so no reservation + internal_id, + type, + static_cast(min(internal_id, _engine_counts[type])) // substitute_id == _engine_counts[subtype] means "no substitute" + }); if (engine_pool_size != Engine::GetPoolSize()) { /* Resize temporary engine data ... */ @@ -739,7 +740,7 @@ static void MapSpriteMappingRecolour(PalSpriteID *grf_sprite) * @param[out] max_palette_offset Optionally returns the number of sprites in the spriteset of the palette. (0 if no spritset) * @return Read TileLayoutFlags. */ -static TileLayoutFlags ReadSpriteLayoutSprite(ByteReader *buf, bool read_flags, bool invert_action1_flag, bool use_cur_spritesets, int feature, PalSpriteID *grf_sprite, uint16 *max_sprite_offset = NULL, uint16 *max_palette_offset = NULL) +static TileLayoutFlags ReadSpriteLayoutSprite(ByteReader *buf, bool read_flags, bool invert_action1_flag, bool use_cur_spritesets, int feature, PalSpriteID *grf_sprite, uint16 *max_sprite_offset = nullptr, uint16 *max_palette_offset = nullptr) { grf_sprite->sprite = buf->ReadWord(); grf_sprite->pal = buf->ReadWord(); @@ -758,7 +759,7 @@ static TileLayoutFlags ReadSpriteLayoutSprite(ByteReader *buf, bool read_flags, grf_sprite->pal = PAL_NONE; } else { SpriteID sprite = use_cur_spritesets ? _cur.GetSprite(feature, index) : index; - if (max_sprite_offset != NULL) *max_sprite_offset = use_cur_spritesets ? _cur.GetNumEnts(feature, index) : UINT16_MAX; + if (max_sprite_offset != nullptr) *max_sprite_offset = use_cur_spritesets ? _cur.GetNumEnts(feature, index) : UINT16_MAX; SB(grf_sprite->sprite, 0, SPRITE_WIDTH, sprite); SetBit(grf_sprite->sprite, SPRITE_MODIFIER_CUSTOM_SPRITE); } @@ -776,7 +777,7 @@ static TileLayoutFlags ReadSpriteLayoutSprite(ByteReader *buf, bool read_flags, grf_sprite->pal = PAL_NONE; } else { SpriteID sprite = use_cur_spritesets ? _cur.GetSprite(feature, index) : index; - if (max_palette_offset != NULL) *max_palette_offset = use_cur_spritesets ? _cur.GetNumEnts(feature, index) : UINT16_MAX; + if (max_palette_offset != nullptr) *max_palette_offset = use_cur_spritesets ? _cur.GetNumEnts(feature, index) : UINT16_MAX; SB(grf_sprite->pal, 0, SPRITE_WIDTH, sprite); SetBit(grf_sprite->pal, SPRITE_MODIFIER_CUSTOM_SPRITE); } @@ -801,7 +802,7 @@ static void ReadSpriteLayoutRegisters(ByteReader *buf, TileLayoutFlags flags, bo { if (!(flags & TLF_DRAWING_FLAGS)) return; - if (dts->registers == NULL) dts->AllocateRegisters(); + if (dts->registers == nullptr) dts->AllocateRegisters(); TileLayoutRegisters ®s = const_cast(dts->registers[index]); regs.flags = flags & TLF_DRAWING_FLAGS; @@ -845,7 +846,7 @@ static void ReadSpriteLayoutRegisters(ByteReader *buf, TileLayoutFlags flags, bo * @param num_building_sprites Number of building sprites to read * @param use_cur_spritesets Whether to use currently referenceable action 1 sets. * @param feature GrfSpecFeature to use spritesets from. - * @param allow_var10 Whether the spritelayout may specifiy var10 values for resolving multiple action-1-2-3 chains + * @param allow_var10 Whether the spritelayout may specify var10 values for resolving multiple action-1-2-3 chains * @param no_z_position Whether bounding boxes have no Z offset * @param dts Layout container to output into * @return True on error (GRF was disabled). @@ -928,9 +929,9 @@ static bool ReadSpriteLayout(ByteReader *buf, uint num_building_sprites, bool us /* When the Action1 sets are unknown, everything should be 0 (no spriteset usage) or UINT16_MAX (some spriteset usage) */ assert(use_cur_spritesets || (is_consistent && (dts->consistent_max_offset == 0 || dts->consistent_max_offset == UINT16_MAX))); - if (!is_consistent || dts->registers != NULL) { + if (!is_consistent || dts->registers != nullptr) { dts->consistent_max_offset = 0; - if (dts->registers == NULL) dts->AllocateRegisters(); + if (dts->registers == nullptr) dts->AllocateRegisters(); for (uint i = 0; i < num_building_sprites + 1; i++) { TileLayoutRegisters ®s = const_cast(dts->registers[i]); @@ -1049,7 +1050,7 @@ static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop for (int i = 0; i < numinfo; i++) { Engine *e = GetNewEngine(_cur.grffile, VEH_TRAIN, engine + i); - if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles + if (e == nullptr) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles EngineInfo *ei = &e->info; RailVehicleInfo *rvi = &e->u.rail; @@ -1058,7 +1059,7 @@ static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop case 0x05: { // Track type uint8 tracktype = buf->ReadByte(); - if (tracktype < _cur.grffile->railtype_list.Length()) { + if (tracktype < _cur.grffile->railtype_list.size()) { _gted[e->index].railtypelabel = _cur.grffile->railtype_list[tracktype]; break; } @@ -1200,7 +1201,7 @@ static ChangeInfoResult RailVehicleChangeInfo(uint engine, int numinfo, int prop break; } - if (_cur.grffile->railtype_list.Length() == 0) { + if (_cur.grffile->railtype_list.size() == 0) { /* Use traction type to select between normal and electrified * rail only when no translation list is in place. */ if (_gted[e->index].railtypelabel == RAILTYPE_RAIL_LABEL && engclass >= EC_ELECTRIC) _gted[e->index].railtypelabel = RAILTYPE_ELECTRIC_LABEL; @@ -1343,12 +1344,18 @@ static ChangeInfoResult RoadVehicleChangeInfo(uint engine, int numinfo, int prop for (int i = 0; i < numinfo; i++) { Engine *e = GetNewEngine(_cur.grffile, VEH_ROAD, engine + i); - if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles + if (e == nullptr) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles EngineInfo *ei = &e->info; RoadVehicleInfo *rvi = &e->u.road; switch (prop) { + case 0x05: // Road/tram type + /* RoadTypeLabel is looked up later after the engine's road/tram + * flag is set, however 0 means the value has not been set. */ + _gted[e->index].roadtramtype = buf->ReadByte() + 1; + break; + case 0x08: // Speed (1 unit is 0.5 kmh) rvi->max_speed = buf->ReadByte(); break; @@ -1531,7 +1538,7 @@ static ChangeInfoResult ShipVehicleChangeInfo(uint engine, int numinfo, int prop for (int i = 0; i < numinfo; i++) { Engine *e = GetNewEngine(_cur.grffile, VEH_SHIP, engine + i); - if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles + if (e == nullptr) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles EngineInfo *ei = &e->info; ShipVehicleInfo *svi = &e->u.ship; @@ -1703,7 +1710,7 @@ static ChangeInfoResult AircraftVehicleChangeInfo(uint engine, int numinfo, int for (int i = 0; i < numinfo; i++) { Engine *e = GetNewEngine(_cur.grffile, VEH_AIRCRAFT, engine + i); - if (e == NULL) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles + if (e == nullptr) return CIR_INVALID_ID; // No engine could be allocated, so neither can any next vehicles EngineInfo *ei = &e->info; AircraftVehicleInfo *avi = &e->u.air; @@ -1861,13 +1868,13 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, Byte } /* Allocate station specs if necessary */ - if (_cur.grffile->stations == NULL) _cur.grffile->stations = CallocT(NUM_STATIONS_PER_GRF); + if (_cur.grffile->stations == nullptr) _cur.grffile->stations = CallocT(NUM_STATIONS_PER_GRF); for (int i = 0; i < numinfo; i++) { StationSpec *statspec = _cur.grffile->stations[stid + i]; /* Check that the station we are modifying is defined. */ - if (statspec == NULL && prop != 0x08) { + if (statspec == nullptr && prop != 0x08) { grfmsg(2, "StationChangeInfo: Attempt to modify undefined station %u, ignoring", stid + i); return CIR_INVALID_ID; } @@ -1877,7 +1884,7 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, Byte StationSpec **spec = &_cur.grffile->stations[stid + i]; /* Property 0x08 is special; it is where the station is allocated */ - if (*spec == NULL) *spec = CallocT(1); + if (*spec == nullptr) *spec = CallocT(1); /* Swap classid because we read it in BE meaning WAYP or DFLT */ uint32 classid = buf->ReadDWord(); @@ -1905,26 +1912,27 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, Byte /* On error, bail out immediately. Temporary GRF data was already freed */ if (_cur.skip_sprites < 0) return CIR_DISABLED; - static SmallVector tmp_layout; - tmp_layout.Clear(); + static std::vector tmp_layout; + tmp_layout.clear(); for (;;) { /* no relative bounding box support */ - DrawTileSeqStruct *dtss = tmp_layout.Append(); - MemSetT(dtss, 0); + /*C++17: DrawTileSeqStruct &dtss = */ tmp_layout.emplace_back(); + DrawTileSeqStruct &dtss = tmp_layout.back(); + MemSetT(&dtss, 0); - dtss->delta_x = buf->ReadByte(); - if (dtss->IsTerminator()) break; - dtss->delta_y = buf->ReadByte(); - dtss->delta_z = buf->ReadByte(); - dtss->size_x = buf->ReadByte(); - dtss->size_y = buf->ReadByte(); - dtss->size_z = buf->ReadByte(); + dtss.delta_x = buf->ReadByte(); + if (dtss.IsTerminator()) break; + dtss.delta_y = buf->ReadByte(); + dtss.delta_z = buf->ReadByte(); + dtss.size_x = buf->ReadByte(); + dtss.size_y = buf->ReadByte(); + dtss.size_z = buf->ReadByte(); - ReadSpriteLayoutSprite(buf, false, true, false, GSF_STATIONS, &dtss->image); + ReadSpriteLayoutSprite(buf, false, true, false, GSF_STATIONS, &dtss.image); /* On error, bail out immediately. Temporary GRF data was already freed */ if (_cur.skip_sprites < 0) return CIR_DISABLED; } - dts->Clone(tmp_layout.Begin()); + dts->Clone(tmp_layout.data()); } break; @@ -1932,7 +1940,7 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, Byte byte srcid = buf->ReadByte(); const StationSpec *srcstatspec = _cur.grffile->stations[srcid]; - if (srcstatspec == NULL) { + if (srcstatspec == nullptr) { grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy sprite layout to %u.", srcid, stid + i); continue; } @@ -1984,7 +1992,7 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, Byte if (number > statspec->platforms[l]) { statspec->layouts[l] = ReallocT(statspec->layouts[l], number); - /* We expect NULL being 0 here, but C99 guarantees that. */ + /* We expect nullptr being 0 here, but C99 guarantees that. */ memset(statspec->layouts[l] + statspec->platforms[l], 0, (number - statspec->platforms[l]) * sizeof(**statspec->layouts)); @@ -2015,7 +2023,7 @@ static ChangeInfoResult StationChangeInfo(uint stid, int numinfo, int prop, Byte byte srcid = buf->ReadByte(); const StationSpec *srcstatspec = _cur.grffile->stations[srcid]; - if (srcstatspec == NULL) { + if (srcstatspec == nullptr) { grfmsg(1, "StationChangeInfo: Station %u is not defined, cannot copy tile layout to %u.", srcid, stid + i); continue; } @@ -2177,7 +2185,7 @@ static ChangeInfoResult BridgeChangeInfo(uint brid, int numinfo, int prop, ByteR byte tableid = buf->ReadByte(); byte numtables = buf->ReadByte(); - if (bridge->sprite_table == NULL) { + if (bridge->sprite_table == nullptr) { /* Allocate memory for sprite table pointers and zero out */ bridge->sprite_table = CallocT(7); } @@ -2189,7 +2197,7 @@ static ChangeInfoResult BridgeChangeInfo(uint brid, int numinfo, int prop, ByteR continue; } - if (bridge->sprite_table[tableid] == NULL) { + if (bridge->sprite_table[tableid] == nullptr) { bridge->sprite_table[tableid] = MallocT(32); } @@ -2323,14 +2331,14 @@ static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, Byt } /* Allocate house specs if they haven't been allocated already. */ - if (_cur.grffile->housespec == NULL) { + if (_cur.grffile->housespec == nullptr) { _cur.grffile->housespec = CallocT(NUM_HOUSES_PER_GRF); } for (int i = 0; i < numinfo; i++) { HouseSpec *housespec = _cur.grffile->housespec[hid + i]; - if (prop != 0x08 && housespec == NULL) { + if (prop != 0x08 && housespec == nullptr) { /* If the house property 08 is not yet set, ignore this property */ ChangeInfoResult cir = IgnoreTownHouseProperty(prop, buf); if (cir > ret) ret = cir; @@ -2354,7 +2362,7 @@ static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, Byt } /* Allocate space for this house. */ - if (*house == NULL) *house = CallocT(1); + if (*house == nullptr) *house = CallocT(1); housespec = *house; @@ -2565,13 +2573,13 @@ static ChangeInfoResult TownHouseChangeInfo(uint hid, int numinfo, int prop, Byt * Get the language map associated with a given NewGRF and language. * @param grfid The NewGRF to get the map for. * @param language_id The (NewGRF) language ID to get the map for. - * @return The LanguageMap, or NULL if it couldn't be found. + * @return The LanguageMap, or nullptr if it couldn't be found. */ /* static */ const LanguageMap *LanguageMap::GetLanguageMap(uint32 grfid, uint8 language_id) { /* LanguageID "MAX_LANG", i.e. 7F is any. This language can't have a gender/case mapping, but has to be handled gracefully. */ const GRFFile *grffile = GetFileByGRFID(grfid); - return (grffile != NULL && grffile->language_map != NULL && language_id < MAX_LANG) ? &grffile->language_map[language_id] : NULL; + return (grffile != nullptr && grffile->language_map != nullptr && language_id < MAX_LANG) ? &grffile->language_map[language_id] : nullptr; } /** @@ -2591,10 +2599,10 @@ static ChangeInfoResult LoadTranslationTable(uint gvid, int numinfo, ByteReader return CIR_INVALID_ID; } - translation_table.Clear(); + translation_table.clear(); for (int i = 0; i < numinfo; i++) { uint32 item = buf->ReadDWord(); - *translation_table.Append() = BSWAP32(item); + translation_table.push_back(BSWAP32(item)); } return CIR_SUCCESS; @@ -2618,6 +2626,12 @@ static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, By case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes) return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->railtype_list, "Rail type"); + case 0x16: // Road type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes) + return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->roadtype_list, "Road type"); + + case 0x17: // Tram type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes) + return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->tramtype_list, "Tram type"); + default: break; } @@ -2754,8 +2768,8 @@ static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, By case 0x14: // Case translation table case 0x15: { // Plural form translation uint curidx = gvid + i; // The current index, i.e. language. - const LanguageMetadata *lang = curidx < MAX_LANG ? GetLanguage(curidx) : NULL; - if (lang == NULL) { + const LanguageMetadata *lang = curidx < MAX_LANG ? GetLanguage(curidx) : nullptr; + if (lang == nullptr) { grfmsg(1, "GlobalVarChangeInfo: Language %d is not known, ignoring", curidx); /* Skip over the data. */ if (prop == 0x15) { @@ -2768,7 +2782,7 @@ static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, By break; } - if (_cur.grffile->language_map == NULL) _cur.grffile->language_map = new LanguageMap[MAX_LANG]; + if (_cur.grffile->language_map == nullptr) _cur.grffile->language_map = new LanguageMap[MAX_LANG]; if (prop == 0x15) { uint plural_form = buf->ReadByte(); @@ -2799,14 +2813,14 @@ static ChangeInfoResult GlobalVarChangeInfo(uint gvid, int numinfo, int prop, By if (map.openttd_id >= MAX_NUM_GENDERS) { grfmsg(1, "GlobalVarChangeInfo: Gender name %s is not known, ignoring", name); } else { - *_cur.grffile->language_map[curidx].gender_map.Append() = map; + _cur.grffile->language_map[curidx].gender_map.push_back(map); } } else { map.openttd_id = lang->GetCaseIndex(name); if (map.openttd_id >= MAX_NUM_CASES) { grfmsg(1, "GlobalVarChangeInfo: Case name %s is not known, ignoring", name); } else { - *_cur.grffile->language_map[curidx].case_map.Append() = map; + _cur.grffile->language_map[curidx].case_map.push_back(map); } } newgrf_id = buf->ReadByte(); @@ -2833,6 +2847,12 @@ static ChangeInfoResult GlobalVarReserveInfo(uint gvid, int numinfo, int prop, B case 0x12: // Rail type translation table; loading during both reservation and activation stage (in case it is selected depending on defined railtypes) return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->railtype_list, "Rail type"); + case 0x16: // Road type translation table; loading during both reservation and activation stage (in case it is selected depending on defined roadtypes) + return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->roadtype_list, "Road type"); + + case 0x17: // Tram type translation table; loading during both reservation and activation stage (in case it is selected depending on defined tramtypes) + return LoadTranslationTable(gvid, numinfo, buf, _cur.grffile->tramtype_list, "Tram type"); + default: break; } @@ -3138,14 +3158,14 @@ static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int pr } /* Allocate industry tile specs if they haven't been allocated already. */ - if (_cur.grffile->indtspec == NULL) { + if (_cur.grffile->indtspec == nullptr) { _cur.grffile->indtspec = CallocT(NUM_INDUSTRYTILES_PER_GRF); } for (int i = 0; i < numinfo; i++) { IndustryTileSpec *tsp = _cur.grffile->indtspec[indtid + i]; - if (prop != 0x08 && tsp == NULL) { + if (prop != 0x08 && tsp == nullptr) { ChangeInfoResult cir = IgnoreIndustryTileProperty(prop, buf); if (cir > ret) ret = cir; continue; @@ -3163,7 +3183,7 @@ static ChangeInfoResult IndustrytilesChangeInfo(uint indtid, int numinfo, int pr } /* Allocate space for this industry. */ - if (*tilespec == NULL) { + if (*tilespec == nullptr) { *tilespec = CallocT(1); tsp = *tilespec; @@ -3354,13 +3374,13 @@ static ChangeInfoResult IgnoreIndustryProperty(int prop, ByteReader *buf) /** * Validate the industry layout; e.g. to prevent duplicate tiles. * @param layout The layout to check. - * @param size The size of the layout. * @return True if the layout is deemed valid. */ -static bool ValidateIndustryLayout(const IndustryTileTable *layout, int size) +static bool ValidateIndustryLayout(const IndustryTileLayout &layout) { - for (int i = 0; i < size - 1; i++) { - for (int j = i + 1; j < size; j++) { + const size_t size = layout.size(); + for (size_t i = 0; i < size - 1; i++) { + for (size_t j = i + 1; j < size; j++) { if (layout[i].ti.x == layout[j].ti.x && layout[i].ti.y == layout[j].ti.y) { return false; @@ -3370,20 +3390,6 @@ static bool ValidateIndustryLayout(const IndustryTileTable *layout, int size) return true; } -/** Clean the tile table of the IndustrySpec if it's needed. */ -static void CleanIndustryTileTable(IndustrySpec *ind) -{ - if (HasBit(ind->cleanup_flag, CLEAN_TILELAYOUT) && ind->table != NULL) { - for (int j = 0; j < ind->num_table; j++) { - /* remove the individual layouts */ - free(ind->table[j]); - } - /* remove the layouts pointers */ - free(ind->table); - ind->table = NULL; - } -} - /** * Define properties for industries * @param indid Local ID of the industry. @@ -3402,14 +3408,14 @@ static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, } /* Allocate industry specs if they haven't been allocated already. */ - if (_cur.grffile->industryspec == NULL) { + if (_cur.grffile->industryspec == nullptr) { _cur.grffile->industryspec = CallocT(NUM_INDUSTRYTYPES_PER_GRF); } for (int i = 0; i < numinfo; i++) { IndustrySpec *indsp = _cur.grffile->industryspec[indid + i]; - if (prop != 0x08 && indsp == NULL) { + if (prop != 0x08 && indsp == nullptr) { ChangeInfoResult cir = IgnoreIndustryProperty(prop, buf); if (cir > ret) ret = cir; continue; @@ -3434,16 +3440,16 @@ static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, /* Allocate space for this industry. * Only need to do it once. If ever it is called again, it should not * do anything */ - if (*indspec == NULL) { - *indspec = CallocT(1); + if (*indspec == nullptr) { + *indspec = new IndustrySpec; indsp = *indspec; - memcpy(indsp, &_origin_industry_specs[subs_id], sizeof(_industry_specs[subs_id])); + *indsp = _origin_industry_specs[subs_id]; indsp->enabled = true; indsp->grf_prop.local_id = indid + i; indsp->grf_prop.subst_id = subs_id; indsp->grf_prop.grffile = _cur.grffile; - /* If the grf industry needs to check its surounding upon creation, it should + /* If the grf industry needs to check its surrounding upon creation, it should * rely on callbacks, not on the original placement functions */ indsp->check_proc = CHECK_NOTHING; } @@ -3464,112 +3470,101 @@ static ChangeInfoResult IndustriesChangeInfo(uint indid, int numinfo, int prop, } case 0x0A: { // Set industry layout(s) - byte new_num_layouts = buf->ReadByte(); // Number of layaouts - /* We read the total size in bytes, but we can't rely on the - * newgrf to provide a sane value. First assume the value is - * sane but later on we make sure we enlarge the array if the - * newgrf contains more data. Each tile uses either 3 or 5 - * bytes, so to play it safe we assume 3. */ - uint32 def_num_tiles = buf->ReadDWord() / 3 + 1; - IndustryTileTable **tile_table = CallocT(new_num_layouts); // Table with tiles to compose an industry - IndustryTileTable *itt = CallocT(def_num_tiles); // Temporary array to read the tile layouts from the GRF - uint size; - const IndustryTileTable *copy_from; + byte new_num_layouts = buf->ReadByte(); + uint32 definition_size = buf->ReadDWord(); + uint32 bytes_read = 0; + std::vector new_layouts; + IndustryTileLayout layout; - try { - for (byte j = 0; j < new_num_layouts; j++) { - for (uint k = 0;; k++) { - if (k >= def_num_tiles) { - grfmsg(3, "IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid); - /* Size reported by newgrf was not big enough so enlarge the array. */ - def_num_tiles *= 2; - itt = ReallocT(itt, def_num_tiles); - } + for (byte j = 0; j < new_num_layouts; j++) { + layout.clear(); - itt[k].ti.x = buf->ReadByte(); // Offsets from northermost tile - - if (itt[k].ti.x == 0xFE && k == 0) { - /* This means we have to borrow the layout from an old industry */ - IndustryType type = buf->ReadByte(); // industry holding required layout - byte laynbr = buf->ReadByte(); // layout number to borrow - - copy_from = _origin_industry_specs[type].table[laynbr]; - for (size = 1;; size++) { - if (copy_from[size - 1].ti.x == -0x80 && copy_from[size - 1].ti.y == 0) break; - } - break; - } - - itt[k].ti.y = buf->ReadByte(); // Or table definition finalisation - - if (itt[k].ti.x == 0 && itt[k].ti.y == 0x80) { - /* Not the same terminator. The one we are using is rather - x = -80, y = x . So, adjust it. */ - itt[k].ti.x = -0x80; - itt[k].ti.y = 0; - itt[k].gfx = 0; - - size = k + 1; - copy_from = itt; - break; - } - - itt[k].gfx = buf->ReadByte(); - - if (itt[k].gfx == 0xFE) { - /* Use a new tile from this GRF */ - int local_tile_id = buf->ReadWord(); - - /* Read the ID from the _industile_mngr. */ - int tempid = _industile_mngr.GetID(local_tile_id, _cur.grffile->grfid); - - if (tempid == INVALID_INDUSTRYTILE) { - grfmsg(2, "IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id, indid); - } else { - /* Declared as been valid, can be used */ - itt[k].gfx = tempid; - } - } else if (itt[k].gfx == 0xFF) { - itt[k].ti.x = (int8)GB(itt[k].ti.x, 0, 8); - itt[k].ti.y = (int8)GB(itt[k].ti.y, 0, 8); - - /* When there were only 256x256 maps, TileIndex was a uint16 and - * itt[k].ti was just a TileIndexDiff that was added to it. - * As such negative "x" values were shifted into the "y" position. - * x = -1, y = 1 -> x = 255, y = 0 - * Since GRF version 8 the position is interpreted as pair of independent int8. - * For GRF version < 8 we need to emulate the old shifting behaviour. - */ - if (_cur.grffile->grf_version < 8 && itt[k].ti.x < 0) itt[k].ti.y += 1; - } + for (uint k = 0;; k++) { + if (bytes_read >= definition_size) { + grfmsg(3, "IndustriesChangeInfo: Incorrect size for industry tile layout definition for industry %u.", indid); + /* Avoid warning twice */ + definition_size = UINT32_MAX; } - if (!ValidateIndustryLayout(copy_from, size)) { - /* The industry layout was not valid, so skip this one. */ - grfmsg(1, "IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid); - new_num_layouts--; - j--; - } else { - tile_table[j] = CallocT(size); - memcpy(tile_table[j], copy_from, sizeof(*copy_from) * size); + layout.push_back(IndustryTileLayoutTile{}); + IndustryTileLayoutTile &it = layout.back(); + + it.ti.x = buf->ReadByte(); // Offsets from northermost tile + ++bytes_read; + + if (it.ti.x == 0xFE && k == 0) { + /* This means we have to borrow the layout from an old industry */ + IndustryType type = buf->ReadByte(); + byte laynbr = buf->ReadByte(); + bytes_read += 2; + + if (type >= lengthof(_origin_industry_specs)) { + grfmsg(1, "IndustriesChangeInfo: Invalid original industry number for layout import, industry %u", indid); + DisableGrf(STR_NEWGRF_ERROR_INVALID_ID); + return CIR_DISABLED; + } + if (laynbr >= _origin_industry_specs[type].layouts.size()) { + grfmsg(1, "IndustriesChangeInfo: Invalid original industry layout index for layout import, industry %u", indid); + DisableGrf(STR_NEWGRF_ERROR_INVALID_ID); + return CIR_DISABLED; + } + layout = _origin_industry_specs[type].layouts[laynbr]; + break; + } + + it.ti.y = buf->ReadByte(); // Or table definition finalisation + ++bytes_read; + + if (it.ti.x == 0 && it.ti.y == 0x80) { + /* Terminator, remove and finish up */ + layout.pop_back(); + break; + } + + it.gfx = buf->ReadByte(); + ++bytes_read; + + if (it.gfx == 0xFE) { + /* Use a new tile from this GRF */ + int local_tile_id = buf->ReadWord(); + bytes_read += 2; + + /* Read the ID from the _industile_mngr. */ + int tempid = _industile_mngr.GetID(local_tile_id, _cur.grffile->grfid); + + if (tempid == INVALID_INDUSTRYTILE) { + grfmsg(2, "IndustriesChangeInfo: Attempt to use industry tile %u with industry id %u, not yet defined. Ignoring.", local_tile_id, indid); + } else { + /* Declared as been valid, can be used */ + it.gfx = tempid; + } + } else if (it.gfx == 0xFF) { + it.ti.x = (int8)GB(it.ti.x, 0, 8); + it.ti.y = (int8)GB(it.ti.y, 0, 8); + + /* When there were only 256x256 maps, TileIndex was a uint16 and + * it.ti was just a TileIndexDiff that was added to it. + * As such negative "x" values were shifted into the "y" position. + * x = -1, y = 1 -> x = 255, y = 0 + * Since GRF version 8 the position is interpreted as pair of independent int8. + * For GRF version < 8 we need to emulate the old shifting behaviour. + */ + if (_cur.grffile->grf_version < 8 && it.ti.x < 0) it.ti.y += 1; } } - } catch (...) { - for (int i = 0; i < new_num_layouts; i++) { - free(tile_table[i]); + + if (!ValidateIndustryLayout(layout)) { + /* The industry layout was not valid, so skip this one. */ + grfmsg(1, "IndustriesChangeInfo: Invalid industry layout for industry id %u. Ignoring", indid); + new_num_layouts--; + j--; + } else { + new_layouts.push_back(layout); } - free(tile_table); - free(itt); - throw; } - /* Clean the tile table if it was already set by a previous prop A. */ - CleanIndustryTileTable(indsp); /* Install final layout construction in the industry spec */ - indsp->num_table = new_num_layouts; - indsp->table = tile_table; - SetBit(indsp->cleanup_flag, CLEAN_TILELAYOUT); - free(itt); + indsp->layouts = new_layouts; break; } @@ -3822,14 +3817,14 @@ static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, B } /* Allocate industry specs if they haven't been allocated already. */ - if (_cur.grffile->airportspec == NULL) { + if (_cur.grffile->airportspec == nullptr) { _cur.grffile->airportspec = CallocT(NUM_AIRPORTS_PER_GRF); } for (int i = 0; i < numinfo; i++) { AirportSpec *as = _cur.grffile->airportspec[airport + i]; - if (as == NULL && prop != 0x08 && prop != 0x09) { + if (as == nullptr && prop != 0x08 && prop != 0x09) { grfmsg(2, "AirportChangeInfo: Attempt to modify undefined airport %u, ignoring", airport + i); return CIR_INVALID_ID; } @@ -3853,7 +3848,7 @@ static ChangeInfoResult AirportChangeInfo(uint airport, int numinfo, int prop, B /* Allocate space for this airport. * Only need to do it once. If ever it is called again, it should not * do anything */ - if (*spec == NULL) { + if (*spec == nullptr) { *spec = MallocT(1); as = *spec; @@ -4040,14 +4035,14 @@ static ChangeInfoResult ObjectChangeInfo(uint id, int numinfo, int prop, ByteRea } /* Allocate object specs if they haven't been allocated already. */ - if (_cur.grffile->objectspec == NULL) { + if (_cur.grffile->objectspec == nullptr) { _cur.grffile->objectspec = CallocT(NUM_OBJECTS_PER_GRF); } for (int i = 0; i < numinfo; i++) { ObjectSpec *spec = _cur.grffile->objectspec[id + i]; - if (prop != 0x08 && spec == NULL) { + if (prop != 0x08 && spec == nullptr) { /* If the object property 08 is not yet set, ignore this property */ ChangeInfoResult cir = IgnoreObjectProperty(prop, buf); if (cir > ret) ret = cir; @@ -4059,7 +4054,7 @@ static ChangeInfoResult ObjectChangeInfo(uint id, int numinfo, int prop, ByteRea ObjectSpec **ospec = &_cur.grffile->objectspec[id + i]; /* Allocate space for this object. */ - if (*ospec == NULL) { + if (*ospec == nullptr) { *ospec = CallocT(1); (*ospec)->views = 1; // Default for NewGRFs that don't set it. } @@ -4335,7 +4330,7 @@ static ChangeInfoResult RailTypeReserveInfo(uint id, int numinfo, int prop, Byte if (_cur.grffile->railtype_map[id + i] != INVALID_RAILTYPE) { int n = buf->ReadByte(); for (int j = 0; j != n; j++) { - *_railtypes[_cur.grffile->railtype_map[id + i]].alternate_labels.Append() = BSWAP32(buf->ReadDWord()); + _railtypes[_cur.grffile->railtype_map[id + i]].alternate_labels.push_back(BSWAP32(buf->ReadDWord())); } break; } @@ -4371,6 +4366,226 @@ static ChangeInfoResult RailTypeReserveInfo(uint id, int numinfo, int prop, Byte return ret; } +/** + * Define properties for roadtypes + * @param id ID of the roadtype. + * @param numinfo Number of subsequent IDs to change the property for. + * @param prop The property to change. + * @param buf The property value. + * @return ChangeInfoResult. + */ +static ChangeInfoResult RoadTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf, RoadTramType rtt) +{ + ChangeInfoResult ret = CIR_SUCCESS; + + extern RoadTypeInfo _roadtypes[ROADTYPE_END]; + RoadType *type_map = (rtt == RTT_TRAM) ? _cur.grffile->tramtype_map : _cur.grffile->roadtype_map; + + if (id + numinfo > ROADTYPE_END) { + grfmsg(1, "RoadTypeChangeInfo: Road type %u is invalid, max %u, ignoring", id + numinfo, ROADTYPE_END); + return CIR_INVALID_ID; + } + + for (int i = 0; i < numinfo; i++) { + RoadType rt = type_map[id + i]; + if (rt == INVALID_ROADTYPE) return CIR_INVALID_ID; + + RoadTypeInfo *rti = &_roadtypes[rt]; + + switch (prop) { + case 0x08: // Label of road type + /* Skipped here as this is loaded during reservation stage. */ + buf->ReadDWord(); + break; + + case 0x09: { // Toolbar caption of roadtype (sets name as well for backwards compatibility for grf ver < 8) + uint16 str = buf->ReadWord(); + AddStringForMapping(str, &rti->strings.toolbar_caption); + break; + } + + case 0x0A: // Menu text of roadtype + AddStringForMapping(buf->ReadWord(), &rti->strings.menu_text); + break; + + case 0x0B: // Build window caption + AddStringForMapping(buf->ReadWord(), &rti->strings.build_caption); + break; + + case 0x0C: // Autoreplace text + AddStringForMapping(buf->ReadWord(), &rti->strings.replace_text); + break; + + case 0x0D: // New engine text + AddStringForMapping(buf->ReadWord(), &rti->strings.new_engine); + break; + + case 0x0F: // Powered roadtype list + case 0x18: // Roadtype list required for date introduction + case 0x19: { // Introduced roadtype list + /* Road type compatibility bits are added to the existing bits + * to allow multiple GRFs to modify compatibility with the + * default road types. */ + 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) { + 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; + } + } + } + break; + } + + case 0x10: // Road Type flags + rti->flags = (RoadTypeFlags)buf->ReadByte(); + break; + + case 0x13: // Construction cost factor + rti->cost_multiplier = buf->ReadWord(); + break; + + case 0x14: // Speed limit + rti->max_speed = buf->ReadWord(); + break; + + case 0x16: // Map colour + rti->map_colour = buf->ReadByte(); + break; + + case 0x17: // Introduction date + rti->introduction_date = buf->ReadDWord(); + break; + + case 0x1A: // Sort order + rti->sorting_order = buf->ReadByte(); + break; + + case 0x1B: // Name of roadtype + AddStringForMapping(buf->ReadWord(), &rti->strings.name); + break; + + case 0x1C: // Maintenance cost factor + rti->maintenance_multiplier = buf->ReadWord(); + break; + + case 0x1D: // Alternate road type label list + /* Skipped here as this is loaded during reservation stage. */ + for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord(); + break; + + default: + ret = CIR_UNKNOWN; + break; + } + } + + return ret; +} + +static ChangeInfoResult RoadTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf) +{ + return RoadTypeChangeInfo(id, numinfo, prop, buf, RTT_ROAD); +} + +static ChangeInfoResult TramTypeChangeInfo(uint id, int numinfo, int prop, ByteReader *buf) +{ + return RoadTypeChangeInfo(id, numinfo, prop, buf, RTT_TRAM); +} + + +static ChangeInfoResult RoadTypeReserveInfo(uint id, int numinfo, int prop, ByteReader *buf, RoadTramType rtt) +{ + ChangeInfoResult ret = CIR_SUCCESS; + + extern RoadTypeInfo _roadtypes[ROADTYPE_END]; + RoadType *type_map = (rtt == RTT_TRAM) ? _cur.grffile->tramtype_map : _cur.grffile->roadtype_map; + + if (id + numinfo > ROADTYPE_END) { + grfmsg(1, "RoadTypeReserveInfo: Road type %u is invalid, max %u, ignoring", id + numinfo, ROADTYPE_END); + return CIR_INVALID_ID; + } + + for (int i = 0; i < numinfo; i++) { + switch (prop) { + case 0x08: { // Label of road type + RoadTypeLabel rtl = buf->ReadDWord(); + rtl = BSWAP32(rtl); + + RoadType rt = GetRoadTypeByLabel(rtl, false); + if (rt == INVALID_ROADTYPE) { + /* Set up new road type */ + rt = AllocateRoadType(rtl, rtt); + } else if (GetRoadTramType(rt) != rtt) { + grfmsg(1, "RoadTypeReserveInfo: Road type %u is invalid type (road/tram), ignoring", id + numinfo); + return CIR_INVALID_ID; + } + + type_map[id + i] = rt; + break; + } + case 0x09: // Toolbar caption of roadtype + case 0x0A: // Menu text + case 0x0B: // Build window caption + case 0x0C: // Autoreplace text + case 0x0D: // New loco + case 0x13: // Construction cost + case 0x14: // Speed limit + case 0x1B: // Name of roadtype + case 0x1C: // Maintenance cost factor + buf->ReadWord(); + break; + + case 0x1D: // Alternate road type label list + if (type_map[id + i] != INVALID_ROADTYPE) { + int n = buf->ReadByte(); + for (int j = 0; j != n; j++) { + _roadtypes[type_map[id + i]].alternate_labels.push_back(BSWAP32(buf->ReadDWord())); + } + break; + } + grfmsg(1, "RoadTypeReserveInfo: Ignoring property 1D for road type %u because no label was set", id + i); + /* FALL THROUGH */ + + case 0x0F: // Powered roadtype list + case 0x18: // Roadtype list required for date introduction + case 0x19: // Introduced roadtype list + for (int j = buf->ReadByte(); j != 0; j--) buf->ReadDWord(); + break; + + case 0x10: // Road Type flags + case 0x16: // Map colour + case 0x1A: // Sort order + buf->ReadByte(); + break; + + case 0x17: // Introduction date + buf->ReadDWord(); + break; + + default: + ret = CIR_UNKNOWN; + break; + } + } + + return ret; +} + +static ChangeInfoResult RoadTypeReserveInfo(uint id, int numinfo, int prop, ByteReader *buf) +{ + return RoadTypeReserveInfo(id, numinfo, prop, buf, RTT_ROAD); +} + +static ChangeInfoResult TramTypeReserveInfo(uint id, int numinfo, int prop, ByteReader *buf) +{ + return RoadTypeReserveInfo(id, numinfo, prop, buf, RTT_TRAM); +} + static ChangeInfoResult AirportTilesChangeInfo(uint airtid, int numinfo, int prop, ByteReader *buf) { ChangeInfoResult ret = CIR_SUCCESS; @@ -4381,14 +4596,14 @@ static ChangeInfoResult AirportTilesChangeInfo(uint airtid, int numinfo, int pro } /* Allocate airport tile specs if they haven't been allocated already. */ - if (_cur.grffile->airtspec == NULL) { + if (_cur.grffile->airtspec == nullptr) { _cur.grffile->airtspec = CallocT(NUM_AIRPORTTILES_PER_GRF); } for (int i = 0; i < numinfo; i++) { AirportTileSpec *tsp = _cur.grffile->airtspec[airtid + i]; - if (prop != 0x08 && tsp == NULL) { + if (prop != 0x08 && tsp == nullptr) { grfmsg(2, "AirportTileChangeInfo: Attempt to modify undefined airport tile %u. Ignoring.", airtid + i); return CIR_INVALID_ID; } @@ -4405,7 +4620,7 @@ static ChangeInfoResult AirportTilesChangeInfo(uint airtid, int numinfo, int pro } /* Allocate space for this airport tile. */ - if (*tilespec == NULL) { + if (*tilespec == nullptr) { *tilespec = CallocT(1); tsp = *tilespec; @@ -4516,13 +4731,15 @@ static void FeatureChangeInfo(ByteReader *buf) /* GSF_GLOBALVAR */ GlobalVarChangeInfo, /* GSF_INDUSTRYTILES */ IndustrytilesChangeInfo, /* GSF_INDUSTRIES */ IndustriesChangeInfo, - /* GSF_CARGOES */ NULL, // Cargo is handled during reservation + /* GSF_CARGOES */ nullptr, // Cargo is handled during reservation /* GSF_SOUNDFX */ SoundEffectChangeInfo, /* GSF_AIRPORTS */ AirportChangeInfo, - /* GSF_SIGNALS */ NULL, + /* GSF_SIGNALS */ nullptr, /* GSF_OBJECTS */ ObjectChangeInfo, /* GSF_RAILTYPES */ RailTypeChangeInfo, /* GSF_AIRPORTTILES */ AirportTilesChangeInfo, + /* GSF_ROADTYPES */ RoadTypeChangeInfo, + /* GSF_TRAMTYPES */ TramTypeChangeInfo, }; uint8 feature = buf->ReadByte(); @@ -4538,7 +4755,7 @@ static void FeatureChangeInfo(ByteReader *buf) grfmsg(6, "FeatureChangeInfo: Feature 0x%02X, %d properties, to apply to %d+%d", feature, numprops, engine, numinfo); - if (feature >= lengthof(handler) || handler[feature] == NULL) { + if (feature >= lengthof(handler) || handler[feature] == nullptr) { if (feature != GSF_CARGOES) grfmsg(1, "FeatureChangeInfo: Unsupported feature 0x%02X, skipping", feature); return; } @@ -4576,7 +4793,7 @@ static void SafeChangeInfo(ByteReader *buf) uint32 s = buf->ReadDWord(); buf->ReadDWord(); // dest const GRFConfig *grfconfig = GetGRFConfig(s); - if (grfconfig != NULL && !HasBit(grfconfig->flags, GCF_STATIC)) { + if (grfconfig != nullptr && !HasBit(grfconfig->flags, GCF_STATIC)) { is_safe = false; break; } @@ -4596,7 +4813,7 @@ static void ReserveChangeInfo(ByteReader *buf) { uint8 feature = buf->ReadByte(); - if (feature != GSF_CARGOES && feature != GSF_GLOBALVAR && feature != GSF_RAILTYPES) return; + if (feature != GSF_CARGOES && feature != GSF_GLOBALVAR && feature != GSF_RAILTYPES && feature != GSF_ROADTYPES && feature != GSF_TRAMTYPES) return; uint8 numprops = buf->ReadByte(); uint8 numinfo = buf->ReadByte(); @@ -4619,6 +4836,14 @@ static void ReserveChangeInfo(ByteReader *buf) case GSF_RAILTYPES: cir = RailTypeReserveInfo(index, numinfo, prop, buf); break; + + case GSF_ROADTYPES: + cir = RoadTypeReserveInfo(index, numinfo, prop, buf); + break; + + case GSF_TRAMTYPES: + cir = TramTypeReserveInfo(index, numinfo, prop, buf); + break; } if (HandleChangeInfoResult("ReserveChangeInfo", cir, feature, prop)) return; @@ -4700,9 +4925,9 @@ static const SpriteGroup *GetGroupFromGroupID(byte setid, byte type, uint16 grou return new CallbackResultSpriteGroup(groupid, _cur.grffile->grf_version >= 8); } - if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == NULL) { + if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == nullptr) { grfmsg(1, "GetGroupFromGroupID(0x%02X:0x%02X): Groupid 0x%04X does not exist, leaving empty", setid, type, groupid); - return NULL; + return nullptr; } return _cur.spritegroups[groupid]; @@ -4725,7 +4950,7 @@ static const SpriteGroup *CreateGroupFromGroupID(byte feature, byte setid, byte if (!_cur.IsValidSpriteSet(feature, spriteid)) { grfmsg(1, "CreateGroupFromGroupID(0x%02X:0x%02X): Sprite set %u invalid", setid, type, spriteid); - return NULL; + return nullptr; } SpriteID spriteset_start = _cur.GetSprite(feature, spriteid); @@ -4751,7 +4976,7 @@ static void NewSpriteGroup(ByteReader *buf) * otherwise it specifies a number of entries, the exact * meaning depends on the feature * V feature-specific-data (huge mess, don't even look it up --pasky) */ - SpriteGroup *act_group = NULL; + SpriteGroup *act_group = nullptr; uint8 feature = buf->ReadByte(); if (feature >= GSF_END) { @@ -4780,6 +5005,7 @@ static void NewSpriteGroup(ByteReader *buf) assert(DeterministicSpriteGroup::CanAllocateItem()); DeterministicSpriteGroup *group = new DeterministicSpriteGroup(); + group->nfo_line = _cur.nfo_line; act_group = group; group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF; @@ -4790,43 +5016,44 @@ static void NewSpriteGroup(ByteReader *buf) case 2: group->size = DSG_SIZE_DWORD; varsize = 4; break; } - static SmallVector adjusts; - adjusts.Clear(); + static std::vector adjusts; + adjusts.clear(); /* Loop through the var adjusts. Unfortunately we don't know how many we have * from the outset, so we shall have to keep reallocing. */ do { - DeterministicSpriteGroupAdjust *adjust = adjusts.Append(); + /*C++17: DeterministicSpriteGroupAdjust &adjust = */ adjusts.emplace_back(); + DeterministicSpriteGroupAdjust &adjust = adjusts.back(); /* The first var adjust doesn't have an operation specified, so we set it to add. */ - adjust->operation = adjusts.Length() == 1 ? DSGA_OP_ADD : (DeterministicSpriteGroupAdjustOperation)buf->ReadByte(); - adjust->variable = buf->ReadByte(); - if (adjust->variable == 0x7E) { + adjust.operation = adjusts.size() == 1 ? DSGA_OP_ADD : (DeterministicSpriteGroupAdjustOperation)buf->ReadByte(); + adjust.variable = buf->ReadByte(); + if (adjust.variable == 0x7E) { /* Link subroutine group */ - adjust->subroutine = GetGroupFromGroupID(setid, type, buf->ReadByte()); + adjust.subroutine = GetGroupFromGroupID(setid, type, buf->ReadByte()); } else { - adjust->parameter = IsInsideMM(adjust->variable, 0x60, 0x80) ? buf->ReadByte() : 0; + adjust.parameter = IsInsideMM(adjust.variable, 0x60, 0x80) ? buf->ReadByte() : 0; } varadjust = buf->ReadByte(); - adjust->shift_num = GB(varadjust, 0, 5); - adjust->type = (DeterministicSpriteGroupAdjustType)GB(varadjust, 6, 2); - adjust->and_mask = buf->ReadVarSize(varsize); + adjust.shift_num = GB(varadjust, 0, 5); + adjust.type = (DeterministicSpriteGroupAdjustType)GB(varadjust, 6, 2); + adjust.and_mask = buf->ReadVarSize(varsize); - if (adjust->type != DSGA_TYPE_NONE) { - adjust->add_val = buf->ReadVarSize(varsize); - adjust->divmod_val = buf->ReadVarSize(varsize); + if (adjust.type != DSGA_TYPE_NONE) { + adjust.add_val = buf->ReadVarSize(varsize); + adjust.divmod_val = buf->ReadVarSize(varsize); } else { - adjust->add_val = 0; - adjust->divmod_val = 0; + adjust.add_val = 0; + adjust.divmod_val = 0; } /* Continue reading var adjusts while bit 5 is set. */ } while (HasBit(varadjust, 5)); - group->num_adjusts = adjusts.Length(); + group->num_adjusts = (uint)adjusts.size(); group->adjusts = MallocT(group->num_adjusts); - MemCpyT(group->adjusts, adjusts.Begin(), group->num_adjusts); + MemCpyT(group->adjusts, adjusts.data(), group->num_adjusts); std::vector ranges; ranges.resize(buf->ReadByte()); @@ -4895,6 +5122,7 @@ static void NewSpriteGroup(ByteReader *buf) { assert(RandomizedSpriteGroup::CanAllocateItem()); RandomizedSpriteGroup *group = new RandomizedSpriteGroup(); + group->nfo_line = _cur.nfo_line; act_group = group; group->var_scope = HasBit(type, 1) ? VSG_SCOPE_PARENT : VSG_SCOPE_SELF; @@ -4930,6 +5158,8 @@ static void NewSpriteGroup(ByteReader *buf) case GSF_CARGOES: case GSF_AIRPORTS: case GSF_RAILTYPES: + case GSF_ROADTYPES: + case GSF_TRAMTYPES: { byte num_loaded = type; byte num_loading = buf->ReadByte(); @@ -4941,6 +5171,7 @@ static void NewSpriteGroup(ByteReader *buf) assert(RealSpriteGroup::CanAllocateItem()); RealSpriteGroup *group = new RealSpriteGroup(); + group->nfo_line = _cur.nfo_line; act_group = group; group->num_loaded = num_loaded; @@ -4974,6 +5205,7 @@ static void NewSpriteGroup(ByteReader *buf) assert(TileLayoutSpriteGroup::CanAllocateItem()); TileLayoutSpriteGroup *group = new TileLayoutSpriteGroup(); + group->nfo_line = _cur.nfo_line; act_group = group; /* On error, bail out immediately. Temporary GRF data was already freed */ @@ -4989,6 +5221,7 @@ static void NewSpriteGroup(ByteReader *buf) assert(IndustryProductionSpriteGroup::CanAllocateItem()); IndustryProductionSpriteGroup *group = new IndustryProductionSpriteGroup(); + group->nfo_line = _cur.nfo_line; act_group = group; group->version = type; if (type == 0) { @@ -5085,7 +5318,7 @@ static CargoID TranslateCargo(uint8 feature, uint8 ctype) if (feature == GSF_STATIONS && ctype == 0xFE) return CT_DEFAULT_NA; if (ctype == 0xFF) return CT_PURCHASE; - if (_cur.grffile->cargo_list.Length() == 0) { + if (_cur.grffile->cargo_list.size() == 0) { /* No cargo table, so use bitnum values */ if (ctype >= 32) { grfmsg(1, "TranslateCargo: Cargo bitnum %d out of range (max 31), skipping.", ctype); @@ -5105,8 +5338,8 @@ static CargoID TranslateCargo(uint8 feature, uint8 ctype) } /* Check if the cargo type is out of bounds of the cargo translation table */ - if (ctype >= _cur.grffile->cargo_list.Length()) { - grfmsg(1, "TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype, _cur.grffile->cargo_list.Length() - 1); + if (ctype >= _cur.grffile->cargo_list.size()) { + grfmsg(1, "TranslateCargo: Cargo type %d out of range (max %d), skipping.", ctype, (unsigned int)_cur.grffile->cargo_list.size() - 1); return CT_INVALID; } @@ -5130,7 +5363,7 @@ static CargoID TranslateCargo(uint8 feature, uint8 ctype) static bool IsValidGroupID(uint16 groupid, const char *function) { - if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == NULL) { + if (groupid > MAX_SPRITEGROUP || _cur.spritegroups[groupid] == nullptr) { grfmsg(1, "%s: Spritegroup 0x%04X out of range or empty, skipping.", function, groupid); return false; } @@ -5167,7 +5400,7 @@ static void VehicleMapSpriteGroup(ByteReader *buf, byte feature, uint8 idcount) EngineID *engines = AllocaM(EngineID, idcount); for (uint i = 0; i < idcount; i++) { Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, buf->ReadExtendedByte()); - if (e == NULL) { + if (e == nullptr) { /* No engine could be allocated?!? Deal with it. Okay, * this might look bad. Also make sure this NewGRF * gets disabled, as a half loaded one is bad. */ @@ -5265,9 +5498,9 @@ static void StationMapSpriteGroup(ByteReader *buf, uint8 idcount) if (ctype == CT_INVALID) continue; for (uint i = 0; i < idcount; i++) { - StationSpec *statspec = _cur.grffile->stations == NULL ? NULL : _cur.grffile->stations[stations[i]]; + StationSpec *statspec = _cur.grffile->stations == nullptr ? nullptr : _cur.grffile->stations[stations[i]]; - if (statspec == NULL) { + if (statspec == nullptr) { grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]); continue; } @@ -5280,14 +5513,14 @@ static void StationMapSpriteGroup(ByteReader *buf, uint8 idcount) if (!IsValidGroupID(groupid, "StationMapSpriteGroup")) return; for (uint i = 0; i < idcount; i++) { - StationSpec *statspec = _cur.grffile->stations == NULL ? NULL : _cur.grffile->stations[stations[i]]; + StationSpec *statspec = _cur.grffile->stations == nullptr ? nullptr : _cur.grffile->stations[stations[i]]; - if (statspec == NULL) { + if (statspec == nullptr) { grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X does not exist, skipping", stations[i]); continue; } - if (statspec->grf_prop.grffile != NULL) { + if (statspec->grf_prop.grffile != nullptr) { grfmsg(1, "StationMapSpriteGroup: Station with ID 0x%02X mapped multiple times, skipping", stations[i]); continue; } @@ -5314,7 +5547,7 @@ static void TownHouseMapSpriteGroup(ByteReader *buf, uint8 idcount) uint16 groupid = buf->ReadWord(); if (!IsValidGroupID(groupid, "TownHouseMapSpriteGroup")) return; - if (_cur.grffile->housespec == NULL) { + if (_cur.grffile->housespec == nullptr) { grfmsg(1, "TownHouseMapSpriteGroup: No houses defined, skipping"); return; } @@ -5322,7 +5555,7 @@ static void TownHouseMapSpriteGroup(ByteReader *buf, uint8 idcount) for (uint i = 0; i < idcount; i++) { HouseSpec *hs = _cur.grffile->housespec[houses[i]]; - if (hs == NULL) { + if (hs == nullptr) { grfmsg(1, "TownHouseMapSpriteGroup: House %d undefined, skipping.", houses[i]); continue; } @@ -5345,7 +5578,7 @@ static void IndustryMapSpriteGroup(ByteReader *buf, uint8 idcount) uint16 groupid = buf->ReadWord(); if (!IsValidGroupID(groupid, "IndustryMapSpriteGroup")) return; - if (_cur.grffile->industryspec == NULL) { + if (_cur.grffile->industryspec == nullptr) { grfmsg(1, "IndustryMapSpriteGroup: No industries defined, skipping"); return; } @@ -5353,7 +5586,7 @@ static void IndustryMapSpriteGroup(ByteReader *buf, uint8 idcount) for (uint i = 0; i < idcount; i++) { IndustrySpec *indsp = _cur.grffile->industryspec[industries[i]]; - if (indsp == NULL) { + if (indsp == nullptr) { grfmsg(1, "IndustryMapSpriteGroup: Industry %d undefined, skipping", industries[i]); continue; } @@ -5376,7 +5609,7 @@ static void IndustrytileMapSpriteGroup(ByteReader *buf, uint8 idcount) uint16 groupid = buf->ReadWord(); if (!IsValidGroupID(groupid, "IndustrytileMapSpriteGroup")) return; - if (_cur.grffile->indtspec == NULL) { + if (_cur.grffile->indtspec == nullptr) { grfmsg(1, "IndustrytileMapSpriteGroup: No industry tiles defined, skipping"); return; } @@ -5384,7 +5617,7 @@ static void IndustrytileMapSpriteGroup(ByteReader *buf, uint8 idcount) for (uint i = 0; i < idcount; i++) { IndustryTileSpec *indtsp = _cur.grffile->indtspec[indtiles[i]]; - if (indtsp == NULL) { + if (indtsp == nullptr) { grfmsg(1, "IndustrytileMapSpriteGroup: Industry tile %d undefined, skipping", indtiles[i]); continue; } @@ -5423,7 +5656,7 @@ static void CargoMapSpriteGroup(ByteReader *buf, uint8 idcount) static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount) { - if (_cur.grffile->objectspec == NULL) { + if (_cur.grffile->objectspec == nullptr) { grfmsg(1, "ObjectMapSpriteGroup: No object tiles defined, skipping"); return; } @@ -5445,7 +5678,7 @@ static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount) for (uint i = 0; i < idcount; i++) { ObjectSpec *spec = _cur.grffile->objectspec[objects[i]]; - if (spec == NULL) { + if (spec == nullptr) { grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]); continue; } @@ -5460,12 +5693,12 @@ static void ObjectMapSpriteGroup(ByteReader *buf, uint8 idcount) for (uint i = 0; i < idcount; i++) { ObjectSpec *spec = _cur.grffile->objectspec[objects[i]]; - if (spec == NULL) { + if (spec == nullptr) { grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X undefined, skipping", objects[i]); continue; } - if (spec->grf_prop.grffile != NULL) { + if (spec->grf_prop.grffile != nullptr) { grfmsg(1, "ObjectMapSpriteGroup: Object with ID 0x%02X mapped multiple times, skipping", objects[i]); continue; } @@ -5480,7 +5713,8 @@ static void RailTypeMapSpriteGroup(ByteReader *buf, uint8 idcount) { uint8 *railtypes = AllocaM(uint8, idcount); for (uint i = 0; i < idcount; i++) { - railtypes[i] = _cur.grffile->railtype_map[buf->ReadByte()]; + uint8 id = buf->ReadByte(); + railtypes[i] = id < RAILTYPE_END ? _cur.grffile->railtype_map[id] : INVALID_RAILTYPE; } uint8 cidcount = buf->ReadByte(); @@ -5506,6 +5740,39 @@ static void RailTypeMapSpriteGroup(ByteReader *buf, uint8 idcount) buf->ReadWord(); } +static void RoadTypeMapSpriteGroup(ByteReader *buf, uint8 idcount, RoadTramType rtt) +{ + RoadType *type_map = (rtt == RTT_TRAM) ? _cur.grffile->tramtype_map : _cur.grffile->roadtype_map; + + uint8 *roadtypes = AllocaM(uint8, idcount); + for (uint i = 0; i < idcount; i++) { + uint8 id = buf->ReadByte(); + roadtypes[i] = id < ROADTYPE_END ? type_map[id] : INVALID_ROADTYPE; + } + + uint8 cidcount = buf->ReadByte(); + for (uint c = 0; c < cidcount; c++) { + uint8 ctype = buf->ReadByte(); + uint16 groupid = buf->ReadWord(); + if (!IsValidGroupID(groupid, "RoadTypeMapSpriteGroup")) continue; + + if (ctype >= ROTSG_END) continue; + + extern RoadTypeInfo _roadtypes[ROADTYPE_END]; + for (uint i = 0; i < idcount; i++) { + if (roadtypes[i] != INVALID_ROADTYPE) { + RoadTypeInfo *rti = &_roadtypes[roadtypes[i]]; + + rti->grffile[ctype] = _cur.grffile; + rti->group[ctype] = _cur.spritegroups[groupid]; + } + } + } + + /* Roadtypes do not use the default group. */ + buf->ReadWord(); +} + static void AirportMapSpriteGroup(ByteReader *buf, uint8 idcount) { uint8 *airports = AllocaM(uint8, idcount); @@ -5520,7 +5787,7 @@ static void AirportMapSpriteGroup(ByteReader *buf, uint8 idcount) uint16 groupid = buf->ReadWord(); if (!IsValidGroupID(groupid, "AirportMapSpriteGroup")) return; - if (_cur.grffile->airportspec == NULL) { + if (_cur.grffile->airportspec == nullptr) { grfmsg(1, "AirportMapSpriteGroup: No airports defined, skipping"); return; } @@ -5528,7 +5795,7 @@ static void AirportMapSpriteGroup(ByteReader *buf, uint8 idcount) for (uint i = 0; i < idcount; i++) { AirportSpec *as = _cur.grffile->airportspec[airports[i]]; - if (as == NULL) { + if (as == nullptr) { grfmsg(1, "AirportMapSpriteGroup: Airport %d undefined, skipping", airports[i]); continue; } @@ -5551,7 +5818,7 @@ static void AirportTileMapSpriteGroup(ByteReader *buf, uint8 idcount) uint16 groupid = buf->ReadWord(); if (!IsValidGroupID(groupid, "AirportTileMapSpriteGroup")) return; - if (_cur.grffile->airtspec == NULL) { + if (_cur.grffile->airtspec == nullptr) { grfmsg(1, "AirportTileMapSpriteGroup: No airport tiles defined, skipping"); return; } @@ -5559,7 +5826,7 @@ static void AirportTileMapSpriteGroup(ByteReader *buf, uint8 idcount) for (uint i = 0; i < idcount; i++) { AirportTileSpec *airtsp = _cur.grffile->airtspec[airptiles[i]]; - if (airtsp == NULL) { + if (airtsp == nullptr) { grfmsg(1, "AirportTileMapSpriteGroup: Airport tile %d undefined, skipping", airptiles[i]); continue; } @@ -5656,6 +5923,14 @@ static void FeatureMapSpriteGroup(ByteReader *buf) RailTypeMapSpriteGroup(buf, idcount); break; + case GSF_ROADTYPES: + RoadTypeMapSpriteGroup(buf, idcount, RTT_ROAD); + break; + + case GSF_TRAMTYPES: + RoadTypeMapSpriteGroup(buf, idcount, RTT_TRAM); + break; + case GSF_AIRPORTTILES: AirportTileMapSpriteGroup(buf, idcount); return; @@ -5688,7 +5963,7 @@ static void FeatureNewName(ByteReader *buf) bool new_scheme = _cur.grffile->grf_version >= 7; uint8 feature = buf->ReadByte(); - if (feature >= GSF_END) { + if (feature >= GSF_END && feature != 0x48) { grfmsg(1, "FeatureNewName: Unsupported feature 0x%02X, skipping", feature); return; } @@ -5723,7 +5998,7 @@ static void FeatureNewName(ByteReader *buf) case GSF_AIRCRAFT: if (!generic) { Engine *e = GetNewEngine(_cur.grffile, (VehicleType)feature, id, HasBit(_cur.grfconfig->flags, GCF_STATIC)); - if (e == NULL) break; + if (e == nullptr) break; StringID string = AddGRFString(_cur.grffile->grfid, e->index, lang, new_scheme, false, name, e->info.string_id); e->info.string_id = string; } else { @@ -5739,7 +6014,7 @@ static void FeatureNewName(ByteReader *buf) switch (GB(id, 8, 8)) { case 0xC4: // Station class name - if (_cur.grffile->stations == NULL || _cur.grffile->stations[GB(id, 0, 8)] == NULL) { + if (_cur.grffile->stations == nullptr || _cur.grffile->stations[GB(id, 0, 8)] == nullptr) { grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8)); } else { StationClassID cls_id = _cur.grffile->stations[GB(id, 0, 8)]->cls_id; @@ -5748,7 +6023,7 @@ static void FeatureNewName(ByteReader *buf) break; case 0xC5: // Station name - if (_cur.grffile->stations == NULL || _cur.grffile->stations[GB(id, 0, 8)] == NULL) { + if (_cur.grffile->stations == nullptr || _cur.grffile->stations[GB(id, 0, 8)] == nullptr) { grfmsg(1, "FeatureNewName: Attempt to name undefined station 0x%X, ignoring", GB(id, 0, 8)); } else { _cur.grffile->stations[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED); @@ -5756,7 +6031,7 @@ static void FeatureNewName(ByteReader *buf) break; case 0xC7: // Airporttile name - if (_cur.grffile->airtspec == NULL || _cur.grffile->airtspec[GB(id, 0, 8)] == NULL) { + if (_cur.grffile->airtspec == nullptr || _cur.grffile->airtspec[GB(id, 0, 8)] == nullptr) { grfmsg(1, "FeatureNewName: Attempt to name undefined airport tile 0x%X, ignoring", GB(id, 0, 8)); } else { _cur.grffile->airtspec[GB(id, 0, 8)]->name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED); @@ -5764,7 +6039,7 @@ static void FeatureNewName(ByteReader *buf) break; case 0xC9: // House name - if (_cur.grffile->housespec == NULL || _cur.grffile->housespec[GB(id, 0, 8)] == NULL) { + if (_cur.grffile->housespec == nullptr || _cur.grffile->housespec[GB(id, 0, 8)] == nullptr) { grfmsg(1, "FeatureNewName: Attempt to name undefined house 0x%X, ignoring.", GB(id, 0, 8)); } else { _cur.grffile->housespec[GB(id, 0, 8)]->building_name = AddGRFString(_cur.grffile->grfid, id, lang, new_scheme, false, name, STR_UNDEFINED); @@ -5911,20 +6186,27 @@ static void GraphicsNew(ByteReader *buf) return; } - /* Load at most max_sprites sprites. Skip remaining sprites. (for compatibility with TTDP and future extentions) */ + /* Load at most max_sprites sprites. Skip remaining sprites. (for compatibility with TTDP and future extensions) */ uint16 skip_num = SanitizeSpriteOffset(num, offset, action5_type->max_sprites, action5_type->name); SpriteID replace = action5_type->sprite_base + offset; /* Load sprites starting from , then skip sprites. */ grfmsg(2, "GraphicsNew: Replacing sprites %d to %d of %s (type 0x%02X) at SpriteID 0x%04X", offset, offset + num - 1, action5_type->name, type, replace); + if (type == 0x0D) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_5; + + if (type == 0x0B) { + static const SpriteID depot_with_track_offset = SPR_TRAMWAY_DEPOT_WITH_TRACK - SPR_TRAMWAY_BASE; + static const SpriteID depot_no_track_offset = SPR_TRAMWAY_DEPOT_NO_TRACK - SPR_TRAMWAY_BASE; + if (offset <= depot_with_track_offset && offset + num > depot_with_track_offset) _loaded_newgrf_features.tram = TRAMWAY_REPLACE_DEPOT_WITH_TRACK; + if (offset <= depot_no_track_offset && offset + num > depot_no_track_offset) _loaded_newgrf_features.tram = TRAMWAY_REPLACE_DEPOT_NO_TRACK; + } + for (; num > 0; num--) { _cur.nfo_line++; LoadNextSprite(replace == 0 ? _cur.spriteid++ : replace++, _cur.file_index, _cur.nfo_line, _cur.grf_container_ver); } - if (type == 0x0D) _loaded_newgrf_features.shore = SHORE_REPLACE_ACTION_5; - _cur.skip_sprites = skip_num; } @@ -6101,7 +6383,7 @@ static uint32 GetParamVal(byte param, uint32 *cond_val) } case 0x85: // TTDPatch flags, only for bit tests - if (cond_val == NULL) { + if (cond_val == nullptr) { /* Supported in Action 0x07 and 0x09, not 0x0D */ return 0; } else { @@ -6144,7 +6426,7 @@ static void CfgApply(ByteReader *buf) size_t pos = FioGetPos(); uint32 num = _cur.grf_container_ver >= 2 ? FioReadDword() : FioReadWord(); uint8 type = FioReadByte(); - byte *preload_sprite = NULL; + byte *preload_sprite = nullptr; /* Check if the sprite is a pseudo sprite. We can't operate on real sprites. */ if (type == 0xFF) { @@ -6206,7 +6488,7 @@ static void CfgApply(ByteReader *buf) bool carry = false; for (i = 0; i < param_size && offset + i < num; i++) { - uint32 value = GetParamVal(param_num + i / 4, NULL); + uint32 value = GetParamVal(param_num + i / 4, nullptr); /* Reset carry flag for each iteration of the variable (only really * matters if param_size is greater than 4) */ if (i % 4 == 0) carry = false; @@ -6292,12 +6574,12 @@ static void SkipIf(ByteReader *buf) GRFConfig *c = GetGRFConfig(cond_val, mask); - if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) { + if (c != nullptr && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) { DisableStaticNewGRFInfluencingNonStaticNewGRFs(c); - c = NULL; + c = nullptr; } - if (condtype != 10 && c == NULL) { + if (condtype != 10 && c == nullptr) { grfmsg(7, "SkipIf: GRFID 0x%08X unknown, skipping test", BSWAP32(cond_val)); return; } @@ -6322,7 +6604,7 @@ static void SkipIf(ByteReader *buf) case 0x0A: // GRFID is not nor will be active /* This is the only condtype that doesn't get ignored if the GRFID is not found */ - result = c == NULL || c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND; + result = c == nullptr || c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND; break; default: grfmsg(1, "SkipIf: Unsupported GRF condition type %02X. Ignoring", condtype); return; @@ -6350,7 +6632,26 @@ static void SkipIf(ByteReader *buf) break; case 0x0E: result = GetRailTypeByLabel(BSWAP32(cond_val)) != INVALID_RAILTYPE; break; - + case 0x0F: { + RoadType rt = GetRoadTypeByLabel(BSWAP32(cond_val)); + result = rt == INVALID_ROADTYPE || !RoadTypeIsRoad(rt); + break; + } + case 0x10: { + RoadType rt = GetRoadTypeByLabel(BSWAP32(cond_val)); + result = rt != INVALID_ROADTYPE && RoadTypeIsRoad(rt); + break; + } + case 0x11: { + RoadType rt = GetRoadTypeByLabel(BSWAP32(cond_val)); + result = rt == INVALID_ROADTYPE || !RoadTypeIsTram(rt); + break; + } + case 0x12: { + RoadType rt = GetRoadTypeByLabel(BSWAP32(cond_val)); + result = rt != INVALID_ROADTYPE && RoadTypeIsTram(rt); + break; + } default: grfmsg(1, "SkipIf: Unsupported condition type %02X. Ignoring", condtype); return; } } @@ -6366,12 +6667,12 @@ 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 = NULL; - for (GRFLabel *label = _cur.grffile->label; label != NULL; label = label->next) { + GRFLabel *choice = nullptr; + for (GRFLabel *label = _cur.grffile->label; label != nullptr; label = label->next) { if (label->label != numsprites) continue; /* Remember a goto before the current line */ - if (choice == NULL) 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; @@ -6379,7 +6680,7 @@ static void SkipIf(ByteReader *buf) } } - if (choice != NULL) { + if (choice != nullptr) { grfmsg(2, "SkipIf: Jumping to label 0x%0X at line %d, test was true", choice->label, choice->nfo_line); FioSeekTo(choice->pos, SEEK_SET); _cur.nfo_line = choice->nfo_line; @@ -6516,7 +6817,7 @@ static void GRFLoadError(ByteReader *buf) { /* <0B> [ 00] [] 00 [] * - * B severity 00: notice, contine loading grf file + * B severity 00: notice, continue loading grf file * 01: warning, continue loading grf file * 02: error, but continue loading grf file, and attempt * loading grf again when loading or starting next game @@ -6571,7 +6872,7 @@ static void GRFLoadError(ByteReader *buf) /* Make sure we show fatal errors, instead of silly infos from before */ delete _cur.grfconfig->error; - _cur.grfconfig->error = NULL; + _cur.grfconfig->error = nullptr; } if (message_id >= lengthof(msgstr) && message_id != 0xFF) { @@ -6585,7 +6886,7 @@ static void GRFLoadError(ByteReader *buf) } /* For now we can only show one message per newgrf file. */ - if (_cur.grfconfig->error != NULL) return; + if (_cur.grfconfig->error != nullptr) return; GRFError *error = new GRFError(sevstr[severity]); @@ -6594,7 +6895,7 @@ static void GRFLoadError(ByteReader *buf) if (buf->HasData()) { const char *message = buf->ReadString(); - error->custom_message = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, message, NULL, SCC_RAW_STRING_POINTER); + error->custom_message = TranslateTTDPatchCodes(_cur.grffile->grfid, lang, true, message, nullptr, SCC_RAW_STRING_POINTER); } else { grfmsg(7, "GRFLoadError: No custom message supplied."); error->custom_message = stredup(""); @@ -6695,7 +6996,7 @@ static uint32 GetPatchVariable(uint8 param) */ case 0x13: { byte map_bits = 0; - byte log_X = MapLogX() - 6; // substraction is required to make the minimal size (64) zero based + byte log_X = MapLogX() - 6; // subtraction is required to make the minimal size (64) zero based byte log_Y = MapLogY() - 6; byte max_edge = max(log_X, log_Y); @@ -6912,11 +7213,11 @@ static void ParamSet(ByteReader *buf) /* Read another GRF File's parameter */ const GRFFile *file = GetFileByGRFID(data); GRFConfig *c = GetGRFConfig(data); - if (c != NULL && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) { + if (c != nullptr && HasBit(c->flags, GCF_STATIC) && !HasBit(_cur.grfconfig->flags, GCF_STATIC) && _networking) { /* Disable the read GRF if it is a static NewGRF. */ DisableStaticNewGRFInfluencingNonStaticNewGRFs(c); src1 = 0; - } else if (file == NULL || c == NULL || c->status == GCS_DISABLED) { + } else if (file == nullptr || c == nullptr || c->status == GCS_DISABLED) { src1 = 0; } else if (src1 == 0xFE) { src1 = c->version; @@ -6930,8 +7231,8 @@ static void ParamSet(ByteReader *buf) * variables available in action 7, or they can be FF to use the value * of . If referring to parameters that are undefined, a value * of 0 is used instead. */ - src1 = (src1 == 0xFF) ? data : GetParamVal(src1, NULL); - src2 = (src2 == 0xFF) ? data : GetParamVal(src2, NULL); + src1 = (src1 == 0xFF) ? data : GetParamVal(src1, nullptr); + src2 = (src2 == 0xFF) ? data : GetParamVal(src2, nullptr); } uint32 res; @@ -6988,7 +7289,7 @@ static void ParamSet(ByteReader *buf) } break; - case 0x0A: // Signed divison + case 0x0A: // Signed division if (src2 == 0) { res = src1; } else { @@ -7117,7 +7418,7 @@ static void GRFInhibit(ByteReader *buf) GRFConfig *file = GetGRFConfig(grfid); /* Unset activation flag */ - if (file != NULL && file != _cur.grfconfig) { + if (file != nullptr && file != _cur.grfconfig) { grfmsg(2, "GRFInhibit: Deactivating file '%s'", file->filename); GRFError *error = DisableGrf(STR_NEWGRF_ERROR_FORCEFULLY_DISABLED, file); error->data = stredup(_cur.grfconfig->GetName()); @@ -7223,15 +7524,15 @@ static void DefineGotoLabel(ByteReader *buf) label->label = nfo_label; label->nfo_line = _cur.nfo_line; label->pos = FioGetPos(); - label->next = NULL; + label->next = nullptr; /* Set up a linked list of goto targets which we will search in an Action 0x7/0x9 */ - if (_cur.grffile->label == NULL) { + 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 != NULL; l = l->next) {} + for (l = _cur.grffile->label; l->next != nullptr; l = l->next) {} l->next = label; } @@ -7249,7 +7550,7 @@ static void ImportGRFSound(SoundEntry *sound) SoundID sound_id = FioReadWord(); file = GetFileByGRFID(grfid); - if (file == NULL || file->sound_offset == 0) { + if (file == nullptr || file->sound_offset == 0) { grfmsg(1, "ImportGRFSound: Source file not available"); return; } @@ -7459,7 +7760,7 @@ static void TranslateGRFStrings(ByteReader *buf) uint32 grfid = buf->ReadDWord(); const GRFConfig *c = GetGRFConfig(grfid); - if (c == NULL || (c->status != GCS_INITIALISED && c->status != GCS_ACTIVATED)) { + if (c == nullptr || (c->status != GCS_INITIALISED && c->status != GCS_ACTIVATED)) { grfmsg(7, "TranslateGRFStrings: GRFID 0x%08x unknown, skipping action 13", BSWAP32(grfid)); return; } @@ -7659,8 +7960,14 @@ static bool ChangeGRFParamLimits(size_t len, ByteReader *buf) grfmsg(2, "StaticGRFInfo: expected 8 bytes for 'INFO'->'PARA'->'LIMI' but got " PRINTF_SIZE ", ignoring this field", len); buf->Skip(len); } else { - _cur_parameter->min_value = buf->ReadDWord(); - _cur_parameter->max_value = buf->ReadDWord(); + uint32 min_value = buf->ReadDWord(); + uint32 max_value = buf->ReadDWord(); + if (min_value <= max_value) { + _cur_parameter->min_value = min_value; + _cur_parameter->max_value = max_value; + } else { + grfmsg(2, "StaticGRFInfo: 'INFO'->'PARA'->'LIMI' values are incoherent, ignoring this field"); + } } return true; } @@ -7810,7 +8117,7 @@ static bool ChangeGRFParamValueNames(ByteReader *buf) if (val_name != _cur_parameter->value_names.End()) { AddGRFTextToList(&val_name->second, langid, _cur.grfconfig->ident.grfid, false, name_string); } else { - GRFText *list = NULL; + GRFText *list = nullptr; AddGRFTextToList(&list, langid, _cur.grfconfig->ident.grfid, false, name_string); _cur_parameter->value_names.Insert(id, list); } @@ -7850,12 +8157,10 @@ static bool HandleParameterInfo(ByteReader *buf) continue; } - if (id >= _cur.grfconfig->param_info.Length()) { - uint num_to_add = id - _cur.grfconfig->param_info.Length() + 1; - GRFParameterInfo **newdata = _cur.grfconfig->param_info.Append(num_to_add); - MemSetT(newdata, 0, num_to_add); + if (id >= _cur.grfconfig->param_info.size()) { + _cur.grfconfig->param_info.resize(id + 1); } - if (_cur.grfconfig->param_info[id] == NULL) { + if (_cur.grfconfig->param_info[id] == nullptr) { _cur.grfconfig->param_info[id] = new GRFParameterInfo(id); } _cur_parameter = _cur.grfconfig->param_info[id]; @@ -8096,12 +8401,11 @@ static void InitializeGRFSpecial() /** Reset and clear all NewGRF stations */ static void ResetCustomStations() { - const GRFFile * const *end = _grf_files.End(); - for (GRFFile **file = _grf_files.Begin(); file != end; file++) { - StationSpec **&stations = (*file)->stations; - if (stations == NULL) continue; + for (GRFFile * const file : _grf_files) { + StationSpec **&stations = file->stations; + if (stations == nullptr) continue; for (uint i = 0; i < NUM_STATIONS_PER_GRF; i++) { - if (stations[i] == NULL) continue; + if (stations[i] == nullptr) continue; StationSpec *statspec = stations[i]; delete[] statspec->renderdata; @@ -8124,37 +8428,35 @@ static void ResetCustomStations() /* Free and reset the station data */ free(stations); - stations = NULL; + stations = nullptr; } } /** Reset and clear all NewGRF houses */ static void ResetCustomHouses() { - const GRFFile * const *end = _grf_files.End(); - for (GRFFile **file = _grf_files.Begin(); file != end; file++) { - HouseSpec **&housespec = (*file)->housespec; - if (housespec == NULL) continue; + for (GRFFile * const file : _grf_files) { + HouseSpec **&housespec = file->housespec; + if (housespec == nullptr) continue; for (uint i = 0; i < NUM_HOUSES_PER_GRF; i++) { free(housespec[i]); } free(housespec); - housespec = NULL; + housespec = nullptr; } } /** Reset and clear all NewGRF airports */ static void ResetCustomAirports() { - const GRFFile * const *end = _grf_files.End(); - for (GRFFile **file = _grf_files.Begin(); file != end; file++) { - AirportSpec **aslist = (*file)->airportspec; - if (aslist != NULL) { + for (GRFFile * const file : _grf_files) { + AirportSpec **aslist = file->airportspec; + if (aslist != nullptr) { for (uint i = 0; i < NUM_AIRPORTS_PER_GRF; i++) { AirportSpec *as = aslist[i]; - if (as != NULL) { + if (as != nullptr) { /* We need to remove the tiles layouts */ for (int j = 0; j < as->num_table; j++) { /* remove the individual layouts */ @@ -8168,16 +8470,16 @@ static void ResetCustomAirports() } } free(aslist); - (*file)->airportspec = NULL; + file->airportspec = nullptr; } - AirportTileSpec **&airporttilespec = (*file)->airtspec; - if (airporttilespec != NULL) { + AirportTileSpec **&airporttilespec = file->airtspec; + if (airporttilespec != nullptr) { for (uint i = 0; i < NUM_AIRPORTTILES_PER_GRF; i++) { free(airporttilespec[i]); } free(airporttilespec); - airporttilespec = NULL; + airporttilespec = nullptr; } } } @@ -8185,78 +8487,65 @@ static void ResetCustomAirports() /** Reset and clear all NewGRF industries */ static void ResetCustomIndustries() { - const GRFFile * const *end = _grf_files.End(); - for (GRFFile **file = _grf_files.Begin(); file != end; file++) { - IndustrySpec **&industryspec = (*file)->industryspec; - IndustryTileSpec **&indtspec = (*file)->indtspec; + for (GRFFile * const file : _grf_files) { + IndustrySpec **&industryspec = file->industryspec; + IndustryTileSpec **&indtspec = file->indtspec; /* We are verifiying both tiles and industries specs loaded from the grf file * First, let's deal with industryspec */ - if (industryspec != NULL) { + if (industryspec != nullptr) { for (uint i = 0; i < NUM_INDUSTRYTYPES_PER_GRF; i++) { IndustrySpec *ind = industryspec[i]; - if (ind == NULL) continue; - - /* We need to remove the sounds array */ - if (HasBit(ind->cleanup_flag, CLEAN_RANDOMSOUNDS)) { - free(ind->random_sounds); - } - - /* We need to remove the tiles layouts */ - CleanIndustryTileTable(ind); - - free(ind); + delete ind; } free(industryspec); - industryspec = NULL; + industryspec = nullptr; } - if (indtspec == NULL) continue; + if (indtspec == nullptr) continue; for (uint i = 0; i < NUM_INDUSTRYTILES_PER_GRF; i++) { free(indtspec[i]); } free(indtspec); - indtspec = NULL; + indtspec = nullptr; } } /** Reset and clear all NewObjects */ static void ResetCustomObjects() { - const GRFFile * const *end = _grf_files.End(); - for (GRFFile **file = _grf_files.Begin(); file != end; file++) { - ObjectSpec **&objectspec = (*file)->objectspec; - if (objectspec == NULL) continue; + for (GRFFile * const file : _grf_files) { + ObjectSpec **&objectspec = file->objectspec; + if (objectspec == nullptr) continue; for (uint i = 0; i < NUM_OBJECTS_PER_GRF; i++) { free(objectspec[i]); } free(objectspec); - objectspec = NULL; + objectspec = nullptr; } } /** Reset and clear all NewGRFs */ static void ResetNewGRF() { - const GRFFile * const *end = _grf_files.End(); - for (GRFFile **file = _grf_files.Begin(); file != end; file++) { - delete *file; + for (GRFFile * const file : _grf_files) { + delete file; } - _grf_files.Clear(); - _cur.grffile = NULL; + _grf_files.clear(); + _cur.grffile = nullptr; } /** Clear all NewGRF errors */ static void ResetNewGRFErrors() { - for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) { - if (!HasBit(c->flags, GCF_COPY) && c->error != NULL) { + for (GRFConfig *c = _grfconfig; c != nullptr; c = c->next) { + if (!HasBit(c->flags, GCF_COPY) && c->error != nullptr) { delete c->error; - c->error = NULL; + c->error = nullptr; } } } @@ -8278,12 +8567,14 @@ void ResetNewGRFData() /* Reset rail type information */ ResetRailTypes(); + /* Copy/reset original road type info data */ + ResetRoadTypes(); + /* Allocate temporary refit/cargo class data */ _gted = CallocT(Engine::GetPoolSize()); /* Fill rail type label temporary data for default trains */ - Engine *e; - FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) { + for (const Engine *e : Engine::IterateType(VEH_TRAIN)) { _gted[e->index].railtypelabel = GetRailTypeInfo(e->u.rail.railtype)->label; } @@ -8346,6 +8637,7 @@ void ResetNewGRFData() _loaded_newgrf_features.has_newhouses = false; _loaded_newgrf_features.has_newindustries = false; _loaded_newgrf_features.shore = SHORE_REPLACE_NONE; + _loaded_newgrf_features.tram = TRAMWAY_REPLACE_DEPOT_NONE; /* Clear all GRF overrides */ _grf_id_overrides.clear(); @@ -8380,13 +8672,13 @@ static void BuildCargoTranslationMap() const CargoSpec *cs = CargoSpec::Get(c); if (!cs->IsValid()) continue; - if (_cur.grffile->cargo_list.Length() == 0) { + if (_cur.grffile->cargo_list.size() == 0) { /* Default translation table, so just a straight mapping to bitnum */ _cur.grffile->cargo_map[c] = cs->bitnum; } else { /* Check the translation table for this cargo's label */ - int index = _cur.grffile->cargo_list.FindIndex(cs->label); - if (index >= 0) _cur.grffile->cargo_map[c] = index; + int idx = find_index(_cur.grffile->cargo_list, {cs->label}); + if (idx >= 0) _cur.grffile->cargo_map[c] = idx; } } } @@ -8398,14 +8690,14 @@ static void BuildCargoTranslationMap() static void InitNewGRFFile(const GRFConfig *config) { GRFFile *newfile = GetFileByFilename(config->filename); - if (newfile != NULL) { + if (newfile != nullptr) { /* We already loaded it once. */ _cur.grffile = newfile; return; } newfile = new GRFFile(config); - *_grf_files.Append() = _cur.grffile = newfile; + _grf_files.push_back(_cur.grffile = newfile); } /** @@ -8433,6 +8725,14 @@ GRFFile::GRFFile(const GRFConfig *config) this->railtype_map[2] = RAILTYPE_MONO; this->railtype_map[3] = RAILTYPE_MAGLEV; + /* Initialise road type map with default road types */ + memset(this->roadtype_map, INVALID_ROADTYPE, sizeof(this->roadtype_map)); + this->roadtype_map[0] = ROADTYPE_ROAD; + + /* Initialise tram type map with default tram types */ + memset(this->tramtype_map, INVALID_ROADTYPE, sizeof(this->tramtype_map)); + this->tramtype_map[0] = ROADTYPE_TRAM; + /* Copy the initial parameter list * 'Uninitialised' parameters are zeroed as that is their default value when dynamically creating them. */ assert_compile(lengthof(this->param) == lengthof(config->param) && lengthof(this->param) == 0x80); @@ -8490,9 +8790,7 @@ static const CargoLabel * const _default_refitmasks[] = { */ static void CalculateRefitMasks() { - Engine *e; - - FOR_ALL_ENGINES(e) { + for (Engine *e : Engine::Iterate()) { EngineID engine = e->index; EngineInfo *ei = &e->info; bool only_defaultcargo; ///< Set if the vehicle shall carry only the default cargo @@ -8556,16 +8854,16 @@ static void CalculateRefitMasks() * cargo type. Finally disable the vehicle, if there is still no cargo. */ if (ei->cargo_type == CT_INVALID && ei->refit_mask != 0) { /* Figure out which CTT to use for the default cargo, if it is 'first refittable'. */ - const uint8 *cargo_map_for_first_refittable = NULL; + const uint8 *cargo_map_for_first_refittable = nullptr; { const GRFFile *file = _gted[engine].defaultcargo_grf; - if (file == NULL) file = e->GetGRF(); - if (file != NULL && file->grf_version >= 8 && file->cargo_list.Length() != 0) { + if (file == nullptr) file = e->GetGRF(); + if (file != nullptr && file->grf_version >= 8 && file->cargo_list.size() != 0) { cargo_map_for_first_refittable = file->cargo_map; } } - if (cargo_map_for_first_refittable != NULL) { + if (cargo_map_for_first_refittable != nullptr) { /* Use first refittable cargo from cargo translation table */ byte best_local_slot = 0xFF; CargoID cargo_type; @@ -8596,7 +8894,7 @@ static void CalculateRefitMasks() static void FinaliseCanals() { for (uint i = 0; i < CF_END; i++) { - if (_water_feature[i].grffile != NULL) { + if (_water_feature[i].grffile != nullptr) { _water_feature[i].callback_mask = _water_feature[i].grffile->canal_local_properties[i].callback_mask; _water_feature[i].flags = _water_feature[i].grffile->canal_local_properties[i].flags; } @@ -8606,10 +8904,8 @@ static void FinaliseCanals() /** Check for invalid engines */ static void FinaliseEngineArray() { - Engine *e; - - FOR_ALL_ENGINES(e) { - if (e->GetGRF() == NULL) { + for (Engine *e : Engine::Iterate()) { + if (e->GetGRF() == nullptr) { const EngineIDMapping &eid = _engine_mngr[e->index]; if (eid.grfid != INVALID_GRFID || eid.internal_id != eid.substitute_id) { e->info.string_id = STR_NEWGRF_INVALID_ENGINE; @@ -8621,13 +8917,13 @@ static void FinaliseEngineArray() /* 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() != NULL && is_custom_sprite(e->u.rail.image_index)) { + 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); } /* 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, NULL); + LiveryScheme ls = GetEngineLiveryScheme(e->index, INVALID_ENGINE, nullptr); SetBit(_loaded_newgrf_features.used_liveries, ls); /* Note: For ships and roadvehicles we assume that they cannot be refitted between passenger and freight */ @@ -8681,12 +8977,12 @@ static void FinaliseCargoArray() static bool IsHouseSpecValid(HouseSpec *hs, const HouseSpec *next1, const HouseSpec *next2, const HouseSpec *next3, const char *filename) { if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 && - (next1 == NULL || !next1->enabled || (next1->building_flags & BUILDING_HAS_1_TILE) != 0)) || + (next1 == nullptr || !next1->enabled || (next1->building_flags & BUILDING_HAS_1_TILE) != 0)) || ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 && - (next2 == NULL || !next2->enabled || (next2->building_flags & BUILDING_HAS_1_TILE) != 0 || - next3 == NULL || !next3->enabled || (next3->building_flags & BUILDING_HAS_1_TILE) != 0))) { + (next2 == nullptr || !next2->enabled || (next2->building_flags & BUILDING_HAS_1_TILE) != 0 || + next3 == nullptr || !next3->enabled || (next3->building_flags & BUILDING_HAS_1_TILE) != 0))) { hs->enabled = false; - if (filename != NULL) DEBUG(grf, 1, "FinaliseHouseArray: %s defines house %d as multitile, but no suitable tiles follow. Disabling house.", filename, hs->grf_prop.local_id); + if (filename != nullptr) DEBUG(grf, 1, "FinaliseHouseArray: %s defines house %d as multitile, but no suitable tiles follow. Disabling house.", filename, hs->grf_prop.local_id); return false; } @@ -8696,13 +8992,13 @@ static bool IsHouseSpecValid(HouseSpec *hs, const HouseSpec *next1, const HouseS if (((hs->building_flags & BUILDING_HAS_2_TILES) != 0 && next1->population != 0) || ((hs->building_flags & BUILDING_HAS_4_TILES) != 0 && (next2->population != 0 || next3->population != 0))) { hs->enabled = false; - if (filename != NULL) DEBUG(grf, 1, "FinaliseHouseArray: %s defines multitile house %d with non-zero population on additional tiles. Disabling house.", filename, hs->grf_prop.local_id); + if (filename != nullptr) DEBUG(grf, 1, "FinaliseHouseArray: %s defines multitile house %d with non-zero population on additional tiles. Disabling house.", filename, hs->grf_prop.local_id); return false; } /* Substitute type is also used for override, and having an override with a different size causes crashes. * This check should only be done for NewGRF houses because grf_prop.subst_id is not set for original houses.*/ - if (filename != NULL && (hs->building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs->grf_prop.subst_id)->building_flags & BUILDING_HAS_1_TILE)) { + if (filename != nullptr && (hs->building_flags & BUILDING_HAS_1_TILE) != (HouseSpec::Get(hs->grf_prop.subst_id)->building_flags & BUILDING_HAS_1_TILE)) { hs->enabled = false; DEBUG(grf, 1, "FinaliseHouseArray: %s defines house %d with different house size then it's substitute type. Disabling house.", filename, hs->grf_prop.local_id); return false; @@ -8711,7 +9007,7 @@ static bool IsHouseSpecValid(HouseSpec *hs, const HouseSpec *next1, const HouseS /* Make sure that additional parts of multitile houses are not available. */ if ((hs->building_flags & BUILDING_HAS_1_TILE) == 0 && (hs->building_availability & HZ_ZONALL) != 0 && (hs->building_availability & HZ_CLIMALL) != 0) { hs->enabled = false; - if (filename != NULL) DEBUG(grf, 1, "FinaliseHouseArray: %s defines house %d without a size but marked it as available. Disabling house.", filename, hs->grf_prop.local_id); + if (filename != nullptr) DEBUG(grf, 1, "FinaliseHouseArray: %s defines house %d without a size but marked it as available. Disabling house.", filename, hs->grf_prop.local_id); return false; } @@ -8730,7 +9026,7 @@ static void EnsureEarlyHouse(HouseZones bitmask) for (int i = 0; i < NUM_HOUSES; i++) { HouseSpec *hs = HouseSpec::Get(i); - if (hs == NULL || !hs->enabled) continue; + if (hs == nullptr || !hs->enabled) continue; if ((hs->building_availability & bitmask) != bitmask) continue; if (hs->min_year < min_year) min_year = hs->min_year; } @@ -8739,7 +9035,7 @@ static void EnsureEarlyHouse(HouseZones bitmask) for (int i = 0; i < NUM_HOUSES; i++) { HouseSpec *hs = HouseSpec::Get(i); - if (hs == NULL || !hs->enabled) continue; + if (hs == nullptr || !hs->enabled) continue; if ((hs->building_availability & bitmask) != bitmask) continue; if (hs->min_year == min_year) hs->min_year = 0; } @@ -8762,21 +9058,20 @@ static void FinaliseHouseArray() * On the other hand, why 1930? Just 'fix' the houses with the lowest * minimum introduction date to 0. */ - const GRFFile * const *end = _grf_files.End(); - for (GRFFile **file = _grf_files.Begin(); file != end; file++) { - HouseSpec **&housespec = (*file)->housespec; - if (housespec == NULL) continue; + for (GRFFile * const file : _grf_files) { + HouseSpec **&housespec = file->housespec; + if (housespec == nullptr) continue; for (int i = 0; i < NUM_HOUSES_PER_GRF; i++) { HouseSpec *hs = housespec[i]; - if (hs == NULL) continue; + if (hs == nullptr) continue; - const HouseSpec *next1 = (i + 1 < NUM_HOUSES_PER_GRF ? housespec[i + 1] : NULL); - const HouseSpec *next2 = (i + 2 < NUM_HOUSES_PER_GRF ? housespec[i + 2] : NULL); - const HouseSpec *next3 = (i + 3 < NUM_HOUSES_PER_GRF ? housespec[i + 3] : NULL); + const HouseSpec *next1 = (i + 1 < NUM_HOUSES_PER_GRF ? housespec[i + 1] : nullptr); + const HouseSpec *next2 = (i + 2 < NUM_HOUSES_PER_GRF ? housespec[i + 2] : nullptr); + const HouseSpec *next3 = (i + 3 < NUM_HOUSES_PER_GRF ? housespec[i + 3] : nullptr); - if (!IsHouseSpecValid(hs, next1, next2, next3, (*file)->filename)) continue; + if (!IsHouseSpecValid(hs, next1, next2, next3, file->filename)) continue; _house_mngr.SetEntitySpec(hs); } @@ -8784,13 +9079,13 @@ static void FinaliseHouseArray() for (int i = 0; i < NUM_HOUSES; i++) { HouseSpec *hs = HouseSpec::Get(i); - const HouseSpec *next1 = (i + 1 < NUM_HOUSES ? HouseSpec::Get(i + 1) : NULL); - const HouseSpec *next2 = (i + 2 < NUM_HOUSES ? HouseSpec::Get(i + 2) : NULL); - const HouseSpec *next3 = (i + 3 < NUM_HOUSES ? HouseSpec::Get(i + 3) : NULL); + const HouseSpec *next1 = (i + 1 < NUM_HOUSES ? HouseSpec::Get(i + 1) : nullptr); + const HouseSpec *next2 = (i + 2 < NUM_HOUSES ? HouseSpec::Get(i + 2) : nullptr); + const HouseSpec *next3 = (i + 3 < NUM_HOUSES ? HouseSpec::Get(i + 3) : nullptr); /* We need to check all houses again to we are sure that multitile houses * did get consecutive IDs and none of the parts are missing. */ - if (!IsHouseSpecValid(hs, next1, next2, next3, NULL)) { + if (!IsHouseSpecValid(hs, next1, next2, next3, nullptr)) { /* GetHouseNorthPart checks 3 houses that are directly before * it in the house pool. If any of those houses have multi-tile * flags set it assumes it's part of a multitile house. Since @@ -8825,15 +9120,14 @@ static void FinaliseHouseArray() */ static void FinaliseIndustriesArray() { - const GRFFile * const *end = _grf_files.End(); - for (GRFFile **file = _grf_files.Begin(); file != end; file++) { - IndustrySpec **&industryspec = (*file)->industryspec; - IndustryTileSpec **&indtspec = (*file)->indtspec; - if (industryspec != NULL) { + for (GRFFile * const file : _grf_files) { + IndustrySpec **&industryspec = file->industryspec; + IndustryTileSpec **&indtspec = file->indtspec; + if (industryspec != nullptr) { for (int i = 0; i < NUM_INDUSTRYTYPES_PER_GRF; i++) { IndustrySpec *indsp = industryspec[i]; - if (indsp != NULL && indsp->enabled) { + if (indsp != nullptr && indsp->enabled) { StringID strid; /* process the conversion of text at the end, so to be sure everything will be fine * and available. Check if it does not return undefind marker, which is a very good sign of a @@ -8866,10 +9160,10 @@ static void FinaliseIndustriesArray() } } - if (indtspec != NULL) { + if (indtspec != nullptr) { for (int i = 0; i < NUM_INDUSTRYTILES_PER_GRF; i++) { IndustryTileSpec *indtsp = indtspec[i]; - if (indtsp != NULL) { + if (indtsp != nullptr) { _industile_mngr.SetEntitySpec(indtsp); } } @@ -8878,7 +9172,7 @@ static void FinaliseIndustriesArray() for (uint j = 0; j < NUM_INDUSTRYTYPES; j++) { IndustrySpec *indsp = &_industry_specs[j]; - if (indsp->enabled && indsp->grf_prop.grffile != NULL) { + if (indsp->enabled && indsp->grf_prop.grffile != nullptr) { for (uint i = 0; i < 3; i++) { indsp->conflicting[i] = MapNewGRFIndustryType(indsp->conflicting[i], indsp->grf_prop.grffile->grfid); } @@ -8896,12 +9190,11 @@ static void FinaliseIndustriesArray() */ static void FinaliseObjectsArray() { - const GRFFile * const *end = _grf_files.End(); - for (GRFFile **file = _grf_files.Begin(); file != end; file++) { - ObjectSpec **&objectspec = (*file)->objectspec; - if (objectspec != NULL) { + for (GRFFile * const file : _grf_files) { + ObjectSpec **&objectspec = file->objectspec; + if (objectspec != nullptr) { for (int i = 0; i < NUM_OBJECTS_PER_GRF; i++) { - if (objectspec[i] != NULL && objectspec[i]->grf_prop.grffile != NULL && objectspec[i]->enabled) { + if (objectspec[i] != nullptr && objectspec[i]->grf_prop.grffile != nullptr && objectspec[i]->enabled) { _object_mngr.SetEntitySpec(objectspec[i]); } } @@ -8916,21 +9209,20 @@ static void FinaliseObjectsArray() */ static void FinaliseAirportsArray() { - const GRFFile * const *end = _grf_files.End(); - for (GRFFile **file = _grf_files.Begin(); file != end; file++) { - AirportSpec **&airportspec = (*file)->airportspec; - if (airportspec != NULL) { + for (GRFFile * const file : _grf_files) { + AirportSpec **&airportspec = file->airportspec; + if (airportspec != nullptr) { for (int i = 0; i < NUM_AIRPORTS_PER_GRF; i++) { - if (airportspec[i] != NULL && airportspec[i]->enabled) { + if (airportspec[i] != nullptr && airportspec[i]->enabled) { _airport_mngr.SetEntitySpec(airportspec[i]); } } } - AirportTileSpec **&airporttilespec = (*file)->airtspec; - if (airporttilespec != NULL) { + AirportTileSpec **&airporttilespec = file->airtspec; + if (airporttilespec != nullptr) { for (uint i = 0; i < NUM_AIRPORTTILES_PER_GRF; i++) { - if (airporttilespec[i] != NULL && airporttilespec[i]->enabled) { + if (airporttilespec[i] != nullptr && airporttilespec[i]->enabled) { _airporttile_mngr.SetEntitySpec(airporttilespec[i]); } } @@ -8959,27 +9251,27 @@ static void DecodeSpecialSprite(byte *buf, uint num, GrfLoadingStage stage) * is not in memory and scanning the file every time would be too expensive. * In other stages we skip action 0x10 since it's already dealt with. */ static const SpecialSpriteHandler handlers[][GLS_END] = { - /* 0x00 */ { NULL, SafeChangeInfo, NULL, NULL, ReserveChangeInfo, FeatureChangeInfo, }, - /* 0x01 */ { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, }, - /* 0x02 */ { NULL, NULL, NULL, NULL, NULL, NewSpriteGroup, }, - /* 0x03 */ { NULL, GRFUnsafe, NULL, NULL, NULL, FeatureMapSpriteGroup, }, - /* 0x04 */ { NULL, NULL, NULL, NULL, NULL, FeatureNewName, }, - /* 0x05 */ { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, }, - /* 0x06 */ { NULL, NULL, NULL, CfgApply, CfgApply, CfgApply, }, - /* 0x07 */ { NULL, NULL, NULL, NULL, SkipIf, SkipIf, }, - /* 0x08 */ { ScanInfo, NULL, NULL, GRFInfo, GRFInfo, GRFInfo, }, - /* 0x09 */ { NULL, NULL, NULL, SkipIf, SkipIf, SkipIf, }, - /* 0x0A */ { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, }, - /* 0x0B */ { NULL, NULL, NULL, GRFLoadError, GRFLoadError, GRFLoadError, }, - /* 0x0C */ { NULL, NULL, NULL, GRFComment, NULL, GRFComment, }, - /* 0x0D */ { NULL, SafeParamSet, NULL, ParamSet, ParamSet, ParamSet, }, - /* 0x0E */ { NULL, SafeGRFInhibit, NULL, GRFInhibit, GRFInhibit, GRFInhibit, }, - /* 0x0F */ { NULL, GRFUnsafe, NULL, FeatureTownName, NULL, NULL, }, - /* 0x10 */ { NULL, NULL, DefineGotoLabel, NULL, NULL, NULL, }, - /* 0x11 */ { SkipAct11,GRFUnsafe, SkipAct11, GRFSound, SkipAct11, GRFSound, }, - /* 0x12 */ { SkipAct12, SkipAct12, SkipAct12, SkipAct12, SkipAct12, LoadFontGlyph, }, - /* 0x13 */ { NULL, NULL, NULL, NULL, NULL, TranslateGRFStrings, }, - /* 0x14 */ { StaticGRFInfo, NULL, NULL, NULL, NULL, NULL, }, + /* 0x00 */ { nullptr, SafeChangeInfo, nullptr, nullptr, ReserveChangeInfo, FeatureChangeInfo, }, + /* 0x01 */ { SkipAct1, SkipAct1, SkipAct1, SkipAct1, SkipAct1, NewSpriteSet, }, + /* 0x02 */ { nullptr, nullptr, nullptr, nullptr, nullptr, NewSpriteGroup, }, + /* 0x03 */ { nullptr, GRFUnsafe, nullptr, nullptr, nullptr, FeatureMapSpriteGroup, }, + /* 0x04 */ { nullptr, nullptr, nullptr, nullptr, nullptr, FeatureNewName, }, + /* 0x05 */ { SkipAct5, SkipAct5, SkipAct5, SkipAct5, SkipAct5, GraphicsNew, }, + /* 0x06 */ { nullptr, nullptr, nullptr, CfgApply, CfgApply, CfgApply, }, + /* 0x07 */ { nullptr, nullptr, nullptr, nullptr, SkipIf, SkipIf, }, + /* 0x08 */ { ScanInfo, nullptr, nullptr, GRFInfo, GRFInfo, GRFInfo, }, + /* 0x09 */ { nullptr, nullptr, nullptr, SkipIf, SkipIf, SkipIf, }, + /* 0x0A */ { SkipActA, SkipActA, SkipActA, SkipActA, SkipActA, SpriteReplace, }, + /* 0x0B */ { nullptr, nullptr, nullptr, GRFLoadError, GRFLoadError, GRFLoadError, }, + /* 0x0C */ { nullptr, nullptr, nullptr, GRFComment, nullptr, GRFComment, }, + /* 0x0D */ { nullptr, SafeParamSet, nullptr, ParamSet, ParamSet, ParamSet, }, + /* 0x0E */ { nullptr, SafeGRFInhibit, nullptr, GRFInhibit, GRFInhibit, GRFInhibit, }, + /* 0x0F */ { nullptr, GRFUnsafe, nullptr, FeatureTownName, nullptr, nullptr, }, + /* 0x10 */ { nullptr, nullptr, DefineGotoLabel, nullptr, nullptr, nullptr, }, + /* 0x11 */ { SkipAct11, GRFUnsafe, SkipAct11, GRFSound, SkipAct11, GRFSound, }, + /* 0x12 */ { SkipAct12, SkipAct12, SkipAct12, SkipAct12, SkipAct12, LoadFontGlyph, }, + /* 0x13 */ { nullptr, nullptr, nullptr, nullptr, nullptr, TranslateGRFStrings, }, + /* 0x14 */ { StaticGRFInfo, nullptr, nullptr, nullptr, nullptr, nullptr, }, }; GRFLocation location(_cur.grfconfig->ident.grfid, _cur.nfo_line); @@ -9010,7 +9302,7 @@ static void DecodeSpecialSprite(byte *buf, uint num, GrfLoadingStage stage) grfmsg(2, "DecodeSpecialSprite: Unexpected import block, skipping"); } else if (action >= lengthof(handlers)) { grfmsg(7, "DecodeSpecialSprite: Skipping unknown action 0x%02X", action); - } else if (handlers[action][stage] == NULL) { + } else if (handlers[action][stage] == nullptr) { grfmsg(7, "DecodeSpecialSprite: Skipping action 0x%02X in stage %d", action, stage); } else { grfmsg(7, "DecodeSpecialSprite: Handling action 0x%02X in stage %d", action, stage); @@ -9071,7 +9363,7 @@ void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage, S * processed once at initialization. */ if (stage != GLS_FILESCAN && stage != GLS_SAFETYSCAN && stage != GLS_LABELSCAN) { _cur.grffile = GetFileByFilename(filename); - if (_cur.grffile == NULL) usererror("File '%s' lost in cache.\n", filename); + if (_cur.grffile == nullptr) usererror("File '%s' lost in cache.\n", filename); if (stage == GLS_RESERVE && config->status != GCS_INITIALISED) return; if (stage == GLS_ACTIVATION && !HasBit(config->flags, GCF_RESERVED)) return; } @@ -9206,6 +9498,21 @@ static void ActivateOldShore() } } +/** + * Replocate the old tram depot sprites to the new position, if no new ones were loaded. + */ +static void ActivateOldTramDepot() +{ + if (_loaded_newgrf_features.tram == TRAMWAY_REPLACE_DEPOT_WITH_TRACK) { + DupSprite(SPR_ROAD_DEPOT + 0, SPR_TRAMWAY_DEPOT_NO_TRACK + 0); // use road depot graphics for "no tracks" + DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 1, SPR_TRAMWAY_DEPOT_NO_TRACK + 1); + DupSprite(SPR_ROAD_DEPOT + 2, SPR_TRAMWAY_DEPOT_NO_TRACK + 2); // use road depot graphics for "no tracks" + DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 3, SPR_TRAMWAY_DEPOT_NO_TRACK + 3); + DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 4, SPR_TRAMWAY_DEPOT_NO_TRACK + 4); + DupSprite(SPR_TRAMWAY_DEPOT_WITH_TRACK + 5, SPR_TRAMWAY_DEPOT_NO_TRACK + 5); + } +} + /** * Decide whether price base multipliers of grfs shall apply globally or only to the grf specifying them */ @@ -9216,7 +9523,7 @@ static void FinalisePriceBaseMultipliers() static const uint32 override_features = (1 << GSF_TRAINS) | (1 << GSF_ROADVEHICLES) | (1 << GSF_SHIPS) | (1 << GSF_AIRCRAFT); /* Evaluate grf overrides */ - int num_grfs = _grf_files.Length(); + int num_grfs = (uint)_grf_files.size(); int *grf_overrides = AllocaM(int, num_grfs); for (int i = 0; i < num_grfs; i++) { grf_overrides[i] = -1; @@ -9226,9 +9533,9 @@ static void FinalisePriceBaseMultipliers() if (override == 0) continue; GRFFile *dest = GetFileByGRFID(override); - if (dest == NULL) continue; + if (dest == nullptr) continue; - grf_overrides[i] = _grf_files.FindIndex(dest); + grf_overrides[i] = find_index(_grf_files, dest); assert(grf_overrides[i] >= 0); } @@ -9288,10 +9595,9 @@ static void FinalisePriceBaseMultipliers() } /* Apply fallback prices for grf version < 8 */ - const GRFFile * const *end = _grf_files.End(); - for (GRFFile **file = _grf_files.Begin(); file != end; file++) { - if ((*file)->grf_version >= 8) continue; - PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers; + for (GRFFile * const file : _grf_files) { + if (file->grf_version >= 8) continue; + PriceMultipliers &price_base_multipliers = file->price_base_multipliers; for (Price p = PR_BEGIN; p < PR_END; p++) { Price fallback_price = _price_base_specs[p].fallback_price; if (fallback_price != INVALID_PRICE && price_base_multipliers[p] == INVALID_PRICE_MODIFIER) { @@ -9303,21 +9609,21 @@ static void FinalisePriceBaseMultipliers() } /* Decide local/global scope of price base multipliers */ - for (GRFFile **file = _grf_files.Begin(); file != end; file++) { - PriceMultipliers &price_base_multipliers = (*file)->price_base_multipliers; + for (GRFFile * const file : _grf_files) { + PriceMultipliers &price_base_multipliers = file->price_base_multipliers; for (Price p = PR_BEGIN; p < PR_END; p++) { if (price_base_multipliers[p] == INVALID_PRICE_MODIFIER) { /* No multiplier was set; set it to a neutral value */ price_base_multipliers[p] = 0; } else { - if (!HasBit((*file)->grf_features, _price_base_specs[p].grf_feature)) { + if (!HasBit(file->grf_features, _price_base_specs[p].grf_feature)) { /* The grf does not define any objects of the feature, * so it must be a difficulty setting. Apply it globally */ - DEBUG(grf, 3, "'%s' sets global price base multiplier %d", (*file)->filename, p); + DEBUG(grf, 3, "'%s' sets global price base multiplier %d", file->filename, p); SetPriceBaseMultiplier(p, price_base_multipliers[p]); price_base_multipliers[p] = 0; } else { - DEBUG(grf, 3, "'%s' sets local price base multiplier %d", (*file)->filename, p); + DEBUG(grf, 3, "'%s' sets local price base multiplier %d", file->filename, p); } } } @@ -9329,10 +9635,10 @@ extern void InitGRFTownGeneratorNames(); /** Finish loading NewGRFs and execute needed post-processing */ static void AfterLoadGRFs() { - for (StringIDMapping *it = _string_to_grf_mapping.Begin(); it != _string_to_grf_mapping.End(); it++) { - *it->target = MapGRFStringID(it->grfid, it->source); + for (StringIDMapping &it : _string_to_grf_mapping) { + *it.target = MapGRFStringID(it.grfid, it.source); } - _string_to_grf_mapping.Clear(); + _string_to_grf_mapping.clear(); /* Free the action 6 override sprites. */ for (GRFLineToSpriteOverride::iterator it = _grf_line_to_action6_sprite_override.begin(); it != _grf_line_to_action6_sprite_override.end(); it++) { @@ -9385,18 +9691,46 @@ static void AfterLoadGRFs() /* Load old shore sprites in new position, if they were replaced by ActionA */ ActivateOldShore(); + /* Load old tram depot sprites in new position, if no new ones are present */ + ActivateOldTramDepot(); + /* Set up custom rail types */ InitRailTypes(); + InitRoadTypes(); - Engine *e; - FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) { + for (Engine *e : Engine::IterateType(VEH_ROAD)) { if (_gted[e->index].rv_max_speed != 0) { /* Set RV maximum speed from the mph/0.8 unit value */ e->u.road.max_speed = _gted[e->index].rv_max_speed * 4; } + + RoadTramType rtt = HasBit(e->info.misc_flags, EF_ROAD_TRAM) ? RTT_TRAM : RTT_ROAD; + + const GRFFile *file = e->GetGRF(); + if (file == nullptr || _gted[e->index].roadtramtype == 0) { + e->u.road.roadtype = (rtt == RTT_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD; + continue; + } + + /* Remove +1 offset. */ + _gted[e->index].roadtramtype--; + + const std::vector *list = (rtt == RTT_TRAM) ? &file->tramtype_list : &file->roadtype_list; + if (_gted[e->index].roadtramtype < list->size()) + { + RoadTypeLabel rtl = (*list)[_gted[e->index].roadtramtype]; + RoadType rt = GetRoadTypeByLabel(rtl); + if (rt != INVALID_ROADTYPE && GetRoadTramType(rt) == rtt) { + e->u.road.roadtype = rt; + continue; + } + } + + /* Road type is not available, so disable this engine */ + e->info.climates = 0; } - FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) { + for (Engine *e : Engine::IterateType(VEH_TRAIN)) { RailType railtype = GetRailTypeByLabel(_gted[e->index].railtypelabel); if (railtype == INVALID_RAILTYPE) { /* Rail type is not available, so disable this engine */ @@ -9448,11 +9782,11 @@ void LoadNewGRF(uint load_index, uint file_index, uint num_baseset) /* * Reset the status of all files, so we can 'retry' to load them. * This is needed when one for example rearranges the NewGRFs in-game - * and a previously disabled NewGRF becomes useable. If it would not + * and a previously disabled NewGRF becomes usable. If it would not * be reset, the NewGRF would remain disabled even though it should * have been enabled. */ - for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) { + for (GRFConfig *c = _grfconfig; c != nullptr; c = c->next) { if (c->status != GCS_NOT_FOUND) c->status = GCS_UNKNOWN; } @@ -9464,7 +9798,7 @@ void LoadNewGRF(uint load_index, uint file_index, uint num_baseset) for (GrfLoadingStage stage = GLS_LABELSCAN; stage <= GLS_ACTIVATION; stage++) { /* Set activated grfs back to will-be-activated between reservation- and activation-stage. * This ensures that action7/9 conditions 0x06 - 0x0A work correctly. */ - for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) { + for (GRFConfig *c = _grfconfig; c != nullptr; c = c->next) { if (c->status == GCS_ACTIVATED) c->status = GCS_INITIALISED; } @@ -9483,7 +9817,7 @@ void LoadNewGRF(uint load_index, uint file_index, uint num_baseset) uint num_non_static = 0; _cur.stage = stage; - for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) { + for (GRFConfig *c = _grfconfig; c != nullptr; c = c->next) { if (c->status == GCS_DISABLED || c->status == GCS_NOT_FOUND) continue; if (stage > GLS_INIT && HasBit(c->flags, GCF_INIT_ONLY)) continue; diff --git a/src/newgrf.h b/src/newgrf.h index 1ab55dd044..00394c681c 100644 --- a/src/newgrf.h +++ b/src/newgrf.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. @@ -14,6 +12,7 @@ #include "cargotype.h" #include "rail_type.h" +#include "road_type.h" #include "fileio_type.h" #include "core/bitmath_func.hpp" #include "core/alloc_type.hpp" @@ -83,6 +82,8 @@ enum GrfSpecFeature { GSF_OBJECTS, GSF_RAILTYPES, GSF_AIRPORTTILES, + GSF_ROADTYPES, + GSF_TRAMTYPES, GSF_END, GSF_FAKE_TOWNS = GSF_END, ///< Fake town GrfSpecFeature for NewGRF debugging (parent scope) @@ -122,17 +123,23 @@ struct GRFFile : ZeroedMemoryAllocator { GRFLabel *label; ///< Pointer to the first label. This is a linked list, not an array. - SmallVector cargo_list; ///< Cargo translation table (local ID -> label) + std::vector cargo_list; ///< Cargo translation table (local ID -> label) uint8 cargo_map[NUM_CARGO]; ///< Inverse cargo translation table (CargoID -> local ID) - SmallVector railtype_list; ///< Railtype translation table - RailTypeByte railtype_map[RAILTYPE_END]; + std::vector railtype_list; ///< Railtype translation table + RailType railtype_map[RAILTYPE_END]; + + std::vector roadtype_list; ///< Roadtype translation table (road) + RoadType roadtype_map[ROADTYPE_END]; + + std::vector tramtype_list; ///, Roadtype translation table (tram) + RoadType tramtype_map[ROADTYPE_END]; CanalProperties canal_local_properties[CF_END]; ///< Canal properties as set by this NewGRF struct LanguageMap *language_map; ///< Mappings related to the languages. - int traininfo_vehicle_pitch; ///< Vertical offset for draing train images in depot GUI and vehicle details + int traininfo_vehicle_pitch; ///< Vertical offset for drawing train images in depot GUI and vehicle details uint traininfo_vehicle_width; ///< Width (in pixels) of a 8/8 train vehicle in depot GUI and vehicle details uint32 grf_features; ///< Bitset of GrfSpecFeature the grf uses @@ -158,12 +165,19 @@ enum ShoreReplacement { SHORE_REPLACE_ONLY_NEW, ///< Only corner-shores were loaded by Action5 (openttd(w/d).grf only). }; +enum TramReplacement { + TRAMWAY_REPLACE_DEPOT_NONE, ///< No tram depot graphics were loaded. + TRAMWAY_REPLACE_DEPOT_WITH_TRACK, ///< Electrified depot graphics with tram track were loaded. + TRAMWAY_REPLACE_DEPOT_NO_TRACK, ///< Electrified depot graphics without tram track were loaded. +}; + struct GRFLoadedFeatures { bool has_2CC; ///< Set if any vehicle is loaded which uses 2cc (two company colours). uint64 used_liveries; ///< Bitmask of #LiveryScheme used by the defined engines. bool has_newhouses; ///< Set if there are any newhouses loaded. bool has_newindustries; ///< Set if there are any newindustries loaded. - ShoreReplacement shore; ///< It which way shore sprites were replaced. + ShoreReplacement shore; ///< In which way shore sprites were replaced. + TramReplacement tram; ///< In which way tram depots were replaced. }; /** diff --git a/src/newgrf_airport.cpp b/src/newgrf_airport.cpp index 6213097bd0..61ad46ac0e 100644 --- a/src/newgrf_airport.cpp +++ b/src/newgrf_airport.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. @@ -21,7 +19,7 @@ /** Resolver for the airport scope. */ struct AirportScopeResolver : public ScopeResolver { - struct Station *st; ///< Station of the airport for which the callback is run, or \c NULL for build gui. + struct Station *st; ///< Station of the airport for which the callback is run, or \c nullptr for build gui. byte airport_id; ///< Type of airport for which the callback is run. byte layout; ///< Layout of the airport to build. TileIndex tile; ///< Tile for the callback, only valid for airporttile callbacks. @@ -30,7 +28,7 @@ struct AirportScopeResolver : public ScopeResolver { * Constructor of the scope resolver for an airport. * @param ro Surrounding resolver. * @param tile %Tile for the callback, only valid for airporttile callbacks. - * @param st %Station of the airport for which the callback is run, or \c NULL for build gui. + * @param st %Station of the airport for which the callback is run, or \c nullptr for build gui. * @param airport_id Type of airport for which the callback is run. * @param layout Layout of the airport to build. */ @@ -39,9 +37,9 @@ struct AirportScopeResolver : public ScopeResolver { { } - /* virtual */ uint32 GetRandomBits() const; - /* virtual */ uint32 GetVariable(byte variable, uint32 parameter, bool *available) const; - /* virtual */ void StorePSA(uint pos, int32 value); + uint32 GetRandomBits() const override; + uint32 GetVariable(byte variable, uint32 parameter, bool *available) const override; + void StorePSA(uint pos, int32 value) override; }; /** Resolver object for airports. */ @@ -51,7 +49,7 @@ struct AirportResolverObject : public ResolverObject { AirportResolverObject(TileIndex tile, Station *st, byte airport_id, byte layout, CallbackID callback = CBID_NO_CALLBACK, uint32 callback_param1 = 0, uint32 callback_param2 = 0); - /* virtual */ ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) + ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) override { switch (scope) { case VSG_SCOPE_SELF: return &this->airport_scope; @@ -59,7 +57,10 @@ struct AirportResolverObject : public ResolverObject { } } - /* virtual */ const SpriteGroup *ResolveReal(const RealSpriteGroup *group) const; + const SpriteGroup *ResolveReal(const RealSpriteGroup *group) const override; + + GrfSpecFeature GetFeature() const override; + uint32 GetDebugID() const override; }; /** @@ -100,6 +101,7 @@ AirportSpec AirportSpec::specs[NUM_AIRPORTS]; ///< Airport specifications. assert(type < lengthof(AirportSpec::specs)); const AirportSpec *as = &AirportSpec::specs[type]; if (type >= NEW_AIRPORT_OFFSET && !as->enabled) { + if (_airport_mngr.GetGRFID(type) == 0) return as; byte subst_id = _airport_mngr.GetSubstituteID(type); if (subst_id == AT_INVALID) return as; as = &AirportSpec::specs[subst_id]; @@ -129,6 +131,24 @@ bool AirportSpec::IsAvailable() const return _cur_year <= this->max_year; } +/** + * Check if the airport would be within the map bounds at the given tile. + * @param table Selected layout table. This affects airport rotation, and therefore dimensions. + * @param tile Top corner of the airport. + * @return true iff the airport would be within the map bounds at the given tile. + */ +bool AirportSpec::IsWithinMapBounds(byte table, TileIndex tile) const +{ + if (table >= this->num_table) return false; + + byte w = this->size_x; + 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(); +} + /** * This function initializes the airportspec array. */ @@ -183,14 +203,14 @@ void AirportOverrideManager::SetEntitySpec(AirportSpec *as) case 0x40: return this->layout; } - if (this->st == NULL) { + if (this->st == nullptr) { *available = false; return UINT_MAX; } switch (variable) { /* Get a variable from the persistent storage */ - case 0x7C: return (this->st->airport.psa != NULL) ? this->st->airport.psa->GetValue(parameter) : 0; + case 0x7C: return (this->st->airport.psa != nullptr) ? this->st->airport.psa->GetValue(parameter) : 0; case 0xF0: return this->st->facilities; case 0xFA: return Clamp(this->st->build_date - DAYS_TILL_ORIGINAL_BASE_YEAR, 0, 65535); @@ -206,12 +226,22 @@ void AirportOverrideManager::SetEntitySpec(AirportSpec *as) if (group->num_loaded > 0) return group->loaded[0]; if (group->num_loading > 0) return group->loading[0]; - return NULL; + return nullptr; +} + +GrfSpecFeature AirportResolverObject::GetFeature() const +{ + return GSF_AIRPORTS; +} + +uint32 AirportResolverObject::GetDebugID() const +{ + return AirportSpec::Get(this->airport_scope.airport_id)->grf_prop.local_id; } /* virtual */ uint32 AirportScopeResolver::GetRandomBits() const { - return this->st == NULL ? 0 : this->st->random_bits; + return this->st == nullptr ? 0 : this->st->random_bits; } /** @@ -221,14 +251,14 @@ void AirportOverrideManager::SetEntitySpec(AirportSpec *as) */ /* virtual */ void AirportScopeResolver::StorePSA(uint pos, int32 value) { - if (this->st == NULL) return; + if (this->st == nullptr) return; - if (this->st->airport.psa == NULL) { + if (this->st->airport.psa == nullptr) { /* There is no need to create a storage if the value is zero. */ if (value == 0) return; /* Create storage on first modification. */ - uint32 grfid = (this->ro.grffile != NULL) ? this->ro.grffile->grfid : 0; + uint32 grfid = (this->ro.grffile != nullptr) ? this->ro.grffile->grfid : 0; assert(PersistentStorage::CanAllocateItem()); this->st->airport.psa = new PersistentStorage(grfid, GSF_AIRPORTS, this->st->airport.tile); } @@ -238,7 +268,7 @@ void AirportOverrideManager::SetEntitySpec(AirportSpec *as) /** * Constructor of the airport resolver. * @param tile %Tile for the callback, only valid for airporttile callbacks. - * @param st %Station of the airport for which the callback is run, or \c NULL for build gui. + * @param st %Station of the airport for which the callback is run, or \c nullptr for build gui. * @param airport_id Type of airport for which the callback is run. * @param layout Layout of the airport to build. * @param callback Callback ID. @@ -254,9 +284,9 @@ AirportResolverObject::AirportResolverObject(TileIndex tile, Station *st, byte a SpriteID GetCustomAirportSprite(const AirportSpec *as, byte layout) { - AirportResolverObject object(INVALID_TILE, NULL, as->GetIndex(), layout); + AirportResolverObject object(INVALID_TILE, nullptr, as->GetIndex(), layout); const SpriteGroup *group = object.Resolve(); - if (group == NULL) return as->preview_sprite; + if (group == nullptr) return as->preview_sprite; return group->GetResult(); } @@ -276,7 +306,7 @@ uint16 GetAirportCallback(CallbackID callback, uint32 param1, uint32 param2, Sta */ StringID GetAirportTextCallback(const AirportSpec *as, byte layout, uint16 callback) { - AirportResolverObject object(INVALID_TILE, NULL, as->GetIndex(), layout, (CallbackID)callback); + AirportResolverObject object(INVALID_TILE, nullptr, as->GetIndex(), layout, (CallbackID)callback); uint16 cb_res = object.ResolveCallback(); if (cb_res == CALLBACK_FAILED || cb_res == 0x400) return STR_UNDEFINED; if (cb_res > 0x400) { diff --git a/src/newgrf_airport.h b/src/newgrf_airport.h index 867362e9ad..264da05ebb 100644 --- a/src/newgrf_airport.h +++ b/src/newgrf_airport.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. @@ -123,6 +121,7 @@ struct AirportSpec { static AirportSpec *GetWithoutOverride(byte type); bool IsAvailable() const; + bool IsWithinMapBounds(byte table, TileIndex index) const; static void ResetAirports(); diff --git a/src/newgrf_airporttiles.cpp b/src/newgrf_airporttiles.cpp index 2d3a5129c9..3059174a86 100644 --- a/src/newgrf_airporttiles.cpp +++ b/src/newgrf_airporttiles.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. @@ -149,7 +147,7 @@ static uint32 GetAirportTileIDAtOffset(TileIndex tile, const Station *st, uint32 } } /* Not an 'old type' tile */ - if (ats->grf_prop.spritegroup[0] != NULL) { // tile has a spritegroup ? + if (ats->grf_prop.spritegroup[0] != nullptr) { // tile has a spritegroup ? if (ats->grf_prop.grffile->grfid == cur_grfid) { // same airport, same grf ? return ats->grf_prop.local_id; } else { @@ -162,7 +160,7 @@ static uint32 GetAirportTileIDAtOffset(TileIndex tile, const Station *st, uint32 /* virtual */ uint32 AirportTileScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const { - assert(this->st != NULL); + assert(this->st != nullptr); extern uint32 GetRelativePosition(TileIndex tile, TileIndex ind_tile); @@ -203,14 +201,14 @@ static uint32 GetAirportTileIDAtOffset(TileIndex tile, const Station *st, uint32 /* virtual */ uint32 AirportTileScopeResolver::GetRandomBits() const { - return (this->st == NULL ? 0 : this->st->random_bits) | (this->tile == INVALID_TILE ? 0 : GetStationTileRandomBits(this->tile) << 16); + return (this->st == nullptr ? 0 : this->st->random_bits) | (this->tile == INVALID_TILE ? 0 : GetStationTileRandomBits(this->tile) << 16); } /** * Constructor of the resolver for airport tiles. * @param ats Specification of the airport tiles. * @param tile %Tile for the callback, only valid for airporttile callbacks. - * @param st Station of the airport for which the callback is run, or \c NULL for build gui. + * @param st Station of the airport for which the callback is run, or \c nullptr for build gui. * @param callback Callback ID. * @param callback_param1 First parameter (var 10) of the callback. * @param callback_param2 Second parameter (var 18) of the callback. @@ -222,6 +220,16 @@ AirportTileResolverObject::AirportTileResolverObject(const AirportTileSpec *ats, this->root_spritegroup = ats->grf_prop.spritegroup[0]; } +GrfSpecFeature AirportTileResolverObject::GetFeature() const +{ + return GSF_AIRPORTTILES; +} + +uint32 AirportTileResolverObject::GetDebugID() const +{ + return this->tiles_scope.ats->grf_prop.local_id; +} + uint16 GetAirportTileCallback(CallbackID callback, uint32 param1, uint32 param2, const AirportTileSpec *ats, Station *st, TileIndex tile, int extra_data = 0) { AirportTileResolverObject object(ats, tile, st, callback, param1, param2); @@ -230,7 +238,7 @@ uint16 GetAirportTileCallback(CallbackID callback, uint32 param1, uint32 param2, static void AirportDrawTileLayout(const TileInfo *ti, const TileLayoutSpriteGroup *group, byte colour, StationGfx gfx) { - const DrawTileSprites *dts = group->ProcessRegisters(NULL); + const DrawTileSprites *dts = group->ProcessRegisters(nullptr); SpriteID image = dts->ground.sprite; SpriteID pal = dts->ground.pal; @@ -261,7 +269,7 @@ bool DrawNewAirportTile(TileInfo *ti, Station *st, StationGfx gfx, const Airport AirportTileResolverObject object(airts, ti->tile, st); const SpriteGroup *group = object.Resolve(); - if (group == NULL || group->type != SGT_TILELAYOUT) { + if (group == nullptr || group->type != SGT_TILELAYOUT) { return false; } @@ -282,7 +290,7 @@ struct AirportTileAnimationBase : public AnimationBaseanimation_special_flags, 0)); } diff --git a/src/newgrf_airporttiles.h b/src/newgrf_airporttiles.h index dc04642037..37460622d4 100644 --- a/src/newgrf_airporttiles.h +++ b/src/newgrf_airporttiles.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. @@ -21,25 +19,26 @@ /** Scope resolver for handling the tiles of an airport. */ struct AirportTileScopeResolver : public ScopeResolver { - struct Station *st; ///< %Station of the airport for which the callback is run, or \c NULL for build gui. + struct Station *st; ///< %Station of the airport for which the callback is run, or \c nullptr for build gui. byte airport_id; ///< Type of airport for which the callback is run. TileIndex tile; ///< Tile for the callback, only valid for airporttile callbacks. + const AirportTileSpec *ats; /** * Constructor of the scope resolver specific for airport tiles. * @param ats Specification of the airport tiles. * @param tile %Tile for the callback, only valid for airporttile callbacks. - * @param st Station of the airport for which the callback is run, or \c NULL for build gui. + * @param st Station of the airport for which the callback is run, or \c nullptr for build gui. */ AirportTileScopeResolver(ResolverObject &ro, const AirportTileSpec *ats, TileIndex tile, Station *st) - : ScopeResolver(ro), st(st), tile(tile) + : ScopeResolver(ro), st(st), tile(tile), ats(ats) { - assert(st != NULL); + assert(st != nullptr); this->airport_id = st->airport.type; } - /* virtual */ uint32 GetRandomBits() const; - /* virtual */ uint32 GetVariable(byte variable, uint32 parameter, bool *available) const; + uint32 GetRandomBits() const override; + uint32 GetVariable(byte variable, uint32 parameter, bool *available) const override; }; /** Resolver for tiles of an airport. */ @@ -49,13 +48,16 @@ struct AirportTileResolverObject : public ResolverObject { AirportTileResolverObject(const AirportTileSpec *ats, TileIndex tile, Station *st, CallbackID callback = CBID_NO_CALLBACK, uint32 callback_param1 = 0, uint32 callback_param2 = 0); - /* virtual */ ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) + ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) override { switch (scope) { case VSG_SCOPE_SELF: return &tiles_scope; default: return ResolverObject::GetScope(scope, relative); } } + + GrfSpecFeature GetFeature() const override; + uint32 GetDebugID() const override; }; /** diff --git a/src/newgrf_animation_base.h b/src/newgrf_animation_base.h index 791f3d691a..ee8622b56e 100644 --- a/src/newgrf_animation_base.h +++ b/src/newgrf_animation_base.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. @@ -39,7 +37,7 @@ struct AnimationBase { */ static void AnimateTile(const Tspec *spec, Tobj *obj, TileIndex tile, bool random_animation, Textra extra_data = 0) { - assert(spec != NULL); + assert(spec != nullptr); /* Acquire the animation speed from the NewGRF. */ uint8 animation_speed = spec->animation.speed; diff --git a/src/newgrf_animation_type.h b/src/newgrf_animation_type.h index d014bf3cde..699a633152 100644 --- a/src/newgrf_animation_type.h +++ b/src/newgrf_animation_type.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/newgrf_callbacks.h b/src/newgrf_callbacks.h index 2c30241f07..ed32a3abf1 100644 --- a/src/newgrf_callbacks.h +++ b/src/newgrf_callbacks.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/newgrf_canal.cpp b/src/newgrf_canal.cpp index 3438bb9850..7295e5551b 100644 --- a/src/newgrf_canal.cpp +++ b/src/newgrf_canal.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. @@ -15,6 +13,7 @@ #include "newgrf_canal.h" #include "water.h" #include "water_map.h" +#include "spritecache.h" #include "safeguards.h" @@ -30,18 +29,19 @@ struct CanalScopeResolver : public ScopeResolver { { } - /* virtual */ uint32 GetRandomBits() const; - /* virtual */ uint32 GetVariable(byte variable, uint32 parameter, bool *available) const; + uint32 GetRandomBits() const override; + uint32 GetVariable(byte variable, uint32 parameter, bool *available) const override; }; /** Resolver object for canals. */ struct CanalResolverObject : public ResolverObject { CanalScopeResolver canal_scope; + CanalFeature feature; CanalResolverObject(CanalFeature feature, TileIndex tile, CallbackID callback = CBID_NO_CALLBACK, uint32 callback_param1 = 0, uint32 callback_param2 = 0); - /* virtual */ ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) + ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) override { switch (scope) { case VSG_SCOPE_SELF: return &this->canal_scope; @@ -49,7 +49,10 @@ struct CanalResolverObject : public ResolverObject { } } - /* virtual */ const SpriteGroup *ResolveReal(const RealSpriteGroup *group) const; + const SpriteGroup *ResolveReal(const RealSpriteGroup *group) const override; + + GrfSpecFeature GetFeature() const override; + uint32 GetDebugID() const override; }; /* virtual */ uint32 CanalScopeResolver::GetRandomBits() const @@ -108,11 +111,21 @@ struct CanalResolverObject : public ResolverObject { /* virtual */ const SpriteGroup *CanalResolverObject::ResolveReal(const RealSpriteGroup *group) const { - if (group->num_loaded == 0) return NULL; + if (group->num_loaded == 0) return nullptr; return group->loaded[0]; } +GrfSpecFeature CanalResolverObject::GetFeature() const +{ + return GSF_CANALS; +} + +uint32 CanalResolverObject::GetDebugID() const +{ + return this->feature; +} + /** * Canal resolver constructor. * @param feature Which canal feature we want. @@ -123,7 +136,7 @@ struct CanalResolverObject : public ResolverObject { */ CanalResolverObject::CanalResolverObject(CanalFeature feature, TileIndex tile, CallbackID callback, uint32 callback_param1, uint32 callback_param2) - : ResolverObject(_water_feature[feature].grffile, callback, callback_param1, callback_param2), canal_scope(*this, tile) + : ResolverObject(_water_feature[feature].grffile, callback, callback_param1, callback_param2), canal_scope(*this, tile), feature(feature) { this->root_spritegroup = _water_feature[feature].group; } @@ -138,7 +151,7 @@ SpriteID GetCanalSprite(CanalFeature feature, TileIndex tile) { CanalResolverObject object(feature, tile); const SpriteGroup *group = object.Resolve(); - if (group == NULL) return 0; + if (group == nullptr) return 0; return group->GetResult(); } diff --git a/src/newgrf_canal.h b/src/newgrf_canal.h index 5ae273bf15..05631216fa 100644 --- a/src/newgrf_canal.h +++ b/src/newgrf_canal.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/newgrf_cargo.cpp b/src/newgrf_cargo.cpp index 7d830c5730..22c7120d82 100644 --- a/src/newgrf_cargo.cpp +++ b/src/newgrf_cargo.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. @@ -17,9 +15,14 @@ /** Resolver of cargo. */ struct CargoResolverObject : public ResolverObject { + const CargoSpec *cargospec; + CargoResolverObject(const CargoSpec *cs, CallbackID callback = CBID_NO_CALLBACK, uint32 callback_param1 = 0, uint32 callback_param2 = 0); - /* virtual */ const SpriteGroup *ResolveReal(const RealSpriteGroup *group) const; + const SpriteGroup *ResolveReal(const RealSpriteGroup *group) const override; + + GrfSpecFeature GetFeature() const override; + uint32 GetDebugID() const override; }; /* virtual */ const SpriteGroup *CargoResolverObject::ResolveReal(const RealSpriteGroup *group) const @@ -29,7 +32,17 @@ struct CargoResolverObject : public ResolverObject { if (group->num_loaded > 0) return group->loaded[0]; if (group->num_loading > 0) return group->loading[0]; - return NULL; + return nullptr; +} + +GrfSpecFeature CargoResolverObject::GetFeature() const +{ + return GSF_CARGOES; +} + +uint32 CargoResolverObject::GetDebugID() const +{ + return this->cargospec->label; } /** @@ -40,7 +53,7 @@ struct CargoResolverObject : public ResolverObject { * @param callback_param2 Second parameter (var 18) of the callback. */ CargoResolverObject::CargoResolverObject(const CargoSpec *cs, CallbackID callback, uint32 callback_param1, uint32 callback_param2) - : ResolverObject(cs->grffile, callback, callback_param1, callback_param2) + : ResolverObject(cs->grffile, callback, callback_param1, callback_param2), cargospec(cs) { this->root_spritegroup = cs->group; } @@ -54,7 +67,7 @@ SpriteID GetCustomCargoSprite(const CargoSpec *cs) { CargoResolverObject object(cs); const SpriteGroup *group = object.Resolve(); - if (group == NULL) return 0; + if (group == nullptr) return 0; return group->GetResult(); } @@ -82,10 +95,10 @@ CargoID GetCargoTranslation(uint8 cargo, const GRFFile *grffile, bool usebit) /* Other cases use (possibly translated) cargobits */ - if (grffile->cargo_list.Length() > 0) { + if (grffile->cargo_list.size() > 0) { /* ...and the cargo is in bounds, then get the cargo ID for * the label */ - if (cargo < grffile->cargo_list.Length()) return GetCargoIDByLabel(grffile->cargo_list[cargo]); + if (cargo < grffile->cargo_list.size()) return GetCargoIDByLabel(grffile->cargo_list[cargo]); } else { /* Else the cargo value is a 'climate independent' 'bitnum' */ return GetCargoIDByBitnum(cargo); diff --git a/src/newgrf_cargo.h b/src/newgrf_cargo.h index 51add1e7a9..ec0e2f019e 100644 --- a/src/newgrf_cargo.h +++ b/src/newgrf_cargo.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/newgrf_class.h b/src/newgrf_class.h index 71b5608d84..7610cfb9d9 100644 --- a/src/newgrf_class.h +++ b/src/newgrf_class.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/newgrf_class_func.h b/src/newgrf_class_func.h index c2a30992ae..f97ba58b95 100644 --- a/src/newgrf_class_func.h +++ b/src/newgrf_class_func.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. @@ -34,7 +32,7 @@ DEFINE_NEWGRF_CLASS_METHOD(void)::ResetClass() this->ui_count = 0; free(this->spec); - this->spec = NULL; + this->spec = nullptr; } /** Reset the classes, i.e. clear everything. */ @@ -154,7 +152,7 @@ DEFINE_NEWGRF_CLASS_METHOD(Tid)::GetUIClass(uint index) DEFINE_NEWGRF_CLASS_METHOD(const Tspec *)::GetSpec(uint index) const { /* If the custom spec isn't defined any more, then the GRF file probably was not loaded. */ - return index < this->GetSpecCount() ? this->spec[index] : NULL; + return index < this->GetSpecCount() ? this->spec[index] : nullptr; } /** @@ -191,7 +189,7 @@ DEFINE_NEWGRF_CLASS_METHOD(int)::GetUIFromIndex(int index) const * Retrieve a spec by GRF location. * @param grfid GRF ID of spec. * @param local_id Index within GRF file of spec. - * @param index Pointer to return the index of the spec in its class. If NULL then not used. + * @param index Pointer to return the index of the spec in its class. If nullptr then not used. * @return The spec. */ DEFINE_NEWGRF_CLASS_METHOD(const Tspec *)::GetByGrf(uint32 grfid, byte local_id, int *index) @@ -201,15 +199,15 @@ DEFINE_NEWGRF_CLASS_METHOD(const Tspec *)::GetByGrf(uint32 grfid, byte local_id, for (Tid i = (Tid)0; i < Tmax; i++) { for (j = 0; j < classes[i].count; j++) { const Tspec *spec = classes[i].spec[j]; - if (spec == NULL) continue; + if (spec == nullptr) continue; if (spec->grf_prop.grffile->grfid == grfid && spec->grf_prop.local_id == local_id) { - if (index != NULL) *index = j; + if (index != nullptr) *index = j; return spec; } } } - return NULL; + return nullptr; } #undef DEFINE_NEWGRF_CLASS_METHOD diff --git a/src/newgrf_commons.cpp b/src/newgrf_commons.cpp index 4caf3a5d47..8209d675cd 100644 --- a/src/newgrf_commons.cpp +++ b/src/newgrf_commons.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. @@ -235,9 +233,9 @@ uint16 IndustryOverrideManager::AddEntityID(byte grf_local_id, uint32 grfid, byt const IndustrySpec *inds = GetIndustrySpec(id); /* This industry must be one that is not available(enabled), mostly because of climate. - * And it must not already be used by a grf (grffile == NULL). + * 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 == NULL) { + if (!inds->enabled && inds->grf_prop.grffile == nullptr) { EntityIDMapping *map = &mapping_ID[id]; if (map->entity_id == 0 && map->grfid == 0) { @@ -279,7 +277,7 @@ void IndustryOverrideManager::SetEntitySpec(IndustrySpec *inds) } /* Now that we know we can use the given id, copy the spec to its final destination... */ - memcpy(&_industry_specs[ind_id], inds, sizeof(*inds)); + _industry_specs[ind_id] = *inds; /* ... and mark it as usable*/ _industry_specs[ind_id].enabled = true; } @@ -463,13 +461,13 @@ uint32 GetNearbyTileInformation(TileIndex tile, bool grf_version8) /** * Returns company information like in vehicle var 43 or station var 43. * @param owner Owner of the object. - * @param l Livery of the object; NULL to use default. + * @param l Livery of the object; nullptr to use default. * @return NewGRF company information. */ uint32 GetCompanyInfo(CompanyID owner, const Livery *l) { - if (l == NULL && Company::IsValidID(owner)) l = &Company::Get(owner)->livery[LS_DEFAULT]; - return owner | (Company::IsValidAiID(owner) ? 0x10000 : 0) | (l != NULL ? (l->colour1 << 24) | (l->colour2 << 28) : 0); + if (l == nullptr && Company::IsValidID(owner)) l = &Company::Get(owner)->livery[LS_DEFAULT]; + return owner | (Company::IsValidAiID(owner) ? 0x10000 : 0) | (l != nullptr ? (l->colour1 << 24) | (l->colour2 << 28) : 0); } /** @@ -579,7 +577,7 @@ bool Convert8bitBooleanCallback(const GRFFile *grffile, uint16 cbid, uint16 cb_r } -/* static */ SmallVector NewGRFSpriteLayout::result_seq; +/* static */ std::vector NewGRFSpriteLayout::result_seq; /** * Clone the building sprites of a spritelayout. @@ -587,8 +585,8 @@ bool Convert8bitBooleanCallback(const GRFFile *grffile, uint16 cbid, uint16 cb_r */ void NewGRFSpriteLayout::Clone(const DrawTileSeqStruct *source) { - assert(this->seq == NULL); - assert(source != NULL); + assert(this->seq == nullptr); + assert(source != nullptr); size_t count = 1; // 1 for the terminator const DrawTileSeqStruct *element; @@ -607,7 +605,7 @@ void NewGRFSpriteLayout::Clone(const NewGRFSpriteLayout *source) { this->Clone((const DrawTileSprites*)source); - if (source->registers != NULL) { + if (source->registers != nullptr) { size_t count = 1; // 1 for the ground sprite const DrawTileSeqStruct *element; foreach_draw_tile_seq(element, source->seq) count++; @@ -625,7 +623,7 @@ void NewGRFSpriteLayout::Clone(const NewGRFSpriteLayout *source) */ void NewGRFSpriteLayout::Allocate(uint num_sprites) { - assert(this->seq == NULL); + assert(this->seq == nullptr); DrawTileSeqStruct *sprites = CallocT(num_sprites + 1); sprites[num_sprites].MakeTerminator(); @@ -637,8 +635,8 @@ void NewGRFSpriteLayout::Allocate(uint num_sprites) */ void NewGRFSpriteLayout::AllocateRegisters() { - assert(this->seq != NULL); - assert(this->registers == NULL); + assert(this->seq != nullptr); + assert(this->registers == nullptr); size_t count = 1; // 1 for the ground sprite const DrawTileSeqStruct *element; @@ -650,7 +648,7 @@ void NewGRFSpriteLayout::AllocateRegisters() /** * Prepares a sprite layout before resolving action-1-2-3 chains. * Integrates offsets into the layout and determines which chains to resolve. - * @note The function uses statically allocated temporary storage, which is reused everytime when calling the function. + * @note The function uses statically allocated temporary storage, which is reused every time when calling the function. * That means, you have to use the sprite layout before calling #PrepareLayout() the next time. * @param orig_offset Offset to apply to non-action-1 sprites. * @param newgrf_ground_offset Offset to apply to action-1 ground sprites. @@ -661,12 +659,13 @@ void NewGRFSpriteLayout::AllocateRegisters() */ uint32 NewGRFSpriteLayout::PrepareLayout(uint32 orig_offset, uint32 newgrf_ground_offset, uint32 newgrf_offset, uint constr_stage, bool separate_ground) const { - result_seq.Clear(); + result_seq.clear(); uint32 var10_values = 0; /* Create a copy of the spritelayout, so we can modify some values. * Also include the groundsprite into the sequence for easier processing. */ - DrawTileSeqStruct *result = result_seq.Append(); + /*C++17: DrawTileSeqStruct *result = &*/ result_seq.emplace_back(); + DrawTileSeqStruct *result = &result_seq.back(); result->image = ground; result->delta_x = 0; result->delta_y = 0; @@ -674,17 +673,17 @@ uint32 NewGRFSpriteLayout::PrepareLayout(uint32 orig_offset, uint32 newgrf_groun const DrawTileSeqStruct *dtss; foreach_draw_tile_seq(dtss, this->seq) { - *result_seq.Append() = *dtss; + result_seq.push_back(*dtss); } - result_seq.Append()->MakeTerminator(); - + result_seq.emplace_back() /*C++17: .MakeTerminator()*/; + result_seq.back().MakeTerminator(); /* Determine the var10 values the action-1-2-3 chains needs to be resolved for, * and apply the default sprite offsets (unless disabled). */ const TileLayoutRegisters *regs = this->registers; bool ground = true; - foreach_draw_tile_seq(result, result_seq.Begin()) { + foreach_draw_tile_seq(result, result_seq.data()) { TileLayoutFlags flags = TLF_NOTHING; - if (regs != NULL) flags = regs->flags; + if (regs != nullptr) flags = regs->flags; /* Record var10 value for the sprite */ if (HasBit(result->image.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE) || (flags & TLF_SPRITE_REG_FLAGS)) { @@ -696,7 +695,7 @@ uint32 NewGRFSpriteLayout::PrepareLayout(uint32 orig_offset, uint32 newgrf_groun if (!(flags & TLF_SPRITE)) { if (HasBit(result->image.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE)) { result->image.sprite += ground ? newgrf_ground_offset : newgrf_offset; - if (constr_stage > 0 && regs != NULL) result->image.sprite += GetConstructionStageOffset(constr_stage, regs->max_sprite_offset); + if (constr_stage > 0 && regs != nullptr) result->image.sprite += GetConstructionStageOffset(constr_stage, regs->max_sprite_offset); } else { result->image.sprite += orig_offset; } @@ -712,12 +711,12 @@ uint32 NewGRFSpriteLayout::PrepareLayout(uint32 orig_offset, uint32 newgrf_groun if (!(flags & TLF_PALETTE)) { if (HasBit(result->image.pal, SPRITE_MODIFIER_CUSTOM_SPRITE)) { result->image.sprite += ground ? newgrf_ground_offset : newgrf_offset; - if (constr_stage > 0 && regs != NULL) result->image.sprite += GetConstructionStageOffset(constr_stage, regs->max_palette_offset); + if (constr_stage > 0 && regs != nullptr) result->image.sprite += GetConstructionStageOffset(constr_stage, regs->max_palette_offset); } } ground = false; - if (regs != NULL) regs++; + if (regs != nullptr) regs++; } return var10_values; @@ -736,9 +735,9 @@ void NewGRFSpriteLayout::ProcessRegisters(uint8 resolved_var10, uint32 resolved_ DrawTileSeqStruct *result; const TileLayoutRegisters *regs = this->registers; bool ground = true; - foreach_draw_tile_seq(result, result_seq.Begin()) { + foreach_draw_tile_seq(result, result_seq.data()) { TileLayoutFlags flags = TLF_NOTHING; - if (regs != NULL) flags = regs->flags; + if (regs != nullptr) flags = regs->flags; /* Is the sprite or bounding box affected by an action-1-2-3 chain? */ if (HasBit(result->image.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE) || (flags & TLF_SPRITE_REG_FLAGS)) { @@ -793,6 +792,6 @@ void NewGRFSpriteLayout::ProcessRegisters(uint8 resolved_var10, uint32 resolved_ } ground = false; - if (regs != NULL) regs++; + if (regs != nullptr) regs++; } } diff --git a/src/newgrf_commons.h b/src/newgrf_commons.h index 5721b7eb20..ed18aaa9e2 100644 --- a/src/newgrf_commons.h +++ b/src/newgrf_commons.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. @@ -132,7 +130,7 @@ struct NewGRFSpriteLayout : ZeroedMemoryAllocator, DrawTileSprites { */ void Clone(const DrawTileSprites *source) { - assert(source != NULL && this != source); + assert(source != nullptr && this != source); this->ground = source->ground; this->Clone(source->seq); } @@ -151,7 +149,7 @@ struct NewGRFSpriteLayout : ZeroedMemoryAllocator, DrawTileSprites { */ bool NeedsPreprocessing() const { - return this->registers != NULL; + return this->registers != nullptr; } uint32 PrepareLayout(uint32 orig_offset, uint32 newgrf_ground_offset, uint32 newgrf_offset, uint constr_stage, bool separate_ground) const; @@ -164,13 +162,13 @@ struct NewGRFSpriteLayout : ZeroedMemoryAllocator, DrawTileSprites { */ const DrawTileSeqStruct *GetLayout(PalSpriteID *ground) const { - DrawTileSeqStruct *front = result_seq.Begin(); + DrawTileSeqStruct *front = result_seq.data(); *ground = front->image; return front + 1; } private: - static SmallVector result_seq; ///< Temporary storage when preprocessing spritelayouts. + static std::vector result_seq; ///< Temporary storage when preprocessing spritelayouts. }; /** @@ -228,6 +226,7 @@ class HouseOverrideManager : public OverrideManagerBase { public: HouseOverrideManager(uint16 offset, uint16 maximum, uint16 invalid) : OverrideManagerBase(offset, maximum, invalid) {} + void SetEntitySpec(const HouseSpec *hs); }; @@ -238,8 +237,9 @@ public: IndustryOverrideManager(uint16 offset, uint16 maximum, uint16 invalid) : OverrideManagerBase(offset, maximum, invalid) {} - virtual uint16 AddEntityID(byte grf_local_id, uint32 grfid, byte substitute_id); - virtual uint16 GetID(uint8 grf_local_id, uint32 grfid) const; + uint16 AddEntityID(byte grf_local_id, uint32 grfid, byte substitute_id) override; + uint16 GetID(uint8 grf_local_id, uint32 grfid) const override; + void SetEntitySpec(IndustrySpec *inds); }; @@ -296,7 +296,7 @@ extern ObjectOverrideManager _object_mngr; uint32 GetTerrainType(TileIndex tile, TileContext context = TCX_NORMAL); TileIndex GetNearbyTile(byte parameter, TileIndex tile, bool signed_offsets = true, Axis axis = INVALID_AXIS); uint32 GetNearbyTileInformation(TileIndex tile, bool grf_version8); -uint32 GetCompanyInfo(CompanyID owner, const struct Livery *l = NULL); +uint32 GetCompanyInfo(CompanyID owner, const struct Livery *l = nullptr); CommandCost GetErrorMessageFromLocationCallbackResult(uint16 cb_res, const GRFFile *grffile, StringID default_error); void ErrorUnknownCallbackResult(uint32 grfid, uint16 cbid, uint16 cb_res); diff --git a/src/newgrf_config.cpp b/src/newgrf_config.cpp index 593851e288..a0960350da 100644 --- a/src/newgrf_config.cpp +++ b/src/newgrf_config.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. @@ -21,6 +19,8 @@ #include "video/video_driver.hpp" #include "strings_func.h" #include "textfile_gui.h" +#include "thread.h" +#include "newgrf_config.h" #include "fileio_func.h" #include "fios.h" @@ -29,7 +29,7 @@ /** Create a new GRFTextWrapper. */ GRFTextWrapper::GRFTextWrapper() : - text(NULL) + text(nullptr) { } @@ -50,7 +50,7 @@ GRFConfig::GRFConfig(const char *filename) : url(new GRFTextWrapper()), num_valid_params(lengthof(param)) { - if (filename != NULL) this->filename = stredup(filename); + if (filename != nullptr) this->filename = stredup(filename); this->name->AddRef(); this->info->AddRef(); this->url->AddRef(); @@ -78,16 +78,16 @@ GRFConfig::GRFConfig(const GRFConfig &config) : { MemCpyT(this->original_md5sum, config.original_md5sum, lengthof(this->original_md5sum)); MemCpyT(this->param, config.param, lengthof(this->param)); - if (config.filename != NULL) this->filename = stredup(config.filename); + if (config.filename != nullptr) this->filename = stredup(config.filename); this->name->AddRef(); this->info->AddRef(); this->url->AddRef(); - if (config.error != NULL) this->error = new GRFError(*config.error); - for (uint i = 0; i < config.param_info.Length(); i++) { - if (config.param_info[i] == NULL) { - *this->param_info.Append() = NULL; + if (config.error != nullptr) this->error = new GRFError(*config.error); + for (uint i = 0; i < config.param_info.size(); i++) { + if (config.param_info[i] == nullptr) { + this->param_info.push_back(nullptr); } else { - *this->param_info.Append() = new GRFParameterInfo(*config.param_info[i]); + this->param_info.push_back(new GRFParameterInfo(*config.param_info[i])); } } } @@ -104,7 +104,7 @@ GRFConfig::~GRFConfig() this->info->Release(); this->url->Release(); - for (uint i = 0; i < this->param_info.Length(); i++) delete this->param_info[i]; + for (uint i = 0; i < this->param_info.size(); i++) delete this->param_info[i]; } /** @@ -155,8 +155,8 @@ void GRFConfig::SetParameterDefaults() if (!this->has_param_defaults) return; - for (uint i = 0; i < this->param_info.Length(); i++) { - if (this->param_info[i] == NULL) continue; + for (uint i = 0; i < this->param_info.size(); i++) { + if (this->param_info[i] == nullptr) continue; this->param_info[i]->SetValue(this, this->param_info[i]->def_value); } } @@ -182,9 +182,9 @@ void GRFConfig::SetSuitablePalette() */ void GRFConfig::FinalizeParameterInfo() { - for (GRFParameterInfo **info = this->param_info.Begin(); info != this->param_info.End(); ++info) { - if (*info == NULL) continue; - (*info)->Finalize(); + for (GRFParameterInfo *info : this->param_info) { + if (info == nullptr) continue; + info->Finalize(); } } @@ -216,8 +216,8 @@ GRFError::GRFError(const GRFError &error) : message(error.message), severity(error.severity) { - if (error.custom_message != NULL) this->custom_message = stredup(error.custom_message); - if (error.data != NULL) this->data = stredup(error.data); + if (error.custom_message != nullptr) this->custom_message = stredup(error.custom_message); + if (error.data != nullptr) this->data = stredup(error.data); memcpy(this->param_value, error.param_value, sizeof(this->param_value)); } @@ -232,8 +232,8 @@ GRFError::~GRFError() * @param nr The newgrf parameter that is changed. */ GRFParameterInfo::GRFParameterInfo(uint nr) : - name(NULL), - desc(NULL), + name(nullptr), + desc(nullptr), type(PTYPE_UINT_ENUM), min_value(0), max_value(UINT32_MAX), @@ -261,8 +261,8 @@ GRFParameterInfo::GRFParameterInfo(GRFParameterInfo &info) : num_bit(info.num_bit), complete_labels(info.complete_labels) { - for (uint i = 0; i < info.value_names.Length(); i++) { - SmallPair *data = info.value_names.Get(i); + for (uint i = 0; i < info.value_names.size(); i++) { + SmallPair *data = info.value_names.data() + i; this->value_names.Insert(data->first, DuplicateGRFText(data->second)); } } @@ -272,8 +272,8 @@ GRFParameterInfo::~GRFParameterInfo() { CleanUpGRFText(this->name); CleanUpGRFText(this->desc); - for (uint i = 0; i < this->value_names.Length(); i++) { - SmallPair *data = this->value_names.Get(i); + for (uint i = 0; i < this->value_names.size(); i++) { + SmallPair *data = this->value_names.data() + i; CleanUpGRFText(data->second); } } @@ -329,9 +329,9 @@ void GRFParameterInfo::Finalize() */ bool UpdateNewGRFConfigPalette(int32 p1) { - for (GRFConfig *c = _grfconfig_newgame; c != NULL; c = c->next) c->SetSuitablePalette(); - for (GRFConfig *c = _grfconfig_static; c != NULL; c = c->next) c->SetSuitablePalette(); - for (GRFConfig *c = _all_grfs; c != NULL; c = c->next) c->SetSuitablePalette(); + for (GRFConfig *c = _grfconfig_newgame; c != nullptr; c = c->next) c->SetSuitablePalette(); + for (GRFConfig *c = _grfconfig_static; c != nullptr; c = c->next) c->SetSuitablePalette(); + for (GRFConfig *c = _all_grfs; c != nullptr; c = c->next) c->SetSuitablePalette(); return true; } @@ -379,7 +379,7 @@ static bool CalcGRFMD5Sum(GRFConfig *config, Subdirectory subdir) /* open the file */ f = FioFOpenFile(config->filename, "rb", subdir, &size); - if (f == NULL) return false; + if (f == nullptr) return false; long start = ftell(f); size = min(size, GRFGetSizeOfDataSection(f)); @@ -439,16 +439,16 @@ bool FillGRFDetails(GRFConfig *config, bool is_static, Subdirectory subdir) /** * Clear a GRF Config list, freeing all nodes. * @param config Start of the list. - * @post \a config is set to \c NULL. + * @post \a config is set to \c nullptr. */ void ClearGRFConfigList(GRFConfig **config) { GRFConfig *c, *next; - for (c = *config; c != NULL; c = next) { + for (c = *config; c != nullptr; c = next) { next = c->next; delete c; } - *config = NULL; + *config = nullptr; } @@ -463,7 +463,7 @@ GRFConfig **CopyGRFConfigList(GRFConfig **dst, const GRFConfig *src, bool init_o { /* Clear destination as it will be overwritten */ ClearGRFConfigList(dst); - for (; src != NULL; src = src->next) { + for (; src != nullptr; src = src->next) { GRFConfig *c = new GRFConfig(*src); ClrBit(c->flags, GCF_INIT_ONLY); @@ -494,9 +494,9 @@ static void RemoveDuplicatesFromGRFConfigList(GRFConfig *list) GRFConfig *prev; GRFConfig *cur; - if (list == NULL) return; + if (list == nullptr) return; - for (prev = list, cur = list->next; cur != NULL; prev = cur, cur = cur->next) { + for (prev = list, cur = list->next; cur != nullptr; prev = cur, cur = cur->next) { if (cur->ident.grfid != list->ident.grfid) continue; prev->next = cur->next; @@ -514,7 +514,7 @@ static void RemoveDuplicatesFromGRFConfigList(GRFConfig *list) void AppendStaticGRFConfigs(GRFConfig **dst) { GRFConfig **tail = dst; - while (*tail != NULL) tail = &(*tail)->next; + while (*tail != nullptr) tail = &(*tail)->next; CopyGRFConfigList(tail, _grfconfig_static, false); RemoveDuplicatesFromGRFConfigList(*dst); @@ -528,7 +528,7 @@ void AppendStaticGRFConfigs(GRFConfig **dst) void AppendToGRFConfigList(GRFConfig **dst, GRFConfig *el) { GRFConfig **tail = dst; - while (*tail != NULL) tail = &(*tail)->next; + while (*tail != nullptr) tail = &(*tail)->next; *tail = el; RemoveDuplicatesFromGRFConfigList(*dst); @@ -558,15 +558,15 @@ GRFListCompatibility IsGoodGRFConfigList(GRFConfig *grfconfig) { GRFListCompatibility res = GLC_ALL_GOOD; - for (GRFConfig *c = grfconfig; c != NULL; c = c->next) { + for (GRFConfig *c = grfconfig; c != nullptr; c = c->next) { const GRFConfig *f = FindGRFConfig(c->ident.grfid, FGCM_EXACT, c->ident.md5sum); - if (f == NULL || HasBit(f->flags, GCF_INVALID)) { + if (f == nullptr || HasBit(f->flags, GCF_INVALID)) { char buf[256]; /* If we have not found the exactly matching GRF try to find one with the * same grfid, as it most likely is compatible */ - f = FindGRFConfig(c->ident.grfid, FGCM_COMPATIBLE, NULL, c->version); - if (f != NULL) { + f = FindGRFConfig(c->ident.grfid, FGCM_COMPATIBLE, nullptr, c->version); + if (f != nullptr) { md5sumToString(buf, lastof(buf), c->ident.md5sum); DEBUG(grf, 1, "NewGRF %08X (%s) not found; checksum %s. Compatibility mode on", BSWAP32(c->ident.grfid), c->filename, buf); if (!HasBit(c->flags, GCF_COMPATIBLE)) { @@ -604,16 +604,16 @@ compatible_grf: c->info->Release(); c->info = f->name; c->info->AddRef(); - c->error = NULL; + c->error = nullptr; c->version = f->version; c->min_loadable_version = f->min_loadable_version; c->num_valid_params = f->num_valid_params; c->has_param_defaults = f->has_param_defaults; - for (uint i = 0; i < f->param_info.Length(); i++) { - if (f->param_info[i] == NULL) { - *c->param_info.Append() = NULL; + for (uint i = 0; i < f->param_info.size(); i++) { + if (f->param_info[i] == nullptr) { + c->param_info.push_back(nullptr); } else { - *c->param_info.Append() = new GRFParameterInfo(*f->param_info[i]); + c->param_info.push_back(new GRFParameterInfo(*f->param_info[i])); } } } @@ -633,7 +633,7 @@ public: { } - /* virtual */ bool AddFile(const char *filename, size_t basepath_length, const char *tar_filename); + bool AddFile(const char *filename, size_t basepath_length, const char *tar_filename) override; /** Do the scan for GRFs. */ static uint DoScan() @@ -653,14 +653,14 @@ bool GRFFileScanner::AddFile(const char *filename, size_t basepath_length, const bool added = true; if (FillGRFDetails(c, false)) { - if (_all_grfs == NULL) { + if (_all_grfs == nullptr) { _all_grfs = c; } else { /* Insert file into list at a position determined by its * name, so the list is sorted as we go along */ GRFConfig **pd, *d; bool stop = false; - for (pd = &_all_grfs; (d = *pd) != NULL; pd = &d->next) { + for (pd = &_all_grfs; (d = *pd) != nullptr; pd = &d->next) { if (c->ident.grfid == d->ident.grfid && memcmp(c->ident.md5sum, d->ident.md5sum, sizeof(c->ident.md5sum)) == 0) added = false; /* Because there can be multiple grfs with the same name, make sure we checked all grfs with the same name, * before inserting the entry. So insert a new grf at the end of all grfs with the same name, instead of @@ -682,18 +682,18 @@ bool GRFFileScanner::AddFile(const char *filename, size_t basepath_length, const this->num_scanned++; if (this->next_update <= _realtime_tick) { - _modal_progress_work_mutex->EndCritical(); - _modal_progress_paint_mutex->BeginCritical(); + _modal_progress_work_mutex.unlock(); + _modal_progress_paint_mutex.lock(); - const char *name = NULL; - if (c->name != NULL) name = GetGRFStringFromGRFText(c->name->text); - if (name == NULL) name = c->filename; + const char *name = nullptr; + if (c->name != nullptr) name = GetGRFStringFromGRFText(c->name->text); + if (name == nullptr) name = c->filename; UpdateNewGRFScanStatus(this->num_scanned, name); - _modal_progress_work_mutex->BeginCritical(); - _modal_progress_paint_mutex->EndCritical(); + _modal_progress_work_mutex.lock(); + _modal_progress_paint_mutex.unlock(); - this->next_update = _realtime_tick + 200; + this->next_update = _realtime_tick + MODAL_PROGRESS_REDRAW_TIMEOUT; } if (!added) { @@ -707,25 +707,22 @@ bool GRFFileScanner::AddFile(const char *filename, size_t basepath_length, const /** * Simple sorter for GRFS - * @param p1 the first GRFConfig * - * @param p2 the second GRFConfig * - * @return the same strcmp would return for the name of the NewGRF. + * @param c1 the first GRFConfig * + * @param c2 the second GRFConfig * + * @return true if the name of first NewGRF is before the name of the second. */ -static int CDECL GRFSorter(GRFConfig * const *p1, GRFConfig * const *p2) +static bool GRFSorter(GRFConfig * const &c1, GRFConfig * const &c2) { - const GRFConfig *c1 = *p1; - const GRFConfig *c2 = *p2; - - return strnatcmp(c1->GetName(), c2->GetName()); + return strnatcmp(c1->GetName(), c2->GetName()) < 0; } /** * Really perform the scan for all NewGRFs. * @param callback The callback to call after the scanning is complete. */ -void DoScanNewGRFFiles(void *callback) +void DoScanNewGRFFiles(NewGRFScanCallback *callback) { - _modal_progress_work_mutex->BeginCritical(); + std::unique_lock lock_work(_modal_progress_work_mutex); ClearGRFConfigList(&_all_grfs); TarScanner::DoScan(TarScanner::NEWGRF); @@ -734,46 +731,41 @@ void DoScanNewGRFFiles(void *callback) uint num = GRFFileScanner::DoScan(); DEBUG(grf, 1, "Scan complete, found %d files", num); - if (num != 0 && _all_grfs != NULL) { + if (num != 0 && _all_grfs != nullptr) { /* Sort the linked list using quicksort. * For that we first have to make an array, then sort and * then remake the linked list. */ - GRFConfig **to_sort = MallocT(num); + std::vector to_sort; uint i = 0; - for (GRFConfig *p = _all_grfs; p != NULL; p = p->next, i++) { - to_sort[i] = p; + for (GRFConfig *p = _all_grfs; p != nullptr; p = p->next, i++) { + to_sort.push_back(p); } /* Number of files is not necessarily right */ num = i; - QSortT(to_sort, num, &GRFSorter); + std::sort(to_sort.begin(), to_sort.end(), GRFSorter); for (i = 1; i < num; i++) { to_sort[i - 1]->next = to_sort[i]; } - to_sort[num - 1]->next = NULL; + to_sort[num - 1]->next = nullptr; _all_grfs = to_sort[0]; - free(to_sort); - -#ifdef ENABLE_NETWORK NetworkAfterNewGRFScan(); -#endif } - _modal_progress_work_mutex->EndCritical(); - _modal_progress_paint_mutex->BeginCritical(); + lock_work.unlock(); + std::lock_guard lock_paint(_modal_progress_paint_mutex); /* Yes... these are the NewGRF windows */ InvalidateWindowClassesData(WC_SAVELOAD, 0, true); InvalidateWindowData(WC_GAME_OPTIONS, WN_GAME_OPTIONS_NEWGRF_STATE, GOID_NEWGRF_RESCANNED, true); - if (callback != NULL) ((NewGRFScanCallback*)callback)->OnNewGRFsScanned(); + if (callback != nullptr) callback->OnNewGRFsScanned(); DeleteWindowByClass(WC_MODAL_PROGRESS); SetModalProgress(false); MarkWholeScreenDirty(); - _modal_progress_paint_mutex->EndCritical(); } /** @@ -787,14 +779,14 @@ void ScanNewGRFFiles(NewGRFScanCallback *callback) /* Only then can we really start, especially by marking the whole screen dirty. Get those other windows hidden!. */ MarkWholeScreenDirty(); - if (!VideoDriver::GetInstance()->HasGUI() || !ThreadObject::New(&DoScanNewGRFFiles, callback, NULL, "ottd:newgrf-scan")) { - _modal_progress_work_mutex->EndCritical(); - _modal_progress_paint_mutex->EndCritical(); + if (!UseThreadedModelProgress() || !VideoDriver::GetInstance()->HasGUI() || !StartNewThread(nullptr, "ottd:newgrf-scan", &DoScanNewGRFFiles, (NewGRFScanCallback *)callback)) { // Without the seemingly superfluous cast, strange compiler errors ensue. + _modal_progress_work_mutex.unlock(); + _modal_progress_paint_mutex.unlock(); DoScanNewGRFFiles(callback); - _modal_progress_paint_mutex->BeginCritical(); - _modal_progress_work_mutex->BeginCritical(); + _modal_progress_paint_mutex.lock(); + _modal_progress_work_mutex.lock(); } else { - UpdateNewGRFScanStatus(0, NULL); + UpdateNewGRFScanStatus(0, nullptr); } } @@ -804,30 +796,28 @@ void ScanNewGRFFiles(NewGRFScanCallback *callback) * @param mode Restrictions for matching grfs * @param md5sum Expected MD5 sum * @param desired_version Requested version - * @return The matching grf, if it exists in #_all_grfs, else \c NULL. + * @return The matching grf, if it exists in #_all_grfs, else \c nullptr. */ const GRFConfig *FindGRFConfig(uint32 grfid, FindGRFConfigMode mode, const uint8 *md5sum, uint32 desired_version) { - assert((mode == FGCM_EXACT) != (md5sum == NULL)); - const GRFConfig *best = NULL; - for (const GRFConfig *c = _all_grfs; c != NULL; c = c->next) { + assert((mode == FGCM_EXACT) != (md5sum == nullptr)); + const GRFConfig *best = nullptr; + for (const GRFConfig *c = _all_grfs; c != nullptr; c = c->next) { /* if md5sum is set, we look for an exact match and continue if not found */ if (!c->ident.HasGrfIdentifier(grfid, md5sum)) continue; /* return it, if the exact same newgrf is found, or if we do not care about finding "the best" */ - if (md5sum != NULL || mode == FGCM_ANY) return c; + if (md5sum != nullptr || mode == FGCM_ANY) return c; /* Skip incompatible stuff, unless explicitly allowed */ if (mode != FGCM_NEWEST && HasBit(c->flags, GCF_INVALID)) continue; /* check version compatibility */ if (mode == FGCM_COMPATIBLE && (c->version < desired_version || c->min_loadable_version > desired_version)) continue; /* remember the newest one as "the best" */ - if (best == NULL || c->version > best->version) best = c; + if (best == nullptr || c->version > best->version) best = c; } return best; } -#ifdef ENABLE_NETWORK - /** Structure for UnknownGRFs; this is a lightweight variant of GRFConfig */ struct UnknownGRF : public GRFIdentifier { UnknownGRF *next; ///< The next unknown GRF. @@ -848,21 +838,21 @@ struct UnknownGRF : public GRFIdentifier { * @param create whether to create a new GRFConfig if the GRFConfig did not * exist in the fake list of GRFConfigs. * @return The GRFTextWrapper of the name of the GRFConfig with the given GRF ID - * and MD5 checksum or NULL when it does not exist and create is false. + * and MD5 checksum or nullptr when it does not exist and create is false. * This value must NEVER be freed by the caller. */ GRFTextWrapper *FindUnknownGRFName(uint32 grfid, uint8 *md5sum, bool create) { UnknownGRF *grf; - static UnknownGRF *unknown_grfs = NULL; + static UnknownGRF *unknown_grfs = nullptr; - for (grf = unknown_grfs; grf != NULL; grf = grf->next) { + for (grf = unknown_grfs; grf != nullptr; grf = grf->next) { if (grf->grfid == grfid) { if (memcmp(md5sum, grf->md5sum, sizeof(grf->md5sum)) == 0) return grf->name; } } - if (!create) return NULL; + if (!create) return nullptr; grf = CallocT(1); grf->grfid = grfid; @@ -877,24 +867,21 @@ GRFTextWrapper *FindUnknownGRFName(uint32 grfid, uint8 *md5sum, bool create) return grf->name; } -#endif /* ENABLE_NETWORK */ - - /** * Retrieve a NewGRF from the current config by its grfid. * @param grfid grf to look for. * @param mask GRFID mask to allow for partial matching. - * @return The grf config, if it exists, else \c NULL. + * @return The grf config, if it exists, else \c nullptr. */ GRFConfig *GetGRFConfig(uint32 grfid, uint32 mask) { GRFConfig *c; - for (c = _grfconfig; c != NULL; c = c->next) { + for (c = _grfconfig; c != nullptr; c = c->next) { if ((c->ident.grfid & mask) == (grfid & mask)) return c; } - return NULL; + return nullptr; } @@ -919,7 +906,7 @@ static const uint32 OPENTTD_GRAPHICS_BASE_GRF_ID = BSWAP32(0xFF4F5400); /** * Search a textfile file next to this NewGRF. * @param type The type of the textfile to search for. - * @return The filename for the textfile, \c NULL otherwise. + * @return The filename for the textfile, \c nullptr otherwise. */ const char *GRFConfig::GetTextfile(TextfileType type) const { diff --git a/src/newgrf_config.h b/src/newgrf_config.h index dc3b884dd3..8c3b2ecdf4 100644 --- a/src/newgrf_config.h +++ b/src/newgrf_config.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. @@ -88,13 +86,13 @@ struct GRFIdentifier { /** * Does the identification match the provided values? * @param grfid Expected grfid. - * @param md5sum Expected md5sum, may be \c NULL (in which case, do not check it). + * @param md5sum Expected md5sum, may be \c nullptr (in which case, do not check it). * @return the object has the provided grfid and md5sum. */ inline bool HasGrfIdentifier(uint32 grfid, const uint8 *md5sum) const { if (this->grfid != grfid) return false; - if (md5sum == NULL) return true; + if (md5sum == nullptr) return true; return memcmp(md5sum, this->md5sum, sizeof(this->md5sum)) == 0; } }; @@ -133,7 +131,7 @@ struct GRFParameterInfo { byte param_nr; ///< GRF parameter to store content in byte first_bit; ///< First bit to use in the GRF parameter byte num_bit; ///< Number of bits to use for this parameter - SmallMap value_names; ///< Names for each value. + SmallMap value_names; ///< Names for each value. bool complete_labels; ///< True if all values have a label. uint32 GetValue(struct GRFConfig *config) const; @@ -151,31 +149,31 @@ struct GRFTextWrapper : public SimpleCountedObject { /** Information about GRF, used in the game and (part of it) in savegames */ struct GRFConfig : ZeroedMemoryAllocator { - GRFConfig(const char *filename = NULL); + GRFConfig(const char *filename = nullptr); GRFConfig(const GRFConfig &config); ~GRFConfig(); - GRFIdentifier ident; ///< grfid and md5sum to uniquely identify newgrfs - uint8 original_md5sum[16]; ///< MD5 checksum of original file if only a 'compatible' file was loaded - char *filename; ///< Filename - either with or without full path - GRFTextWrapper *name; ///< NOSAVE: GRF name (Action 0x08) - GRFTextWrapper *info; ///< NOSAVE: GRF info (author, copyright, ...) (Action 0x08) - GRFTextWrapper *url; ///< NOSAVE: URL belonging to this GRF. - GRFError *error; ///< NOSAVE: Error/Warning during GRF loading (Action 0x0B) + GRFIdentifier ident; ///< grfid and md5sum to uniquely identify newgrfs + uint8 original_md5sum[16]; ///< MD5 checksum of original file if only a 'compatible' file was loaded + char *filename; ///< Filename - either with or without full path + GRFTextWrapper *name; ///< NOSAVE: GRF name (Action 0x08) + GRFTextWrapper *info; ///< NOSAVE: GRF info (author, copyright, ...) (Action 0x08) + GRFTextWrapper *url; ///< NOSAVE: URL belonging to this GRF. + GRFError *error; ///< NOSAVE: Error/Warning during GRF loading (Action 0x0B) - uint32 version; ///< NOSAVE: Version a NewGRF can set so only the newest NewGRF is shown - uint32 min_loadable_version; ///< NOSAVE: Minimum compatible version a NewGRF can define - uint8 flags; ///< NOSAVE: GCF_Flags, bitset - GRFStatus status; ///< NOSAVE: GRFStatus, enum - uint32 grf_bugs; ///< NOSAVE: bugs in this GRF in this run, @see enum GRFBugs - uint32 param[0x80]; ///< GRF parameters - uint8 num_params; ///< Number of used parameters - uint8 num_valid_params; ///< NOSAVE: Number of valid parameters (action 0x14) - uint8 palette; ///< GRFPalette, bitset - SmallVector param_info; ///< NOSAVE: extra information about the parameters - bool has_param_defaults; ///< NOSAVE: did this newgrf specify any defaults for it's parameters + uint32 version; ///< NOSAVE: Version a NewGRF can set so only the newest NewGRF is shown + uint32 min_loadable_version; ///< NOSAVE: Minimum compatible version a NewGRF can define + uint8 flags; ///< NOSAVE: GCF_Flags, bitset + GRFStatus status; ///< NOSAVE: GRFStatus, enum + uint32 grf_bugs; ///< NOSAVE: bugs in this GRF in this run, @see enum GRFBugs + uint32 param[0x80]; ///< GRF parameters + uint8 num_params; ///< Number of used parameters + uint8 num_valid_params; ///< NOSAVE: Number of valid parameters (action 0x14) + uint8 palette; ///< GRFPalette, bitset + std::vector param_info; ///< NOSAVE: extra information about the parameters + bool has_param_defaults; ///< NOSAVE: did this newgrf specify any defaults for it's parameters - struct GRFConfig *next; ///< NOSAVE: Next item in the linked list + struct GRFConfig *next; ///< NOSAVE: Next item in the linked list void CopyParams(const GRFConfig &src); @@ -215,7 +213,7 @@ struct NewGRFScanCallback { size_t GRFGetSizeOfDataSection(FILE *f); void ScanNewGRFFiles(NewGRFScanCallback *callback); -const GRFConfig *FindGRFConfig(uint32 grfid, FindGRFConfigMode mode, const uint8 *md5sum = NULL, uint32 desired_version = 0); +const GRFConfig *FindGRFConfig(uint32 grfid, FindGRFConfigMode mode, const uint8 *md5sum = nullptr, uint32 desired_version = 0); GRFConfig *GetGRFConfig(uint32 grfid, uint32 mask = 0xFFFFFFFF); GRFConfig **CopyGRFConfigList(GRFConfig **dst, const GRFConfig *src, bool init_only); void AppendStaticGRFConfigs(GRFConfig **dst); @@ -229,11 +227,9 @@ char *GRFBuildParamList(char *dst, const GRFConfig *c, const char *last); /* In newgrf_gui.cpp */ void ShowNewGRFSettings(bool editable, bool show_params, bool exec_changes, GRFConfig **config); -#ifdef ENABLE_NETWORK /** For communication about GRFs over the network */ #define UNKNOWN_GRF_NAME_PLACEHOLDER "" GRFTextWrapper *FindUnknownGRFName(uint32 grfid, uint8 *md5sum, bool create); -#endif /* ENABLE_NETWORK */ void UpdateNewGRFScanStatus(uint num, const char *name); bool UpdateNewGRFConfigPalette(int32 p1 = 0); diff --git a/src/newgrf_debug.h b/src/newgrf_debug.h index 6e514c4ce1..1679e17eee 100644 --- a/src/newgrf_debug.h +++ b/src/newgrf_debug.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. @@ -29,7 +27,7 @@ struct NewGrfDebugSpritePicker { NewGrfDebugSpritePickerMode mode; ///< Current state void *clicked_pixel; ///< Clicked pixel (pointer to blitter buffer) uint32 click_time; ///< Realtime tick when clicked to detect next frame - SmallVector sprites; ///< Sprites found + std::vector sprites; ///< Sprites found }; extern NewGrfDebugSpritePicker _newgrf_debug_sprite_picker; diff --git a/src/newgrf_debug_gui.cpp b/src/newgrf_debug_gui.cpp index faa9b1f62b..506b521efb 100644 --- a/src/newgrf_debug_gui.cpp +++ b/src/newgrf_debug_gui.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. @@ -47,7 +45,7 @@ #include "safeguards.h" /** The sprite picker. */ -NewGrfDebugSpritePicker _newgrf_debug_sprite_picker = { SPM_NONE, NULL, 0, SmallVector() }; +NewGrfDebugSpritePicker _newgrf_debug_sprite_picker = { SPM_NONE, nullptr, 0, std::vector() }; /** * Get the feature index related to the window number. @@ -192,11 +190,11 @@ public: * Gets the first position of the array containing the persistent storage. * @param index Index of the item. * @param grfid Parameter for the PSA. Only required for items with parameters. - * @return Pointer to the first position of the storage array or NULL if not present. + * @return Pointer to the first position of the storage array or nullptr if not present. */ virtual const int32 *GetPSAFirstPosition(uint index, uint32 grfid) const { - return NULL; + return nullptr; } protected: @@ -252,18 +250,18 @@ static inline GrfSpecFeature GetFeatureNum(uint window_number) /** * Get the NIFeature related to the window number. * @param window_number The window to get the NIFeature for. - * @return the NIFeature, or NULL is there isn't one. + * @return the NIFeature, or nullptr is there isn't one. */ static inline const NIFeature *GetFeature(uint window_number) { GrfSpecFeature idx = GetFeatureNum(window_number); - return idx < GSF_FAKE_END ? _nifeatures[idx] : NULL; + return idx < GSF_FAKE_END ? _nifeatures[idx] : nullptr; } /** * Get the NIHelper related to the window number. * @param window_number The window to get the NIHelper for. - * @pre GetFeature(window_number) != NULL + * @pre GetFeature(window_number) != nullptr * @return the NIHelper */ static inline const NIHelper *GetFeatureHelper(uint window_number) @@ -332,7 +330,7 @@ struct NewGRFInspectWindow : Window { assert(this->HasChainIndex()); const Vehicle *v = Vehicle::Get(index); v = v->Move(this->chain_index); - if (v != NULL) index = v->index; + if (v != nullptr) index = v->index; } return index; } @@ -348,7 +346,7 @@ struct NewGRFInspectWindow : Window { const Vehicle *v = Vehicle::Get(::GetFeatureIndex(this->window_number)); v = v->Move(this->chain_index); - if (v == NULL) this->chain_index = 0; + if (v == nullptr) this->chain_index = 0; } NewGRFInspectWindow(WindowDesc *desc, WindowNumber wno) : Window(desc) @@ -363,14 +361,14 @@ struct NewGRFInspectWindow : Window { this->OnInvalidateData(0, true); } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { if (widget != WID_NGRFI_CAPTION) return; GetFeatureHelper(this->window_number)->SetStringParameters(this->GetFeatureIndex()); } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_NGRFI_VEH_CHAIN: { @@ -410,7 +408,7 @@ struct NewGRFInspectWindow : Window { ::DrawString(r.left + LEFT_OFFSET, r.right - RIGHT_OFFSET, r.top + TOP_OFFSET + (offset * this->resize.step_height), buf, TC_BLACK); } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { switch (widget) { case WID_NGRFI_VEH_CHAIN: { @@ -418,7 +416,7 @@ struct NewGRFInspectWindow : Window { int total_width = 0; int sel_start = 0; int sel_end = 0; - for (const Vehicle *u = v->First(); u != NULL; u = u->Next()) { + for (const Vehicle *u = v->First(); u != nullptr; u = u->Next()) { if (u == v) sel_start = total_width; switch (u->type) { case VEH_TRAIN: total_width += Train ::From(u)->GetDisplayImageWidth(); break; @@ -459,9 +457,9 @@ struct NewGRFInspectWindow : Window { const void *base_spec = nih->GetSpec(index); uint i = 0; - if (nif->variables != NULL) { + if (nif->variables != nullptr) { this->DrawString(r, i++, "Variables:"); - for (const NIVariable *niv = nif->variables; niv->name != NULL; niv++) { + for (const NIVariable *niv = nif->variables; niv->name != nullptr; niv++) { bool avail = true; uint param = HasVariableParameter(niv->var) ? NewGRFInspectWindow::var60params[GetFeatureNum(this->window_number)][niv->var - 0x60] : 0; uint value = nih->Resolve(index, niv->var, param, &avail); @@ -478,7 +476,7 @@ struct NewGRFInspectWindow : Window { uint psa_size = nih->GetPSASize(index, this->caller_grfid); const int32 *psa = nih->GetPSAFirstPosition(index, this->caller_grfid); - if (psa_size != 0 && psa != NULL) { + if (psa_size != 0 && psa != nullptr) { if (nih->PSAWithParameter()) { this->DrawString(r, i++, "Persistent storage [%08X]:", BSWAP32(this->caller_grfid)); } else { @@ -490,9 +488,9 @@ struct NewGRFInspectWindow : Window { } } - if (nif->properties != NULL) { + if (nif->properties != nullptr) { this->DrawString(r, i++, "Properties:"); - for (const NIProperty *nip = nif->properties; nip->name != NULL; nip++) { + for (const NIProperty *nip = nif->properties; nip->name != nullptr; nip++) { const void *ptr = (const byte *)base + nip->offset; uint value; switch (nip->read_size) { @@ -523,9 +521,9 @@ struct NewGRFInspectWindow : Window { } } - if (nif->callbacks != NULL) { + if (nif->callbacks != nullptr) { this->DrawString(r, i++, "Callbacks:"); - for (const NICallback *nic = nif->callbacks; nic->name != NULL; nic++) { + for (const NICallback *nic = nif->callbacks; nic->name != nullptr; nic++) { if (nic->cb_bit != CBM_NO_BIT) { const void *ptr = (const byte *)base_spec + nic->offset; uint value; @@ -550,7 +548,7 @@ struct NewGRFInspectWindow : Window { const_cast(this)->vscroll->SetCount(i); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_NGRFI_PARENT: { @@ -571,7 +569,7 @@ struct NewGRFInspectWindow : Window { if (this->HasChainIndex()) { uint index = this->GetFeatureIndex(); Vehicle *v = Vehicle::Get(index); - if (v != NULL && v->Next() != NULL) { + if (v != nullptr && v->Next() != nullptr) { this->chain_index++; this->InvalidateData(); } @@ -581,14 +579,14 @@ struct NewGRFInspectWindow : Window { case WID_NGRFI_MAINPANEL: { /* Does this feature have variables? */ const NIFeature *nif = GetFeature(this->window_number); - if (nif->variables == NULL) return; + 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); if (line == INT_MAX) return; /* Find the variable related to the line */ - for (const NIVariable *niv = nif->variables; niv->name != NULL; niv++, line--) { + for (const NIVariable *niv = nif->variables; niv->name != nullptr; niv++, line--) { if (line != 1) continue; // 1 because of the "Variables:" line if (!HasVariableParameter(niv->var)) break; @@ -600,15 +598,15 @@ struct NewGRFInspectWindow : Window { } } - virtual void OnQueryTextFinished(char *str) + void OnQueryTextFinished(char *str) override { if (StrEmpty(str)) return; - NewGRFInspectWindow::var60params[GetFeatureNum(this->window_number)][this->current_edit_param - 0x60] = strtol(str, NULL, 16); + NewGRFInspectWindow::var60params[GetFeatureNum(this->window_number)][this->current_edit_param - 0x60] = strtol(str, nullptr, 16); this->SetDirty(); } - virtual void OnResize() + void OnResize() override { this->vscroll->SetCapacityFromWidget(this, WID_NGRFI_MAINPANEL, TOP_OFFSET + BOTTOM_OFFSET); } @@ -618,14 +616,14 @@ struct NewGRFInspectWindow : Window { * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; if (this->HasChainIndex()) { this->ValidateChainIndex(); this->SetWidgetDisabledState(WID_NGRFI_VEH_PREV, this->chain_index == 0); Vehicle *v = Vehicle::Get(this->GetFeatureIndex()); - this->SetWidgetDisabledState(WID_NGRFI_VEH_NEXT, v == NULL || v->Next() == NULL); + this->SetWidgetDisabledState(WID_NGRFI_VEH_NEXT, v == nullptr || v->Next() == nullptr); } } }; @@ -756,7 +754,7 @@ void DeleteNewGRFInspectWindow(GrfSpecFeature feature, uint index) bool IsNewGRFInspectable(GrfSpecFeature feature, uint index) { const NIFeature *nif = GetFeature(GetInspectWindowNumber(feature, index)); - if (nif == NULL) return false; + if (nif == nullptr) return false; return nif->helper->IsInspectable(index); } @@ -822,7 +820,7 @@ struct SpriteAlignerWindow : Window { while (GetSpriteType(this->current_sprite) != ST_NORMAL) this->current_sprite++; } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { const Sprite *spr = GetSprite(this->current_sprite, ST_NORMAL); switch (widget) { @@ -840,8 +838,8 @@ struct SpriteAlignerWindow : Window { /* Relative offset is new absolute offset - starting absolute offset. * Show 0, 0 as the relative offsets if entry is not in the map (meaning they have not been changed yet). */ - const SmallPair *key_offs_pair = this->offs_start_map.Find(this->current_sprite); - if (key_offs_pair != this->offs_start_map.End()) { + const auto key_offs_pair = this->offs_start_map.Find(this->current_sprite); + if (key_offs_pair != this->offs_start_map.end()) { SetDParam(0, spr->x_offs - key_offs_pair->second.first); SetDParam(1, spr->y_offs - key_offs_pair->second.second); } else { @@ -856,7 +854,7 @@ struct SpriteAlignerWindow : Window { } } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { if (widget != WID_SA_LIST) return; @@ -867,7 +865,7 @@ struct SpriteAlignerWindow : Window { size->height = (1 + 200 / resize->height) * resize->height; } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { switch (widget) { case WID_SA_SPRITE: { @@ -883,7 +881,7 @@ struct SpriteAlignerWindow : Window { DrawPixelInfo *old_dpi = _cur_dpi; _cur_dpi = &new_dpi; - DrawSprite(this->current_sprite, PAL_NONE, x, y, NULL, ZOOM_LVL_GUI); + DrawSprite(this->current_sprite, PAL_NONE, x, y, nullptr, ZOOM_LVL_GUI); _cur_dpi = old_dpi; @@ -894,8 +892,8 @@ struct SpriteAlignerWindow : Window { const NWidgetBase *nwid = this->GetWidget(widget); int step_size = nwid->resize_y; - SmallVector &list = _newgrf_debug_sprite_picker.sprites; - int max = min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), list.Length()); + std::vector &list = _newgrf_debug_sprite_picker.sprites; + int max = min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), (uint)list.size()); int y = Center(r.top + WD_FRAMERECT_TOP, step_size, FONT_HEIGHT_NORMAL); for (int i = this->vscroll->GetPosition(); i < max; i++) { @@ -908,7 +906,7 @@ struct SpriteAlignerWindow : Window { } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_SA_PREVIOUS: @@ -940,7 +938,7 @@ struct SpriteAlignerWindow : Window { int step_size = nwid->resize_y; uint i = this->vscroll->GetPosition() + (pt.y - nwid->pos_y) / step_size; - if (i < _newgrf_debug_sprite_picker.sprites.Length()) { + if (i < _newgrf_debug_sprite_picker.sprites.size()) { SpriteID spr = _newgrf_debug_sprite_picker.sprites[i]; if (GetSpriteType(spr) == ST_NORMAL) this->current_sprite = spr; } @@ -972,7 +970,7 @@ struct SpriteAlignerWindow : Window { this->offs_start_map.Insert(this->current_sprite, XyOffs(spr->x_offs, spr->y_offs)); } switch (widget) { - /* Move ten units at a time if ctrl is pressed. */ + /* Move eight units at a time if ctrl is pressed. */ case WID_SA_UP: spr->y_offs -= _ctrl_pressed ? 8 : 1; break; case WID_SA_DOWN: spr->y_offs += _ctrl_pressed ? 8 : 1; break; case WID_SA_LEFT: spr->x_offs -= _ctrl_pressed ? 8 : 1; break; @@ -992,7 +990,7 @@ struct SpriteAlignerWindow : Window { } } - virtual void OnQueryTextFinished(char *str) + void OnQueryTextFinished(char *str) override { if (StrEmpty(str)) return; @@ -1009,17 +1007,17 @@ struct SpriteAlignerWindow : Window { * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; if (data == 1) { /* Sprite picker finished */ this->RaiseWidget(WID_SA_PICKER); - this->vscroll->SetCount(_newgrf_debug_sprite_picker.sprites.Length()); + this->vscroll->SetCount((uint)_newgrf_debug_sprite_picker.sprites.size()); } } - virtual void OnResize() + void OnResize() override { this->vscroll->SetCapacityFromWidget(this, WID_SA_LIST); } diff --git a/src/newgrf_engine.cpp b/src/newgrf_engine.cpp index 660b7e476b..db2f5ac43c 100644 --- a/src/newgrf_engine.cpp +++ b/src/newgrf_engine.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. @@ -23,6 +21,7 @@ #include "station_base.h" #include "company_base.h" #include "newgrf_railtype.h" +#include "newgrf_roadtype.h" #include "ship.h" #include "safeguards.h" @@ -65,7 +64,7 @@ const SpriteGroup *GetWagonOverrideSpriteSet(EngineID engine, CargoID cargo, Eng if (wo->train_id[j] == overriding_engine) return wo->group; } } - return NULL; + return nullptr; } /** @@ -79,7 +78,7 @@ void UnloadWagonOverrides(Engine *e) } free(e->overrides); e->overrides_count = 0; - e->overrides = NULL; + e->overrides = nullptr; } @@ -88,7 +87,7 @@ void SetCustomEngineSprites(EngineID engine, byte cargo, const SpriteGroup *grou Engine *e = Engine::Get(engine); assert(cargo < lengthof(e->grf_prop.spritegroup)); - if (e->grf_prop.spritegroup[cargo] != NULL) { + if (e->grf_prop.spritegroup[cargo] != nullptr) { grfmsg(6, "SetCustomEngineSprites: engine %d cargo %d already has group -- replacing", engine, cargo); } e->grf_prop.spritegroup[cargo] = group; @@ -166,7 +165,7 @@ enum TTDPAircraftMovementStates { static byte MapAircraftMovementState(const Aircraft *v) { const Station *st = GetTargetAirportIfValid(v); - if (st == NULL) return AMS_TTDP_FLIGHT_TO_TOWER; + if (st == nullptr) return AMS_TTDP_FLIGHT_TO_TOWER; const AirportFTAClass *afc = st->airport.GetFTA(); uint16 amdflag = afc->MovingData(v->pos)->flag; @@ -247,7 +246,7 @@ static byte MapAircraftMovementState(const Aircraft *v) return AMS_TTDP_TO_INWAY; case HELILANDING: - case HELIENDLANDING: // Helicoptor is decending. + case HELIENDLANDING: // Helicoptor is descending. if (amdflag & AMED_HELI_LOWER) { return afc->delta_z == 0 ? AMS_TTDP_HELI_LAND_AIRPORT : AMS_TTDP_HELI_LAND_HELIPORT; @@ -339,12 +338,12 @@ static byte MapAircraftMovementAction(const Aircraft *v) /* virtual */ uint32 VehicleScopeResolver::GetRandomBits() const { - return this->v == NULL ? 0 : this->v->random_bits; + return this->v == nullptr ? 0 : this->v->random_bits; } /* virtual */ uint32 VehicleScopeResolver::GetTriggers() const { - return this->v == NULL ? 0 : this->v->waiting_triggers; + return this->v == nullptr ? 0 : this->v->waiting_triggers; } @@ -355,12 +354,12 @@ static byte MapAircraftMovementAction(const Aircraft *v) case VSG_SCOPE_PARENT: return &this->parent_scope; case VSG_SCOPE_RELATIVE: { int32 count = GB(relative, 0, 4); - if (this->self_scope.v != NULL && (relative != this->cached_relative_count || count == 0)) { + if (this->self_scope.v != nullptr && (relative != this->cached_relative_count || count == 0)) { /* Note: This caching only works as long as the VSG_SCOPE_RELATIVE cannot be used in * VarAct2 with procedure calls. */ if (count == 0) count = GetRegister(0x100); - const Vehicle *v = NULL; + const Vehicle *v = nullptr; switch (GB(relative, 6, 2)) { default: NOT_REACHED(); case 0x00: // count back (away from the engine), starting at this vehicle @@ -377,12 +376,12 @@ static byte MapAircraftMovementAction(const Aircraft *v) const Vehicle *self = this->self_scope.v; for (const Vehicle *u = self->First(); u != self; u = u->Next()) { if (u->engine_type != self->engine_type) { - v = NULL; + v = nullptr; } else { - if (v == NULL) v = u; + if (v == nullptr) v = u; } } - if (v == NULL) v = self; + if (v == nullptr) v = self; break; } } @@ -400,16 +399,16 @@ static byte MapAircraftMovementAction(const Aircraft *v) * This always uses dual company colours independent of GUI settings. So it is desync-safe. * * @param engine Engine type - * @param v Vehicle, NULL in purchase list. + * @param v Vehicle, nullptr in purchase list. * @return Livery to use */ static const Livery *LiveryHelper(EngineID engine, const Vehicle *v) { const Livery *l; - if (v == NULL) { - if (!Company::IsValidID(_current_company)) return NULL; - l = GetEngineLivery(engine, _current_company, INVALID_ENGINE, NULL, LIT_ALL); + if (v == nullptr) { + if (!Company::IsValidID(_current_company)) return nullptr; + l = GetEngineLivery(engine, _current_company, INVALID_ENGINE, nullptr, LIT_ALL); } else if (v->IsGroundVehicle()) { l = GetEngineLivery(v->engine_type, v->owner, v->GetGroundVehicleCache()->first_engine, v, LIT_ALL); } else { @@ -437,7 +436,7 @@ static uint32 PositionHelper(const Vehicle *v, bool consecutive) if (consecutive && u->engine_type != v->engine_type) chain_before = 0; } - while (u->Next() != NULL && (!consecutive || u->Next()->engine_type == v->engine_type)) { + while (u->Next() != nullptr && (!consecutive || u->Next()->engine_type == v->engine_type)) { chain_after++; u = u->Next(); } @@ -480,7 +479,7 @@ static uint32 VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *object, memset(common_cargoes, 0, sizeof(common_cargoes)); memset(common_subtypes, 0, sizeof(common_subtypes)); - for (u = v; u != NULL; u = u->Next()) { + for (u = v; u != nullptr; u = u->Next()) { if (v->type == VEH_TRAIN) user_def_data |= Train::From(u)->tcache.user_def_data; /* Skip empty engines */ @@ -500,7 +499,7 @@ static uint32 VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *object, } /* Count subcargo types of common_cargo_type */ - for (u = v; u != NULL; u = u->Next()) { + for (u = v; u != nullptr; u = u->Next()) { /* Skip empty engines and engines not carrying common_cargo_type */ if (u->cargo_type != common_cargo_type || !u->GetEngine()->CanCarryCargo()) continue; @@ -530,12 +529,12 @@ static uint32 VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *object, * - For translating the cargo type we need to use the GRF which is resolving the variable, which * is object->ro.grffile. * In case of CBID_TRAIN_ALLOW_WAGON_ATTACH this is not the same as v->GetGRF(). - * - The grffile == NULL case only happens if this function is called for default vehicles. + * - The grffile == nullptr case only happens if this function is called for default vehicles. * And this is only done by CheckCaches(). */ const GRFFile *grffile = object->ro.grffile; uint8 common_bitnum = (common_cargo_type == CT_INVALID) ? 0xFF : - (grffile == NULL || grffile->grf_version < 8) ? CargoSpec::Get(common_cargo_type)->bitnum : grffile->cargo_map[common_cargo_type]; + (grffile == nullptr || grffile->grf_version < 8) ? CargoSpec::Get(common_cargo_type)->bitnum : grffile->cargo_map[common_cargo_type]; return (v->grf_cache.consist_cargo_information & 0xFFFF00FF) | common_bitnum << 8; } @@ -557,7 +556,7 @@ static uint32 VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *object, const Station *st = GetTargetAirportIfValid(Aircraft::From(v)); - if (st != NULL && st->airport.tile != INVALID_TILE) { + if (st != nullptr && st->airport.tile != INVALID_TILE) { airporttype = st->airport.GetSpec()->ttd_airport_type; } @@ -574,8 +573,8 @@ static uint32 VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *object, const Vehicle *u_p = v->Previous(); const Vehicle *u_n = v->Next(); - DirDiff f = (u_p == NULL) ? DIRDIFF_SAME : DirDifference(u_p->direction, v->direction); - DirDiff b = (u_n == NULL) ? DIRDIFF_SAME : DirDifference(v->direction, u_n->direction); + DirDiff f = (u_p == nullptr) ? DIRDIFF_SAME : DirDifference(u_p->direction, v->direction); + DirDiff b = (u_n == nullptr) ? DIRDIFF_SAME : DirDifference(v->direction, u_n->direction); DirDiff t = ChangeDirDiff(f, b); return ((t > DIRDIFF_REVERSE ? t | 8 : t) << 16) | @@ -606,11 +605,21 @@ static uint32 VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *object, case 0x48: return v->GetEngine()->flags; // Vehicle Type Info case 0x49: return v->build_year; - case 0x4A: { - if (v->type != VEH_TRAIN) return 0; - RailType rt = GetTileRailType(v->tile); - return (HasPowerOnRail(Train::From(v)->railtype, rt) ? 0x100 : 0) | GetReverseRailTypeTranslation(rt, object->ro.grffile); - } + case 0x4A: + switch (v->type) { + case VEH_TRAIN: { + RailType rt = GetTileRailType(v->tile); + return (HasPowerOnRail(Train::From(v)->railtype, rt) ? 0x100 : 0) | GetReverseRailTypeTranslation(rt, object->ro.grffile); + } + + case VEH_ROAD: { + RoadType rt = GetRoadType(v->tile, GetRoadTramType(RoadVehicle::From(v)->roadtype)); + return 0x100 | GetReverseRoadTypeTranslation(rt, object->ro.grffile); + } + + default: + return 0; + } case 0x4B: // Long date of last service return v->date_of_last_service; @@ -636,7 +645,7 @@ static uint32 VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *object, { uint count = 0; - for (; v != NULL; v = v->Next()) { + for (; v != nullptr; v = v->Next()) { if (v->GetEngine()->grf_prop.local_id == parameter) count++; } return count; @@ -653,7 +662,7 @@ static uint32 VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *object, object->ro.callback == CBID_VEHICLE_START_STOP_CHECK || object->ro.callback == CBID_VEHICLE_32DAY_CALLBACK || object->ro.callback == CBID_VEHICLE_COLOUR_MAPPING || object->ro.callback == CBID_VEHICLE_SPAWN_VISUAL_EFFECT) { Vehicle *u = v->Move((int32)GetRegister(0x10F)); - if (u == NULL) return 0; // available, but zero + if (u == nullptr) return 0; // available, but zero if (parameter == 0x5F) { /* This seems to be the only variable that makes sense to access via var 61, but is not handled by VehicleGetVariable */ @@ -676,7 +685,7 @@ static uint32 VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *object, if (!v->IsGroundVehicle()) return 0; const Vehicle *u = v->Move((int8)parameter); - if (u == NULL) return 0; + if (u == nullptr) return 0; /* Get direction difference. */ bool prev = (int8)parameter < 0; @@ -810,7 +819,7 @@ static uint32 VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *object, case 0x57: return GB(ClampToI32(v->GetDisplayProfitLastYear()), 8, 24); case 0x58: return GB(ClampToI32(v->GetDisplayProfitLastYear()), 16, 16); case 0x59: return GB(ClampToI32(v->GetDisplayProfitLastYear()), 24, 8); - case 0x5A: return v->Next() == NULL ? INVALID_VEHICLE : v->Next()->index; + case 0x5A: return v->Next() == nullptr ? INVALID_VEHICLE : v->Next()->index; case 0x5C: return ClampToI32(v->value); case 0x5D: return GB(ClampToI32(v->value), 8, 24); case 0x5E: return GB(ClampToI32(v->value), 16, 16); @@ -882,10 +891,10 @@ static uint32 VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *object, /* virtual */ uint32 VehicleScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const { - if (this->v == NULL) { + if (this->v == nullptr) { /* Vehicle does not exist, so we're in a purchase list */ switch (variable) { - case 0x43: return GetCompanyInfo(_current_company, LiveryHelper(this->self_type, NULL)); // Owner information + case 0x43: return GetCompanyInfo(_current_company, LiveryHelper(this->self_type, nullptr)); // Owner information case 0x46: return 0; // Motion counter case 0x47: { // Vehicle cargo info const Engine *e = Engine::Get(this->self_type); @@ -919,17 +928,17 @@ static uint32 VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *object, { const Vehicle *v = this->self_scope.v; - if (v == NULL) { + if (v == nullptr) { if (group->num_loading > 0) return group->loading[0]; if (group->num_loaded > 0) return group->loaded[0]; - return NULL; + return nullptr; } bool in_motion = !v->First()->current_order.IsType(OT_LOADING); uint totalsets = in_motion ? group->num_loaded : group->num_loading; - if (totalsets == 0) return NULL; + if (totalsets == 0) return nullptr; uint set = (v->cargo.StoredCount() * totalsets) / max((uint16)1, v->cargo_cap); set = min(set, totalsets - 1); @@ -937,6 +946,22 @@ static uint32 VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *object, return in_motion ? group->loaded[set] : group->loading[set]; } +GrfSpecFeature VehicleResolverObject::GetFeature() const +{ + switch (Engine::Get(this->self_scope.self_type)->type) { + case VEH_TRAIN: return GSF_TRAINS; + case VEH_ROAD: return GSF_ROADVEHICLES; + case VEH_SHIP: return GSF_SHIPS; + case VEH_AIRCRAFT: return GSF_AIRCRAFT; + default: return GSF_INVALID; + } +} + +uint32 VehicleResolverObject::GetDebugID() const +{ + return Engine::Get(this->self_scope.self_type)->grf_prop.local_id; +} + /** * Get the grf file associated with an engine type. * @param engine_type Engine to query. @@ -945,7 +970,7 @@ static uint32 VehicleGetVariable(Vehicle *v, const VehicleScopeResolver *object, static const GRFFile *GetEngineGrfFile(EngineID engine_type) { const Engine *e = Engine::Get(engine_type); - return (e != NULL) ? e->GetGRF() : NULL; + return (e != nullptr) ? e->GetGRF() : nullptr; } /** @@ -962,14 +987,14 @@ VehicleResolverObject::VehicleResolverObject(EngineID engine_type, const Vehicle CallbackID callback, uint32 callback_param1, uint32 callback_param2) : ResolverObject(GetEngineGrfFile(engine_type), callback, callback_param1, callback_param2), self_scope(*this, engine_type, v, info_view), - parent_scope(*this, engine_type, ((v != NULL) ? v->First() : v), info_view), + parent_scope(*this, engine_type, ((v != nullptr) ? v->First() : v), info_view), relative_scope(*this, engine_type, v, info_view), cached_relative_count(0) { if (wagon_override == WO_SELF) { this->root_spritegroup = GetWagonOverrideSpriteSet(engine_type, CT_DEFAULT, engine_type); } else { - if (wagon_override != WO_NONE && v != NULL && v->IsGroundVehicle()) { + if (wagon_override != WO_NONE && v != nullptr && v->IsGroundVehicle()) { assert(v->engine_type == engine_type); // overrides make little sense with fake scopes /* For trains we always use cached value, except for callbacks because the override spriteset @@ -982,11 +1007,11 @@ VehicleResolverObject::VehicleResolverObject(EngineID engine_type, const Vehicle } } - if (this->root_spritegroup == NULL) { + if (this->root_spritegroup == nullptr) { const Engine *e = Engine::Get(engine_type); - CargoID cargo = v != NULL ? v->cargo_type : CT_PURCHASE; + CargoID cargo = v != nullptr ? v->cargo_type : CT_PURCHASE; assert(cargo < lengthof(e->grf_prop.spritegroup)); - this->root_spritegroup = e->grf_prop.spritegroup[cargo] != NULL ? e->grf_prop.spritegroup[cargo] : e->grf_prop.spritegroup[CT_DEFAULT]; + this->root_spritegroup = e->grf_prop.spritegroup[cargo] != nullptr ? e->grf_prop.spritegroup[cargo] : e->grf_prop.spritegroup[CT_DEFAULT]; } } } @@ -1005,7 +1030,7 @@ void GetCustomEngineSprite(EngineID engine, const Vehicle *v, Direction directio object.callback_param1 = image_type | (stack << 8); const SpriteGroup *group = object.Resolve(); uint32 reg100 = sprite_stack ? GetRegister(0x100) : 0; - if (group != NULL && group->GetNumResults() != 0) { + if (group != nullptr && group->GetNumResults() != 0) { result->seq[result->count].sprite = group->GetResult() + (direction % group->GetNumResults()); result->seq[result->count].pal = GB(reg100, 0, 16); // zero means default recolouring result->count++; @@ -1025,7 +1050,7 @@ void GetRotorOverrideSprite(EngineID engine, const struct Aircraft *v, bool info VehicleResolverObject object(engine, v, VehicleResolverObject::WO_SELF, info_view, CBID_NO_CALLBACK); result->Clear(); - uint rotor_pos = v == NULL || info_view ? 0 : v->Next()->Next()->state; + uint rotor_pos = v == nullptr || info_view ? 0 : v->Next()->Next()->state; bool sprite_stack = HasBit(e->info.misc_flags, EF_SPRITE_STACK); uint max_stack = sprite_stack ? lengthof(result->seq) : 1; @@ -1034,7 +1059,7 @@ void GetRotorOverrideSprite(EngineID engine, const struct Aircraft *v, bool info object.callback_param1 = image_type | (stack << 8); const SpriteGroup *group = object.Resolve(); uint32 reg100 = sprite_stack ? GetRegister(0x100) : 0; - if (group != NULL && group->GetNumResults() != 0) { + if (group != nullptr && group->GetNumResults() != 0) { result->seq[result->count].sprite = group->GetResult() + (rotor_pos % group->GetNumResults()); result->seq[result->count].pal = GB(reg100, 0, 16); // zero means default recolouring result->count++; @@ -1052,7 +1077,7 @@ void GetRotorOverrideSprite(EngineID engine, const struct Aircraft *v, bool info bool UsesWagonOverride(const Vehicle *v) { assert(v->type == VEH_TRAIN); - return Train::From(v)->tcache.cached_override != NULL; + return Train::From(v)->tcache.cached_override != nullptr; } /** @@ -1061,7 +1086,7 @@ bool UsesWagonOverride(const Vehicle *v) * @param param1 First parameter of the callback * @param param2 Second parameter of the callback * @param engine Engine type of the vehicle to evaluate the callback for - * @param v The vehicle to evaluate the callback for, or NULL if it doesnt exist yet + * @param v The vehicle to evaluate the callback for, or nullptr if it doesn't exist yet * @return The value the callback returned, or CALLBACK_FAILED if it failed */ uint16 GetVehicleCallback(CallbackID callback, uint32 param1, uint32 param2, EngineID engine, const Vehicle *v) @@ -1076,7 +1101,7 @@ uint16 GetVehicleCallback(CallbackID callback, uint32 param1, uint32 param2, Eng * @param param1 First parameter of the callback * @param param2 Second parameter of the callback * @param engine Engine type of the vehicle to evaluate the callback for - * @param v The vehicle to evaluate the callback for, or NULL if it doesn't exist yet + * @param v The vehicle to evaluate the callback for, or nullptr if it doesn't exist yet * @param parent The vehicle to use for parent scope * @return The value the callback returned, or CALLBACK_FAILED if it failed */ @@ -1107,14 +1132,14 @@ uint GetEngineProperty(EngineID engine, PropertyID property, uint orig_value, co static void DoTriggerVehicle(Vehicle *v, VehicleTrigger trigger, byte base_random_bits, bool first) { /* We can't trigger a non-existent vehicle... */ - assert(v != NULL); + assert(v != nullptr); VehicleResolverObject object(v->engine_type, v, VehicleResolverObject::WO_CACHED, false, CBID_RANDOM_TRIGGER); object.waiting_triggers = v->waiting_triggers | trigger; v->waiting_triggers = object.waiting_triggers; // store now for var 5F const SpriteGroup *group = object.Resolve(); - if (group == NULL) return; + if (group == nullptr) return; /* Store remaining triggers. */ v->waiting_triggers = object.GetRemainingTriggers(); @@ -1142,7 +1167,7 @@ static void DoTriggerVehicle(Vehicle *v, VehicleTrigger trigger, byte base_rando /* We now trigger the next vehicle in chain recursively. * The random bits portions may be different for each * vehicle in chain. */ - if (v->Next() != NULL) DoTriggerVehicle(v->Next(), trigger, 0, true); + if (v->Next() != nullptr) DoTriggerVehicle(v->Next(), trigger, 0, true); break; case VEHICLE_TRIGGER_EMPTY: @@ -1150,14 +1175,14 @@ static void DoTriggerVehicle(Vehicle *v, VehicleTrigger trigger, byte base_rando * recursively. The random bits portions must be same * for each vehicle in chain, so we give them all * first chained vehicle's portion of random bits. */ - if (v->Next() != NULL) DoTriggerVehicle(v->Next(), trigger, first ? new_random_bits : base_random_bits, false); + if (v->Next() != nullptr) DoTriggerVehicle(v->Next(), trigger, first ? new_random_bits : base_random_bits, false); break; case VEHICLE_TRIGGER_ANY_NEW_CARGO: /* Now pass the trigger recursively to the next vehicle * in chain. */ assert(!first); - if (v->Next() != NULL) DoTriggerVehicle(v->Next(), VEHICLE_TRIGGER_ANY_NEW_CARGO, base_random_bits, false); + if (v->Next() != nullptr) DoTriggerVehicle(v->Next(), VEHICLE_TRIGGER_ANY_NEW_CARGO, base_random_bits, false); break; case VEHICLE_TRIGGER_CALLBACK_32: @@ -1185,7 +1210,7 @@ struct ListOrderChange { uint target; ///< local ID }; -static SmallVector _list_order_changes; +static std::vector _list_order_changes; /** * Record a vehicle ListOrderChange. @@ -1196,9 +1221,7 @@ static SmallVector _list_order_changes; void AlterVehicleListOrder(EngineID engine, uint target) { /* Add the list order change to a queue */ - ListOrderChange *loc = _list_order_changes.Append(); - loc->engine = engine; - loc->target = target; + _list_order_changes.push_back({engine, target}); } /** @@ -1207,19 +1230,19 @@ void AlterVehicleListOrder(EngineID engine, uint target) * @param b right side * @return comparison result */ -static int CDECL EnginePreSort(const EngineID *a, const EngineID *b) +static bool EnginePreSort(const EngineID &a, const EngineID &b) { - const EngineIDMapping *id_a = _engine_mngr.Get(*a); - const EngineIDMapping *id_b = _engine_mngr.Get(*b); + const EngineIDMapping &id_a = _engine_mngr.at(a); + const EngineIDMapping &id_b = _engine_mngr.at(b); /* 1. Sort by engine type */ - if (id_a->type != id_b->type) return (int)id_a->type - (int)id_b->type; + if (id_a.type != id_b.type) return (int)id_a.type < (int)id_b.type; /* 2. Sort by scope-GRFID */ - if (id_a->grfid != id_b->grfid) return id_a->grfid < id_b->grfid ? -1 : 1; + if (id_a.grfid != id_b.grfid) return id_a.grfid < id_b.grfid; /* 3. Sort by local ID */ - return (int)id_a->internal_id - (int)id_b->internal_id; + return (int)id_a.internal_id < (int)id_b.internal_id; } /** @@ -1228,32 +1251,30 @@ static int CDECL EnginePreSort(const EngineID *a, const EngineID *b) void CommitVehicleListOrderChanges() { /* Pre-sort engines by scope-grfid and local index */ - SmallVector ordering; - Engine *e; - FOR_ALL_ENGINES(e) { - *ordering.Append() = e->index; + std::vector ordering; + for (const Engine *e : Engine::Iterate()) { + ordering.push_back(e->index); } - QSortT(ordering.Begin(), ordering.Length(), EnginePreSort); + std::sort(ordering.begin(), ordering.end(), EnginePreSort); /* Apply Insertion-Sort operations */ - const ListOrderChange *end = _list_order_changes.End(); - for (const ListOrderChange *it = _list_order_changes.Begin(); it != end; ++it) { - EngineID source = it->engine; - uint local_target = it->target; + for (const ListOrderChange &it : _list_order_changes) { + EngineID source = it.engine; + uint local_target = it.target; - const EngineIDMapping *id_source = _engine_mngr.Get(source); + const EngineIDMapping *id_source = _engine_mngr.data() + source; if (id_source->internal_id == local_target) continue; EngineID target = _engine_mngr.GetID(id_source->type, local_target, id_source->grfid); if (target == INVALID_ENGINE) continue; - int source_index = ordering.FindIndex(source); - int target_index = ordering.FindIndex(target); + int source_index = find_index(ordering, source); + int target_index = find_index(ordering, target); assert(source_index >= 0 && target_index >= 0); assert(source_index != target_index); - EngineID *list = ordering.Begin(); + EngineID *list = ordering.data(); if (source_index < target_index) { --target_index; for (int i = source_index; i < target_index; ++i) list[i] = list[i + 1]; @@ -1265,14 +1286,15 @@ void CommitVehicleListOrderChanges() } /* Store final sort-order */ - const EngineID *idend = ordering.End(); uint index = 0; - for (const EngineID *it = ordering.Begin(); it != idend; ++it, ++index) { - Engine::Get(*it)->list_position = index; + for (const EngineID &eid : ordering) { + Engine::Get(eid)->list_position = index; + ++index; } /* Clear out the queue */ - _list_order_changes.Reset(); + _list_order_changes.clear(); + _list_order_changes.shrink_to_fit(); } /** diff --git a/src/newgrf_engine.h b/src/newgrf_engine.h index 51adb0b7fb..f830ff499d 100644 --- a/src/newgrf_engine.h +++ b/src/newgrf_engine.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. @@ -40,9 +38,9 @@ struct VehicleScopeResolver : public ScopeResolver { void SetVehicle(const Vehicle *v) { this->v = v; } - /* virtual */ uint32 GetRandomBits() const; - /* virtual */ uint32 GetVariable(byte variable, uint32 parameter, bool *available) const; - /* virtual */ uint32 GetTriggers() const; + uint32 GetRandomBits() const override; + uint32 GetVariable(byte variable, uint32 parameter, bool *available) const override; + uint32 GetTriggers() const override; }; /** Resolver for a vehicle (chain) */ @@ -64,9 +62,12 @@ struct VehicleResolverObject : public ResolverObject { VehicleResolverObject(EngineID engine_type, const Vehicle *v, WagonOverride wagon_override, bool info_view = false, CallbackID callback = CBID_NO_CALLBACK, uint32 callback_param1 = 0, uint32 callback_param2 = 0); - /* virtual */ ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0); + ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) override; - /* virtual */ const SpriteGroup *ResolveReal(const RealSpriteGroup *group) const; + const SpriteGroup *ResolveReal(const RealSpriteGroup *group) const override; + + GrfSpecFeature GetFeature() const override; + uint32 GetDebugID() const override; }; static const uint TRAININFO_DEFAULT_VEHICLE_WIDTH = 29; @@ -81,11 +82,11 @@ void SetCustomEngineSprites(EngineID engine, byte cargo, const struct SpriteGrou void GetCustomEngineSprite(EngineID engine, const Vehicle *v, Direction direction, EngineImageType image_type, VehicleSpriteSeq *result); #define GetCustomVehicleSprite(v, direction, image_type, result) GetCustomEngineSprite(v->engine_type, v, direction, image_type, result) -#define GetCustomVehicleIcon(et, direction, image_type, result) GetCustomEngineSprite(et, NULL, direction, image_type, result) +#define GetCustomVehicleIcon(et, direction, image_type, result) GetCustomEngineSprite(et, nullptr, direction, image_type, result) void GetRotorOverrideSprite(EngineID engine, const struct Aircraft *v, bool info_view, EngineImageType image_type, VehicleSpriteSeq *result); #define GetCustomRotorSprite(v, i, image_type, result) GetRotorOverrideSprite(v->engine_type, v, i, image_type, result) -#define GetCustomRotorIcon(et, image_type, result) GetRotorOverrideSprite(et, NULL, true, image_type, result) +#define GetCustomRotorIcon(et, image_type, result) GetRotorOverrideSprite(et, nullptr, true, image_type, result) /* Forward declaration of GRFFile, to avoid unnecessary inclusion of newgrf.h * elsewhere... */ @@ -100,7 +101,7 @@ bool UsesWagonOverride(const Vehicle *v); /* Handler to Evaluate callback 36. If the callback fails (i.e. most of the * time) orig_value is returned */ uint GetVehicleProperty(const Vehicle *v, PropertyID property, uint orig_value); -uint GetEngineProperty(EngineID engine, PropertyID property, uint orig_value, const Vehicle *v = NULL); +uint GetEngineProperty(EngineID engine, PropertyID property, uint orig_value, const Vehicle *v = nullptr); enum VehicleTrigger { VEHICLE_TRIGGER_NEW_CARGO = 0x01, diff --git a/src/newgrf_generic.cpp b/src/newgrf_generic.cpp index eb2cbf08f1..6538b79b66 100644 --- a/src/newgrf_generic.cpp +++ b/src/newgrf_generic.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. @@ -31,6 +29,8 @@ struct GenericScopeResolver : public ScopeResolver { uint8 count; uint8 station_size; + uint8 feature; + /** * Generic scope resolver. * @param ro Surrounding resolver. @@ -38,11 +38,11 @@ struct GenericScopeResolver : public ScopeResolver { */ GenericScopeResolver(ResolverObject &ro, bool ai_callback) : ScopeResolver(ro), cargo_type(0), default_selection(0), src_industry(0), dst_industry(0), distance(0), - event(), count(0), station_size(0), ai_callback(ai_callback) + event(), count(0), station_size(0), feature(GSF_INVALID), ai_callback(ai_callback) { } - /* virtual */ uint32 GetVariable(byte variable, uint32 parameter, bool *available) const; + uint32 GetVariable(byte variable, uint32 parameter, bool *available) const override; private: bool ai_callback; ///< Callback comes from the AI. @@ -55,7 +55,7 @@ struct GenericResolverObject : public ResolverObject { GenericResolverObject(bool ai_callback, CallbackID callback = CBID_NO_CALLBACK); - /* virtual */ ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) + ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) override { switch (scope) { case VSG_SCOPE_SELF: return &this->generic_scope; @@ -63,7 +63,17 @@ struct GenericResolverObject : public ResolverObject { } } - /* virtual */ const SpriteGroup *ResolveReal(const RealSpriteGroup *group) const; + const SpriteGroup *ResolveReal(const RealSpriteGroup *group) const override; + + GrfSpecFeature GetFeature() const override + { + return (GrfSpecFeature)this->generic_scope.feature; + } + + uint32 GetDebugID() const override + { + return 0; + } }; struct GenericCallback { @@ -140,7 +150,7 @@ void AddGenericCallback(uint8 feature, const GRFFile *file, const SpriteGroup *g /* virtual */ const SpriteGroup *GenericResolverObject::ResolveReal(const RealSpriteGroup *group) const { - if (group->num_loaded == 0) return NULL; + if (group->num_loaded == 0) return nullptr; return group->loaded[0]; } @@ -150,7 +160,7 @@ void AddGenericCallback(uint8 feature, const GRFFile *file, const SpriteGroup *g * @param ai_callback Callback comes from the AI. * @param callback Callback ID. */ -GenericResolverObject::GenericResolverObject(bool ai_callback, CallbackID callback) : ResolverObject(NULL, callback), generic_scope(*this, ai_callback) +GenericResolverObject::GenericResolverObject(bool ai_callback, CallbackID callback) : ResolverObject(nullptr, callback), generic_scope(*this, ai_callback) { } @@ -162,7 +172,7 @@ GenericResolverObject::GenericResolverObject(bool ai_callback, CallbackID callba * @param object pre-populated resolver object * @param param1_grfv7 callback_param1 for GRFs up to version 7. * @param param1_grfv8 callback_param1 for GRFs from version 8 on. - * @param[out] file Optionally returns the GRFFile which made the final decision for the callback result. May be NULL if not required. + * @param[out] file Optionally returns the GRFFile which made the final decision for the callback result. May be nullptr if not required. * @return callback value if successful or CALLBACK_FAILED */ static uint16 GetGenericCallbackResult(uint8 feature, ResolverObject &object, uint32 param1_grfv7, uint32 param1_grfv8, const GRFFile **file) @@ -179,7 +189,7 @@ static uint16 GetGenericCallbackResult(uint8 feature, ResolverObject &object, ui if (result == CALLBACK_FAILED) continue; /* Return NewGRF file if necessary */ - if (file != NULL) *file = it->file; + if (file != nullptr) *file = it->file; return result; } @@ -201,7 +211,7 @@ static uint16 GetGenericCallbackResult(uint8 feature, ResolverObject &object, ui * @param event 'AI construction event' to pass to callback. (Variable 86) * @param count 'Construction number' to pass to callback. (Variable 87) * @param station_size 'Station size' to pass to callback. (Variable 88) - * @param[out] file Optionally returns the GRFFile which made the final decision for the callback result. May be NULL if not required. + * @param[out] file Optionally returns the GRFFile which made the final decision for the callback result. May be nullptr if not required. * @return callback value if successful or CALLBACK_FAILED */ 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) @@ -228,6 +238,7 @@ uint16 GetAiPurchaseCallbackResult(uint8 feature, CargoID cargo_type, uint8 defa object.generic_scope.event = event; object.generic_scope.count = count; object.generic_scope.station_size = station_size; + object.generic_scope.feature = feature; uint16 callback = GetGenericCallbackResult(feature, object, 0, 0, file); if (callback != CALLBACK_FAILED) callback = GB(callback, 0, 8); @@ -249,6 +260,7 @@ void AmbientSoundEffectCallback(TileIndex tile) /* Prepare resolver object. */ GenericResolverObject object(false, CBID_SOUNDS_AMBIENT_EFFECT); + object.generic_scope.feature = GSF_SOUNDFX; uint32 param1_v7 = GetTileType(tile) << 28 | Clamp(TileHeight(tile), 0, 15) << 24 | GB(r, 16, 8) << 16 | GetTerrainType(tile); uint32 param1_v8 = GetTileType(tile) << 24 | GetTileZ(tile) << 16 | GB(r, 16, 8) << 8 | (HasTileWaterClass(tile) ? GetWaterClass(tile) : 0) << 3 | GetTerrainType(tile); diff --git a/src/newgrf_generic.h b/src/newgrf_generic.h index 6251b9ffbd..0d4c8c1411 100644 --- a/src/newgrf_generic.h +++ b/src/newgrf_generic.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/newgrf_gui.cpp b/src/newgrf_gui.cpp index 400b2332b6..a2bd94475c 100644 --- a/src/newgrf_gui.cpp +++ b/src/newgrf_gui.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. @@ -48,11 +46,11 @@ void ShowNewGRFError() /* Do not show errors when entering the main screen */ if (_game_mode == GM_MENU) return; - for (const GRFConfig *c = _grfconfig; c != NULL; c = c->next) { + for (const GRFConfig *c = _grfconfig; c != nullptr; c = c->next) { /* We only want to show fatal errors */ - if (c->error == NULL || c->error->severity != STR_NEWGRF_ERROR_MSG_FATAL) continue; + if (c->error == nullptr || c->error->severity != STR_NEWGRF_ERROR_MSG_FATAL) continue; - SetDParam (0, c->error->custom_message == NULL ? c->error->message : STR_JUST_RAW_STRING); + SetDParam (0, c->error->custom_message == nullptr ? c->error->message : STR_JUST_RAW_STRING); SetDParamStr(1, c->error->custom_message); SetDParamStr(2, c->filename); SetDParamStr(3, c->error->data); @@ -66,7 +64,7 @@ void ShowNewGRFError() static void ShowNewGRFInfo(const GRFConfig *c, uint x, uint y, uint right, uint bottom, bool show_params) { - if (c->error != NULL) { + if (c->error != nullptr) { char message[512]; SetDParamStr(0, c->error->custom_message); // is skipped by built-in messages SetDParamStr(1, c->filename); @@ -74,14 +72,14 @@ static void ShowNewGRFInfo(const GRFConfig *c, uint x, uint y, uint right, uint for (uint i = 0; i < lengthof(c->error->param_value); i++) { SetDParam(3 + i, c->error->param_value[i]); } - GetString(message, c->error->custom_message == NULL ? c->error->message : STR_JUST_RAW_STRING, lastof(message)); + GetString(message, c->error->custom_message == nullptr ? c->error->message : STR_JUST_RAW_STRING, lastof(message)); SetDParamStr(0, message); y = DrawStringMultiLine(x, right, y, bottom, c->error->severity); } /* Draw filename or not if it is not known (GRF sent over internet) */ - if (c->filename != NULL) { + if (c->filename != nullptr) { SetDParamStr(0, c->filename); y = DrawStringMultiLine(x, right, y, bottom, STR_NEWGRF_SETTINGS_FILENAME); } @@ -166,7 +164,7 @@ struct NewGRFParametersWindow : public Window { clicked_row(UINT_MAX), editable(editable) { - this->action14present = (c->num_valid_params != lengthof(c->param) || c->param_info.Length() != 0); + this->action14present = (c->num_valid_params != lengthof(c->param) || c->param_info.size() != 0); this->CreateNestedTree(); this->vscroll = this->GetScrollbar(WID_NP_SCROLLBAR); @@ -190,7 +188,7 @@ struct NewGRFParametersWindow : public Window { return &dummy_parameter_info; } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_NP_NUMPAR_DEC: @@ -220,11 +218,11 @@ 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}; - for (uint i = 0; i < this->grf_config->param_info.Length(); i++) { + 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 == NULL) continue; + if (par_info == nullptr) continue; const char *desc = GetGRFStringFromGRFText(par_info->desc); - if (desc == NULL) continue; + if (desc == nullptr) continue; Dimension d = GetStringMultiLineBoundingBox(desc, suggestion); d.height += WD_TEXTPANEL_TOP + WD_TEXTPANEL_BOTTOM; suggestion = maxdim(d, suggestion); @@ -234,7 +232,7 @@ struct NewGRFParametersWindow : public Window { } } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { switch (widget) { case WID_NP_NUMPAR: @@ -243,13 +241,13 @@ struct NewGRFParametersWindow : public Window { } } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { if (widget == WID_NP_DESCRIPTION) { - const GRFParameterInfo *par_info = (this->clicked_row < this->grf_config->param_info.Length()) ? this->grf_config->param_info[this->clicked_row] : NULL; - if (par_info == NULL) return; + const GRFParameterInfo *par_info = (this->clicked_row < this->grf_config->param_info.size()) ? this->grf_config->param_info[this->clicked_row] : nullptr; + if (par_info == nullptr) return; const char *desc = GetGRFStringFromGRFText(par_info->desc); - if (desc == NULL) return; + 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); return; } else if (widget != WID_NP_BACKGROUND) { @@ -265,8 +263,8 @@ struct NewGRFParametersWindow : public Window { 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++) { - GRFParameterInfo *par_info = (i < this->grf_config->param_info.Length()) ? this->grf_config->param_info[i] : NULL; - if (par_info == NULL) par_info = GetDummyParameterInfo(i); + GRFParameterInfo *par_info = (i < this->grf_config->param_info.size()) ? this->grf_config->param_info[i] : nullptr; + if (par_info == nullptr) par_info = GetDummyParameterInfo(i); uint32 current_value = par_info->GetValue(this->grf_config); bool selected = (i == this->clicked_row); @@ -283,7 +281,7 @@ struct NewGRFParametersWindow : public Window { SetDParam(3, current_value); if (par_info->value_names.Contains(current_value)) { const char *label = GetGRFStringFromGRFText(par_info->value_names.Find(current_value)->second); - if (label != NULL) { + if (label != nullptr) { SetDParam(2, STR_JUST_RAW_STRING); SetDParamStr(3, label); } @@ -291,7 +289,7 @@ struct NewGRFParametersWindow : public Window { } const char *name = GetGRFStringFromGRFText(par_info->name); - if (name != NULL) { + if (name != nullptr) { SetDParam(0, STR_JUST_RAW_STRING); SetDParamStr(1, name); } else { @@ -304,7 +302,7 @@ struct NewGRFParametersWindow : public Window { } } - virtual void OnPaint() + void OnPaint() override { if (this->closing_dropdown) { this->closing_dropdown = false; @@ -313,7 +311,7 @@ struct NewGRFParametersWindow : public Window { this->DrawWidgets(); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_NP_NUMPAR_DEC: @@ -350,8 +348,8 @@ struct NewGRFParametersWindow : public Window { if (_current_text_dir == TD_RTL) x = wid->current_x - 1 - x; x -= 4; - GRFParameterInfo *par_info = (num < this->grf_config->param_info.Length()) ? this->grf_config->param_info[num] : NULL; - if (par_info == NULL) par_info = GetDummyParameterInfo(num); + 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); /* One of the arrows is clicked */ uint32 old_val = par_info->GetValue(this->grf_config); @@ -376,12 +374,12 @@ struct NewGRFParametersWindow : public Window { this->clicked_dropdown = true; this->closing_dropdown = false; - DropDownList *list = new DropDownList(); + DropDownList list; for (uint32 i = par_info->min_value; i <= par_info->max_value; i++) { - *list->Append() = new DropDownListCharStringItem(GetGRFStringFromGRFText(par_info->value_names.Find(i)->second), i, false); + list.emplace_back(new DropDownListCharStringItem(GetGRFStringFromGRFText(par_info->value_names.Find(i)->second), i, false)); } - ShowDropDownListAt(this, list, old_val, -1, wi_rect, COLOUR_ORANGE, true); + ShowDropDownListAt(this, std::move(list), old_val, -1, wi_rect, COLOUR_ORANGE, true); } } } else if (IsInsideMM(x, 0, SETTING_BUTTON_WIDTH)) { @@ -427,27 +425,27 @@ struct NewGRFParametersWindow : public Window { } } - virtual void OnQueryTextFinished(char *str) + void OnQueryTextFinished(char *str) override { if (StrEmpty(str)) return; int32 value = atoi(str); - GRFParameterInfo *par_info = ((uint)this->clicked_row < this->grf_config->param_info.Length()) ? this->grf_config->param_info[this->clicked_row] : NULL; - if (par_info == NULL) par_info = GetDummyParameterInfo(this->clicked_row); + GRFParameterInfo *par_info = ((uint)this->clicked_row < this->grf_config->param_info.size()) ? this->grf_config->param_info[this->clicked_row] : nullptr; + if (par_info == nullptr) par_info = GetDummyParameterInfo(this->clicked_row); uint32 val = Clamp(value, par_info->min_value, par_info->max_value); par_info->SetValue(this->grf_config, val); this->SetDirty(); } - virtual void OnDropdownSelect(int widget, int index) + void OnDropdownSelect(int widget, int index) override { assert(this->clicked_dropdown); - GRFParameterInfo *par_info = ((uint)this->clicked_row < this->grf_config->param_info.Length()) ? this->grf_config->param_info[this->clicked_row] : NULL; - if (par_info == NULL) par_info = GetDummyParameterInfo(this->clicked_row); + GRFParameterInfo *par_info = ((uint)this->clicked_row < this->grf_config->param_info.size()) ? this->grf_config->param_info[this->clicked_row] : nullptr; + if (par_info == nullptr) par_info = GetDummyParameterInfo(this->clicked_row); par_info->SetValue(this->grf_config, index); this->SetDirty(); } - virtual void OnDropdownClose(Point pt, int widget, int index, bool instant_close) + 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. @@ -458,7 +456,7 @@ struct NewGRFParametersWindow : public Window { this->SetDirty(); } - virtual void OnResize() + void OnResize() override { this->vscroll->SetCapacityFromWidget(this, WID_NP_BACKGROUND); } @@ -468,7 +466,7 @@ struct NewGRFParametersWindow : public Window { * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; if (!this->action14present) { @@ -483,7 +481,7 @@ struct NewGRFParametersWindow : public Window { } } - virtual void OnRealtimeTick(uint delta_ms) + void OnRealtimeTick(uint delta_ms) override { if (timeout.Elapsed(delta_ms)) { this->clicked_button = UINT_MAX; @@ -550,7 +548,7 @@ struct NewGRFTextfileWindow : public TextfileWindow { this->LoadTextfile(textfile, NEWGRF_DIR); } - /* virtual */ void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { if (widget == WID_TF_CAPTION) { SetDParam(0, STR_CONTENT_TYPE_NEWGRF); @@ -565,26 +563,6 @@ void ShowNewGRFTextfileWindow(TextfileType file_type, const GRFConfig *c) new NewGRFTextfileWindow(file_type, c); } -static GRFPresetList _grf_preset_list; ///< List of known NewGRF presets. @see GetGRFPresetList - -class DropDownListPresetItem : public DropDownListItem { -public: - DropDownListPresetItem(int result) : DropDownListItem(result, false) {} - - virtual ~DropDownListPresetItem() {} - - bool Selectable() const - { - return true; - } - - void Draw(int left, int right, int top, int bottom, bool sel, int bg_colour) const - { - DrawString(left + 2, right + 2, top, _grf_preset_list[this->result], sel ? TC_WHITE : TC_BLACK); - } -}; - - typedef std::map GrfIdMap; ///< Map of grfid to the grf config. /** @@ -594,7 +572,7 @@ typedef std::map GrfIdMap; ///< Map of grfid to the g */ static void FillGrfidMap(const GRFConfig *c, GrfIdMap *grfid_map) { - while (c != NULL) { + while (c != nullptr) { std::pair p(c->ident.grfid, c); grfid_map->insert(p); c = c->next; @@ -618,11 +596,13 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { static GUIGRFConfigList::FilterFunction * const filter_funcs[]; ///< Filter functions of the #GUIGRFConfigList. GUIGRFConfigList avails; ///< Available (non-active) grfs. - const GRFConfig *avail_sel; ///< Currently selected available grf. \c NULL is none is selected. + const GRFConfig *avail_sel; ///< Currently selected available grf. \c nullptr is none is selected. int avail_pos; ///< Index of #avail_sel if existing, else \c -1. StringFilter string_filter; ///< Filter for available grf. QueryString filter_editbox; ///< Filter editbox; + StringList grf_presets; ///< List of known NewGRF presets. + GRFConfig *actives; ///< Temporary active grf list to which changes are made. GRFConfig *active_sel; ///< Selected active grf item. @@ -638,10 +618,10 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { NewGRFWindow(WindowDesc *desc, bool editable, bool show_params, bool execute, GRFConfig **orig_list) : Window(desc), filter_editbox(EDITBOX_MAX_SIZE) { - this->avail_sel = NULL; + this->avail_sel = nullptr; this->avail_pos = -1; - this->active_sel = NULL; - this->actives = NULL; + this->active_sel = nullptr; + this->actives = nullptr; this->orig_list = orig_list; this->editable = editable; this->execute = execute; @@ -650,7 +630,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { this->active_over = -1; CopyGRFConfigList(&this->actives, *orig_list, false); - GetGRFPresetList(&_grf_preset_list); + this->grf_presets = GetGRFPresetList(); this->CreateNestedTree(); this->vscroll = this->GetScrollbar(WID_NS_SCROLLBAR); @@ -690,7 +670,6 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { /* Remove the temporary copy of grf-list used in window */ ClearGRFConfigList(&this->actives); - _grf_preset_list.Clear(); } /** @@ -702,7 +681,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { GrfIdMap grfid_map; FillGrfidMap(this->actives, &grfid_map); - for (const GRFConfig *a = _all_grfs; a != NULL; a = a->next) { + for (const GRFConfig *a = _all_grfs; a != nullptr; a = a->next) { GrfIdMap::const_iterator iter = grfid_map.find(a->ident.grfid); if (iter != grfid_map.end() && a->version > iter->second->version) return true; } @@ -715,7 +694,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { GrfIdMap grfid_map; FillGrfidMap(this->actives, &grfid_map); - for (const GRFConfig *a = _all_grfs; a != NULL; a = a->next) { + for (const GRFConfig *a = _all_grfs; a != nullptr; a = a->next) { GrfIdMap::iterator iter = grfid_map.find(a->ident.grfid); if (iter == grfid_map.end() || iter->second->version >= a->version) continue; @@ -727,7 +706,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { if (this->active_sel == *c) { DeleteWindowByClass(WC_GRF_PARAMETERS); DeleteWindowByClass(WC_TEXTFILE); - this->active_sel = NULL; + this->active_sel = nullptr; } delete *c; *c = d; @@ -735,7 +714,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { } } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_NS_FILE_LIST: @@ -764,11 +743,9 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { case WID_NS_PRESET_LIST: { Dimension d = GetStringBoundingBox(STR_NUM_CUSTOM); - for (uint i = 0; i < _grf_preset_list.Length(); i++) { - if (_grf_preset_list[i] != NULL) { - SetDParamStr(0, _grf_preset_list[i]); - d = maxdim(d, GetStringBoundingBox(STR_JUST_RAW_STRING)); - } + for (const auto &i : this->grf_presets) { + SetDParamStr(0, i.c_str()); + d = maxdim(d, GetStringBoundingBox(STR_JUST_RAW_STRING)); } d.width += padding.width; d.height = GetMinSizing(NWST_BUTTON, d.height); @@ -788,13 +765,13 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { } } - virtual void OnResize() + void OnResize() override { this->vscroll->SetCapacityFromWidget(this, WID_NS_FILE_LIST); if (this->vscroll2) this->vscroll2->SetCapacityFromWidget(this, WID_NS_AVAIL_LIST); } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { switch (widget) { case WID_NS_PRESET_LIST: @@ -802,7 +779,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { SetDParam(0, STR_NUM_CUSTOM); } else { SetDParam(0, STR_JUST_RAW_STRING); - SetDParamStr(1, _grf_preset_list[this->preset]); + SetDParamStr(1, this->grf_presets[this->preset].c_str()); } break; } @@ -843,7 +820,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { return pal; } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { switch (widget) { case WID_NS_FILE_LIST: { @@ -864,7 +841,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { uint warning_left = rtl ? r.right - square.width - warning.width - 10 : r.left + square.width + 10; int i = 0; - for (const GRFConfig *c = this->actives; c != NULL; c = c->next, i++) { + for (const GRFConfig *c = this->actives; c != nullptr; c = c->next, i++) { if (this->vscroll->IsVisible(i)) { const char *text = c->GetName(); bool h = (this->active_sel == c); @@ -875,15 +852,15 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { } else if (i == this->active_over) { /* Get index of current selection. */ int active_sel_pos = 0; - for (GRFConfig *c = this->actives; c != NULL && c != this->active_sel; c = c->next, active_sel_pos++) {} + 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); } } DrawSprite(SPR_SQUARE, pal, square_left, y + square_offset_y); - if (c->error != NULL) DrawSprite(SPR_WARNING_SIGN, 0, warning_left, y + warning_offset_y); - uint txtoffset = c->error == NULL ? 0 : warning.width; + if (c->error != nullptr) DrawSprite(SPR_WARNING_SIGN, 0, warning_left, y + 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; } @@ -901,7 +878,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { 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 = min(min_index + this->vscroll2->GetCapacity(), this->avails.Length()); + uint max_index = min(min_index + this->vscroll2->GetCapacity(), (uint)this->avails.size()); for (uint i = min_index; i < max_index; i++) { const GRFConfig *c = this->avails[i]; @@ -923,8 +900,8 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { case WID_NS_NEWGRF_INFO: { const GRFConfig *selected = this->active_sel; - if (selected == NULL) selected = this->avail_sel; - if (selected != NULL) { + 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); } break; @@ -932,35 +909,33 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { if (widget >= WID_NS_NEWGRF_TEXTFILE && widget < WID_NS_NEWGRF_TEXTFILE + TFT_END) { - if (this->active_sel == NULL && this->avail_sel == NULL) return; + if (this->active_sel == nullptr && this->avail_sel == nullptr) return; - ShowNewGRFTextfileWindow((TextfileType)(widget - WID_NS_NEWGRF_TEXTFILE), this->active_sel != NULL ? this->active_sel : this->avail_sel); + ShowNewGRFTextfileWindow((TextfileType)(widget - WID_NS_NEWGRF_TEXTFILE), this->active_sel != nullptr ? this->active_sel : this->avail_sel); return; } switch (widget) { case WID_NS_PRESET_LIST: { - DropDownList *list = new DropDownList(); + DropDownList list; /* Add 'None' option for clearing list */ - *list->Append() = new DropDownListStringItem(STR_NONE, -1, false); + list.emplace_back(new DropDownListStringItem(STR_NONE, -1, false)); - for (uint i = 0; i < _grf_preset_list.Length(); i++) { - if (_grf_preset_list[i] != NULL) { - *list->Append() = new DropDownListPresetItem(i); - } + for (uint i = 0; i < this->grf_presets.size(); i++) { + list.emplace_back(new DropDownListCharStringItem(this->grf_presets[i].c_str(), i, false)); } this->DeleteChildWindows(WC_QUERY_STRING); // Remove the parameter query window - ShowDropDownList(this, list, this->preset, WID_NS_PRESET_LIST); + ShowDropDownList(this, std::move(list), this->preset, WID_NS_PRESET_LIST); break; } case WID_NS_OPEN_URL: { - const GRFConfig *c = (this->avail_sel == NULL) ? this->active_sel : this->avail_sel; + const GRFConfig *c = (this->avail_sel == nullptr) ? this->active_sel : this->avail_sel; extern void OpenBrowser(const char *url); OpenBrowser(c->GetURL()); @@ -968,24 +943,24 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { } case WID_NS_PRESET_SAVE: - ShowSavePresetWindow((this->preset == -1) ? NULL : _grf_preset_list[this->preset]); + ShowSavePresetWindow((this->preset == -1) ? nullptr : this->grf_presets[this->preset].c_str()); break; case WID_NS_PRESET_DELETE: if (this->preset == -1) return; - DeleteGRFPresetFromConfig(_grf_preset_list[this->preset]); - GetGRFPresetList(&_grf_preset_list); + DeleteGRFPresetFromConfig(this->grf_presets[this->preset].c_str()); + this->grf_presets = GetGRFPresetList(); this->preset = -1; this->InvalidateData(); this->DeleteChildWindows(WC_QUERY_STRING); // Remove the parameter query window break; case WID_NS_MOVE_UP: { // Move GRF up - if (this->active_sel == NULL || !this->editable) break; + if (this->active_sel == nullptr || !this->editable) break; int pos = 0; - for (GRFConfig **pc = &this->actives; *pc != NULL; pc = &(*pc)->next, pos++) { + for (GRFConfig **pc = &this->actives; *pc != nullptr; pc = &(*pc)->next, pos++) { GRFConfig *c = *pc; if (c->next == this->active_sel) { c->next = this->active_sel->next; @@ -1001,10 +976,10 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { } case WID_NS_MOVE_DOWN: { // Move GRF down - if (this->active_sel == NULL || !this->editable) break; + if (this->active_sel == nullptr || !this->editable) break; int pos = 1; // Start at 1 as we swap the selected newgrf with the next one - for (GRFConfig **pc = &this->actives; *pc != NULL; pc = &(*pc)->next, pos++) { + for (GRFConfig **pc = &this->actives; *pc != nullptr; pc = &(*pc)->next, pos++) { GRFConfig *c = *pc; if (c == this->active_sel) { *pc = c->next; @@ -1025,19 +1000,19 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { uint i = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_NS_FILE_LIST); GRFConfig *c; - for (c = this->actives; c != NULL && i > 0; c = c->next, i--) {} + for (c = this->actives; c != nullptr && i > 0; c = c->next, i--) {} if (this->active_sel != c) { DeleteWindowByClass(WC_GRF_PARAMETERS); DeleteWindowByClass(WC_TEXTFILE); } this->active_sel = c; - this->avail_sel = NULL; + this->avail_sel = nullptr; this->avail_pos = -1; this->InvalidateData(); if (click_count == 1) { - if (this->editable && this->active_sel != NULL) SetObjectToPlaceWnd(SPR_CURSOR_MOUSE, PAL_NONE, HT_DRAG, this); + if (this->editable && this->active_sel != nullptr) SetObjectToPlaceWnd(SPR_CURSOR_MOUSE, PAL_NONE, HT_DRAG, this); break; } /* With double click, continue */ @@ -1045,20 +1020,20 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { } case WID_NS_REMOVE: { // Remove GRF - if (this->active_sel == NULL || !this->editable) break; + if (this->active_sel == nullptr || !this->editable) break; DeleteWindowByClass(WC_GRF_PARAMETERS); DeleteWindowByClass(WC_TEXTFILE); /* Choose the next GRF file to be the selected file. */ GRFConfig *newsel = this->active_sel->next; - for (GRFConfig **pc = &this->actives; *pc != NULL; pc = &(*pc)->next) { + for (GRFConfig **pc = &this->actives; *pc != nullptr; pc = &(*pc)->next) { GRFConfig *c = *pc; /* If the new selection is empty (i.e. we're deleting the last item * in the list, pick the file just before the selected file */ - if (newsel == NULL && c->next == this->active_sel) newsel = c; + if (newsel == nullptr && c->next == this->active_sel) newsel = c; if (c == this->active_sel) { - if (newsel == c) newsel = NULL; + if (newsel == c) newsel = nullptr; *pc = c->next; delete c; @@ -1069,14 +1044,14 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { this->active_sel = newsel; this->preset = -1; this->avail_pos = -1; - this->avail_sel = NULL; + this->avail_sel = nullptr; this->avails.ForceRebuild(); this->InvalidateData(GOID_NEWGRF_LIST_EDITED); break; } case WID_NS_UPGRADE: { // Upgrade GRF. - if (!this->editable || this->actives == NULL) break; + if (!this->editable || this->actives == nullptr) break; UpgradeCurrent(); this->InvalidateData(GOID_NEWGRF_LIST_EDITED); break; @@ -1086,16 +1061,16 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { ResetObjectToPlace(); uint i = this->vscroll2->GetScrolledRowFromWidget(pt.y, this, WID_NS_AVAIL_LIST); - this->active_sel = NULL; + this->active_sel = nullptr; DeleteWindowByClass(WC_GRF_PARAMETERS); - if (i < this->avails.Length()) { + if (i < this->avails.size()) { if (this->avail_sel != this->avails[i]) DeleteWindowByClass(WC_TEXTFILE); this->avail_sel = this->avails[i]; this->avail_pos = i; } this->InvalidateData(); if (click_count == 1) { - if (this->editable && this->avail_sel != NULL && !HasBit(this->avail_sel->flags, GCF_INVALID)) SetObjectToPlaceWnd(SPR_CURSOR_MOUSE, PAL_NONE, HT_DRAG, this); + if (this->editable && this->avail_sel != nullptr && !HasBit(this->avail_sel->flags, GCF_INVALID)) SetObjectToPlaceWnd(SPR_CURSOR_MOUSE, PAL_NONE, HT_DRAG, this); break; } /* With double click, continue */ @@ -1103,7 +1078,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { } case WID_NS_ADD: - if (this->avail_sel == NULL || !this->editable || HasBit(this->avail_sel->flags, GCF_INVALID)) break; + if (this->avail_sel == nullptr || !this->editable || HasBit(this->avail_sel->flags, GCF_INVALID)) break; this->AddGRFToActive(); break; @@ -1127,14 +1102,14 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { case WID_NS_VIEW_PARAMETERS: case WID_NS_SET_PARAMETERS: { // Edit parameters - if (this->active_sel == NULL || !this->show_params || this->active_sel->num_valid_params == 0) break; + if (this->active_sel == nullptr || !this->show_params || this->active_sel->num_valid_params == 0) break; OpenGRFParameterWindow(this->active_sel, this->editable); break; } case WID_NS_TOGGLE_PALETTE: - if (this->active_sel != NULL && this->editable) { + if (this->active_sel != nullptr && this->editable) { this->active_sel->palette ^= GRFP_USE_MASK; this->SetDirty(); } @@ -1145,11 +1120,9 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { if (!_network_available) { ShowErrorMessage(STR_NETWORK_ERROR_NOTAVAILABLE, INVALID_STRING_ID, WL_ERROR); } else { -#if defined(ENABLE_NETWORK) this->DeleteChildWindows(WC_QUERY_STRING); // Remove the parameter query window ShowMissingContentWindow(this->actives); -#endif } break; @@ -1160,16 +1133,16 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { } } - virtual void OnNewGRFsScanned() + void OnNewGRFsScanned() override { - if (this->active_sel == NULL) DeleteWindowByClass(WC_TEXTFILE); - this->avail_sel = NULL; + if (this->active_sel == nullptr) DeleteWindowByClass(WC_TEXTFILE); + this->avail_sel = nullptr; this->avail_pos = -1; this->avails.ForceRebuild(); this->DeleteChildWindows(WC_QUERY_STRING); // Remove the parameter query window } - virtual void OnDropdownSelect(int widget, int index) + void OnDropdownSelect(int widget, int index) override { if (!this->editable) return; @@ -1177,27 +1150,27 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { this->preset = index; if (index != -1) { - this->actives = LoadGRFPresetFromConfig(_grf_preset_list[index]); + this->actives = LoadGRFPresetFromConfig(this->grf_presets[index].c_str()); } this->avails.ForceRebuild(); ResetObjectToPlace(); DeleteWindowByClass(WC_GRF_PARAMETERS); DeleteWindowByClass(WC_TEXTFILE); - this->active_sel = NULL; + this->active_sel = nullptr; this->InvalidateData(GOID_NEWGRF_PRESET_LOADED); } - virtual void OnQueryTextFinished(char *str) + void OnQueryTextFinished(char *str) override { - if (str == NULL) return; + if (str == nullptr) return; SaveGRFPresetToConfig(str, this->actives); - GetGRFPresetList(&_grf_preset_list); + this->grf_presets = GetGRFPresetList(); /* Switch to this preset */ - for (uint i = 0; i < _grf_preset_list.Length(); i++) { - if (_grf_preset_list[i] != NULL && strcmp(_grf_preset_list[i], str) == 0) { + for (uint i = 0; i < this->grf_presets.size(); i++) { + if (this->grf_presets[i] == str) { this->preset = i; break; } @@ -1211,7 +1184,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { * @param data Information about the changed data. @see GameOptionsInvalidationData * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; switch (data) { @@ -1221,13 +1194,13 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { case GOID_NEWGRF_RESCANNED: /* Search the list for items that are now found and mark them as such. */ - for (GRFConfig **l = &this->actives; *l != NULL; l = &(*l)->next) { + for (GRFConfig **l = &this->actives; *l != nullptr; l = &(*l)->next) { GRFConfig *c = *l; bool compatible = HasBit(c->flags, GCF_COMPATIBLE); if (c->status != GCS_NOT_FOUND && !compatible) continue; const GRFConfig *f = FindGRFConfig(c->ident.grfid, FGCM_EXACT, compatible ? c->original_md5sum : c->ident.md5sum); - if (f == NULL || HasBit(f->flags, GCF_INVALID)) continue; + if (f == nullptr || HasBit(f->flags, GCF_INVALID)) continue; *l = new GRFConfig(*f); (*l)->next = c->next; @@ -1247,7 +1220,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { case GOID_NEWGRF_PRESET_LOADED: { /* Update scrollbars */ int i = 0; - for (const GRFConfig *c = this->actives; c != NULL; c = c->next, i++) {} + for (const GRFConfig *c = this->actives; c != nullptr; c = c->next, i++) {} this->vscroll->SetCount(i + 1); // Reserve empty space for drag and drop handling. @@ -1264,10 +1237,10 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { WID_NS_TOGGLE_PALETTE, WIDGET_LIST_END ); - this->SetWidgetDisabledState(WID_NS_ADD, !this->editable || this->avail_sel == NULL || HasBit(this->avail_sel->flags, GCF_INVALID)); - this->SetWidgetDisabledState(WID_NS_UPGRADE, !this->editable || this->actives == NULL || !this->CanUpgradeCurrent()); + this->SetWidgetDisabledState(WID_NS_ADD, !this->editable || this->avail_sel == nullptr || HasBit(this->avail_sel->flags, GCF_INVALID)); + this->SetWidgetDisabledState(WID_NS_UPGRADE, !this->editable || this->actives == nullptr || !this->CanUpgradeCurrent()); - bool disable_all = this->active_sel == NULL || !this->editable; + bool disable_all = this->active_sel == nullptr || !this->editable; this->SetWidgetsDisabledState(disable_all, WID_NS_REMOVE, WID_NS_MOVE_UP, @@ -1275,28 +1248,28 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { WIDGET_LIST_END ); - const GRFConfig *c = (this->avail_sel == NULL) ? this->active_sel : this->avail_sel; + const GRFConfig *c = (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 == NULL || c->GetTextfile(tft) == NULL); + this->SetWidgetDisabledState(WID_NS_NEWGRF_TEXTFILE + tft, c == nullptr || c->GetTextfile(tft) == nullptr); } - this->SetWidgetDisabledState(WID_NS_OPEN_URL, c == NULL || StrEmpty(c->GetURL())); + this->SetWidgetDisabledState(WID_NS_OPEN_URL, c == nullptr || StrEmpty(c->GetURL())); - this->SetWidgetDisabledState(WID_NS_SET_PARAMETERS, !this->show_params || this->active_sel == NULL || this->active_sel->num_valid_params == 0); - this->SetWidgetDisabledState(WID_NS_VIEW_PARAMETERS, !this->show_params || this->active_sel == NULL || this->active_sel->num_valid_params == 0); + 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))); if (!disable_all) { /* All widgets are now enabled, so disable widgets we can't use */ if (this->active_sel == this->actives) this->DisableWidget(WID_NS_MOVE_UP); - if (this->active_sel->next == NULL) this->DisableWidget(WID_NS_MOVE_DOWN); + if (this->active_sel->next == nullptr) this->DisableWidget(WID_NS_MOVE_DOWN); } this->SetWidgetDisabledState(WID_NS_PRESET_DELETE, this->preset == -1); bool has_missing = false; bool has_compatible = false; - for (const GRFConfig *c = this->actives; !has_missing && c != NULL; c = c->next) { + for (const GRFConfig *c = this->actives; !has_missing && c != nullptr; c = c->next) { has_missing |= c->status == GCS_NOT_FOUND; has_compatible |= HasBit(c->flags, GCF_COMPATIBLE); } @@ -1319,7 +1292,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { this->SetWidgetDisabledState(WID_NS_PRESET_SAVE, has_missing); } - virtual EventState OnKeyPress(WChar key, uint16 keycode) + EventState OnKeyPress(WChar key, uint16 keycode) override { if (!this->editable) return ES_NOT_HANDLED; @@ -1331,7 +1304,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { case WKC_DOWN: /* scroll down by one */ - if (this->avail_pos < (int)this->avails.Length() - 1) this->avail_pos++; + if (this->avail_pos < (int)this->avails.size() - 1) this->avail_pos++; break; case WKC_PAGEUP: @@ -1341,7 +1314,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { case WKC_PAGEDOWN: /* scroll down a page */ - this->avail_pos = min(this->avail_pos + this->vscroll2->GetCapacity(), (int)this->avails.Length() - 1); + this->avail_pos = min(this->avail_pos + this->vscroll2->GetCapacity(), (int)this->avails.size() - 1); break; case WKC_HOME: @@ -1351,16 +1324,16 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { case WKC_END: /* jump to end */ - this->avail_pos = this->avails.Length() - 1; + this->avail_pos = (uint)this->avails.size() - 1; break; default: return ES_NOT_HANDLED; } - if (this->avails.Length() == 0) this->avail_pos = -1; + if (this->avails.size() == 0) this->avail_pos = -1; if (this->avail_pos >= 0) { - this->active_sel = NULL; + this->active_sel = nullptr; DeleteWindowByClass(WC_GRF_PARAMETERS); if (this->avail_sel != this->avails[this->avail_pos]) DeleteWindowByClass(WC_TEXTFILE); this->avail_sel = this->avails[this->avail_pos]; @@ -1371,7 +1344,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { return ES_HANDLED; } - virtual void OnEditboxChanged(int wid) + void OnEditboxChanged(int wid) override { if (!this->editable) return; @@ -1381,12 +1354,12 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { this->InvalidateData(0); } - virtual void OnDragDrop(Point pt, int widget) + void OnDragDrop(Point pt, int widget) override { if (!this->editable) return; if (widget == WID_NS_FILE_LIST) { - if (this->active_sel != NULL) { + if (this->active_sel != nullptr) { /* Get pointer to the selected file in the active list. */ int from_pos = 0; GRFConfig **from_prev; @@ -1397,7 +1370,7 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { if (to_pos != from_pos) { // Don't move NewGRF file over itself. /* Get pointer to destination position. */ GRFConfig **to_prev = &this->actives; - for (int i = from_pos < to_pos ? -1 : 0; *to_prev != NULL && i < to_pos; to_prev = &(*to_prev)->next, i++) {} + for (int i = from_pos < to_pos ? -1 : 0; *to_prev != nullptr && i < to_pos; to_prev = &(*to_prev)->next, i++) {} /* Detach NewGRF file from its original position. */ *from_prev = this->active_sel->next; @@ -1410,11 +1383,11 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { this->preset = -1; this->InvalidateData(); } - } else if (this->avail_sel != NULL) { + } else if (this->avail_sel != nullptr) { int to_pos = min(this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_NS_FILE_LIST), this->vscroll->GetCount() - 1); this->AddGRFToActive(to_pos); } - } else if (widget == WID_NS_AVAIL_LIST && this->active_sel != NULL) { + } else if (widget == WID_NS_AVAIL_LIST && this->active_sel != nullptr) { /* Remove active NewGRF file by dragging it over available list. */ Point dummy = {-1, -1}; this->OnClick(dummy, WID_NS_REMOVE, 1); @@ -1429,21 +1402,21 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { } } - virtual void OnMouseDrag(Point pt, int widget) + void OnMouseDrag(Point pt, int widget) override { if (!this->editable) return; - if (widget == WID_NS_FILE_LIST && (this->active_sel != NULL || this->avail_sel != NULL)) { + if (widget == WID_NS_FILE_LIST && (this->active_sel != nullptr || this->avail_sel != nullptr)) { /* An NewGRF file is dragged over the active list. */ int to_pos = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_NS_FILE_LIST); /* Skip the last dummy line if the source is from the active list. */ - to_pos = min(to_pos, this->vscroll->GetCount() - (this->active_sel != NULL ? 2 : 1)); + to_pos = min(to_pos, this->vscroll->GetCount() - (this->active_sel != nullptr ? 2 : 1)); if (to_pos != this->active_over) { this->active_over = to_pos; this->SetWidgetDirty(WID_NS_FILE_LIST); } - } else if (widget == WID_NS_AVAIL_LIST && this->active_sel != NULL) { + } else if (widget == WID_NS_AVAIL_LIST && this->active_sel != nullptr) { this->active_over = -2; this->SetWidgetDirty(WID_NS_AVAIL_LIST); } else if (this->active_over != -1) { @@ -1454,15 +1427,15 @@ struct NewGRFWindow : public Window, NewGRFScanCallback { private: /** Sort grfs by name. */ - static int CDECL NameSorter(const GRFConfig * const *a, const GRFConfig * const *b) + static bool NameSorter(const GRFConfig * const &a, const GRFConfig * const &b) { - int i = strnatcmp((*a)->GetName(), (*b)->GetName(), true); // Sort by name (natural sorting). - if (i != 0) return i; + int i = strnatcmp(a->GetName(), b->GetName(), true); // Sort by name (natural sorting). + if (i != 0) return i < 0; - i = (*a)->version - (*b)->version; - if (i != 0) return i; + i = a->version - b->version; + if (i != 0) return i < 0; - return memcmp((*a)->ident.md5sum, (*b)->ident.md5sum, lengthof((*b)->ident.md5sum)); + return memcmp(a->ident.md5sum, b->ident.md5sum, lengthof(b->ident.md5sum)) < 0; } /** Filter grfs by tags/name */ @@ -1479,15 +1452,15 @@ private: { if (!this->avails.NeedRebuild()) return; - this->avails.Clear(); + this->avails.clear(); - for (const GRFConfig *c = _all_grfs; c != NULL; c = c->next) { + for (const GRFConfig *c = _all_grfs; c != nullptr; c = c->next) { bool found = false; - for (const GRFConfig *grf = this->actives; grf != NULL && !found; grf = grf->next) found = grf->ident.HasGrfIdentifier(c->ident.grfid, c->ident.md5sum); + for (const GRFConfig *grf = this->actives; grf != nullptr && !found; grf = grf->next) found = grf->ident.HasGrfIdentifier(c->ident.grfid, c->ident.md5sum); if (found) continue; if (_settings_client.gui.newgrf_show_old_versions) { - *this->avails.Append() = c; + this->avails.push_back(c); } else { const GRFConfig *best = FindGRFConfig(c->ident.grfid, HasBit(c->flags, GCF_INVALID) ? FGCM_NEWEST : FGCM_NEWEST_VALID); /* @@ -1498,22 +1471,24 @@ private: * show that NewGRF!. */ if (best->version == 0 || best->ident.HasGrfIdentifier(c->ident.grfid, c->ident.md5sum)) { - *this->avails.Append() = c; + this->avails.push_back(c); } } } this->avails.Filter(this->string_filter); - this->avails.Compact(); + this->avails.shrink_to_fit(); this->avails.RebuildDone(); this->avails.Sort(); - if (this->avail_sel != NULL) { - this->avail_pos = this->avails.FindIndex(this->avail_sel); - if (this->avail_pos < 0) this->avail_sel = NULL; + if (this->avail_sel != nullptr) { + this->avail_pos = find_index(this->avails, this->avail_sel); + if (this->avail_pos == -1) { + this->avail_sel = nullptr; + } } - if (this->vscroll2) this->vscroll2->SetCount(this->avails.Length()); // Update the scrollbar + if (this->vscroll2) this->vscroll2->SetCount((uint)this->avails.size()); // Update the scrollbar } /** @@ -1523,15 +1498,15 @@ private: */ bool AddGRFToActive(int ins_pos = -1) { - if (this->avail_sel == NULL || !this->editable || HasBit(this->avail_sel->flags, GCF_INVALID)) return false; + if (this->avail_sel == nullptr || !this->editable || HasBit(this->avail_sel->flags, GCF_INVALID)) return false; DeleteWindowByClass(WC_TEXTFILE); uint count = 0; - GRFConfig **entry = NULL; + GRFConfig **entry = nullptr; GRFConfig **list; /* Find last entry in the list, checking for duplicate grfid on the way */ - for (list = &this->actives; *list != NULL; list = &(*list)->next, ins_pos--) { + for (list = &this->actives; *list != nullptr; list = &(*list)->next, ins_pos--) { if (ins_pos == 0) entry = list; // Insert position? Save. if ((*list)->ident.grfid == this->avail_sel->ident.grfid) { ShowErrorMessage(STR_NEWGRF_DUPLICATE_GRFID, INVALID_STRING_ID, WL_INFO); @@ -1539,7 +1514,7 @@ private: } if (!HasBit((*list)->flags, GCF_STATIC)) count++; } - if (entry == NULL) entry = list; + if (entry == nullptr) entry = list; if (count >= NETWORK_MAX_GRF_COUNT) { ShowErrorMessage(STR_NEWGRF_TOO_MANY_NEWGRFS, INVALID_STRING_ID, WL_INFO); return false; @@ -1554,7 +1529,7 @@ private: /* Select next (or previous, if last one) item in the list. */ int new_pos = this->avail_pos + 1; - if (new_pos >= (int)this->avails.Length()) new_pos = this->avail_pos - 1; + if (new_pos >= (int)this->avails.size()) new_pos = this->avail_pos - 1; this->avail_pos = new_pos; if (new_pos >= 0) this->avail_sel = this->avails[new_pos]; @@ -1564,7 +1539,6 @@ private: } }; -#if defined(ENABLE_NETWORK) /** * Show the content list window with all missing grfs from the given list. * @param list The list of grfs to check for missing / not exactly matching ones. @@ -1573,7 +1547,7 @@ void ShowMissingContentWindow(const GRFConfig *list) { /* Only show the things in the current list, or everything when nothing's selected */ ContentVector cv; - for (const GRFConfig *c = list; c != NULL; c = c->next) { + for (const GRFConfig *c = list; c != nullptr; c = c->next) { if (c->status != GCS_NOT_FOUND && !HasBit(c->flags, GCF_COMPATIBLE)) continue; ContentInfo *ci = new ContentInfo(); @@ -1582,11 +1556,10 @@ void ShowMissingContentWindow(const GRFConfig *list) strecpy(ci->name, c->GetName(), lastof(ci->name)); ci->unique_id = BSWAP32(c->ident.grfid); memcpy(ci->md5sum, HasBit(c->flags, GCF_COMPATIBLE) ? c->original_md5sum : c->ident.md5sum, sizeof(ci->md5sum)); - *cv.Append() = ci; + cv.push_back(ci); } - ShowNetworkContentListWindow(cv.Length() == 0 ? NULL : &cv, CONTENT_TYPE_NEWGRF); + ShowNetworkContentListWindow(cv.size() == 0 ? nullptr : &cv, CONTENT_TYPE_NEWGRF); } -#endif Listing NewGRFWindow::last_sorting = {false, 0}; Filtering NewGRFWindow::last_filtering = {false, 0}; @@ -1630,10 +1603,10 @@ public: this->editable = true; // Temporary setting, 'real' value is set in SetupSmallestSize(). } - virtual void SetupSmallestSize(Window *w, bool init_array) + void SetupSmallestSize(Window *w, bool init_array) override { /* Copy state flag from the window. */ - assert(dynamic_cast(w) != NULL); + assert(dynamic_cast(w) != nullptr); NewGRFWindow *ngw = (NewGRFWindow *)w; this->editable = ngw->editable; @@ -1673,7 +1646,7 @@ public: this->smallest_y = ComputeMaxSize(min_acs_height, this->smallest_y + this->resize_y - 1, this->resize_y); } - virtual void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl) + void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl) override { this->StoreSizePosition(sizing, x, y, given_width, given_height); @@ -1792,17 +1765,17 @@ public: } } - virtual NWidgetCore *GetWidgetFromPos(int x, int y) + NWidgetCore *GetWidgetFromPos(int x, int y) override { - if (!IsInsideBS(x, this->pos_x, this->current_x) || !IsInsideBS(y, this->pos_y, this->current_y)) return NULL; + if (!IsInsideBS(x, this->pos_x, this->current_x) || !IsInsideBS(y, this->pos_y, this->current_y)) return nullptr; - NWidgetCore *nw = this->avs->GetWidgetFromPos(x, y); - if (nw == NULL) nw = this->acs->GetWidgetFromPos(x, y); - if (nw == NULL) nw = this->inf->GetWidgetFromPos(x, y); + NWidgetCore *nw = (this->editable) ? this->avs->GetWidgetFromPos(x, y) : nullptr; + if (nw == nullptr) nw = this->acs->GetWidgetFromPos(x, y); + if (nw == nullptr) nw = this->inf->GetWidgetFromPos(x, y); return nw; } - virtual void Draw(const Window *w) + void Draw(const Window *w) override { this->avs->Draw(w); this->acs->Draw(w); @@ -2012,19 +1985,13 @@ static const NWidgetPart _nested_newgrf_infopanel_wide_widgets[] = { static bool _newgrf_display_editable = false; // Quick hack NWidgetBase* NewGRFDisplay(int *biggest_index) { - NWidgetBase *avs = _newgrf_display_editable ? - MakeNWidgets(_nested_newgrf_availables_widgets, lengthof(_nested_newgrf_availables_widgets), biggest_index, NULL) : - MakeNWidgets(_nested_newgrf_actives_wide_widgets, lengthof(_nested_newgrf_actives_wide_widgets), biggest_index, NULL); + NWidgetBase *avs = MakeNWidgets(_nested_newgrf_availables_widgets, lengthof(_nested_newgrf_availables_widgets), biggest_index, nullptr); int biggest2; - NWidgetBase *acs = _newgrf_display_editable ? - MakeNWidgets(_nested_newgrf_actives_widgets, lengthof(_nested_newgrf_actives_widgets), &biggest2, NULL) : - MakeNWidgets(_nested_newgrf_buttons_wide_widgets, lengthof(_nested_newgrf_buttons_wide_widgets), &biggest2, NULL); + NWidgetBase *acs = MakeNWidgets(_nested_newgrf_actives_widgets, lengthof(_nested_newgrf_actives_widgets), &biggest2, nullptr); *biggest_index = max(*biggest_index, biggest2); - NWidgetBase *inf = _newgrf_display_editable ? - MakeNWidgets(_nested_newgrf_infopanel_widgets, lengthof(_nested_newgrf_infopanel_widgets), &biggest2, NULL) : - MakeNWidgets(_nested_newgrf_infopanel_wide_widgets, lengthof(_nested_newgrf_infopanel_wide_widgets), &biggest2, NULL); + NWidgetBase *inf = MakeNWidgets(_nested_newgrf_infopanel_widgets, lengthof(_nested_newgrf_infopanel_widgets), &biggest2, nullptr); *biggest_index = max(*biggest_index, biggest2); return new NWidgetNewGRFDisplay(avs, acs, inf); @@ -2076,9 +2043,9 @@ static void NewGRFConfirmationCallback(Window *w, bool confirmed) /* Show new, updated list */ GRFConfig *c; int i = 0; - for (c = nw->actives; c != NULL && c != nw->active_sel; c = c->next, i++) {} + for (c = nw->actives; c != nullptr && c != nw->active_sel; c = c->next, i++) {} CopyGRFConfigList(&nw->actives, *nw->orig_list, false); - for (c = nw->actives; c != NULL && i > 0; c = c->next, i--) {} + for (c = nw->actives; c != nullptr && i > 0; c = c->next, i--) {} nw->active_sel = c; nw->avails.ForceRebuild(); @@ -2140,21 +2107,21 @@ static WindowDesc _save_preset_desc( /** Class for the save preset window. */ struct SavePresetWindow : public Window { QueryString presetname_editbox; ///< Edit box of the save preset. - GRFPresetList presets; ///< Available presets. + StringList presets; ///< Available presets. Scrollbar *vscroll; ///< Pointer to the scrollbar widget. int selected; ///< Selected entry in the preset list, or \c -1 if none selected. /** * Constructor of the save preset window. - * @param initial_text Initial text to display in the edit box, or \c NULL. + * @param initial_text Initial text to display in the edit box, or \c nullptr. */ SavePresetWindow(const char *initial_text) : Window(&_save_preset_desc), presetname_editbox(32) { - GetGRFPresetList(&this->presets); + this->presets = GetGRFPresetList(); this->selected = -1; - if (initial_text != NULL) { - for (uint i = 0; i < this->presets.Length(); i++) { - if (!strcmp(initial_text, this->presets[i])) { + if (initial_text != nullptr) { + for (uint i = 0; i < this->presets.size(); i++) { + if (this->presets[i] == initial_text) { this->selected = i; break; } @@ -2169,33 +2136,33 @@ struct SavePresetWindow : public Window { this->vscroll = this->GetScrollbar(WID_SVP_SCROLLBAR); this->FinishInitNested(0); - this->vscroll->SetCount(this->presets.Length()); + this->vscroll->SetCount((uint)this->presets.size()); this->SetFocusedWidget(WID_SVP_EDITBOX); - if (initial_text != NULL) this->presetname_editbox.text.Assign(initial_text); + if (initial_text != nullptr) this->presetname_editbox.text.Assign(initial_text); } ~SavePresetWindow() { } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_SVP_PRESET_LIST: { resize->height = FONT_HEIGHT_NORMAL + 2U; size->height = 0; - for (uint i = 0; i < this->presets.Length(); i++) { - Dimension d = GetStringBoundingBox(this->presets[i]); + for (uint i = 0; i < this->presets.size(); i++) { + Dimension d = GetStringBoundingBox(this->presets[i].c_str()); size->width = max(size->width, d.width + WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT); resize->height = max(resize->height, d.height); } - size->height = ClampU(this->presets.Length(), 5, 20) * resize->height + 1; + size->height = ClampU((uint)this->presets.size(), 5, 20) * resize->height + 1; break; } } } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { switch (widget) { case WID_SVP_PRESET_LIST: { @@ -2205,12 +2172,12 @@ struct SavePresetWindow : public Window { int offset_y = (step_height - FONT_HEIGHT_NORMAL) / 2; uint y = r.top + WD_FRAMERECT_TOP; uint min_index = this->vscroll->GetPosition(); - uint max_index = min(min_index + this->vscroll->GetCapacity(), this->presets.Length()); + uint max_index = 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); - const char *text = this->presets[i]; + 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; } @@ -2219,14 +2186,14 @@ struct SavePresetWindow : public Window { } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_SVP_PRESET_LIST: { uint row = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SVP_PRESET_LIST); - if (row < this->presets.Length()) { + if (row < this->presets.size()) { this->selected = row; - this->presetname_editbox.text.Assign(this->presets[row]); + this->presetname_editbox.text.Assign(this->presets[row].c_str()); this->SetWidgetDirty(WID_SVP_PRESET_LIST); this->SetWidgetDirty(WID_SVP_EDITBOX); } @@ -2239,14 +2206,14 @@ struct SavePresetWindow : public Window { case WID_SVP_SAVE: { Window *w = FindWindowById(WC_GAME_OPTIONS, WN_GAME_OPTIONS_NEWGRF_STATE); - if (w != NULL && !StrEmpty(this->presetname_editbox.text.buf)) w->OnQueryTextFinished(this->presetname_editbox.text.buf); + if (w != nullptr && !StrEmpty(this->presetname_editbox.text.buf)) w->OnQueryTextFinished(this->presetname_editbox.text.buf); delete this; break; } } } - virtual void OnResize() + void OnResize() override { this->vscroll->SetCapacityFromWidget(this, WID_SVP_PRESET_LIST); } @@ -2254,7 +2221,7 @@ struct SavePresetWindow : public Window { /** * Open the window for saving a preset. - * @param initial_text Initial text to display in the edit box, or \c NULL. + * @param initial_text Initial text to display in the edit box, or \c nullptr. */ static void ShowSavePresetWindow(const char *initial_text) { @@ -2279,7 +2246,7 @@ static const NWidgetPart _nested_scan_progress_widgets[] = { /** Description of the widgets and other settings of the window. */ static WindowDesc _scan_progress_desc( - WDP_CENTER, NULL, 0, 0, + WDP_CENTER, nullptr, 0, 0, WC_MODAL_PROGRESS, WC_NONE, 0, _nested_scan_progress_widgets, lengthof(_nested_scan_progress_widgets) @@ -2291,7 +2258,7 @@ struct ScanProgressWindow : public Window { int scanned; ///< The number of NewGRFs that we have seen. /** Create the window. */ - ScanProgressWindow() : Window(&_scan_progress_desc), last_name(NULL), scanned(0) + ScanProgressWindow() : Window(&_scan_progress_desc), last_name(nullptr), scanned(0) { this->InitNested(1); } @@ -2302,7 +2269,7 @@ struct ScanProgressWindow : public Window { free(last_name); } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_SP_PROGRESS_BAR: { @@ -2325,7 +2292,7 @@ struct ScanProgressWindow : public Window { } } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { switch (widget) { case WID_SP_PROGRESS_BAR: { @@ -2343,7 +2310,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 == NULL ? "" : this->last_name, TC_BLACK, 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); break; } } @@ -2356,7 +2323,7 @@ struct ScanProgressWindow : public Window { void UpdateNewGRFScanStatus(uint num, const char *name) { free(this->last_name); - if (name == NULL) { + if (name == nullptr) { char buf[256]; GetString(buf, STR_NEWGRF_SCAN_ARCHIVES, lastof(buf)); this->last_name = stredup(buf); @@ -2378,6 +2345,6 @@ struct ScanProgressWindow : public Window { void UpdateNewGRFScanStatus(uint num, const char *name) { ScanProgressWindow *w = dynamic_cast(FindWindowByClass(WC_MODAL_PROGRESS)); - if (w == NULL) w = new ScanProgressWindow(); + if (w == nullptr) w = new ScanProgressWindow(); w->UpdateNewGRFScanStatus(num, name); } diff --git a/src/newgrf_house.cpp b/src/newgrf_house.cpp index 314f02b3dc..b585a682dc 100644 --- a/src/newgrf_house.cpp +++ b/src/newgrf_house.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. @@ -34,12 +32,12 @@ HouseOverrideManager _house_mngr(NEW_HOUSE_OFFSET, NUM_HOUSES, INVALID_HOUSE_ID) /** * Retrieve the grf file associated with a house. * @param house_id House to query. - * @return The associated GRF file (may be \c NULL). + * @return The associated GRF file (may be \c nullptr). */ static const GRFFile *GetHouseSpecGrf(HouseID house_id) { const HouseSpec *hs = HouseSpec::Get(house_id); - return (hs != NULL) ? hs->grf_prop.grffile : NULL; + return (hs != nullptr) ? hs->grf_prop.grffile : nullptr; } /** @@ -64,6 +62,16 @@ HouseResolverObject::HouseResolverObject(HouseID house_id, TileIndex tile, Town this->root_spritegroup = HouseSpec::Get(house_id)->grf_prop.spritegroup[0]; } +GrfSpecFeature HouseResolverObject::GetFeature() const +{ + return GSF_HOUSES; +} + +uint32 HouseResolverObject::GetDebugID() const +{ + return HouseSpec::Get(this->house_scope.house_id)->grf_prop.local_id; +} + HouseClassID AllocateHouseClassID(byte grf_class_id, uint32 grfid) { /* Start from 1 because 0 means that no class has been assigned. */ @@ -85,8 +93,7 @@ void InitializeBuildingCounts() { memset(&_building_counts, 0, sizeof(_building_counts)); - Town *t; - FOR_ALL_TOWNS(t) { + for (Town *t : Town::Iterate()) { memset(&t->cache.building_counts, 0, sizeof(t->cache.building_counts)); } } @@ -190,7 +197,7 @@ static bool SearchNearbyHouseID(TileIndex tile, void *user_data) if (IsTileType(tile, MP_HOUSE)) { HouseID house = GetHouseType(tile); // tile been examined const HouseSpec *hs = HouseSpec::Get(house); - if (hs->grf_prop.grffile != NULL) { // must be one from a grf file + if (hs->grf_prop.grffile != nullptr) { // must be one from a grf file SearchNearbyHouseData *nbhd = (SearchNearbyHouseData *)user_data; TileIndex north_tile = tile + GetHouseNorthPart(house); // modifies 'house'! @@ -214,7 +221,7 @@ static bool SearchNearbyHouseClass(TileIndex tile, void *user_data) if (IsTileType(tile, MP_HOUSE)) { HouseID house = GetHouseType(tile); // tile been examined const HouseSpec *hs = HouseSpec::Get(house); - if (hs->grf_prop.grffile != NULL) { // must be one from a grf file + if (hs->grf_prop.grffile != nullptr) { // must be one from a grf file SearchNearbyHouseData *nbhd = (SearchNearbyHouseData *)user_data; TileIndex north_tile = tile + GetHouseNorthPart(house); // modifies 'house'! @@ -238,7 +245,7 @@ static bool SearchNearbyHouseGRFID(TileIndex tile, void *user_data) if (IsTileType(tile, MP_HOUSE)) { HouseID house = GetHouseType(tile); // tile been examined const HouseSpec *hs = HouseSpec::Get(house); - if (hs->grf_prop.grffile != NULL) { // must be one from a grf file + if (hs->grf_prop.grffile != nullptr) { // must be one from a grf file SearchNearbyHouseData *nbhd = (SearchNearbyHouseData *)user_data; TileIndex north_tile = tile + GetHouseNorthPart(house); // modifies 'house'! @@ -320,7 +327,7 @@ static uint32 GetDistanceFromNearbyHouse(uint8 parameter, TileIndex tile, HouseI /* Building counts for new houses with id = parameter. */ case 0x61: { const HouseSpec *hs = HouseSpec::Get(this->house_id); - if (hs->grf_prop.grffile == NULL) return 0; + if (hs->grf_prop.grffile == nullptr) return 0; HouseID new_house = _house_mngr.GetID(parameter, hs->grf_prop.grffile->grfid); return new_house == INVALID_HOUSE_ID ? 0 : GetNumHouses(new_house, this->town); @@ -350,8 +357,7 @@ static uint32 GetDistanceFromNearbyHouse(uint8 parameter, TileIndex tile, HouseI /* Collect acceptance stats. */ uint32 res = 0; - for (Station * const * st_iter = sl->Begin(); st_iter != sl->End(); st_iter++) { - const Station *st = *st_iter; + for (Station *st : *sl) { if (HasBit(st->goods[cid].status, GoodsEntry::GES_EVER_ACCEPTED)) SetBit(res, 0); if (HasBit(st->goods[cid].status, GoodsEntry::GES_LAST_MONTH)) SetBit(res, 1); if (HasBit(st->goods[cid].status, GoodsEntry::GES_CURRENT_MONTH)) SetBit(res, 2); @@ -463,7 +469,7 @@ void DrawNewHouseTile(TileInfo *ti, HouseID house_id) HouseResolverObject object(house_id, ti->tile, Town::GetByTile(ti->tile)); const SpriteGroup *group = object.Resolve(); - if (group != NULL && group->type == SGT_TILELAYOUT) { + if (group != nullptr && group->type == SGT_TILELAYOUT) { /* Limit the building stage to the number of stages supplied. */ const TileLayoutSpriteGroup *tlgroup = (const TileLayoutSpriteGroup *)group; byte stage = GetHouseBuildingStage(ti->tile); @@ -489,7 +495,7 @@ struct HouseAnimationBase : public AnimationBaseextra_flags, CALLBACK_1A_RANDOM_BITS)); } @@ -582,14 +588,14 @@ static void DoTriggerHouse(TileIndex tile, HouseTrigger trigger, byte base_rando HouseID hid = GetHouseType(tile); HouseSpec *hs = HouseSpec::Get(hid); - if (hs->grf_prop.spritegroup[0] == NULL) return; + if (hs->grf_prop.spritegroup[0] == nullptr) return; HouseResolverObject object(hid, tile, Town::GetByTile(tile), CBID_RANDOM_TRIGGER); object.waiting_triggers = GetHouseTriggers(tile) | trigger; SetHouseTriggers(tile, object.waiting_triggers); // store now for var 5F const SpriteGroup *group = object.Resolve(); - if (group == NULL) return; + if (group == nullptr) return; /* Store remaining triggers. */ SetHouseTriggers(tile, object.GetRemainingTriggers()); diff --git a/src/newgrf_house.h b/src/newgrf_house.h index bb364f6fc6..b4c1f61de3 100644 --- a/src/newgrf_house.h +++ b/src/newgrf_house.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. @@ -44,9 +42,9 @@ struct HouseScopeResolver : public ScopeResolver { { } - /* virtual */ uint32 GetRandomBits() const; - /* virtual */ uint32 GetVariable(byte variable, uint32 parameter, bool *available) const; - /* virtual */ uint32 GetTriggers() const; + uint32 GetRandomBits() const override; + uint32 GetVariable(byte variable, uint32 parameter, bool *available) const override; + uint32 GetTriggers() const override; }; /** Resolver object to be used for houses (feature 07 spritegroups). */ @@ -58,7 +56,7 @@ struct HouseResolverObject : public ResolverObject { CallbackID callback = CBID_NO_CALLBACK, uint32 param1 = 0, uint32 param2 = 0, bool not_yet_constructed = false, uint8 initial_random_bits = 0, CargoTypes watched_cargo_triggers = 0); - /* virtual */ ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) + ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) override { switch (scope) { case VSG_SCOPE_SELF: return &this->house_scope; @@ -66,6 +64,9 @@ struct HouseResolverObject : public ResolverObject { default: return ResolverObject::GetScope(scope, relative); } } + + GrfSpecFeature GetFeature() const override; + uint32 GetDebugID() const override; }; /** diff --git a/src/newgrf_industries.cpp b/src/newgrf_industries.cpp index 980059cabb..a8748a4953 100644 --- a/src/newgrf_industries.cpp +++ b/src/newgrf_industries.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. @@ -79,7 +77,7 @@ uint32 GetIndustryIDAtOffset(TileIndex tile, const Industry *i, uint32 cur_grfid } } /* Not an 'old type' tile */ - if (indtsp->grf_prop.spritegroup[0] != NULL) { // tile has a spritegroup ? + if (indtsp->grf_prop.spritegroup[0] != nullptr) { // tile has a spritegroup ? if (indtsp->grf_prop.grffile->grfid == cur_grfid) { // same industry, same grf ? return indtsp->grf_prop.local_id; } else { @@ -93,8 +91,7 @@ uint32 GetIndustryIDAtOffset(TileIndex tile, const Industry *i, uint32 cur_grfid static uint32 GetClosestIndustry(TileIndex tile, IndustryType type, const Industry *current) { uint32 best_dist = UINT32_MAX; - const Industry *i; - FOR_ALL_INDUSTRIES(i) { + for (const Industry *i : Industry::Iterate()) { if (i->type != type || i == current) continue; best_dist = min(best_dist, DistanceManhattan(tile, i->location.tile)); @@ -147,8 +144,7 @@ static uint32 GetCountAndDistanceOfClosestInstance(byte param_setID, byte layout } else { /* Count only those who match the same industry type and layout filter * Unfortunately, we have to do it manually */ - const Industry *i; - FOR_ALL_INDUSTRIES(i) { + for (const Industry *i : Industry::Iterate()) { if (i->type == ind_index && i != current && (i->selected_layout == layout_filter || layout_filter == 0) && (!town_filter || i->town == current->town)) { closest_dist = min(closest_dist, DistanceManhattan(current->location.tile, i->location.tile)); count++; @@ -202,7 +198,7 @@ static uint32 GetCountAndDistanceOfClosestInstance(byte param_setID, byte layout const IndustrySpec *indspec = GetIndustrySpec(this->type); - if (this->industry == NULL) { + if (this->industry == nullptr) { DEBUG(grf, 1, "Unhandled variable 0x%X (no available industry) in callback 0x%x", variable, this->ro.callback); *available = false; @@ -240,7 +236,7 @@ static uint32 GetCountAndDistanceOfClosestInstance(byte param_setID, byte layout bool is_ai = false; const Company *c = Company::GetIfValid(this->industry->founder); - if (c != NULL) { + if (c != nullptr) { const Livery *l = &c->livery[LS_DEFAULT]; is_ai = c->is_ai; @@ -308,16 +304,22 @@ static uint32 GetCountAndDistanceOfClosestInstance(byte param_setID, byte layout case 0x6A: case 0x6B: case 0x6C: - case 0x6D: { + case 0x6D: + case 0x70: + case 0x71: { CargoID cargo = GetCargoTranslation(parameter, this->ro.grffile); int index = this->industry->GetCargoProducedIndex(cargo); if (index < 0) return 0; // invalid cargo - if (variable == 0x69) return this->industry->produced_cargo_waiting[index]; - if (variable == 0x6A) return this->industry->this_month_production[index]; - if (variable == 0x6B) return this->industry->this_month_transported[index]; - if (variable == 0x6C) return this->industry->last_month_production[index]; - if (variable == 0x6D) return this->industry->last_month_transported[index]; - NOT_REACHED(); + switch (variable) { + case 0x69: return this->industry->produced_cargo_waiting[index]; + case 0x6A: return this->industry->this_month_production[index]; + case 0x6B: return this->industry->this_month_transported[index]; + case 0x6C: return this->industry->last_month_production[index]; + case 0x6D: return this->industry->last_month_transported[index]; + case 0x70: return this->industry->production_rate[index]; + case 0x71: return this->industry->last_month_pct_transported[index]; + default: NOT_REACHED(); + } } @@ -332,7 +334,7 @@ static uint32 GetCountAndDistanceOfClosestInstance(byte param_setID, byte layout } /* Get a variable from the persistent storage */ - case 0x7C: return (this->industry->psa != NULL) ? this->industry->psa->GetValue(parameter) : 0; + case 0x7C: return (this->industry->psa != nullptr) ? this->industry->psa->GetValue(parameter) : 0; /* Industry structure access*/ case 0x80: return this->industry->location.tile; @@ -405,7 +407,7 @@ static uint32 GetCountAndDistanceOfClosestInstance(byte param_setID, byte layout /* virtual */ uint32 IndustriesScopeResolver::GetRandomBits() const { - return this->industry != NULL ? this->industry->random : 0; + return this->industry != nullptr ? this->industry->random : 0; } /* virtual */ uint32 IndustriesScopeResolver::GetTriggers() const @@ -417,13 +419,13 @@ static uint32 GetCountAndDistanceOfClosestInstance(byte param_setID, byte layout { if (this->industry->index == INVALID_INDUSTRY) return; - if (this->industry->psa == NULL) { + if (this->industry->psa == nullptr) { /* There is no need to create a storage if the value is zero. */ if (value == 0) return; /* Create storage on first modification. */ const IndustrySpec *indsp = GetIndustrySpec(this->industry->type); - uint32 grfid = (indsp->grf_prop.grffile != NULL) ? indsp->grf_prop.grffile->grfid : 0; + uint32 grfid = (indsp->grf_prop.grffile != nullptr) ? indsp->grf_prop.grffile->grfid : 0; assert(PersistentStorage::CanAllocateItem()); this->industry->psa = new PersistentStorage(grfid, GSF_INDUSTRIES, this->industry->location.tile); } @@ -439,7 +441,7 @@ static uint32 GetCountAndDistanceOfClosestInstance(byte param_setID, byte layout static const GRFFile *GetGrffile(IndustryType type) { const IndustrySpec *indspec = GetIndustrySpec(type); - return (indspec != NULL) ? indspec->grf_prop.grffile : NULL; + return (indspec != nullptr) ? indspec->grf_prop.grffile : nullptr; } /** @@ -456,7 +458,7 @@ IndustriesResolverObject::IndustriesResolverObject(TileIndex tile, Industry *ind CallbackID callback, uint32 callback_param1, uint32 callback_param2) : ResolverObject(GetGrffile(type), callback, callback_param1, callback_param2), industries_scope(*this, tile, indus, type, random_bits), - town_scope(NULL) + town_scope(nullptr) { this->root_spritegroup = GetIndustrySpec(type)->grf_prop.spritegroup[0]; } @@ -472,21 +474,31 @@ IndustriesResolverObject::~IndustriesResolverObject() */ TownScopeResolver *IndustriesResolverObject::GetTown() { - if (this->town_scope == NULL) { - Town *t = NULL; + if (this->town_scope == nullptr) { + Town *t = nullptr; bool readonly = true; - if (this->industries_scope.industry != NULL) { + if (this->industries_scope.industry != nullptr) { t = this->industries_scope.industry->town; readonly = this->industries_scope.industry->index == INVALID_INDUSTRY; } else if (this->industries_scope.tile != INVALID_TILE) { t = ClosestTownFromTile(this->industries_scope.tile, UINT_MAX); } - if (t == NULL) return NULL; + if (t == nullptr) return nullptr; this->town_scope = new TownScopeResolver(*this, t, readonly); } return this->town_scope; } +GrfSpecFeature IndustriesResolverObject::GetFeature() const +{ + return GSF_INDUSTRIES; +} + +uint32 IndustriesResolverObject::GetDebugID() const +{ + return GetIndustrySpec(this->industries_scope.type)->grf_prop.local_id; +} + /** * Perform an industry callback. * @param callback The callback to perform. @@ -514,7 +526,7 @@ uint16 GetIndustryCallback(CallbackID callback, uint32 param1, uint32 param2, In * @param creation_type The circumstances the industry is created under. * @return Succeeded or failed command. */ -CommandCost CheckIfCallBackAllowsCreation(TileIndex tile, IndustryType type, uint layout, uint32 seed, uint16 initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type) +CommandCost CheckIfCallBackAllowsCreation(TileIndex tile, IndustryType type, size_t layout, uint32 seed, uint16 initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type) { const IndustrySpec *indspec = GetIndustrySpec(type); @@ -523,11 +535,11 @@ CommandCost CheckIfCallBackAllowsCreation(TileIndex tile, IndustryType type, uin ind.location.tile = tile; ind.location.w = 0; // important to mark the industry invalid ind.type = type; - ind.selected_layout = layout; + ind.selected_layout = (byte)layout; ind.town = ClosestTownFromTile(tile, UINT_MAX); ind.random = initial_random_bits; ind.founder = founder; - ind.psa = NULL; + ind.psa = nullptr; IndustriesResolverObject object(tile, &ind, type, seed, CBID_INDUSTRY_LOCATION, 0, creation_type); uint16 result = object.ResolveCallback(); @@ -550,7 +562,7 @@ uint32 GetIndustryProbabilityCallback(IndustryType type, IndustryAvailabilityCal const IndustrySpec *indspec = GetIndustrySpec(type); if (HasBit(indspec->callback_mask, CBM_IND_PROBABILITY)) { - uint16 res = GetIndustryCallback(CBID_INDUSTRY_PROBABILITY, 0, creation_type, NULL, type, INVALID_TILE); + uint16 res = GetIndustryCallback(CBID_INDUSTRY_PROBABILITY, 0, creation_type, nullptr, type, INVALID_TILE); if (res != CALLBACK_FAILED) { if (indspec->grf_prop.grffile->grf_version < 8) { /* Disallow if result != 0 */ @@ -602,7 +614,7 @@ void IndustryProductionCallback(Industry *ind, int reason) SB(object.callback_param2, 8, 16, loop); const SpriteGroup *tgroup = object.Resolve(); - if (tgroup == NULL || tgroup->type != SGT_INDUSTRY_PRODUCTION) break; + if (tgroup == nullptr || tgroup->type != SGT_INDUSTRY_PRODUCTION) break; const IndustryProductionSpriteGroup *group = (const IndustryProductionSpriteGroup *)tgroup; if (group->version == 0xFF) { diff --git a/src/newgrf_industries.h b/src/newgrf_industries.h index fa809fcd73..01a185aa19 100644 --- a/src/newgrf_industries.h +++ b/src/newgrf_industries.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. @@ -34,16 +32,16 @@ struct IndustriesScopeResolver : public ScopeResolver { { } - /* virtual */ uint32 GetRandomBits() const; - /* virtual */ uint32 GetVariable(byte variable, uint32 parameter, bool *available) const; - /* virtual */ uint32 GetTriggers() const; - /* virtual */ void StorePSA(uint pos, int32 value); + uint32 GetRandomBits() const override; + uint32 GetVariable(byte variable, uint32 parameter, bool *available) const override; + uint32 GetTriggers() const override; + void StorePSA(uint pos, int32 value) override; }; /** Resolver for industries. */ struct IndustriesResolverObject : public ResolverObject { IndustriesScopeResolver industries_scope; ///< Scope resolver for the industry. - TownScopeResolver *town_scope; ///< Scope resolver for the associated town (if needed and available, else \c NULL). + TownScopeResolver *town_scope; ///< Scope resolver for the associated town (if needed and available, else \c nullptr). IndustriesResolverObject(TileIndex tile, Industry *indus, IndustryType type, uint32 random_bits = 0, CallbackID callback = CBID_NO_CALLBACK, uint32 callback_param1 = 0, uint32 callback_param2 = 0); @@ -51,13 +49,13 @@ struct IndustriesResolverObject : public ResolverObject { TownScopeResolver *GetTown(); - /* virtual */ ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) + ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) override { switch (scope) { case VSG_SCOPE_SELF: return &industries_scope; case VSG_SCOPE_PARENT: { TownScopeResolver *tsr = this->GetTown(); - if (tsr != NULL) return tsr; + if (tsr != nullptr) return tsr; } FALLTHROUGH; @@ -65,6 +63,9 @@ struct IndustriesResolverObject : public ResolverObject { return ResolverObject::GetScope(scope, relative); } } + + GrfSpecFeature GetFeature() const override; + uint32 GetDebugID() const override; }; /** When should the industry(tile) be triggered for random bits? */ @@ -89,7 +90,7 @@ enum IndustryAvailabilityCallType { uint16 GetIndustryCallback(CallbackID callback, uint32 param1, uint32 param2, Industry *industry, IndustryType type, TileIndex tile); uint32 GetIndustryIDAtOffset(TileIndex new_tile, const Industry *i, uint32 cur_grfid); void IndustryProductionCallback(Industry *ind, int reason); -CommandCost CheckIfCallBackAllowsCreation(TileIndex tile, IndustryType type, uint layout, uint32 seed, uint16 initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type); +CommandCost CheckIfCallBackAllowsCreation(TileIndex tile, IndustryType type, size_t layout, uint32 seed, uint16 initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type); uint32 GetIndustryProbabilityCallback(IndustryType type, IndustryAvailabilityCallType creation_type, uint32 default_prob); bool IndustryTemporarilyRefusesCargo(Industry *ind, CargoID cargo_type); diff --git a/src/newgrf_industrytiles.cpp b/src/newgrf_industrytiles.cpp index 0b2a55000e..e9c99f6cd5 100644 --- a/src/newgrf_industrytiles.cpp +++ b/src/newgrf_industrytiles.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. @@ -80,7 +78,7 @@ uint32 GetRelativePosition(TileIndex tile, TileIndex ind_tile) /* Land info of nearby tiles */ case 0x60: return GetNearbyIndustryTileInformation(parameter, this->tile, - this->industry == NULL ? (IndustryID)INVALID_INDUSTRY : this->industry->index, true, this->ro.grffile->grf_version >= 8); + this->industry == nullptr ? (IndustryID)INVALID_INDUSTRY : this->industry->index, true, this->ro.grffile->grf_version >= 8); /* Animation stage of nearby tiles */ case 0x61: { @@ -103,7 +101,7 @@ uint32 GetRelativePosition(TileIndex tile, TileIndex ind_tile) /* virtual */ uint32 IndustryTileScopeResolver::GetRandomBits() const { - assert(this->industry != NULL && IsValidTile(this->tile)); + assert(this->industry != nullptr && IsValidTile(this->tile)); assert(this->industry->index == INVALID_INDUSTRY || IsTileType(this->tile, MP_INDUSTRY)); return (this->industry->index != INVALID_INDUSTRY) ? GetIndustryRandomBits(this->tile) : 0; @@ -111,7 +109,7 @@ uint32 GetRelativePosition(TileIndex tile, TileIndex ind_tile) /* virtual */ uint32 IndustryTileScopeResolver::GetTriggers() const { - assert(this->industry != NULL && IsValidTile(this->tile)); + assert(this->industry != nullptr && IsValidTile(this->tile)); assert(this->industry->index == INVALID_INDUSTRY || IsTileType(this->tile, MP_INDUSTRY)); if (this->industry->index == INVALID_INDUSTRY) return 0; return GetIndustryTriggers(this->tile); @@ -125,7 +123,7 @@ uint32 GetRelativePosition(TileIndex tile, TileIndex ind_tile) static const GRFFile *GetIndTileGrffile(IndustryGfx gfx) { const IndustryTileSpec *its = GetIndustryTileSpec(gfx); - return (its != NULL) ? its->grf_prop.grffile : NULL; + return (its != nullptr) ? its->grf_prop.grffile : nullptr; } /** @@ -141,11 +139,22 @@ IndustryTileResolverObject::IndustryTileResolverObject(IndustryGfx gfx, TileInde CallbackID callback, uint32 callback_param1, uint32 callback_param2) : ResolverObject(GetIndTileGrffile(gfx), callback, callback_param1, callback_param2), indtile_scope(*this, indus, tile), - ind_scope(*this, tile, indus, indus->type) + ind_scope(*this, tile, indus, indus->type), + gfx(gfx) { this->root_spritegroup = GetIndustryTileSpec(gfx)->grf_prop.spritegroup[0]; } +GrfSpecFeature IndustryTileResolverObject::GetFeature() const +{ + return GSF_INDUSTRYTILES; +} + +uint32 IndustryTileResolverObject::GetDebugID() const +{ + return GetIndustryTileSpec(gfx)->grf_prop.local_id; +} + static void IndustryDrawTileLayout(const TileInfo *ti, const TileLayoutSpriteGroup *group, byte rnd_colour, byte stage, IndustryGfx gfx) { const DrawTileSprites *dts = group->ProcessRegisters(&stage); @@ -171,7 +180,7 @@ static void IndustryDrawTileLayout(const TileInfo *ti, const TileLayoutSpriteGro uint16 GetIndustryTileCallback(CallbackID callback, uint32 param1, uint32 param2, IndustryGfx gfx_id, Industry *industry, TileIndex tile) { - assert(industry != NULL && IsValidTile(tile)); + assert(industry != nullptr && IsValidTile(tile)); assert(industry->index == INVALID_INDUSTRY || IsTileType(tile, MP_INDUSTRY)); IndustryTileResolverObject object(gfx_id, tile, industry, callback, param1, param2); @@ -194,7 +203,7 @@ bool DrawNewIndustryTile(TileInfo *ti, Industry *i, IndustryGfx gfx, const Indus IndustryTileResolverObject object(gfx, ti->tile, i); const SpriteGroup *group = object.Resolve(); - if (group == NULL || group->type != SGT_TILELAYOUT) return false; + if (group == nullptr || group->type != SGT_TILELAYOUT) return false; /* Limit the building stage to the number of stages supplied. */ const TileLayoutSpriteGroup *tlgroup = (const TileLayoutSpriteGroup *)group; @@ -212,13 +221,13 @@ extern bool IsSlopeRefused(Slope current, Slope refused); * @param its Tile specification. * @param type Industry type. * @param gfx Gfx of the tile. - * @param itspec_index Layout. + * @param layout_index Layout. * @param initial_random_bits Random bits of industry after construction * @param founder Industry founder * @param creation_type The circumstances the industry is created under. * @return Succeeded or failed command. */ -CommandCost PerformIndustryTileSlopeCheck(TileIndex ind_base_tile, TileIndex ind_tile, const IndustryTileSpec *its, IndustryType type, IndustryGfx gfx, uint itspec_index, uint16 initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type) +CommandCost PerformIndustryTileSlopeCheck(TileIndex ind_base_tile, TileIndex ind_tile, const IndustryTileSpec *its, IndustryType type, IndustryGfx gfx, size_t layout_index, uint16 initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type) { Industry ind; ind.index = INVALID_INDUSTRY; @@ -228,7 +237,7 @@ CommandCost PerformIndustryTileSlopeCheck(TileIndex ind_base_tile, TileIndex ind ind.random = initial_random_bits; ind.founder = founder; - uint16 callback_res = GetIndustryTileCallback(CBID_INDTILE_SHAPE_CHECK, 0, creation_type << 8 | itspec_index, gfx, &ind, ind_tile); + uint16 callback_res = GetIndustryTileCallback(CBID_INDTILE_SHAPE_CHECK, 0, creation_type << 8 | (uint32)layout_index, gfx, &ind, ind_tile); if (callback_res == CALLBACK_FAILED) { if (!IsSlopeRefused(GetTileSlope(ind_tile), its->slopes_refused)) return CommandCost(); return_cmd_error(STR_ERROR_SITE_UNSUITABLE); @@ -259,7 +268,7 @@ struct IndustryAnimationBase : public AnimationBasespecial_flags & INDTILE_SPECIAL_NEXTFRAME_RANDOMBITS) != 0); } @@ -305,14 +314,14 @@ static void DoTriggerIndustryTile(TileIndex tile, IndustryTileTrigger trigger, I IndustryGfx gfx = GetIndustryGfx(tile); const IndustryTileSpec *itspec = GetIndustryTileSpec(gfx); - if (itspec->grf_prop.spritegroup[0] == NULL) return; + if (itspec->grf_prop.spritegroup[0] == nullptr) return; IndustryTileResolverObject object(gfx, tile, ind, CBID_RANDOM_TRIGGER); object.waiting_triggers = GetIndustryTriggers(tile) | trigger; SetIndustryTriggers(tile, object.waiting_triggers); // store now for var 5F const SpriteGroup *group = object.Resolve(); - if (group == NULL) return; + if (group == nullptr) return; /* Store remaining triggers. */ SetIndustryTriggers(tile, object.GetRemainingTriggers()); @@ -335,7 +344,7 @@ static void DoTriggerIndustryTile(TileIndex tile, IndustryTileTrigger trigger, I */ static void DoReseedIndustry(Industry *ind, uint32 reseed) { - if (reseed == 0 || ind == NULL) return; + if (reseed == 0 || ind == nullptr) return; uint16 random_bits = Random(); ind->random &= reseed; diff --git a/src/newgrf_industrytiles.h b/src/newgrf_industrytiles.h index 6051c1062b..e5494ea302 100644 --- a/src/newgrf_industrytiles.h +++ b/src/newgrf_industrytiles.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. @@ -32,20 +30,21 @@ struct IndustryTileScopeResolver : public ScopeResolver { { } - /* virtual */ uint32 GetRandomBits() const; - /* virtual */ uint32 GetVariable(byte variable, uint32 parameter, bool *available) const; - /* virtual */ uint32 GetTriggers() const; + uint32 GetRandomBits() const override; + uint32 GetVariable(byte variable, uint32 parameter, bool *available) const override; + uint32 GetTriggers() const override; }; /** Resolver for industry tiles. */ struct IndustryTileResolverObject : public ResolverObject { IndustryTileScopeResolver indtile_scope; ///< Scope resolver for the industry tile. IndustriesScopeResolver ind_scope; ///< Scope resolver for the industry owning the tile. + IndustryGfx gfx; IndustryTileResolverObject(IndustryGfx gfx, TileIndex tile, Industry *indus, CallbackID callback = CBID_NO_CALLBACK, uint32 callback_param1 = 0, uint32 callback_param2 = 0); - /* virtual */ ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) + ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) override { switch (scope) { case VSG_SCOPE_SELF: return &indtile_scope; @@ -53,11 +52,14 @@ struct IndustryTileResolverObject : public ResolverObject { default: return ResolverObject::GetScope(scope, relative); } } + + GrfSpecFeature GetFeature() const override; + uint32 GetDebugID() const override; }; bool DrawNewIndustryTile(TileInfo *ti, Industry *i, IndustryGfx gfx, const IndustryTileSpec *inds); uint16 GetIndustryTileCallback(CallbackID callback, uint32 param1, uint32 param2, IndustryGfx gfx_id, Industry *industry, TileIndex tile); -CommandCost PerformIndustryTileSlopeCheck(TileIndex ind_base_tile, TileIndex ind_tile, const IndustryTileSpec *its, IndustryType type, IndustryGfx gfx, uint itspec_index, uint16 initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type); +CommandCost PerformIndustryTileSlopeCheck(TileIndex ind_base_tile, TileIndex ind_tile, const IndustryTileSpec *its, IndustryType type, IndustryGfx gfx, size_t layout_index, uint16 initial_random_bits, Owner founder, IndustryAvailabilityCallType creation_type); void AnimateNewIndustryTile(TileIndex tile); bool StartStopIndustryTileAnimation(TileIndex tile, IndustryAnimationTrigger iat, uint32 random = Random()); diff --git a/src/newgrf_object.cpp b/src/newgrf_object.cpp index 1501cb9b8a..8827245d36 100644 --- a/src/newgrf_object.cpp +++ b/src/newgrf_object.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. @@ -151,7 +149,7 @@ static uint32 GetObjectIDAtOffset(TileIndex tile, uint32 cur_grfid) const ObjectSpec *spec = ObjectSpec::Get(o->type); /* Default objects have no associated NewGRF file */ - if (spec->grf_prop.grffile == NULL) { + if (spec->grf_prop.grffile == nullptr) { return 0xFFFE; // Defined in another grf file } @@ -188,8 +186,7 @@ static uint32 GetNearbyObjectTileInformation(byte parameter, TileIndex tile, Obj static uint32 GetClosestObject(TileIndex tile, ObjectType type, const Object *current) { uint32 best_dist = UINT32_MAX; - const Object *o; - FOR_ALL_OBJECTS(o) { + for (const Object *o : Object::Iterate()) { if (o->type != type || o == current) continue; best_dist = min(best_dist, DistanceManhattan(tile, o->location.tile)); @@ -237,9 +234,9 @@ static uint32 GetCountAndDistanceOfClosestInstance(byte local_id, uint32 grfid, { /* We get the town from the object, or we calculate the closest * town if we need to when there's no object. */ - const Town *t = NULL; + const Town *t = nullptr; - if (this->obj == NULL) { + if (this->obj == nullptr) { switch (variable) { /* Allow these when there's no object. */ case 0x41: @@ -325,7 +322,7 @@ static uint32 GetCountAndDistanceOfClosestInstance(byte local_id, uint32 grfid, } /* Land info of nearby tiles */ - case 0x62: return GetNearbyObjectTileInformation(parameter, this->tile, this->obj == NULL ? INVALID_OBJECT : this->obj->index, this->ro.grffile->grf_version >= 8); + case 0x62: return GetNearbyObjectTileInformation(parameter, this->tile, this->obj == nullptr ? INVALID_OBJECT : this->obj->index, this->ro.grffile->grf_version >= 8); /* Animation counter of nearby tile */ case 0x63: { @@ -355,10 +352,10 @@ unhandled: */ ObjectResolverObject::ObjectResolverObject(const ObjectSpec *spec, Object *obj, TileIndex tile, uint8 view, CallbackID callback, uint32 param1, uint32 param2) - : ResolverObject(spec->grf_prop.grffile, callback, param1, param2), object_scope(*this, obj, tile, view) + : ResolverObject(spec->grf_prop.grffile, callback, param1, param2), object_scope(*this, obj, spec, tile, view) { - this->town_scope = NULL; - this->root_spritegroup = (obj == NULL && spec->grf_prop.spritegroup[CT_PURCHASE_OBJECT] != NULL) ? + this->town_scope = nullptr; + this->root_spritegroup = (obj == nullptr && spec->grf_prop.spritegroup[CT_PURCHASE_OBJECT] != nullptr) ? spec->grf_prop.spritegroup[CT_PURCHASE_OBJECT] : spec->grf_prop.spritegroup[0]; } @@ -374,19 +371,29 @@ ObjectResolverObject::~ObjectResolverObject() */ TownScopeResolver *ObjectResolverObject::GetTown() { - if (this->town_scope == NULL) { + if (this->town_scope == nullptr) { Town *t; - if (this->object_scope.obj != NULL) { + if (this->object_scope.obj != nullptr) { t = this->object_scope.obj->town; } else { t = ClosestTownFromTile(this->object_scope.tile, UINT_MAX); } - if (t == NULL) return NULL; - this->town_scope = new TownScopeResolver(*this, t, this->object_scope.obj == NULL); + if (t == nullptr) return nullptr; + this->town_scope = new TownScopeResolver(*this, t, this->object_scope.obj == nullptr); } return this->town_scope; } +GrfSpecFeature ObjectResolverObject::GetFeature() const +{ + return GSF_OBJECTS; +} + +uint32 ObjectResolverObject::GetDebugID() const +{ + return this->object_scope.spec->grf_prop.local_id; +} + /** * Perform a callback for an object. * @param callback The callback to perform. @@ -395,7 +402,7 @@ TownScopeResolver *ObjectResolverObject::GetTown() * @param spec The specification of the object / the entry point. * @param o The object to call the callback for. * @param tile The tile the callback is called for. - * @param view The view of the object (only used when o == NULL). + * @param view The view of the object (only used when o == nullptr). * @return The result of the callback. */ uint16 GetObjectCallback(CallbackID callback, uint32 param1, uint32 param2, const ObjectSpec *spec, Object *o, TileIndex tile, uint8 view) @@ -412,7 +419,7 @@ uint16 GetObjectCallback(CallbackID callback, uint32 param1, uint32 param2, cons */ static void DrawTileLayout(const TileInfo *ti, const TileLayoutSpriteGroup *group, const ObjectSpec *spec) { - const DrawTileSprites *dts = group->ProcessRegisters(NULL); + const DrawTileSprites *dts = group->ProcessRegisters(nullptr); PaletteID palette = ((spec->flags & OBJECT_FLAG_2CC_COLOUR) ? SPR_2CCMAP_BASE : PALETTE_RECOLOUR_START) + Object::GetByTile(ti->tile)->colour; SpriteID image = dts->ground.sprite; @@ -442,7 +449,7 @@ void DrawNewObjectTile(TileInfo *ti, const ObjectSpec *spec) ObjectResolverObject object(spec, o, ti->tile); const SpriteGroup *group = object.Resolve(); - if (group == NULL || group->type != SGT_TILELAYOUT) return; + if (group == nullptr || group->type != SGT_TILELAYOUT) return; DrawTileLayout(ti, (const TileLayoutSpriteGroup *)group, spec); } @@ -456,11 +463,11 @@ void DrawNewObjectTile(TileInfo *ti, const ObjectSpec *spec) */ void DrawNewObjectTileInGUI(int x, int y, const ObjectSpec *spec, uint8 view) { - ObjectResolverObject object(spec, NULL, INVALID_TILE, view); + ObjectResolverObject object(spec, nullptr, INVALID_TILE, view); const SpriteGroup *group = object.Resolve(); - if (group == NULL || group->type != SGT_TILELAYOUT) return; + if (group == nullptr || group->type != SGT_TILELAYOUT) return; - const DrawTileSprites *dts = ((const TileLayoutSpriteGroup *)group)->ProcessRegisters(NULL); + const DrawTileSprites *dts = ((const TileLayoutSpriteGroup *)group)->ProcessRegisters(nullptr); PaletteID palette; if (Company::IsValidID(_local_company)) { @@ -518,7 +525,7 @@ struct ObjectAnimationBase : public AnimationBaseflags & OBJECT_FLAG_ANIMATION)) return; + if (spec == nullptr || !(spec->flags & OBJECT_FLAG_ANIMATION)) return; ObjectAnimationBase::AnimateTile(spec, Object::GetByTile(tile), tile, (spec->flags & OBJECT_FLAG_ANIM_RANDOM_BITS) != 0); } diff --git a/src/newgrf_object.h b/src/newgrf_object.h index 43c8de031c..1776b760ab 100644 --- a/src/newgrf_object.h +++ b/src/newgrf_object.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. @@ -100,9 +98,10 @@ struct ObjectSpec { /** Object scope resolver. */ struct ObjectScopeResolver : public ScopeResolver { - struct Object *obj; ///< The object the callback is ran for. - TileIndex tile; ///< The tile related to the object. - uint8 view; ///< The view of the object. + struct Object *obj; ///< The object the callback is ran for. + const ObjectSpec *spec; ///< Specification of the object type. + TileIndex tile; ///< The tile related to the object. + uint8 view; ///< The view of the object. /** * Constructor of an object scope resolver. @@ -111,13 +110,13 @@ struct ObjectScopeResolver : public ScopeResolver { * @param tile %Tile of the object. * @param view View of the object. */ - ObjectScopeResolver(ResolverObject &ro, Object *obj, TileIndex tile, uint8 view = 0) - : ScopeResolver(ro), obj(obj), tile(tile), view(view) + ObjectScopeResolver(ResolverObject &ro, Object *obj, const ObjectSpec *spec, TileIndex tile, uint8 view = 0) + : ScopeResolver(ro), obj(obj), spec(spec), tile(tile), view(view) { } - /* virtual */ uint32 GetRandomBits() const; - /* virtual */ uint32 GetVariable(byte variable, uint32 parameter, bool *available) const; + uint32 GetRandomBits() const override; + uint32 GetVariable(byte variable, uint32 parameter, bool *available) const override; }; /** A resolver object to be used with feature 0F spritegroups. */ @@ -129,7 +128,7 @@ struct ObjectResolverObject : public ResolverObject { CallbackID callback = CBID_NO_CALLBACK, uint32 param1 = 0, uint32 param2 = 0); ~ObjectResolverObject(); - /* virtual */ ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) + ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) override { switch (scope) { case VSG_SCOPE_SELF: @@ -137,7 +136,7 @@ struct ObjectResolverObject : public ResolverObject { case VSG_SCOPE_PARENT: { TownScopeResolver *tsr = this->GetTown(); - if (tsr != NULL) return tsr; + if (tsr != nullptr) return tsr; FALLTHROUGH; } @@ -146,6 +145,9 @@ struct ObjectResolverObject : public ResolverObject { } } + GrfSpecFeature GetFeature() const override; + uint32 GetDebugID() const override; + private: TownScopeResolver *GetTown(); }; diff --git a/src/newgrf_profiling.cpp b/src/newgrf_profiling.cpp new file mode 100644 index 0000000000..e9a0dd92d2 --- /dev/null +++ b/src/newgrf_profiling.cpp @@ -0,0 +1,162 @@ +/* + * 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_profiling.cpp Profiling of NewGRF action 2 handling. */ + +#include "newgrf_profiling.h" +#include "date_func.h" +#include "fileio_func.h" +#include "string_func.h" +#include "console_func.h" +#include "spritecache.h" + +#include +#include + + +std::vector _newgrf_profilers; +Date _newgrf_profile_end_date; + + +/** + * Create profiler object and begin profiling session. + * @param grffile The GRF file to collect profiling data on + * @param end_date Game date to end profiling on + */ +NewGRFProfiler::NewGRFProfiler(const GRFFile *grffile) : grffile{ grffile }, active{ false }, cur_call{} +{ +} + +/** + * Complete profiling session and write data to file + */ +NewGRFProfiler::~NewGRFProfiler() +{ +} + +/** + * Capture the start of a sprite group resolution. + * @param resolver Data about sprite group being resolved + */ +void NewGRFProfiler::BeginResolve(const ResolverObject &resolver) +{ + using namespace std::chrono; + this->cur_call.root_sprite = resolver.root_spritegroup->nfo_line; + this->cur_call.subs = 0; + this->cur_call.time = (uint32)time_point_cast(high_resolution_clock::now()).time_since_epoch().count(); + this->cur_call.tick = _tick_counter; + this->cur_call.cb = resolver.callback; + this->cur_call.feat = resolver.GetFeature(); + this->cur_call.item = resolver.GetDebugID(); +} + +/** + * Capture the completion of a sprite group resolution. + */ +void NewGRFProfiler::EndResolve(const SpriteGroup *result) +{ + using namespace std::chrono; + this->cur_call.time = (uint32)time_point_cast(high_resolution_clock::now()).time_since_epoch().count() - this->cur_call.time; + + if (result == nullptr) { + this->cur_call.result = 0; + } else if (result->type == SGT_CALLBACK) { + this->cur_call.result = static_cast(result)->result; + } else if (result->type == SGT_RESULT) { + this->cur_call.result = GetSpriteLocalID(static_cast(result)->sprite); + } else { + this->cur_call.result = result->nfo_line; + } + + this->calls.push_back(this->cur_call); +} + +/** + * Capture a recursive sprite group resolution. + */ +void NewGRFProfiler::RecursiveResolve() +{ + this->cur_call.subs += 1; +} + +void NewGRFProfiler::Start() +{ + this->Abort(); + this->active = true; + this->start_tick = _tick_counter; +} + +uint32 NewGRFProfiler::Finish() +{ + if (!this->active) return 0; + + if (this->calls.empty()) { + IConsolePrintF(CC_DEBUG, "Finished profile of NewGRF [%08X], no events collected, not writing a file", BSWAP32(this->grffile->grfid)); + return 0; + } + + std::string filename = this->GetOutputFilename(); + IConsolePrintF(CC_DEBUG, "Finished profile of NewGRF [%08X], writing %u events to %s", BSWAP32(this->grffile->grfid), (uint)this->calls.size(), filename.c_str()); + + FILE *f = FioFOpenFile(filename.c_str(), "wt", Subdirectory::NO_DIRECTORY); + FileCloser fcloser(f); + + uint32 total_microseconds = 0; + + fputs("Tick,Sprite,Feature,Item,CallbackID,Microseconds,Depth,Result\n", f); + for (const Call &c : this->calls) { + fprintf(f, "%u,%u,0x%X,%d,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; + } + + this->Abort(); + + return total_microseconds; +} + +void NewGRFProfiler::Abort() +{ + this->active = false; + this->calls.clear(); +} + +/** + * Get name of the file that will be written. + * @return File name of profiling output file. + */ +std::string NewGRFProfiler::GetOutputFilename() const +{ + time_t write_time = time(nullptr); + + char timestamp[16] = {}; + strftime(timestamp, lengthof(timestamp), "%Y%m%d-%H%M", localtime(&write_time)); + + char filepath[MAX_PATH] = {}; + seprintf(filepath, lastof(filepath), "%sgrfprofile-%s-%08X.csv", FiosGetScreenshotDir(), timestamp, BSWAP32(this->grffile->grfid)); + + return std::string(filepath); +} + +uint32 NewGRFProfiler::FinishAll() +{ + int max_ticks = 0; + uint32 total_microseconds = 0; + for (NewGRFProfiler &pr : _newgrf_profilers) { + if (pr.active) { + total_microseconds += pr.Finish(); + max_ticks = max(max_ticks, _tick_counter - pr.start_tick); + } + } + + if (total_microseconds > 0 && max_ticks > 0) { + IConsolePrintF(CC_DEBUG, "Total NewGRF callback processing: %u microseconds over %d ticks", total_microseconds, max_ticks); + } + + _newgrf_profile_end_date = MAX_DAY; + + return total_microseconds; +} diff --git a/src/newgrf_profiling.h b/src/newgrf_profiling.h new file mode 100644 index 0000000000..e5b2813f59 --- /dev/null +++ b/src/newgrf_profiling.h @@ -0,0 +1,63 @@ +/* + * 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_profiling.h Profiling of NewGRF action 2 handling. */ + +#ifndef NEWGRF_PROFILING_H +#define NEWGRF_PROFILING_H + +#include "stdafx.h" +#include "date_type.h" +#include "newgrf.h" +#include "newgrf_callbacks.h" +#include "newgrf_spritegroup.h" + +#include +#include +#include + +/** + * Callback profiler for NewGRF development + */ +struct NewGRFProfiler { + NewGRFProfiler(const GRFFile *grffile); + ~NewGRFProfiler(); + + void BeginResolve(const ResolverObject &resolver); + void EndResolve(const SpriteGroup *result); + void RecursiveResolve(); + + void Start(); + uint32 Finish(); + void Abort(); + std::string GetOutputFilename() const; + + static uint32 FinishAll(); + + /** Measurement of a single sprite group resolution */ + struct Call { + uint32 root_sprite; ///< Pseudo-sprite index in GRF file + uint32 item; ///< Local ID of item being resolved for + uint32 result; ///< Result of callback + uint32 subs; ///< Sub-calls to other sprite groups + uint32 time; ///< Time taken for resolution (microseconds) + uint16 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 + uint16 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 +}; + +extern std::vector _newgrf_profilers; +extern Date _newgrf_profile_end_date; + +#endif /* NEWGRF_PROFILING_H */ diff --git a/src/newgrf_properties.h b/src/newgrf_properties.h index e1240f29ee..835a873847 100644 --- a/src/newgrf_properties.h +++ b/src/newgrf_properties.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/newgrf_railtype.cpp b/src/newgrf_railtype.cpp index 8421844717..2a98948e7b 100644 --- a/src/newgrf_railtype.cpp +++ b/src/newgrf_railtype.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. @@ -44,13 +42,13 @@ if (IsRailDepotTile(this->tile)) return Depot::GetByTile(this->tile)->build_date; return _date; case 0x44: { - const Town *t = NULL; + const Town *t = nullptr; if (IsRailDepotTile(this->tile)) { t = Depot::GetByTile(this->tile)->town; } else if (IsLevelCrossingTile(this->tile)) { t = ClosestTownFromTile(this->tile, UINT_MAX); } - return t != NULL ? GetTownRadiusGroup(t, this->tile) : HZB_TOWN_EDGE; + return t != nullptr ? GetTownRadiusGroup(t, this->tile) : HZB_TOWN_EDGE; } } @@ -64,12 +62,22 @@ { if (group->num_loading > 0) return group->loading[0]; if (group->num_loaded > 0) return group->loaded[0]; - return NULL; + return nullptr; +} + +GrfSpecFeature RailTypeResolverObject::GetFeature() const +{ + return GSF_RAILTYPES; +} + +uint32 RailTypeResolverObject::GetDebugID() const +{ + return this->railtype_scope.rti->label; } /** * Resolver object for rail types. - * @param rti Railtype. NULL in NewGRF Inspect window. + * @param rti Railtype. nullptr in NewGRF Inspect window. * @param tile %Tile containing the track. For track on a bridge this is the southern bridgehead. * @param context Are we resolving sprites for the upper halftile, or on a bridge? * @param rtsg Railpart of interest @@ -77,9 +85,9 @@ * @param param2 Extra parameter (second parameter of the callback, except railtypes do not have callbacks). */ RailTypeResolverObject::RailTypeResolverObject(const RailtypeInfo *rti, TileIndex tile, TileContext context, RailTypeSpriteGroup rtsg, uint32 param1, uint32 param2) - : ResolverObject(rti != NULL ? rti->grffile[rtsg] : NULL, CBID_NO_CALLBACK, param1, param2), railtype_scope(*this, tile, context) + : ResolverObject(rti != nullptr ? rti->grffile[rtsg] : nullptr, CBID_NO_CALLBACK, param1, param2), railtype_scope(*this, rti, tile, context) { - this->root_spritegroup = rti != NULL ? rti->group[rtsg] : NULL; + this->root_spritegroup = rti != nullptr ? rti->group[rtsg] : nullptr; } /** @@ -88,18 +96,18 @@ RailTypeResolverObject::RailTypeResolverObject(const RailtypeInfo *rti, TileInde * @param tile The tile to get the sprite for. * @param rtsg The type of sprite to draw. * @param context Where are we drawing the tile? - * @param[out] num_results If not NULL, return the number of sprites in the spriteset. + * @param[out] num_results If not nullptr, return the number of sprites in the spriteset. * @return The sprite to draw. */ SpriteID GetCustomRailSprite(const RailtypeInfo *rti, TileIndex tile, RailTypeSpriteGroup rtsg, TileContext context, uint *num_results) { assert(rtsg < RTSG_END); - if (rti->group[rtsg] == NULL) return 0; + if (rti->group[rtsg] == nullptr) return 0; RailTypeResolverObject object(rti, tile, context, rtsg); const SpriteGroup *group = object.Resolve(); - if (group == NULL || group->GetNumResults() == 0) return 0; + if (group == nullptr || group->GetNumResults() == 0) return 0; if (num_results) *num_results = group->GetNumResults(); @@ -118,14 +126,14 @@ SpriteID GetCustomRailSprite(const RailtypeInfo *rti, TileIndex tile, RailTypeSp */ SpriteID GetCustomSignalSprite(const RailtypeInfo *rti, TileIndex tile, SignalType type, SignalVariant var, SignalState state, bool gui) { - if (rti->group[RTSG_SIGNALS] == NULL) return 0; + if (rti->group[RTSG_SIGNALS] == nullptr) return 0; uint32 param1 = gui ? 0x10 : 0x00; uint32 param2 = (type << 16) | (var << 8) | state; RailTypeResolverObject object(rti, tile, TCX_NORMAL, RTSG_SIGNALS, param1, param2); const SpriteGroup *group = object.Resolve(); - if (group == NULL || group->GetNumResults() == 0) return 0; + if (group == nullptr || group->GetNumResults() == 0) return 0; return group->GetResult(); } @@ -139,12 +147,13 @@ SpriteID GetCustomSignalSprite(const RailtypeInfo *rti, TileIndex tile, SignalTy uint8 GetReverseRailTypeTranslation(RailType railtype, const GRFFile *grffile) { /* No rail type table present, return rail type as-is */ - if (grffile == NULL || grffile->railtype_list.Length() == 0) return railtype; + if (grffile == nullptr || grffile->railtype_list.size() == 0) return railtype; /* Look for a matching rail type label in the table */ RailTypeLabel label = GetRailTypeInfo(railtype)->label; - int index = grffile->railtype_list.FindIndex(label); - if (index >= 0) return index; + + int idx = find_index(grffile->railtype_list, label); + if (idx >= 0) return idx; /* If not found, return as invalid */ return 0xFF; diff --git a/src/newgrf_railtype.h b/src/newgrf_railtype.h index 5fadcd2ab5..1e0ff01d82 100644 --- a/src/newgrf_railtype.h +++ b/src/newgrf_railtype.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. @@ -20,6 +18,7 @@ struct RailTypeScopeResolver : public ScopeResolver { TileIndex tile; ///< Tracktile. For track on a bridge this is the southern bridgehead. TileContext context; ///< Are we resolving sprites for the upper halftile, or on a bridge? + const RailtypeInfo *rti; /** * Constructor of the railtype scope resolvers. @@ -27,13 +26,13 @@ struct RailTypeScopeResolver : public ScopeResolver { * @param tile %Tile containing the track. For track on a bridge this is the southern bridgehead. * @param context Are we resolving sprites for the upper halftile, or on a bridge? */ - RailTypeScopeResolver(ResolverObject &ro, TileIndex tile, TileContext context) - : ScopeResolver(ro), tile(tile), context(context) + RailTypeScopeResolver(ResolverObject &ro, const RailtypeInfo *rti, TileIndex tile, TileContext context) + : ScopeResolver(ro), tile(tile), context(context), rti(rti) { } - /* virtual */ uint32 GetRandomBits() const; - /* virtual */ uint32 GetVariable(byte variable, uint32 parameter, bool *available) const; + uint32 GetRandomBits() const override; + uint32 GetVariable(byte variable, uint32 parameter, bool *available) const override; }; /** Resolver object for rail types. */ @@ -42,7 +41,7 @@ struct RailTypeResolverObject : public ResolverObject { RailTypeResolverObject(const RailtypeInfo *rti, TileIndex tile, TileContext context, RailTypeSpriteGroup rtsg, uint32 param1 = 0, uint32 param2 = 0); - /* virtual */ ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) + ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) override { switch (scope) { case VSG_SCOPE_SELF: return &this->railtype_scope; @@ -50,10 +49,13 @@ struct RailTypeResolverObject : public ResolverObject { } } - /* virtual */ const SpriteGroup *ResolveReal(const RealSpriteGroup *group) const; + const SpriteGroup *ResolveReal(const RealSpriteGroup *group) const override; + + GrfSpecFeature GetFeature() const override; + uint32 GetDebugID() const override; }; -SpriteID GetCustomRailSprite(const RailtypeInfo *rti, TileIndex tile, RailTypeSpriteGroup rtsg, TileContext context = TCX_NORMAL, uint *num_results = NULL); +SpriteID GetCustomRailSprite(const RailtypeInfo *rti, TileIndex tile, RailTypeSpriteGroup rtsg, TileContext context = TCX_NORMAL, uint *num_results = nullptr); SpriteID GetCustomSignalSprite(const RailtypeInfo *rti, TileIndex tile, SignalType type, SignalVariant var, SignalState state, bool gui = false); uint8 GetReverseRailTypeTranslation(RailType railtype, const GRFFile *grffile); diff --git a/src/newgrf_roadtype.cpp b/src/newgrf_roadtype.cpp new file mode 100644 index 0000000000..c49faa59f1 --- /dev/null +++ b/src/newgrf_roadtype.cpp @@ -0,0 +1,157 @@ +/* + * 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_roadtype.cpp NewGRF handling of road types. */ + +#include "stdafx.h" +#include "debug.h" +#include "newgrf_roadtype.h" +#include "date_func.h" +#include "depot_base.h" +#include "town.h" + +#include "safeguards.h" + +/* virtual */ uint32 RoadTypeScopeResolver::GetRandomBits() const +{ + uint tmp = CountBits(this->tile + (TileX(this->tile) + TileY(this->tile)) * TILE_SIZE); + return GB(tmp, 0, 2); +} + +/* virtual */ uint32 RoadTypeScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const +{ + if (this->tile == INVALID_TILE) { + switch (variable) { + case 0x40: return 0; + case 0x41: return 0; + case 0x42: return 0; + case 0x43: return _date; + case 0x44: return HZB_TOWN_EDGE; + } + } + + switch (variable) { + case 0x40: return GetTerrainType(this->tile, this->context); + case 0x41: return 0; + case 0x42: return IsLevelCrossingTile(this->tile) && IsCrossingBarred(this->tile); + case 0x43: + if (IsRoadDepotTile(this->tile)) return Depot::GetByTile(this->tile)->build_date; + return _date; + case 0x44: { + const Town *t = nullptr; + if (IsRoadDepotTile(this->tile)) { + t = Depot::GetByTile(this->tile)->town; + } else if (IsTileType(this->tile, MP_ROAD)) { + t = ClosestTownFromTile(this->tile, UINT_MAX); + } + return t != nullptr ? GetTownRadiusGroup(t, this->tile) : HZB_TOWN_EDGE; + } + } + + DEBUG(grf, 1, "Unhandled road type tile variable 0x%X", variable); + + *available = false; + return UINT_MAX; +} + +/* virtual */ const SpriteGroup *RoadTypeResolverObject::ResolveReal(const RealSpriteGroup *group) const +{ + if (group->num_loading > 0) return group->loading[0]; + if (group->num_loaded > 0) return group->loaded[0]; + return nullptr; +} + +GrfSpecFeature RoadTypeResolverObject::GetFeature() const +{ + RoadType rt = GetRoadTypeByLabel(this->roadtype_scope.rti->label, false); + switch (GetRoadTramType(rt)) { + case RTT_ROAD: return GSF_ROADTYPES; + case RTT_TRAM: return GSF_TRAMTYPES; + default: return GSF_INVALID; + } +} + +uint32 RoadTypeResolverObject::GetDebugID() const +{ + return this->roadtype_scope.rti->label; +} + +/** + * Constructor of the roadtype scope resolvers. + * @param ro Surrounding resolver. + * @param tile %Tile containing the track. For track on a bridge this is the southern bridgehead. + * @param context Are we resolving sprites for the upper halftile, or on a bridge? + */ +RoadTypeScopeResolver::RoadTypeScopeResolver(ResolverObject &ro, const RoadTypeInfo *rti, TileIndex tile, TileContext context) : ScopeResolver(ro) +{ + this->tile = tile; + this->context = context; + this->rti = rti; +} + +/** + * Resolver object for road types. + * @param rti Roadtype. nullptr in NewGRF Inspect window. + * @param tile %Tile containing the track. For track on a bridge this is the southern bridgehead. + * @param context Are we resolving sprites for the upper halftile, or on a bridge? + * @param rtsg Roadpart of interest + * @param param1 Extra parameter (first parameter of the callback, except roadtypes do not have callbacks). + * @param param2 Extra parameter (second parameter of the callback, except roadtypes do not have callbacks). + */ +RoadTypeResolverObject::RoadTypeResolverObject(const RoadTypeInfo *rti, TileIndex tile, TileContext context, RoadTypeSpriteGroup rtsg, uint32 param1, uint32 param2) + : ResolverObject(rti != nullptr ? rti->grffile[rtsg] : nullptr, CBID_NO_CALLBACK, param1, param2), roadtype_scope(*this, rti, tile, context) +{ + this->root_spritegroup = rti != nullptr ? rti->group[rtsg] : nullptr; +} + +/** + * Get the sprite to draw for the given tile. + * @param rti The road type data (spec). + * @param tile The tile to get the sprite for. + * @param rtsg The type of sprite to draw. + * @param content Where are we drawing the tile? + * @param [out] num_results If not nullptr, return the number of sprites in the spriteset. + * @return The sprite to draw. + */ +SpriteID GetCustomRoadSprite(const RoadTypeInfo *rti, TileIndex tile, RoadTypeSpriteGroup rtsg, TileContext context, uint *num_results) +{ + assert(rtsg < ROTSG_END); + + if (rti->group[rtsg] == nullptr) return 0; + + RoadTypeResolverObject object(rti, tile, context, rtsg); + const SpriteGroup *group = object.Resolve(); + if (group == nullptr || group->GetNumResults() == 0) return 0; + + if (num_results) *num_results = group->GetNumResults(); + + return group->GetResult(); +} + +/** + * Perform a reverse roadtype lookup to get the GRF internal ID. + * @param roadtype The global (OpenTTD) roadtype. + * @param grffile The GRF to do the lookup for. + * @return the GRF internal ID. + */ +uint8 GetReverseRoadTypeTranslation(RoadType roadtype, const GRFFile *grffile) +{ + /* No road type table present, return road type as-is */ + if (grffile == nullptr) return roadtype; + + const std::vector *list = RoadTypeIsRoad(roadtype) ? &grffile->roadtype_list : &grffile->tramtype_list; + if (list->size() == 0) return roadtype; + + /* Look for a matching road type label in the table */ + RoadTypeLabel label = GetRoadTypeInfo(roadtype)->label; + + int index = find_index(*list, label); + if (index >= 0) return index; + + /* If not found, return as invalid */ + return 0xFF; +} diff --git a/src/newgrf_roadtype.h b/src/newgrf_roadtype.h new file mode 100644 index 0000000000..07451f6566 --- /dev/null +++ b/src/newgrf_roadtype.h @@ -0,0 +1,53 @@ +/* + * 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_roadtype.h NewGRF handling of road types. */ + +#ifndef NEWGRF_ROADTYPE_H +#define NEWGRF_ROADTYPE_H + +#include "road.h" +#include "newgrf_commons.h" +#include "newgrf_spritegroup.h" + +/** Resolver for the railtype scope. */ +struct RoadTypeScopeResolver : public ScopeResolver { + TileIndex tile; ///< Tracktile. For track on a bridge this is the southern bridgehead. + TileContext context; ///< Are we resolving sprites for the upper halftile, or on a bridge? + const RoadTypeInfo *rti; + + RoadTypeScopeResolver(ResolverObject &ro, const RoadTypeInfo *rti, TileIndex tile, TileContext context); + + /* virtual */ uint32 GetRandomBits() const; + /* virtual */ uint32 GetVariable(byte variable, uint32 parameter, bool *available) const; +}; + +/** Resolver object for road types. */ +struct RoadTypeResolverObject : public ResolverObject { + RoadTypeScopeResolver roadtype_scope; ///< Resolver for the roadtype scope. + + RoadTypeResolverObject(const RoadTypeInfo *rti, TileIndex tile, TileContext context, RoadTypeSpriteGroup rtsg, uint32 param1 = 0, uint32 param2 = 0); + + ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) override + { + switch (scope) { + case VSG_SCOPE_SELF: return &this->roadtype_scope; + default: return ResolverObject::GetScope(scope, relative); + } + } + + const SpriteGroup *ResolveReal(const RealSpriteGroup *group) const override; + + GrfSpecFeature GetFeature() const override; + uint32 GetDebugID() const override; +}; + +SpriteID GetCustomRoadSprite(const RoadTypeInfo *rti, TileIndex tile, RoadTypeSpriteGroup rtsg, TileContext context = TCX_NORMAL, uint *num_results = nullptr); + +uint8 GetReverseRoadTypeTranslation(RoadType roadtype, const GRFFile *grffile); + +#endif /* NEWGRF_ROADTYPE_H */ diff --git a/src/newgrf_sound.cpp b/src/newgrf_sound.cpp index 0cc113d9df..aead090016 100644 --- a/src/newgrf_sound.cpp +++ b/src/newgrf_sound.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. @@ -22,7 +20,7 @@ #include "safeguards.h" -static SmallVector _sounds; +static std::vector _sounds; /** @@ -32,15 +30,15 @@ static SmallVector _sounds; */ SoundEntry *AllocateSound(uint num) { - SoundEntry *sound = _sounds.Append(num); - MemSetT(sound, 0, num); - return sound; + size_t pos = _sounds.size(); + _sounds.insert(_sounds.end(), num, SoundEntry()); + return &_sounds[pos]; } void InitializeSoundPool() { - _sounds.Clear(); + _sounds.clear(); /* Copy original sound data to the pool */ SndCopyToPool(); @@ -49,14 +47,14 @@ void InitializeSoundPool() SoundEntry *GetSound(SoundID index) { - if (index >= _sounds.Length()) return NULL; + if (index >= _sounds.size()) return nullptr; return &_sounds[index]; } uint GetNumSounds() { - return _sounds.Length(); + return (uint)_sounds.size(); } @@ -173,7 +171,7 @@ SoundID GetNewGRFSoundID(const GRFFile *file, SoundID sound_id) if (sound_id < ORIGINAL_SAMPLE_COUNT) return sound_id; sound_id -= ORIGINAL_SAMPLE_COUNT; - if (file == NULL || sound_id >= file->num_sounds) return INVALID_SOUND; + if (file == nullptr || sound_id >= file->num_sounds) return INVALID_SOUND; return file->sound_offset + sound_id; } @@ -192,7 +190,7 @@ bool PlayVehicleSound(const Vehicle *v, VehicleSoundEvent event) uint16 callback; /* If the engine has no GRF ID associated it can't ever play any new sounds */ - if (file == NULL) return false; + if (file == nullptr) return false; /* Check that the vehicle type uses the sound effect callback */ if (!HasBit(EngInfo(v->engine_type)->callback_mask, CBM_VEHICLE_SOUND_EFFECT)) return false; diff --git a/src/newgrf_sound.h b/src/newgrf_sound.h index efded063c8..d908173ac8 100644 --- a/src/newgrf_sound.h +++ b/src/newgrf_sound.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/newgrf_spritegroup.cpp b/src/newgrf_spritegroup.cpp index 1bcb4a0359..824ba0439e 100644 --- a/src/newgrf_spritegroup.cpp +++ b/src/newgrf_spritegroup.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. @@ -13,6 +11,7 @@ #include #include "debug.h" #include "newgrf_spritegroup.h" +#include "newgrf_profiling.h" #include "core/pool_func.hpp" #include "safeguards.h" @@ -26,7 +25,7 @@ TemporaryStorageArray _temp_store; /** * ResolverObject (re)entry point. * This cannot be made a call to a virtual function because virtual functions - * do not like NULL and checking for NULL *everywhere* is more cumbersome than + * do not like nullptr and checking for nullptr *everywhere* is more cumbersome than * this little helper function. * @param group the group to resolve for * @param object information needed to resolve the group @@ -35,11 +34,24 @@ TemporaryStorageArray _temp_store; */ /* static */ const SpriteGroup *SpriteGroup::Resolve(const SpriteGroup *group, ResolverObject &object, bool top_level) { - if (group == NULL) return NULL; - if (top_level) { + if (group == nullptr) return nullptr; + + const GRFFile *grf = object.grffile; + auto profiler = std::find_if(_newgrf_profilers.begin(), _newgrf_profilers.end(), [&](const NewGRFProfiler &pr) { return pr.grffile == grf; }); + + if (profiler == _newgrf_profilers.end() || !profiler->active) { + if (top_level) _temp_store.ClearChanges(); + return group->Resolve(object); + } else if (top_level) { + profiler->BeginResolve(object); _temp_store.ClearChanges(); + const SpriteGroup *result = group->Resolve(object); + profiler->EndResolve(result); + return result; + } else { + profiler->RecursiveResolve(); + return group->Resolve(object); } - return group->Resolve(object); } RealSpriteGroup::~RealSpriteGroup() @@ -73,7 +85,7 @@ static inline uint32 GetVariable(const ResolverObject &object, ScopeResolver *sc case 0x7D: return _temp_store.GetValue(parameter); case 0x7F: - if (object.grffile == NULL) return 0; + if (object.grffile == nullptr) return 0; return object.grffile->GetParam(parameter); default: @@ -130,7 +142,7 @@ static inline uint32 GetVariable(const ResolverObject &object, ScopeResolver *sc */ /* virtual */ const SpriteGroup *ResolverObject::ResolveReal(const RealSpriteGroup *group) const { - return NULL; + return nullptr; } /** @@ -207,7 +219,7 @@ const SpriteGroup *DeterministicSpriteGroup::Resolve(ResolverObject &object) con bool available = true; if (adjust->variable == 0x7E) { const SpriteGroup *subgroup = SpriteGroup::Resolve(adjust->subroutine, object, false); - if (subgroup == NULL) { + if (subgroup == nullptr) { value = CALLBACK_FAILED; } else { value = subgroup->GetCallbackResult(); @@ -293,24 +305,24 @@ const SpriteGroup *RealSpriteGroup::Resolve(ResolverObject &object) const * Process registers and the construction stage into the sprite layout. * The passed construction stage might get reset to zero, if it gets incorporated into the layout * during the preprocessing. - * @param[in,out] stage Construction stage (0-3), or NULL if not applicable. + * @param[in,out] stage Construction stage (0-3), or nullptr if not applicable. * @return sprite layout to draw. */ const DrawTileSprites *TileLayoutSpriteGroup::ProcessRegisters(uint8 *stage) const { if (!this->dts.NeedsPreprocessing()) { - if (stage != NULL && this->dts.consistent_max_offset > 0) *stage = GetConstructionStageOffset(*stage, this->dts.consistent_max_offset); + if (stage != nullptr && this->dts.consistent_max_offset > 0) *stage = GetConstructionStageOffset(*stage, this->dts.consistent_max_offset); return &this->dts; } static DrawTileSprites result; - uint8 actual_stage = stage != NULL ? *stage : 0; + uint8 actual_stage = stage != nullptr ? *stage : 0; this->dts.PrepareLayout(0, 0, 0, actual_stage, false); this->dts.ProcessRegisters(0, 0, false); result.seq = this->dts.GetLayout(&result.ground); /* Stage has been processed by PrepareLayout(), set it to zero. */ - if (stage != NULL) *stage = 0; + if (stage != nullptr) *stage = 0; return &result; } diff --git a/src/newgrf_spritegroup.h b/src/newgrf_spritegroup.h index 2db78f6bad..80f70df55d 100644 --- a/src/newgrf_spritegroup.h +++ b/src/newgrf_spritegroup.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. @@ -58,13 +56,14 @@ extern SpriteGroupPool _spritegroup_pool; /* Common wrapper for all the different sprite group types */ struct SpriteGroup : SpriteGroupPool::PoolItem<&_spritegroup_pool> { protected: - SpriteGroup(SpriteGroupType type) : type(type) {} + SpriteGroup(SpriteGroupType type) : nfo_line(0), type(type) {} /** Base sprite group resolver */ virtual const SpriteGroup *Resolve(ResolverObject &object) const { return this; }; public: virtual ~SpriteGroup() {} + uint32 nfo_line; SpriteGroupType type; virtual SpriteID GetResult() const { return 0; } @@ -316,13 +315,13 @@ struct ScopeResolver { struct ResolverObject { /** * Resolver constructor. - * @param grffile NewGRF file associated with the object (or \c NULL if none). + * @param grffile NewGRF file associated with the object (or \c nullptr if none). * @param callback Callback code being resolved (default value is #CBID_NO_CALLBACK). * @param callback_param1 First parameter (var 10) of the callback (only used when \a callback is also set). * @param callback_param2 Second parameter (var 18) of the callback (only used when \a callback is also set). */ ResolverObject(const GRFFile *grffile, CallbackID callback = CBID_NO_CALLBACK, uint32 callback_param1 = 0, uint32 callback_param2 = 0) - : default_scope(*this), callback(callback), callback_param1(callback_param1), callback_param2(callback_param2), grffile(grffile), root_spritegroup(NULL) + : default_scope(*this), callback(callback), callback_param1(callback_param1), callback_param2(callback_param2), grffile(grffile), root_spritegroup(nullptr) { this->ResetState(); } @@ -360,7 +359,7 @@ struct ResolverObject { uint16 ResolveCallback() { const SpriteGroup *result = Resolve(); - return result != NULL ? result->GetCallbackResult() : CALLBACK_FAILED; + return result != nullptr ? result->GetCallbackResult() : CALLBACK_FAILED; } virtual const SpriteGroup *ResolveReal(const RealSpriteGroup *group) const; @@ -400,6 +399,18 @@ struct ResolverObject { this->used_triggers = 0; memset(this->reseed, 0, sizeof(this->reseed)); } + + /** + * Get the feature number being resolved for. + * This function is mainly intended for the callback profiling feature. + */ + virtual GrfSpecFeature GetFeature() const { return GSF_INVALID; } + /** + * Get an identifier for the item being resolved. + * This function is mainly intended for the callback profiling feature, + * and should return an identifier recognisable by the NewGRF developer. + */ + virtual uint32 GetDebugID() const { return 0; } }; #endif /* NEWGRF_SPRITEGROUP_H */ diff --git a/src/newgrf_station.cpp b/src/newgrf_station.cpp index d9b79c55a1..19f32bd754 100644 --- a/src/newgrf_station.cpp +++ b/src/newgrf_station.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. @@ -35,11 +33,11 @@ template /* Set up initial data */ classes[0].global_id = 'DFLT'; classes[0].name = STR_STATION_CLASS_DFLT; - classes[0].Insert(NULL); + classes[0].Insert(nullptr); classes[1].global_id = 'WAYP'; classes[1].name = STR_STATION_CLASS_WAYP; - classes[1].Insert(NULL); + classes[1].Insert(nullptr); } template @@ -225,13 +223,13 @@ static uint32 GetRailContinuationInfo(TileIndex tile) /* Station Resolver Functions */ /* virtual */ uint32 StationScopeResolver::GetRandomBits() const { - return (this->st == NULL ? 0 : this->st->random_bits) | (this->tile == INVALID_TILE ? 0 : GetStationTileRandomBits(this->tile) << 16); + return (this->st == nullptr ? 0 : this->st->random_bits) | (this->tile == INVALID_TILE ? 0 : GetStationTileRandomBits(this->tile) << 16); } /* virtual */ uint32 StationScopeResolver::GetTriggers() const { - return this->st == NULL ? 0 : this->st->waiting_triggers; + return this->st == nullptr ? 0 : this->st->waiting_triggers; } @@ -257,22 +255,22 @@ static struct { */ TownScopeResolver *StationResolverObject::GetTown() { - if (this->town_scope == NULL) { - Town *t = NULL; - if (this->station_scope.st != NULL) { + if (this->town_scope == nullptr) { + Town *t = nullptr; + if (this->station_scope.st != nullptr) { t = this->station_scope.st->town; } else if (this->station_scope.tile != INVALID_TILE) { t = ClosestTownFromTile(this->station_scope.tile, UINT_MAX); } - if (t == NULL) return NULL; - this->town_scope = new TownScopeResolver(*this, t, this->station_scope.st == NULL); + if (t == nullptr) return nullptr; + this->town_scope = new TownScopeResolver(*this, t, this->station_scope.st == nullptr); } return this->town_scope; } /* virtual */ uint32 StationScopeResolver::GetVariable(byte variable, uint32 parameter, bool *available) const { - if (this->st == NULL) { + if (this->st == nullptr) { /* Station does not exist, so we're in a purchase list or the land slope check callback. */ switch (variable) { case 0x40: @@ -370,6 +368,16 @@ TownScopeResolver *StationResolverObject::GetTown() return res; } + case 0x6A: { // GRFID of nearby station tiles + TileIndex nearby_tile = GetNearbyTile(parameter, this->tile); + + if (!HasStationTileRail(nearby_tile)) return 0xFFFFFFFF; + if (!IsCustomStationSpecIndex(nearby_tile)) return 0; + + const StationSpecList ssl = BaseStation::GetByTile(nearby_tile)->speclist[GetCustomStationSpecIndex(nearby_tile)]; + return ssl.grfid; + } + /* General station variables */ case 0x82: return 50; case 0x84: return this->st->string_id; @@ -396,8 +404,8 @@ uint32 Station::GetNewGRFVariable(const ResolverObject &object, byte variable, b case 0x8A: return this->had_vehicle_of_type; case 0xF1: return (this->airport.tile != INVALID_TILE) ? this->airport.GetSpec()->ttd_airport_type : ATP_TTDP_LARGE; - case 0xF2: return (this->truck_stops != NULL) ? this->truck_stops->status : 0; - case 0xF3: return (this->bus_stops != NULL) ? this->bus_stops->status : 0; + case 0xF2: return (this->truck_stops != nullptr) ? this->truck_stops->status : 0; + case 0xF3: return (this->bus_stops != nullptr) ? this->bus_stops->status : 0; case 0xF6: return this->airport.flags; case 0xF7: return GB(this->airport.flags, 8, 8); } @@ -486,7 +494,7 @@ uint32 Waypoint::GetNewGRFVariable(const ResolverObject &object, byte variable, /* virtual */ const SpriteGroup *StationResolverObject::ResolveReal(const RealSpriteGroup *group) const { - if (this->station_scope.st == NULL || this->station_scope.statspec->cls_id == STAT_CLASS_WAYP) { + if (this->station_scope.st == nullptr || this->station_scope.statspec->cls_id == STAT_CLASS_WAYP) { return group->loading[0]; } @@ -529,6 +537,16 @@ uint32 Waypoint::GetNewGRFVariable(const ResolverObject &object, byte variable, return group->loading[0]; } +GrfSpecFeature StationResolverObject::GetFeature() const +{ + return GSF_STATIONS; +} + +uint32 StationResolverObject::GetDebugID() const +{ + return this->station_scope.statspec->grf_prop.local_id; +} + /** * Resolver for stations. * @param statspec Station (type) specification. @@ -541,14 +559,14 @@ uint32 Waypoint::GetNewGRFVariable(const ResolverObject &object, byte variable, StationResolverObject::StationResolverObject(const StationSpec *statspec, BaseStation *st, TileIndex tile, CallbackID callback, uint32 callback_param1, uint32 callback_param2) : ResolverObject(statspec->grf_prop.grffile, callback, callback_param1, callback_param2), - station_scope(*this, statspec, st, tile), town_scope(NULL) + station_scope(*this, statspec, st, tile), town_scope(nullptr) { /* Invalidate all cached vars */ _svc.valid = 0; CargoID ctype = CT_DEFAULT_NA; - if (this->station_scope.st == NULL) { + if (this->station_scope.st == nullptr) { /* No station, so we are in a purchase list */ ctype = CT_PURCHASE; } else if (Station::IsExpected(this->station_scope.st)) { @@ -556,7 +574,7 @@ StationResolverObject::StationResolverObject(const StationSpec *statspec, BaseSt /* Pick the first cargo that we have waiting */ const CargoSpec *cs; FOR_ALL_CARGOSPECS(cs) { - if (this->station_scope.statspec->grf_prop.spritegroup[cs->Index()] != NULL && + if (this->station_scope.statspec->grf_prop.spritegroup[cs->Index()] != nullptr && st->goods[cs->Index()].cargo.TotalCount() > 0) { ctype = cs->Index(); break; @@ -564,7 +582,7 @@ StationResolverObject::StationResolverObject(const StationSpec *statspec, BaseSt } } - if (this->station_scope.statspec->grf_prop.spritegroup[ctype] == NULL) { + if (this->station_scope.statspec->grf_prop.spritegroup[ctype] == nullptr) { ctype = CT_DEFAULT; } @@ -581,7 +599,7 @@ StationResolverObject::~StationResolverObject() /** * Resolve sprites for drawing a station tile. * @param statspec Station spec - * @param st Station (NULL in GUI) + * @param st Station (nullptr in GUI) * @param tile Station tile being drawn (INVALID_TILE in GUI) * @param var10 Value to put in variable 10; normally 0; 1 when resolving the groundsprite and SSF_SEPARATE_GROUND is set. * @return First sprite of the Action 1 spriteset to use, minus an offset of 0x42D to accommodate for weird NewGRF specs. @@ -590,7 +608,7 @@ SpriteID GetCustomStationRelocation(const StationSpec *statspec, BaseStation *st { StationResolverObject object(statspec, st, tile, CBID_NO_CALLBACK, var10); const SpriteGroup *group = object.Resolve(); - if (group == NULL || group->type != SGT_RESULT) return 0; + if (group == nullptr || group->type != SGT_RESULT) return 0; return group->GetResult() - 0x42D; } @@ -609,7 +627,7 @@ SpriteID GetCustomStationFoundationRelocation(const StationSpec *statspec, BaseS StationResolverObject object(statspec, st, tile, CBID_NO_CALLBACK, 2, layout | (edge_info << 16)); const SpriteGroup *group = object.Resolve(); - if (group == NULL || group->type != SGT_RESULT) return 0; + if (group == nullptr || group->type != SGT_RESULT) return 0; /* Note: SpriteGroup::Resolve zeroes all registers, so register 0x100 is initialised to 0. (compatibility) */ return group->GetResult() + GetRegister(0x100); @@ -637,7 +655,7 @@ CommandCost PerformStationTileSlopeCheck(TileIndex north_tile, TileIndex cur_til TileIndexDiff diff = cur_tile - north_tile; Slope slope = GetTileSlope(cur_tile); - StationResolverObject object(statspec, NULL, cur_tile, CBID_STATION_LAND_SLOPE_CHECK, + StationResolverObject object(statspec, nullptr, cur_tile, CBID_STATION_LAND_SLOPE_CHECK, (slope << 4) | (slope ^ (axis == AXIS_Y && HasBit(slope, CORNER_W) != HasBit(slope, CORNER_E) ? SLOPE_EW : 0)), (numtracks << 24) | (plat_len << 16) | (axis == AXIS_Y ? TileX(diff) << 8 | TileY(diff) : TileY(diff) << 8 | TileX(diff))); object.station_scope.axis = axis; @@ -664,10 +682,10 @@ int AllocateSpecToStation(const StationSpec *statspec, BaseStation *st, bool exe { uint i; - if (statspec == NULL || st == NULL) return 0; + if (statspec == nullptr || st == nullptr) return 0; for (i = 1; i < st->num_specs && i < NUM_STATIONSSPECS_PER_STATION; i++) { - if (st->speclist[i].spec == NULL && st->speclist[i].grfid == 0) break; + if (st->speclist[i].spec == nullptr && st->speclist[i].grfid == 0) break; } if (i == NUM_STATIONSSPECS_PER_STATION) { @@ -690,7 +708,7 @@ int AllocateSpecToStation(const StationSpec *statspec, BaseStation *st, bool exe if (st->num_specs == 2) { /* Initial allocation */ - st->speclist[0].spec = NULL; + st->speclist[0].spec = nullptr; st->speclist[0].grfid = 0; st->speclist[0].localidx = 0; } @@ -727,7 +745,7 @@ void DeallocateSpecFromStation(BaseStation *st, byte specindex) } /* This specindex is no longer in use, so deallocate it */ - st->speclist[specindex].spec = NULL; + st->speclist[specindex].spec = nullptr; st->speclist[specindex].grfid = 0; st->speclist[specindex].localidx = 0; @@ -740,7 +758,7 @@ void DeallocateSpecFromStation(BaseStation *st, byte specindex) } else { free(st->speclist); st->num_specs = 0; - st->speclist = NULL; + st->speclist = nullptr; st->cached_anim_triggers = 0; st->cached_cargo_triggers = 0; return; @@ -762,42 +780,42 @@ void DeallocateSpecFromStation(BaseStation *st, byte specindex) */ bool DrawStationTile(int x, int y, RailType railtype, Axis axis, StationClassID sclass, uint station) { - const DrawTileSprites *sprites = NULL; + const DrawTileSprites *sprites = nullptr; const RailtypeInfo *rti = GetRailTypeInfo(railtype); PaletteID palette = COMPANY_SPRITE_COLOUR(_local_company); uint tile = 2; const StationSpec *statspec = StationClass::Get(sclass)->GetSpec(station); - if (statspec == NULL) return false; + if (statspec == nullptr) return false; if (HasBit(statspec->callback_mask, CBM_STATION_SPRITE_LAYOUT)) { - uint16 callback = GetStationCallback(CBID_STATION_SPRITE_LAYOUT, 0x2110000, 0, statspec, NULL, INVALID_TILE); + uint16 callback = GetStationCallback(CBID_STATION_SPRITE_LAYOUT, 0x2110000, 0, statspec, nullptr, INVALID_TILE); if (callback != CALLBACK_FAILED) tile = callback; } uint32 total_offset = rti->GetRailtypeSpriteOffset(); uint32 relocation = 0; uint32 ground_relocation = 0; - const NewGRFSpriteLayout *layout = NULL; + const NewGRFSpriteLayout *layout = nullptr; DrawTileSprites tmp_rail_layout; - if (statspec->renderdata == NULL) { + if (statspec->renderdata == nullptr) { sprites = GetStationTileLayout(STATION_RAIL, tile + axis); } else { layout = &statspec->renderdata[(tile < statspec->tiles) ? tile + axis : (uint)axis]; if (!layout->NeedsPreprocessing()) { sprites = layout; - layout = NULL; + layout = nullptr; } } - if (layout != NULL) { + if (layout != nullptr) { /* Sprite layout which needs preprocessing */ bool separate_ground = HasBit(statspec->flags, SSF_SEPARATE_GROUND); uint32 var10_values = layout->PrepareLayout(total_offset, rti->fallback_railtype, 0, 0, separate_ground); uint8 var10; FOR_EACH_SET_BIT(var10, var10_values) { - uint32 var10_relocation = GetCustomStationRelocation(statspec, NULL, INVALID_TILE, var10); + uint32 var10_relocation = GetCustomStationRelocation(statspec, nullptr, INVALID_TILE, var10); layout->ProcessRegisters(var10, var10_relocation, separate_ground); } @@ -806,9 +824,9 @@ bool DrawStationTile(int x, int y, RailType railtype, Axis axis, StationClassID total_offset = 0; } else { /* Simple sprite layout */ - ground_relocation = relocation = GetCustomStationRelocation(statspec, NULL, INVALID_TILE, 0); + ground_relocation = relocation = GetCustomStationRelocation(statspec, nullptr, INVALID_TILE, 0); if (HasBit(sprites->ground.sprite, SPRITE_MODIFIER_CUSTOM_SPRITE)) { - ground_relocation = GetCustomStationRelocation(statspec, NULL, INVALID_TILE, 1); + ground_relocation = GetCustomStationRelocation(statspec, nullptr, INVALID_TILE, 1); } ground_relocation += rti->fallback_railtype; } @@ -816,7 +834,7 @@ bool DrawStationTile(int x, int y, RailType railtype, Axis axis, StationClassID SpriteID image = sprites->ground.sprite; PaletteID pal = sprites->ground.pal; RailTrackOffset overlay_offset; - if (rti->UsesOverlay() && SplitGroundSpriteForOverlay(NULL, &image, &overlay_offset)) { + if (rti->UsesOverlay() && SplitGroundSpriteForOverlay(nullptr, &image, &overlay_offset)) { SpriteID ground = GetCustomRailSprite(rti, INVALID_TILE, RTSG_GROUND); DrawSprite(image, PAL_NONE, x, y); DrawSprite(ground + overlay_offset, PAL_NONE, x, y); @@ -834,11 +852,11 @@ bool DrawStationTile(int x, int y, RailType railtype, Axis axis, StationClassID const StationSpec *GetStationSpec(TileIndex t) { - if (!IsCustomStationSpecIndex(t)) return NULL; + if (!IsCustomStationSpecIndex(t)) return nullptr; const BaseStation *st = BaseStation::GetByTile(t); uint specindex = GetCustomStationSpecIndex(t); - return specindex < st->num_specs ? st->speclist[specindex].spec : NULL; + return specindex < st->num_specs ? st->speclist[specindex].spec : nullptr; } @@ -852,7 +870,7 @@ bool IsStationTileBlocked(TileIndex tile) { const StationSpec *statspec = GetStationSpec(tile); - return statspec != NULL && HasBit(statspec->blocked, GetStationGfx(tile)); + return statspec != nullptr && HasBit(statspec->blocked, GetStationGfx(tile)); } /** @@ -866,7 +884,7 @@ bool CanStationTileHavePylons(TileIndex tile) const StationSpec *statspec = GetStationSpec(tile); uint gfx = GetStationGfx(tile); /* Default stations do not draw pylons under roofs (gfx >= 4) */ - return statspec != NULL ? HasBit(statspec->pylons, gfx) : gfx < 4; + return statspec != nullptr ? HasBit(statspec->pylons, gfx) : gfx < 4; } /** @@ -878,7 +896,7 @@ bool CanStationTileHavePylons(TileIndex tile) bool CanStationTileHaveWires(TileIndex tile) { const StationSpec *statspec = GetStationSpec(tile); - return statspec == NULL || !HasBit(statspec->wires, GetStationGfx(tile)); + return statspec == nullptr || !HasBit(statspec->wires, GetStationGfx(tile)); } /** Wrapper for animation control, see GetStationCallback. */ @@ -899,7 +917,7 @@ struct StationAnimationBase : public AnimationBaseflags, SSF_CB141_RANDOM_BITS)); } @@ -912,7 +930,7 @@ void TriggerStationAnimation(BaseStation *st, TileIndex tile, StationAnimationTr }; /* Get Station if it wasn't supplied */ - if (st == NULL) st = BaseStation::GetByTile(tile); + if (st == nullptr) st = BaseStation::GetByTile(tile); /* Check the cached animation trigger bitmask to see if we need * to bother with any further processing. */ @@ -925,7 +943,7 @@ void TriggerStationAnimation(BaseStation *st, TileIndex tile, StationAnimationTr TILE_AREA_LOOP(tile, area) { if (st->TileBelongsToRailStation(tile)) { const StationSpec *ss = GetStationSpec(tile); - if (ss != NULL && HasBit(ss->animation.triggers, trigger)) { + if (ss != nullptr && HasBit(ss->animation.triggers, trigger)) { CargoID cargo; if (cargo_type == CT_INVALID) { cargo = CT_INVALID; @@ -953,7 +971,7 @@ void TriggerStationRandomisation(Station *st, TileIndex tile, StationRandomTrigg }; /* Get Station if it wasn't supplied */ - if (st == NULL) st = Station::GetByTile(tile); + if (st == nullptr) st = Station::GetByTile(tile); /* Check the cached cargo trigger bitmask to see if we need * to bother with any further processing. */ @@ -981,7 +999,7 @@ void TriggerStationRandomisation(Station *st, TileIndex tile, StationRandomTrigg TILE_AREA_LOOP(tile, area) { if (st->TileBelongsToRailStation(tile)) { const StationSpec *ss = GetStationSpec(tile); - if (ss == NULL) continue; + if (ss == nullptr) continue; /* Cargo taken "will only be triggered if all of those * cargo types have no more cargo waiting." */ @@ -994,7 +1012,7 @@ void TriggerStationRandomisation(Station *st, TileIndex tile, StationRandomTrigg object.waiting_triggers = st->waiting_triggers; const SpriteGroup *group = object.Resolve(); - if (group == NULL) continue; + if (group == nullptr) continue; used_triggers |= object.used_triggers; @@ -1036,7 +1054,7 @@ void StationUpdateCachedTriggers(BaseStation *st) * of this station. */ for (uint i = 0; i < st->num_specs; i++) { const StationSpec *ss = st->speclist[i].spec; - if (ss != NULL) { + if (ss != nullptr) { st->cached_anim_triggers |= ss->animation.triggers; st->cached_cargo_triggers |= ss->cargo_triggers; } diff --git a/src/newgrf_station.h b/src/newgrf_station.h index 123330d0ad..fac5d64ddd 100644 --- a/src/newgrf_station.h +++ b/src/newgrf_station.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. @@ -42,10 +40,10 @@ struct StationScopeResolver : public ScopeResolver { { } - /* virtual */ uint32 GetRandomBits() const; - /* virtual */ uint32 GetTriggers() const; + uint32 GetRandomBits() const override; + uint32 GetTriggers() const override; - /* virtual */ uint32 GetVariable(byte variable, uint32 parameter, bool *available) const; + uint32 GetVariable(byte variable, uint32 parameter, bool *available) const override; }; /** Station resolver. */ @@ -59,7 +57,7 @@ struct StationResolverObject : public ResolverObject { TownScopeResolver *GetTown(); - /* virtual */ ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) + ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) override { switch (scope) { case VSG_SCOPE_SELF: @@ -67,7 +65,7 @@ struct StationResolverObject : public ResolverObject { case VSG_SCOPE_PARENT: { TownScopeResolver *tsr = this->GetTown(); - if (tsr != NULL) return tsr; + if (tsr != nullptr) return tsr; FALLTHROUGH; } @@ -76,16 +74,18 @@ struct StationResolverObject : public ResolverObject { } } - /* virtual */ const SpriteGroup *ResolveReal(const RealSpriteGroup *group) const; + const SpriteGroup *ResolveReal(const RealSpriteGroup *group) const override; + + GrfSpecFeature GetFeature() const override; + uint32 GetDebugID() const override; }; -enum StationClassID { +enum StationClassID : byte { STAT_CLASS_BEGIN = 0, ///< the lowest valid value STAT_CLASS_DFLT = 0, ///< Default station class. STAT_CLASS_WAYP, ///< Waypoint class. - STAT_CLASS_MAX = 256, ///< Maximum number of classes. + STAT_CLASS_MAX = 255, ///< Maximum number of classes. }; -typedef SimpleTinyEnumT StationClassIDByte; template <> struct EnumPropsT : MakeEnumPropsT {}; /** Allow incrementing of StationClassID variables */ diff --git a/src/newgrf_storage.cpp b/src/newgrf_storage.cpp index e91e1f90c8..15214d91bb 100644 --- a/src/newgrf_storage.cpp +++ b/src/newgrf_storage.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. diff --git a/src/newgrf_storage.h b/src/newgrf_storage.h index a0c1558f8e..61206a587b 100644 --- a/src/newgrf_storage.h +++ b/src/newgrf_storage.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. @@ -70,7 +68,7 @@ struct PersistentStorageArray : BasePersistentStorageArray { TYPE *prev_storage; ///< Memory to store "old" states so we can revert them on the performance of test cases for commands etc. /** Simply construct the array */ - PersistentStorageArray() : prev_storage(NULL) + PersistentStorageArray() : prev_storage(nullptr) { memset(this->storage, 0, sizeof(this->storage)); } @@ -105,8 +103,8 @@ struct PersistentStorageArray : BasePersistentStorageArray { /* We do not have made a backup; lets do so */ if (AreChangesPersistent()) { - assert(this->prev_storage == NULL); - } else if (this->prev_storage == NULL) { + assert(this->prev_storage == nullptr); + } else if (this->prev_storage == nullptr) { this->prev_storage = MallocT(SIZE); memcpy(this->prev_storage, this->storage, sizeof(this->storage)); @@ -133,10 +131,10 @@ struct PersistentStorageArray : BasePersistentStorageArray { void ClearChanges() { - if (this->prev_storage != NULL) { + if (this->prev_storage != nullptr) { memcpy(this->storage, this->prev_storage, sizeof(this->storage)); free(this->prev_storage); - this->prev_storage = NULL; + this->prev_storage = nullptr; } } }; @@ -232,7 +230,4 @@ struct PersistentStorage : PersistentStorageArray, PersistentStorage assert_compile(cpp_lengthof(OldPersistentStorage, storage) <= cpp_lengthof(PersistentStorage, storage)); -#define FOR_ALL_STORAGES_FROM(var, start) FOR_ALL_ITEMS_FROM(PersistentStorage, storage_index, var, start) -#define FOR_ALL_STORAGES(var) FOR_ALL_STORAGES_FROM(var, 0) - #endif /* NEWGRF_STORAGE_H */ diff --git a/src/newgrf_text.cpp b/src/newgrf_text.cpp index b92b84355a..c08877198d 100644 --- a/src/newgrf_text.cpp +++ b/src/newgrf_text.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. @@ -14,10 +12,14 @@ * holding everything that the newgrf action 04 will send over to OpenTTD. * One of the biggest problems is that Dynamic lang Array uses ISO codes * as way to identifying current user lang, while newgrf uses bit shift codes - * not related to ISO. So equivalence functionnality had to be set. + * not related to ISO. So equivalence functionality had to be set. */ #include "stdafx.h" + +#include +#include + #include "newgrf.h" #include "strings_func.h" #include "newgrf_storage.h" @@ -115,7 +117,7 @@ private: * @param text_ The text to store in this GRFText. * @param len_ The length of the text to store. */ - GRFText(byte langid_, const char *text_, size_t len_) : next(NULL), len(len_), langid(langid_) + GRFText(byte langid_, const char *text_, size_t len_) : next(nullptr), len(len_), langid(langid_) { /* We need to use memcpy instead of strcpy due to * the possibility of "choice lists" and therefore @@ -167,9 +169,9 @@ static byte _currentLangID = GRFLX_ENGLISH; ///< by default, english is used. */ int LanguageMap::GetMapping(int newgrf_id, bool gender) const { - const SmallVector &map = gender ? this->gender_map : this->case_map; - for (const Mapping *m = map.Begin(); m != map.End(); m++) { - if (m->newgrf_id == newgrf_id) return m->openttd_id; + const std::vector &map = gender ? this->gender_map : this->case_map; + for (const Mapping &m : map) { + if (m.newgrf_id == newgrf_id) return m.openttd_id; } return -1; } @@ -182,9 +184,9 @@ int LanguageMap::GetMapping(int newgrf_id, bool gender) const */ int LanguageMap::GetReverseMapping(int openttd_id, bool gender) const { - const SmallVector &map = gender ? this->gender_map : this->case_map; - for (const Mapping *m = map.Begin(); m != map.End(); m++) { - if (m->openttd_id == openttd_id) return m->newgrf_id; + const std::vector &map = gender ? this->gender_map : this->case_map; + for (const Mapping &m : map) { + if (m.openttd_id == openttd_id) return m.newgrf_id; } return -1; } @@ -194,8 +196,8 @@ struct UnmappedChoiceList : ZeroedMemoryAllocator { /** Clean everything up. */ ~UnmappedChoiceList() { - for (SmallPair *p = this->strings.Begin(); p < this->strings.End(); p++) { - free(p->second); + for (SmallPair p : this->strings) { + free(p.second); } } @@ -232,7 +234,7 @@ struct UnmappedChoiceList : ZeroedMemoryAllocator { } char *d = old_d; - if (lm == NULL) { + if (lm == nullptr) { /* In case there is no mapping, just ignore everything but the default. * A probable cause for this happening is when the language file has * been removed by the user and as such no mapping could be made. */ @@ -342,7 +344,7 @@ char *TranslateTTDPatchCodes(uint32 grfid, uint8 language_id, bool allow_newline size_t len = Utf8Decode(&c, str); /* Helper variable for a possible (string) mapping. */ - UnmappedChoiceList *mapping = NULL; + UnmappedChoiceList *mapping = nullptr; if (c == NFO_UTF8_IDENTIFIER) { unicode = true; @@ -461,7 +463,7 @@ char *TranslateTTDPatchCodes(uint32 grfid, uint8 language_id, bool allow_newline if (str[0] == '\0') goto string_end; const LanguageMap *lm = LanguageMap::GetLanguageMap(grfid, language_id); int index = *str++; - int mapped = lm != NULL ? lm->GetMapping(index, code == 0x0E) : -1; + int mapped = lm != nullptr ? lm->GetMapping(index, code == 0x0E) : -1; if (mapped >= 0) { d += Utf8Encode(d, code == 0x0E ? SCC_GENDER_INDEX : SCC_SET_CASE); d += Utf8Encode(d, code == 0x0E ? mapped : mapped + 1); @@ -472,7 +474,7 @@ char *TranslateTTDPatchCodes(uint32 grfid, uint8 language_id, bool allow_newline case 0x10: case 0x11: if (str[0] == '\0') goto string_end; - if (mapping == NULL) { + if (mapping == nullptr) { if (code == 0x10) str++; // Skip the index grfmsg(1, "choice list %s marker found when not expected", code == 0x10 ? "next" : "default"); break; @@ -490,7 +492,7 @@ char *TranslateTTDPatchCodes(uint32 grfid, uint8 language_id, bool allow_newline break; case 0x12: - if (mapping == NULL) { + if (mapping == nullptr) { grfmsg(1, "choice list end marker found when not expected"); } else { /* Terminate the previous string. */ @@ -499,7 +501,7 @@ char *TranslateTTDPatchCodes(uint32 grfid, uint8 language_id, bool allow_newline /* Now we can start flushing everything and clean everything up. */ d = mapping->Flush(LanguageMap::GetLanguageMap(grfid, language_id)); delete mapping; - mapping = NULL; + mapping = nullptr; } break; @@ -507,7 +509,7 @@ char *TranslateTTDPatchCodes(uint32 grfid, uint8 language_id, bool allow_newline case 0x14: case 0x15: if (str[0] == '\0') goto string_end; - if (mapping != NULL) { + if (mapping != nullptr) { grfmsg(1, "choice lists can't be stacked, it's going to get messy now..."); if (code != 0x14) str++; } else { @@ -528,6 +530,9 @@ char *TranslateTTDPatchCodes(uint32 grfid, uint8 language_id, bool allow_newline d += Utf8Encode(d, SCC_NEWGRF_PRINT_DWORD_DATE_LONG + code - 0x16); break; + case 0x1F: d += Utf8Encode(d, SCC_PUSH_COLOUR); break; + case 0x20: d += Utf8Encode(d, SCC_POP_COLOUR); break; + default: grfmsg(1, "missing handler for extended format code"); break; @@ -559,13 +564,13 @@ char *TranslateTTDPatchCodes(uint32 grfid, uint8 language_id, bool allow_newline } string_end: - if (mapping != NULL) { + if (mapping != nullptr) { grfmsg(1, "choice list was incomplete, the whole list is ignored"); delete mapping; } *d = '\0'; - if (olen != NULL) *olen = d - tmp + 1; + if (olen != nullptr) *olen = d - tmp + 1; tmp = ReallocT(tmp, d - tmp + 1); return tmp; } @@ -580,7 +585,7 @@ void AddGRFTextToList(GRFText **list, GRFText *text_to_add) GRFText **ptext, *text; /* Loop through all languages and see if we can replace a string */ - for (ptext = list; (text = *ptext) != NULL; ptext = &text->next) { + for (ptext = list; (text = *ptext) != nullptr; ptext = &text->next) { if (text->langid == text_to_add->langid) { text_to_add->next = text->next; *ptext = text_to_add; @@ -630,9 +635,9 @@ void AddGRFTextToList(struct GRFText **list, const char *text_to_add) */ GRFText *DuplicateGRFText(GRFText *orig) { - GRFText *newtext = NULL; + GRFText *newtext = nullptr; GRFText **ptext = &newtext; - for (; orig != NULL; orig = orig->next) { + for (; orig != nullptr; orig = orig->next) { *ptext = GRFText::Copy(orig); ptext = &(*ptext)->next; } @@ -684,7 +689,7 @@ StringID AddGRFString(uint32 grfid, uint16 stringid, byte langid_to_add, bool ne /* If we didn't find our stringid and grfid in the list, allocate a new id */ if (id == _num_grf_texts) _num_grf_texts++; - if (_grf_text[id].textholder == NULL) { + if (_grf_text[id].textholder == nullptr) { _grf_text[id].grfid = grfid; _grf_text[id].stringid = stringid; _grf_text[id].def_string = def_string; @@ -715,20 +720,20 @@ StringID GetGRFStringID(uint32 grfid, StringID stringid) * Get a C-string from a GRFText-list. If there is a translation for the * current language it is returned, otherwise the default translation * is returned. If there is neither a default nor a translation for the - * current language NULL is returned. + * current language nullptr is returned. * @param text The GRFText to get the string from. */ const char *GetGRFStringFromGRFText(const GRFText *text) { - const char *default_text = NULL; + const char *default_text = nullptr; /* Search the list of lang-strings of this stringid for current lang */ - for (; text != NULL; text = text->next) { + for (; text != nullptr; text = text->next) { if (text->langid == _currentLangID) return text->text; /* If the current string is English or American, set it as the * fallback language if the specific language isn't available. */ - if (text->langid == GRFLX_UNSPECIFIED || (default_text == NULL && (text->langid == GRFLX_ENGLISH || text->langid == GRFLX_AMERICAN))) { + if (text->langid == GRFLX_UNSPECIFIED || (default_text == nullptr && (text->langid == GRFLX_ENGLISH || text->langid == GRFLX_AMERICAN))) { default_text = text->text; } } @@ -744,7 +749,7 @@ const char *GetGRFStringPtr(uint16 stringid) assert(_grf_text[stringid].grfid != 0); const char *str = GetGRFStringFromGRFText(_grf_text[stringid].textholder); - if (str != NULL) return str; + if (str != nullptr) return str; /* Use the default string ID if the fallback string isn't available */ return GetStringPtr(_grf_text[stringid].def_string); @@ -783,7 +788,7 @@ bool CheckGrfLangID(byte lang_id, byte grf_version) */ void CleanUpGRFText(GRFText *grftext) { - while (grftext != NULL) { + while (grftext != nullptr) { GRFText *grftext2 = grftext->next; delete grftext; grftext = grftext2; @@ -802,29 +807,21 @@ void CleanUpStrings() CleanUpGRFText(_grf_text[id].textholder); _grf_text[id].grfid = 0; _grf_text[id].stringid = 0; - _grf_text[id].textholder = NULL; + _grf_text[id].textholder = nullptr; } _num_grf_texts = 0; } struct TextRefStack { - byte stack[0x30]; + std::array stack; byte position; const GRFFile *grffile; bool used; - TextRefStack() : position(0), grffile(NULL), used(false) {} + TextRefStack() : position(0), grffile(nullptr), used(false) {} - TextRefStack(const TextRefStack &stack) : - position(stack.position), - grffile(stack.grffile), - used(stack.used) - { - memcpy(this->stack, stack.stack, sizeof(this->stack)); - } - - uint8 PopUnsignedByte() { assert(this->position < lengthof(this->stack)); return this->stack[this->position++]; } + uint8 PopUnsignedByte() { assert(this->position < this->stack.size()); return this->stack[this->position++]; } int8 PopSignedByte() { return (int8)this->PopUnsignedByte(); } uint16 PopUnsignedWord() @@ -862,9 +859,8 @@ struct TextRefStack { if (this->position >= 2) { this->position -= 2; } else { - for (int i = lengthof(stack) - 1; i >= this->position + 2; i--) { - this->stack[i] = this->stack[i - 2]; - } + // Rotate right 2 positions + std::rotate(this->stack.rbegin(), this->stack.rbegin() + 2, this->stack.rend()); } this->stack[this->position] = GB(word, 0, 8); this->stack[this->position + 1] = GB(word, 8, 8); @@ -872,7 +868,7 @@ struct TextRefStack { void ResetStack(const GRFFile *grffile) { - assert(grffile != NULL); + assert(grffile != nullptr); this->position = 0; this->grffile = grffile; this->used = true; @@ -928,7 +924,7 @@ void RestoreTextRefStackBackup(struct TextRefStack *backup) * * @param grffile the NewGRF providing the stack data * @param numEntries number of entries to copy from the registers - * @param values values to copy onto the stack; if NULL the temporary NewGRF registers will be used instead + * @param values values to copy onto the stack; if nullptr the temporary NewGRF registers will be used instead */ void StartTextRefStackUsage(const GRFFile *grffile, byte numEntries, const uint32 *values) { @@ -936,12 +932,12 @@ void StartTextRefStackUsage(const GRFFile *grffile, byte numEntries, const uint3 _newgrf_textrefstack.ResetStack(grffile); - byte *p = _newgrf_textrefstack.stack; + auto stack_it = _newgrf_textrefstack.stack.begin(); for (uint i = 0; i < numEntries; i++) { - uint32 value = values != NULL ? values[i] : _temp_store.GetValue(0x100 + i); + uint32 value = values != nullptr ? values[i] : _temp_store.GetValue(0x100 + i); for (uint j = 0; j < 32; j += 8) { - *p = GB(value, j, 8); - p++; + *stack_it = GB(value, j, 8); + stack_it++; } } } diff --git a/src/newgrf_text.h b/src/newgrf_text.h index 033967d307..709f4dd244 100644 --- a/src/newgrf_text.h +++ b/src/newgrf_text.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. @@ -26,7 +24,7 @@ const char *GetGRFStringFromGRFText(const struct GRFText *text); const char *GetGRFStringPtr(uint16 stringid); void CleanUpStrings(); void SetCurrentGrfLangID(byte language_id); -char *TranslateTTDPatchCodes(uint32 grfid, uint8 language_id, bool allow_newlines, const char *str, int *olen = NULL, StringControlCode byte80 = SCC_NEWGRF_PRINT_WORD_STRING_ID); +char *TranslateTTDPatchCodes(uint32 grfid, uint8 language_id, bool allow_newlines, const char *str, int *olen = nullptr, StringControlCode byte80 = SCC_NEWGRF_PRINT_WORD_STRING_ID); struct GRFText *DuplicateGRFText(struct GRFText *orig); void AddGRFTextToList(struct GRFText **list, struct GRFText *text_to_add); void AddGRFTextToList(struct GRFText **list, byte langid, uint32 grfid, bool allow_newlines, const char *text_to_add); @@ -35,7 +33,7 @@ void CleanUpGRFText(struct GRFText *grftext); bool CheckGrfLangID(byte lang_id, byte grf_version); -void StartTextRefStackUsage(const GRFFile *grffile, byte numEntries, const uint32 *values = NULL); +void StartTextRefStackUsage(const GRFFile *grffile, byte numEntries, const uint32 *values = nullptr); void StopTextRefStackUsage(); void RewindTextRefStack(); bool UsingNewGRFTextStack(); @@ -57,9 +55,9 @@ struct LanguageMap { * the genders/cases/plural OpenTTD IDs to the NewGRF's internal IDs. In this * case a NewGRF developer/translator might want a different translation for * both cases. Thus we are basically implementing a multi-map. */ - SmallVector gender_map; ///< Mapping of NewGRF and OpenTTD IDs for genders. - SmallVector case_map; ///< Mapping of NewGRF and OpenTTD IDs for cases. - int plural_form; ///< The plural form used for this language. + std::vector gender_map; ///< Mapping of NewGRF and OpenTTD IDs for genders. + std::vector case_map; ///< Mapping of NewGRF and OpenTTD IDs for cases. + int plural_form; ///< The plural form used for this language. int GetMapping(int newgrf_id, bool gender) const; int GetReverseMapping(int openttd_id, bool gender) const; diff --git a/src/newgrf_town.cpp b/src/newgrf_town.cpp index 00fcf76b63..35581f940e 100644 --- a/src/newgrf_town.cpp +++ b/src/newgrf_town.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,7 +31,7 @@ /* Check the persistent storage for the GrfID stored in register 100h. */ uint32 grfid = GetRegister(0x100); if (grfid == 0xFFFFFFFF) { - if (this->ro.grffile == NULL) return 0; + if (this->ro.grffile == nullptr) return 0; grfid = this->ro.grffile->grfid; } @@ -123,9 +121,9 @@ { if (this->readonly) return; - assert(this->t != NULL); + assert(this->t != nullptr); /* We can't store anything if the caller has no #GRFFile. */ - if (this->ro.grffile == NULL) return; + if (this->ro.grffile == nullptr) return; /* Check the persistent storage for the GrfID stored in register 100h. */ uint32 grfid = GetRegister(0x100); diff --git a/src/newgrf_town.h b/src/newgrf_town.h index 7c4fb5395c..c5970d2976 100644 --- a/src/newgrf_town.h +++ b/src/newgrf_town.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. @@ -46,7 +44,7 @@ struct TownResolverObject : public ResolverObject { TownResolverObject(const struct GRFFile *grffile, Town *t, bool readonly); - /* virtual */ ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) + ScopeResolver *GetScope(VarSpriteGroupScope scope = VSG_SCOPE_SELF, byte relative = 0) override { switch (scope) { case VSG_SCOPE_SELF: return &town_scope; diff --git a/src/newgrf_townname.cpp b/src/newgrf_townname.cpp index 42aae3f147..207114f61d 100644 --- a/src/newgrf_townname.cpp +++ b/src/newgrf_townname.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. @@ -21,21 +19,21 @@ #include "safeguards.h" -static GRFTownName *_grf_townnames = NULL; +static GRFTownName *_grf_townnames = nullptr; GRFTownName *GetGRFTownName(uint32 grfid) { GRFTownName *t = _grf_townnames; - for (; t != NULL; t = t->next) { + for (; t != nullptr; t = t->next) { if (t->grfid == grfid) return t; } - return NULL; + return nullptr; } GRFTownName *AddGRFTownName(uint32 grfid) { GRFTownName *t = GetGRFTownName(grfid); - if (t == NULL) { + if (t == nullptr) { t = CallocT(1); t->grfid = grfid; t->next = _grf_townnames; @@ -47,9 +45,9 @@ GRFTownName *AddGRFTownName(uint32 grfid) void DelGRFTownName(uint32 grfid) { GRFTownName *t = _grf_townnames; - GRFTownName *p = NULL; - for (;t != NULL; p = t, t = t->next) if (t->grfid == grfid) break; - if (t != NULL) { + GRFTownName *p = nullptr; + for (;t != nullptr; p = t, t = t->next) if (t->grfid == grfid) break; + if (t != nullptr) { for (int i = 0; i < 128; i++) { for (int j = 0; j < t->nbparts[i]; j++) { for (int k = 0; k < t->partlist[i][j].partcount; k++) { @@ -59,7 +57,7 @@ void DelGRFTownName(uint32 grfid) } free(t->partlist[i]); } - if (p != NULL) { + if (p != nullptr) { p->next = t->next; } else { _grf_townnames = t->next; @@ -70,7 +68,7 @@ void DelGRFTownName(uint32 grfid) static char *RandomPart(char *buf, GRFTownName *t, uint32 seed, byte id, const char *last) { - assert(t != NULL); + assert(t != nullptr); for (int i = 0; i < t->nbparts[id]; i++) { byte count = t->partlist[id][i].bitcount; uint16 maxprob = t->partlist[id][i].maxprob; @@ -93,7 +91,7 @@ static char *RandomPart(char *buf, GRFTownName *t, uint32 seed, byte id, const c char *GRFTownNameGenerate(char *buf, uint32 grfid, uint16 gen, uint32 seed, const char *last) { strecpy(buf, "", last); - for (GRFTownName *t = _grf_townnames; t != NULL; t = t->next) { + for (GRFTownName *t = _grf_townnames; t != nullptr; t = t->next) { if (t->grfid == grfid) { assert(gen < t->nb_gen); buf = RandomPart(buf, t, seed, t->id[gen], last); @@ -106,9 +104,9 @@ char *GRFTownNameGenerate(char *buf, uint32 grfid, uint16 gen, uint32 seed, cons StringID *GetGRFTownNameList() { int nb_names = 0, n = 0; - for (GRFTownName *t = _grf_townnames; t != NULL; t = t->next) nb_names += t->nb_gen; + for (GRFTownName *t = _grf_townnames; t != nullptr; t = t->next) nb_names += t->nb_gen; StringID *list = MallocT(nb_names + 1); - for (GRFTownName *t = _grf_townnames; t != NULL; t = t->next) { + for (GRFTownName *t = _grf_townnames; t != nullptr; t = t->next) { for (int j = 0; j < t->nb_gen; j++) list[n++] = t->name[j]; } list[n] = INVALID_STRING_ID; @@ -117,12 +115,12 @@ StringID *GetGRFTownNameList() void CleanUpGRFTownNames() { - while (_grf_townnames != NULL) DelGRFTownName(_grf_townnames->grfid); + while (_grf_townnames != nullptr) DelGRFTownName(_grf_townnames->grfid); } uint32 GetGRFTownNameId(int gen) { - for (GRFTownName *t = _grf_townnames; t != NULL; t = t->next) { + for (GRFTownName *t = _grf_townnames; t != nullptr; t = t->next) { if (gen < t->nb_gen) return t->grfid; gen -= t->nb_gen; } @@ -132,7 +130,7 @@ uint32 GetGRFTownNameId(int gen) uint16 GetGRFTownNameType(int gen) { - for (GRFTownName *t = _grf_townnames; t != NULL; t = t->next) { + for (GRFTownName *t = _grf_townnames; t != nullptr; t = t->next) { if (gen < t->nb_gen) return gen; gen -= t->nb_gen; } diff --git a/src/newgrf_townname.h b/src/newgrf_townname.h index 0b1b389cbe..6406e74345 100644 --- a/src/newgrf_townname.h +++ b/src/newgrf_townname.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/news_func.h b/src/news_func.h index cd0862f348..352193f1ed 100644 --- a/src/news_func.h +++ b/src/news_func.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. @@ -17,7 +15,7 @@ #include "station_type.h" #include "industry_type.h" -void AddNewsItem(StringID string, NewsType type, NewsFlag flags, NewsReferenceType reftype1 = NR_NONE, uint32 ref1 = UINT32_MAX, NewsReferenceType reftype2 = NR_NONE, uint32 ref2 = UINT32_MAX, void *free_data = NULL); +void AddNewsItem(StringID string, NewsType type, NewsFlag flags, NewsReferenceType reftype1 = NR_NONE, uint32 ref1 = UINT32_MAX, NewsReferenceType reftype2 = NR_NONE, uint32 ref2 = UINT32_MAX, void *free_data = nullptr); static inline void AddCompanyNewsItem(StringID string, CompanyNewsInformation *cni) { @@ -44,7 +42,7 @@ static inline void AddVehicleAdviceNewsItem(StringID string, VehicleID vehicle) AddNewsItem(string, NT_ADVICE, NF_INCOLOUR | NF_SMALL | NF_VEHICLE_PARAM0, NR_VEHICLE, vehicle); } -static inline void AddTileNewsItem(StringID string, NewsType type, TileIndex tile, void *free_data = NULL) +static inline void AddTileNewsItem(StringID string, NewsType type, TileIndex tile, void *free_data = nullptr) { AddNewsItem(string, type, NF_NO_TRANSPARENT | NF_SHADE | NF_THIN, NR_TILE, tile, NR_NONE, UINT32_MAX, free_data); } diff --git a/src/news_gui.cpp b/src/news_gui.cpp index bd6d896466..33dddf14e9 100644 --- a/src/news_gui.cpp +++ b/src/news_gui.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. @@ -18,6 +16,7 @@ #include "vehicle_base.h" #include "vehicle_func.h" #include "vehicle_gui.h" +#include "roadveh.h" #include "station_base.h" #include "industry.h" #include "town.h" @@ -34,6 +33,7 @@ #include "company_base.h" #include "settings_internal.h" #include "guitimer_func.h" +#include "group_gui.h" #include "widgets/news_widget.h" @@ -41,23 +41,23 @@ #include "safeguards.h" -const NewsItem *_statusbar_news_item = NULL; +const NewsItem *_statusbar_news_item = nullptr; -static uint MIN_NEWS_AMOUNT = 30; ///< preferred minimum amount of news messages -static uint _total_news = 0; ///< current number of news items -NewsItem *_oldest_news = NULL; ///< head of news items queue -static NewsItem *_latest_news = NULL; ///< tail of news items queue +static uint MIN_NEWS_AMOUNT = 30; ///< preferred minimum amount of news messages +static uint _total_news = 0; ///< current number of news items +static NewsItem *_oldest_news = nullptr; ///< head of news items queue +NewsItem *_latest_news = nullptr; ///< tail of news items queue /** * Forced news item. * Users can force an item by accessing the history or "last message". * If the message being shown was forced by the user, a pointer is stored - * in _forced_news. Otherwise, \a _forced_news variable is NULL. + * in _forced_news. Otherwise, \a _forced_news variable is nullptr. */ -static const NewsItem *_forced_news = NULL; ///< item the user has asked for +static const NewsItem *_forced_news = nullptr; /** Current news item (last item shown regularly). */ -static const NewsItem *_current_news = NULL; +static const NewsItem *_current_news = nullptr; /** @@ -93,7 +93,7 @@ static const NWidgetPart _nested_normal_news_widgets[] = { }; static WindowDesc _normal_news_desc( - WDP_MANUAL, NULL, 0, 0, + WDP_MANUAL, nullptr, 0, 0, WC_NEWS_WINDOW, WC_NONE, 0, _nested_normal_news_widgets, lengthof(_nested_normal_news_widgets) @@ -120,7 +120,7 @@ static const NWidgetPart _nested_vehicle_news_widgets[] = { }; static WindowDesc _vehicle_news_desc( - WDP_MANUAL, NULL, 0, 0, + WDP_MANUAL, nullptr, 0, 0, WC_NEWS_WINDOW, WC_NONE, 0, _nested_vehicle_news_widgets, lengthof(_nested_vehicle_news_widgets) @@ -148,7 +148,7 @@ static const NWidgetPart _nested_company_news_widgets[] = { }; static WindowDesc _company_news_desc( - WDP_MANUAL, NULL, 0, 0, + WDP_MANUAL, nullptr, 0, 0, WC_NEWS_WINDOW, WC_NONE, 0, _nested_company_news_widgets, lengthof(_nested_company_news_widgets) @@ -171,7 +171,7 @@ static const NWidgetPart _nested_thin_news_widgets[] = { }; static WindowDesc _thin_news_desc( - WDP_MANUAL, NULL, 0, 0, + WDP_MANUAL, nullptr, 0, 0, WC_NEWS_WINDOW, WC_NONE, 0, _nested_thin_news_widgets, lengthof(_nested_thin_news_widgets) @@ -183,6 +183,8 @@ static const NWidgetPart _nested_small_news_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_LIGHT_BLUE, WID_N_CLOSEBOX), NWidget(WWT_EMPTY, COLOUR_LIGHT_BLUE, WID_N_CAPTION), SetFill(1, 0), + NWidget(WWT_TEXTBTN, COLOUR_LIGHT_BLUE, WID_N_SHOW_GROUP), SetMinimalSize(14, 11), SetResize(1, 0), + SetDataTip(STR_NULL /* filled in later */, STR_NEWS_SHOW_VEHICLE_GROUP_TOOLTIP), EndContainer(), /* Main part */ @@ -195,7 +197,7 @@ static const NWidgetPart _nested_small_news_widgets[] = { }; static WindowDesc _small_news_desc( - WDP_MANUAL, NULL, 0, 0, + WDP_MANUAL, nullptr, 0, 0, WC_NEWS_WINDOW, WC_NONE, 0, _nested_small_news_widgets, lengthof(_nested_small_news_widgets) @@ -251,8 +253,8 @@ NewsDisplay NewsTypeData::GetDisplay() const { uint index; const SettingDesc *sd = GetSettingFromName(this->name, &index); - assert(sd != NULL); - void *ptr = GetVariableAddress(NULL, &sd->save); + assert(sd != nullptr); + void *ptr = GetVariableAddress(nullptr, &sd->save); return (NewsDisplay)ReadValue(ptr, sd->save.conv); } @@ -269,7 +271,7 @@ struct NewsWindow : Window { { NewsWindow::duration = 16650; const Window *w = FindWindowByClass(WC_SEND_NETWORK_MSG); - this->chat_height = (w != NULL) ? w->height : 0; + this->chat_height = (w != nullptr) ? w->height : 0; this->status_height = FindWindowById(WC_STATUS_BAR, 0)->height; this->flags |= WF_DISABLE_VP_SCROLL; @@ -281,11 +283,32 @@ struct NewsWindow : Window { /* For company news with a face we have a separate headline in param[0] */ if (desc == &_company_news_desc) this->GetWidget(WID_N_TITLE)->widget_data = this->ni->params[0]; + NWidgetCore *nwid = this->GetWidget(WID_N_SHOW_GROUP); + if (ni->reftype1 == NR_VEHICLE && nwid != nullptr) { + const Vehicle *v = Vehicle::Get(ni->ref1); + switch (v->type) { + case VEH_TRAIN: + nwid->widget_data = STR_TRAIN; + break; + case VEH_ROAD: + nwid->widget_data = RoadVehicle::From(v)->IsBus() ? STR_BUS : STR_LORRY; + break; + case VEH_SHIP: + nwid->widget_data = STR_SHIP; + break; + case VEH_AIRCRAFT: + nwid->widget_data = STR_PLANE; + break; + default: + break; // Do nothing + } + } + this->FinishInitNested(0); /* Initialize viewport if it exists. */ NWidgetViewport *nvp = this->GetWidget(WID_N_VIEWPORT); - if (nvp != NULL) { + if (nvp != nullptr) { nvp->InitializeViewport(this, ni->reftype1 == NR_VEHICLE ? 0x80000000 | ni->ref1 : GetReferenceTile(ni->reftype1, ni->ref1), ZOOM_LVL_NEWS); if (this->ni->flags & NF_NO_TRANSPARENT) nvp->disp_flags |= ND_NO_TRANSPARENCY; if ((this->ni->flags & NF_INCOLOUR) == 0) { @@ -308,13 +331,13 @@ struct NewsWindow : Window { GfxFillRect(r.left, r.bottom, r.right, r.bottom, PC_BLACK); } - virtual Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number) + Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number) override { Point pt = { 0, _screen.height }; return pt; } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { StringID str = STR_NULL; switch (widget) { @@ -331,6 +354,11 @@ struct NewsWindow : Window { *size = maxdim(*size, GetSpriteSize(SPR_GRADIENT)); break; + case WID_N_MGR_NAME: + SetDParamStr(0, static_cast(this->ni->free_data)->president_name); + str = STR_JUST_RAW_STRING; + break; + case WID_N_MESSAGE: size->width = GetMinSizing(NWST_WINDOW_LENGTH, size->width); CopyInDParam(0, this->ni->params, lengthof(this->ni->params)); @@ -352,6 +380,24 @@ struct NewsWindow : Window { str = GetEngineInfoString(engine); break; } + + 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; + *size = d2; + } else { + /* Hide 'Show group window' button if this news is not about a vehicle. */ + size->width = 0; + size->height = 0; + resize->width = 0; + resize->height = 0; + fill->width = 0; + fill->height = 0; + } + return; + default: return; // Do nothing } @@ -366,12 +412,12 @@ struct NewsWindow : Window { *size = maxdim(*size, d); } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { if (widget == WID_N_DATE) SetDParam(0, this->ni->date); } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { switch (widget) { case WID_N_CAPTION: @@ -428,13 +474,13 @@ struct NewsWindow : Window { } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_N_CLOSEBOX: NewsWindow::duration = 0; delete this; - _forced_news = NULL; + _forced_news = nullptr; break; case WID_N_CAPTION: @@ -447,6 +493,12 @@ struct NewsWindow : Window { case WID_N_VIEWPORT: break; // Ignore clicks + case WID_N_SHOW_GROUP: + if (this->ni->reftype1 == NR_VEHICLE) { + const Vehicle *v = Vehicle::Get(this->ni->ref1); + ShowCompanyGroupForVehicle(v); + } + break; default: if (this->ni->reftype1 == NR_VEHICLE) { const Vehicle *v = Vehicle::Get(this->ni->ref1); @@ -467,7 +519,7 @@ struct NewsWindow : Window { } } - virtual EventState OnKeyPress(WChar key, uint16 keycode) + EventState OnKeyPress(WChar key, uint16 keycode) override { if (keycode == WKC_SPACE) { /* Don't continue. */ @@ -482,7 +534,7 @@ struct NewsWindow : Window { * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; /* The chatbar has notified us that is was either created or closed */ @@ -491,7 +543,7 @@ struct NewsWindow : Window { this->SetWindowTop(newtop); } - virtual void OnRealtimeTick(uint delta_ms) + void OnRealtimeTick(uint delta_ms) override { int count = this->timer.CountElapsed(delta_ms); if (count > 0) { @@ -516,7 +568,7 @@ private: int mintop = min(newtop, this->top); int maxtop = max(newtop, this->top); - if (this->viewport != NULL) this->viewport->top += newtop - this->top; + if (this->viewport != nullptr) this->viewport->top += newtop - this->top; this->top = newtop; SetDirtyBlocks(this->left, mintop, this->left + this->width, maxtop + this->height); @@ -573,54 +625,62 @@ static void ShowTicker(const NewsItem *ni) /** Initialize the news-items data structures */ void InitNewsItemStructs() { - for (NewsItem *ni = _oldest_news; ni != NULL; ) { + for (NewsItem *ni = _oldest_news; ni != nullptr; ) { NewsItem *next = ni->next; delete ni; ni = next; } _total_news = 0; - _oldest_news = NULL; - _latest_news = NULL; - _forced_news = NULL; - _current_news = NULL; - _statusbar_news_item = NULL; + _oldest_news = nullptr; + _latest_news = nullptr; + _forced_news = nullptr; + _current_news = nullptr; + _statusbar_news_item = nullptr; NewsWindow::duration = 0; } /** - * Are we ready to show another news item? - * Only if nothing is in the newsticker and no newspaper is displayed + * Are we ready to show another ticker item? + * Only if nothing is in the newsticker is displayed */ -static bool ReadyForNextItem() +static bool ReadyForNextTickerItem() { - const NewsItem *ni = _forced_news == NULL ? _current_news : _forced_news; - if (ni == NULL) return true; + const NewsItem *ni = _statusbar_news_item; + if (ni == nullptr) return true; /* Ticker message * Check if the status bar message is still being displayed? */ if (IsNewsTickerShown()) return false; - - /* neither newsticker nor newspaper are running */ - return (NewsWindow::duration <= 0 || FindWindowById(WC_NEWS_WINDOW, 0) == NULL); + return true; } -/** Move to the next news item */ -static void MoveToNextItem() +/** + * Are we ready to show another news item? + * Only if no newspaper is displayed + */ +static bool ReadyForNextNewsItem() +{ + const NewsItem *ni = _forced_news == nullptr ? _current_news : _forced_news; + if (ni == nullptr) return true; + + /* neither newsticker nor newspaper are running */ + return (NewsWindow::duration <= 0 || FindWindowById(WC_NEWS_WINDOW, 0) == nullptr); +} + +/** Move to the next ticker item */ +static void MoveToNextTickerItem() { InvalidateWindowData(WC_STATUS_BAR, 0, SBI_NEWS_DELETED); // invalidate the statusbar - DeleteWindowById(WC_NEWS_WINDOW, 0); // close the newspapers window if shown - _forced_news = NULL; - _statusbar_news_item = NULL; /* if we're not at the last item, then move on */ - if (_current_news != _latest_news) { - _current_news = (_current_news == NULL) ? _oldest_news : _current_news->next; - const NewsItem *ni = _current_news; + while (_statusbar_news_item != _latest_news) { + _statusbar_news_item = (_statusbar_news_item == nullptr) ? _oldest_news : _statusbar_news_item->next; + const NewsItem *ni = _statusbar_news_item; const NewsType type = ni->type; /* check the date, don't show too old items */ - if (_date - _news_type_data[type].age > ni->date) return; + if (_date - _news_type_data[type].age > ni->date) continue; switch (_news_type_data[type].GetDisplay()) { default: NOT_REACHED(); @@ -632,10 +692,41 @@ static void MoveToNextItem() ShowTicker(ni); break; + case ND_FULL: // Full - show newspaper, skipped here + continue; + } + return; + } +} + +/** Move to the next news item */ +static void MoveToNextNewsItem() +{ + DeleteWindowById(WC_NEWS_WINDOW, 0); // close the newspapers window if shown + _forced_news = nullptr; + + /* if we're not at the last item, then move on */ + while (_current_news != _latest_news) { + _current_news = (_current_news == nullptr) ? _oldest_news : _current_news->next; + const NewsItem *ni = _current_news; + const NewsType type = ni->type; + + /* check the date, don't show too old items */ + if (_date - _news_type_data[type].age > ni->date) continue; + + switch (_news_type_data[type].GetDisplay()) { + default: NOT_REACHED(); + case ND_OFF: // Off - show nothing only a small reminder in the status bar, skipped here + continue; + + case ND_SUMMARY: // Summary - show ticker, skipped here + continue; + case ND_FULL: // Full - show newspaper ShowNewspaper(ni); break; } + return; } } @@ -645,9 +736,9 @@ static void MoveToNextItem() * @param type news category * @param flags display flags for the news * @param reftype1 Type of ref1 - * @param ref1 Reference 1 to some object: Used for a possible viewport, scrolling after clicking on the news, and for deleteing the news when the object is deleted. + * @param ref1 Reference 1 to some object: Used for a possible viewport, scrolling after clicking on the news, and for deleting the news when the object is deleted. * @param reftype2 Type of ref2 - * @param ref2 Reference 2 to some object: Used for scrolling after clicking on the news, and for deleteing the news when the object is deleted. + * @param ref2 Reference 2 to some object: Used for scrolling after clicking on the news, and for deleting the news when the object is deleted. * @param free_data Pointer to data that must be freed once the news message is cleared * * @see NewsSubtype @@ -675,16 +766,16 @@ void AddNewsItem(StringID string, NewsType type, NewsFlag flags, NewsReferenceTy CopyOutDParam(ni->params, 0, lengthof(ni->params)); if (_total_news++ == 0) { - assert(_oldest_news == NULL); + assert(_oldest_news == nullptr); _oldest_news = ni; - ni->prev = NULL; + ni->prev = nullptr; } else { - assert(_latest_news->next == NULL); + assert(_latest_news->next == nullptr); _latest_news->next = ni; ni->prev = _latest_news; } - ni->next = NULL; + ni->next = nullptr; _latest_news = ni; SetWindowDirty(WC_MESSAGE_HISTORY, 0); @@ -758,14 +849,14 @@ CommandCost CmdCustomNewsItem(TileIndex tile, DoCommandFlag flags, uint32 p1, ui static void DeleteNewsItem(NewsItem *ni) { /* Delete the news from the news queue. */ - if (ni->prev != NULL) { + if (ni->prev != nullptr) { ni->prev->next = ni->next; } else { assert(_oldest_news == ni); _oldest_news = ni->next; } - if (ni->next != NULL) { + if (ni->next != nullptr) { ni->next->prev = ni->prev; } else { assert(_latest_news == ni); @@ -774,14 +865,23 @@ static void DeleteNewsItem(NewsItem *ni) _total_news--; - if (_forced_news == ni || _current_news == ni || _statusbar_news_item == ni) { + if (_forced_news == ni || _current_news == ni) { /* When we're the current news, go to the previous item first; * we just possibly made that the last news item. */ if (_current_news == ni) _current_news = ni->prev; /* About to remove the currently forced item (shown as newspapers) || - * about to remove the currently displayed item (newspapers, ticker, or just a reminder) */ - MoveToNextItem(); + * about to remove the currently displayed item (newspapers) */ + MoveToNextNewsItem(); + } + + if (_statusbar_news_item == ni) { + /* When we're the current news, go to the previous item first; + * we just possibly made that the last news item. */ + _statusbar_news_item = ni->prev; + + /* About to remove the currently displayed item (ticker, or just a reminder) */ + MoveToNextTickerItem(); } delete ni; @@ -799,7 +899,7 @@ void DeleteVehicleNews(VehicleID vid, StringID news) { NewsItem *ni = _oldest_news; - while (ni != NULL) { + while (ni != nullptr) { NewsItem *next = ni->next; if (((ni->reftype1 == NR_VEHICLE && ni->ref1 == vid) || (ni->reftype2 == NR_VEHICLE && ni->ref2 == vid)) && (news == INVALID_STRING_ID || ni->string_id == news)) { @@ -818,7 +918,7 @@ void DeleteStationNews(StationID sid) { NewsItem *ni = _oldest_news; - while (ni != NULL) { + while (ni != nullptr) { NewsItem *next = ni->next; if ((ni->reftype1 == NR_STATION && ni->ref1 == sid) || (ni->reftype2 == NR_STATION && ni->ref2 == sid)) { DeleteNewsItem(ni); @@ -835,7 +935,7 @@ void DeleteIndustryNews(IndustryID iid) { NewsItem *ni = _oldest_news; - while (ni != NULL) { + while (ni != nullptr) { NewsItem *next = ni->next; if ((ni->reftype1 == NR_INDUSTRY && ni->ref1 == iid) || (ni->reftype2 == NR_INDUSTRY && ni->ref2 == iid)) { DeleteNewsItem(ni); @@ -851,7 +951,7 @@ void DeleteInvalidEngineNews() { NewsItem *ni = _oldest_news; - while (ni != NULL) { + while (ni != nullptr) { NewsItem *next = ni->next; if ((ni->reftype1 == NR_ENGINE && (!Engine::IsValidID(ni->ref1) || !Engine::Get(ni->ref1)->IsEnabled())) || (ni->reftype2 == NR_ENGINE && (!Engine::IsValidID(ni->ref2) || !Engine::Get(ni->ref2)->IsEnabled()))) { @@ -864,7 +964,7 @@ void DeleteInvalidEngineNews() static void RemoveOldNewsItems() { NewsItem *next; - for (NewsItem *cur = _oldest_news; _total_news > MIN_NEWS_AMOUNT && cur != NULL; cur = next) { + for (NewsItem *cur = _oldest_news; _total_news > MIN_NEWS_AMOUNT && cur != nullptr; cur = next) { next = cur->next; if (_date - _news_type_data[cur->type].age * _settings_client.gui.news_message_timeout > cur->date) DeleteNewsItem(cur); } @@ -878,7 +978,7 @@ static void RemoveOldNewsItems() */ void ChangeVehicleNews(VehicleID from_index, VehicleID to_index) { - for (NewsItem *ni = _oldest_news; ni != NULL; ni = ni->next) { + for (NewsItem *ni = _oldest_news; ni != nullptr; ni = ni->next) { if (ni->reftype1 == NR_VEHICLE && ni->ref1 == from_index) ni->ref1 = to_index; if (ni->reftype2 == NR_VEHICLE && ni->ref2 == from_index) ni->ref2 = to_index; if (ni->flags & NF_VEHICLE_PARAM0 && ni->params[0] == from_index) ni->params[0] = to_index; @@ -893,7 +993,7 @@ void NewsLoop() /* There is no status bar, so no reason to show news; * especially important with the end game screen when * there is no status bar but possible news. */ - if (FindWindowById(WC_STATUS_BAR, 0) == NULL) return; + if (FindWindowById(WC_STATUS_BAR, 0) == nullptr) return; static byte _last_clean_month = 0; @@ -902,7 +1002,8 @@ void NewsLoop() _last_clean_month = _cur_month; } - if (ReadyForNextItem()) MoveToNextItem(); + if (ReadyForNextTickerItem()) MoveToNextTickerItem(); + if (ReadyForNextNewsItem()) MoveToNextNewsItem(); } /** Do a forced show of a specific message */ @@ -916,7 +1017,7 @@ static void ShowNewsMessage(const NewsItem *ni) /* setup forced news item */ _forced_news = ni; - if (_forced_news != NULL) { + if (_forced_news != nullptr) { DeleteWindowById(WC_NEWS_WINDOW, 0); ShowNewspaper(ni); } @@ -925,19 +1026,19 @@ static void ShowNewsMessage(const NewsItem *ni) /** Show previous news item */ void ShowLastNewsMessage() { - const NewsItem *ni = NULL; + const NewsItem *ni = nullptr; if (_total_news == 0) { return; - } else if (_forced_news == NULL) { + } else if (_forced_news == nullptr) { /* Not forced any news yet, show the current one, unless a news window is * open (which can only be the current one), then show the previous item */ - if (_current_news == NULL) { + if (_current_news == nullptr) { /* No news were shown yet resp. the last shown one was already deleted. * Threat this as if _forced_news reached _oldest_news; so, wrap around and start anew with the latest. */ ni = _latest_news; } else { const Window *w = FindWindowById(WC_NEWS_WINDOW, 0); - ni = (w == NULL || (_current_news == _oldest_news)) ? _current_news : _current_news->prev; + ni = (w == nullptr || (_current_news == _oldest_news)) ? _current_news : _current_news->prev; } } else if (_forced_news == _oldest_news) { /* We have reached the oldest news, start anew with the latest */ @@ -954,7 +1055,7 @@ void ShowLastNewsMessage() } ni = ni->prev; - if (ni == NULL) { + if (ni == nullptr) { if (wrap) break; /* We have reached the oldest news, start anew with the latest */ ni = _latest_news; @@ -1025,7 +1126,7 @@ struct MessageHistoryWindow : Window { this->OnInvalidateData(0); } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { if (widget == WID_MH_BACKGROUND) { this->line_height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL + 2); @@ -1041,13 +1142,13 @@ struct MessageHistoryWindow : Window { } } - virtual void OnPaint() + void OnPaint() override { this->OnInvalidateData(0); this->DrawWidgets(); } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { if (widget != WID_MH_BACKGROUND || _total_news == 0) return; @@ -1055,7 +1156,7 @@ struct MessageHistoryWindow : Window { NewsItem *ni = _latest_news; for (int n = this->vscroll->GetPosition(); n > 0; n--) { ni = ni->prev; - if (ni == NULL) return; + if (ni == nullptr) return; } /* Fill the widget with news items. */ @@ -1073,7 +1174,7 @@ struct MessageHistoryWindow : Window { y += this->line_height; ni = ni->prev; - if (ni == NULL) return; + if (ni == nullptr) return; } } @@ -1082,28 +1183,28 @@ struct MessageHistoryWindow : Window { * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; this->vscroll->SetCount(_total_news); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { if (widget == WID_MH_BACKGROUND) { NewsItem *ni = _latest_news; - if (ni == NULL) return; + if (ni == nullptr) return; for (int n = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_MH_BACKGROUND, WD_FRAMERECT_TOP, this->line_height); n > 0; n--) { ni = ni->prev; - if (ni == NULL) return; + if (ni == nullptr) return; } ShowNewsMessage(ni); } } - virtual void OnResize() + void OnResize() override { this->vscroll->SetCapacityFromWidget(this, WID_MH_BACKGROUND); } diff --git a/src/news_gui.h b/src/news_gui.h index 0f42c68c6c..e6f4bb38bc 100644 --- a/src/news_gui.h +++ b/src/news_gui.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. @@ -17,6 +15,6 @@ void ShowLastNewsMessage(); void ShowMessageHistory(); -extern NewsItem *_oldest_news; +extern NewsItem *_latest_news; #endif /* NEWS_GUI_H */ diff --git a/src/news_type.h b/src/news_type.h index cad15ecbef..1929804e4b 100644 --- a/src/news_type.h +++ b/src/news_type.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. @@ -128,8 +126,8 @@ struct NewsItem { NewsReferenceType reftype1; ///< Type of ref1 NewsReferenceType reftype2; ///< Type of ref2 - uint32 ref1; ///< Reference 1 to some object: Used for a possible viewport, scrolling after clicking on the news, and for deleteing the news when the object is deleted. - uint32 ref2; ///< Reference 2 to some object: Used for scrolling after clicking on the news, and for deleteing the news when the object is deleted. + uint32 ref1; ///< Reference 1 to some object: Used for a possible viewport, scrolling after clicking on the news, and for deleting the news when the object is deleted. + uint32 ref2; ///< Reference 2 to some object: Used for scrolling after clicking on the news, and for deleting the news when the object is deleted. void *free_data; ///< Data to be freed when the news item has reached its end. @@ -155,7 +153,7 @@ struct CompanyNewsInformation { uint32 face; ///< The face of the president byte colour; ///< The colour related to the company - void FillData(const struct Company *c, const struct Company *other = NULL); + void FillData(const struct Company *c, const struct Company *other = nullptr); }; #endif /* NEWS_TYPE_H */ diff --git a/src/object.h b/src/object.h index 0ab92d3769..e3f0c84ff5 100644 --- a/src/object.h +++ b/src/object.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. @@ -18,7 +16,7 @@ void UpdateCompanyHQ(TileIndex tile, uint score); -void BuildObject(ObjectType type, TileIndex tile, CompanyID owner = OWNER_NONE, struct Town *town = NULL, uint8 view = 0); +void BuildObject(ObjectType type, TileIndex tile, CompanyID owner = OWNER_NONE, struct Town *town = nullptr, uint8 view = 0); void ShowBuildObjectPicker(); diff --git a/src/object_base.h b/src/object_base.h index 47e5a7f94c..a468a01ee9 100644 --- a/src/object_base.h +++ b/src/object_base.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. @@ -80,9 +78,6 @@ protected: static uint16 counts[NUM_OBJECTS]; ///< Number of objects per type ingame }; -#define FOR_ALL_OBJECTS_FROM(var, start) FOR_ALL_ITEMS_FROM(Object, object_index, var, start) -#define FOR_ALL_OBJECTS(var) FOR_ALL_OBJECTS_FROM(var, 0) - /** * Keeps track of removed objects during execution/testruns of commands. */ @@ -92,6 +87,6 @@ struct ClearedObjectArea { }; ClearedObjectArea *FindClearedObject(TileIndex tile); -extern SmallVector _cleared_object_areas; +extern std::vector _cleared_object_areas; #endif /* OBJECT_BASE_H */ diff --git a/src/object_cmd.cpp b/src/object_cmd.cpp index 9f03813dfb..3fb61d647e 100644 --- a/src/object_cmd.cpp +++ b/src/object_cmd.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. @@ -90,7 +88,7 @@ void BuildObject(ObjectType type, TileIndex tile, CompanyID owner, Town *town, u Object *o = new Object(); o->type = type; o->location = ta; - o->town = town == NULL ? CalcClosestTownFromTile(tile) : town; + o->town = town == nullptr ? CalcClosestTownFromTile(tile) : town; o->build_date = _date; o->view = view; @@ -114,7 +112,7 @@ void BuildObject(ObjectType type, TileIndex tile, CompanyID owner, Town *town, u } } - assert(o->town != NULL); + assert(o->town != nullptr); TILE_AREA_LOOP(t, ta) { WaterClass wc = (IsWaterTile(t) ? GetWaterClass(t) : WATER_CLASS_INVALID); @@ -158,12 +156,11 @@ void UpdateCompanyHQ(TileIndex tile, uint score) { if (tile == INVALID_TILE) return; - byte val; - (val = 0, score < 170) || - (val++, score < 350) || - (val++, score < 520) || - (val++, score < 720) || - (val++, true); + byte val = 0; + if (score >= 170) val++; + if (score >= 350) val++; + if (score >= 520) val++; + if (score >= 720) val++; while (GetCompanyHQSize(tile) < val) { IncreaseCompanyHQSize(tile); @@ -176,8 +173,7 @@ void UpdateCompanyHQ(TileIndex tile, uint score) */ void UpdateObjectColours(const Company *c) { - Object *obj; - FOR_ALL_OBJECTS(obj) { + for (Object *obj : Object::Iterate()) { Owner owner = GetTileOwner(obj->location.tile); /* Not the current owner, so colour doesn't change. */ if (owner != c->index) continue; @@ -264,7 +260,7 @@ CommandCost CmdBuildObject(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 uint16 callback = CALLBACK_FAILED; if (HasBit(spec->callback_mask, CBM_OBJ_SLOPE_CHECK)) { TileIndex diff = t - tile; - callback = GetObjectCallback(CBID_OBJECT_LAND_SLOPE_CHECK, GetTileSlope(t), TileY(diff) << 4 | TileX(diff), spec, NULL, t, view); + callback = GetObjectCallback(CBID_OBJECT_LAND_SLOPE_CHECK, GetTileSlope(t), TileY(diff) << 4 | TileX(diff), spec, nullptr, t, view); } if (callback == CALLBACK_FAILED) { @@ -343,7 +339,7 @@ CommandCost CmdBuildObject(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 } if (flags & DC_EXEC) { - BuildObject(type, tile, _current_company, NULL, view); + BuildObject(type, tile, _current_company, nullptr, view); /* Make sure the HQ starts at the right size. */ if (type == OBJECT_HQ) UpdateCompanyHQ(tile, hq_score); @@ -367,7 +363,7 @@ static void DrawTile_Object(TileInfo *ti) if ((spec->flags & OBJECT_FLAG_HAS_NO_FOUNDATION) == 0) DrawFoundation(ti, GetFoundation_Object(ti->tile, ti->tileh)); if (type < NEW_OBJECT_OFFSET) { - const DrawTileSprites *dts = NULL; + const DrawTileSprites *dts = nullptr; Owner to = GetTileOwner(ti->tile); PaletteID palette = to == OWNER_NONE ? PAL_NONE : COMPANY_SPRITE_COLOUR(to); @@ -443,23 +439,22 @@ static void ReallyClearObjectTile(Object *o) delete o; } -SmallVector _cleared_object_areas; +std::vector _cleared_object_areas; /** * Find the entry in _cleared_object_areas which occupies a certain tile. * @param tile Tile of interest - * @return Occupying entry, or NULL if none + * @return Occupying entry, or nullptr if none */ ClearedObjectArea *FindClearedObject(TileIndex tile) { TileArea ta = TileArea(tile, 1, 1); - const ClearedObjectArea *end = _cleared_object_areas.End(); - for (ClearedObjectArea *coa = _cleared_object_areas.Begin(); coa != end; coa++) { - if (coa->area.Intersects(ta)) return coa; + for (ClearedObjectArea &coa : _cleared_object_areas) { + if (coa.area.Intersects(ta)) return &coa; } - return NULL; + return nullptr; } static CommandCost ClearTile_Object(TileIndex tile, DoCommandFlag flags) @@ -531,9 +526,7 @@ static CommandCost ClearTile_Object(TileIndex tile, DoCommandFlag flags) break; } - ClearedObjectArea *cleared_area = _cleared_object_areas.Append(); - cleared_area->first_tile = tile; - cleared_area->area = ta; + _cleared_object_areas.push_back({tile, ta}); if (flags & DC_EXEC) ReallyClearObjectTile(o); @@ -563,6 +556,14 @@ static void AddAcceptedCargo_Object(TileIndex tile, CargoArray &acceptance, Carg SetBit(*always_accepted, CT_MAIL); } +static void AddProducedCargo_Object(TileIndex tile, CargoArray &produced) +{ + if (!IsObjectType(tile, OBJECT_HQ)) return; + + produced[CT_PASSENGERS]++; + produced[CT_MAIL]++; +} + static void GetTileDesc_Object(TileIndex tile, TileDesc *td) { @@ -571,7 +572,7 @@ static void GetTileDesc_Object(TileIndex tile, TileDesc *td) td->owner[0] = GetTileOwner(tile); td->build_date = Object::GetByTile(tile)->build_date; - if (spec->grf_prop.grffile != NULL) { + if (spec->grf_prop.grffile != nullptr) { td->grf = GetGRFConfig(spec->grf_prop.grffile->grfid)->GetName(); } } @@ -698,7 +699,7 @@ static bool TryBuildTransmitter() int h; if (IsTileType(tile, MP_CLEAR) && IsTileFlat(tile, &h) && h >= 4 && !IsBridgeAbove(tile)) { TileIndex t = tile; - if (CircularTileSearch(&t, 9, HasTransmitter, NULL)) return false; + if (CircularTileSearch(&t, 9, HasTransmitter, nullptr)) return false; BuildObject(OBJECT_TRANSMITTER, tile); return true; @@ -758,7 +759,7 @@ void GenerateObjects() default: uint8 view = RandomRange(spec->views); - if (CmdBuildObject(RandomTile(), DC_EXEC | DC_AUTO | DC_NO_TEST_TOWN_RATING | DC_NO_MODIFY_TOWN_RATING, i, view, NULL).Succeeded()) amount--; + if (CmdBuildObject(RandomTile(), DC_EXEC | DC_AUTO | DC_NO_TEST_TOWN_RATING | DC_NO_MODIFY_TOWN_RATING, i, view, nullptr).Succeeded()) amount--; break; } } @@ -772,9 +773,10 @@ static void ChangeTileOwner_Object(TileIndex tile, Owner old_owner, Owner new_ow bool do_clear = false; - if (IsObjectType(tile, OBJECT_OWNED_LAND) && new_owner != INVALID_OWNER) { + ObjectType type = GetObjectType(tile); + if ((type == OBJECT_OWNED_LAND || type >= NEW_OBJECT_OFFSET) && new_owner != INVALID_OWNER) { SetTileOwner(tile, new_owner); - } else if (IsObjectType(tile, OBJECT_STATUE)) { + } else if (type == OBJECT_STATUE) { Town *t = Object::GetByTile(tile)->town; ClrBit(t->statues, old_owner); if (new_owner != INVALID_OWNER && !HasBit(t->statues, new_owner)) { @@ -792,7 +794,7 @@ static void ChangeTileOwner_Object(TileIndex tile, Owner old_owner, Owner new_ow if (do_clear) { ReallyClearObjectTile(Object::GetByTile(tile)); - /* When clearing objects, they may turn into canal, which may require transfering ownership. */ + /* When clearing objects, they may turn into canal, which may require transferring ownership. */ ChangeTileOwner(tile, old_owner, new_owner); } } @@ -843,8 +845,8 @@ extern const TileTypeProcs _tile_type_object_procs = { AnimateTile_Object, // animate_tile_proc TileLoop_Object, // tile_loop_proc ChangeTileOwner_Object, // change_tile_owner_proc - NULL, // add_produced_cargo_proc - NULL, // vehicle_enter_tile_proc + AddProducedCargo_Object, // add_produced_cargo_proc + nullptr, // vehicle_enter_tile_proc GetFoundation_Object, // get_foundation_proc TerraformTile_Object, // terraform_tile_proc }; diff --git a/src/object_gui.cpp b/src/object_gui.cpp index af9e688857..278976445b 100644 --- a/src/object_gui.cpp +++ b/src/object_gui.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. @@ -99,18 +97,18 @@ public: this->GetWidget(WID_BO_OBJECT_MATRIX)->SetCount(4); } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { switch (widget) { case WID_BO_OBJECT_NAME: { const ObjectSpec *spec = ObjectClass::Get(_selected_object_class)->GetSpec(_selected_object_index); - SetDParam(0, spec != NULL ? spec->name : STR_EMPTY); + SetDParam(0, spec != nullptr ? spec->name : STR_EMPTY); break; } case WID_BO_OBJECT_SIZE: { const ObjectSpec *spec = ObjectClass::Get(_selected_object_class)->GetSpec(_selected_object_index); - int size = spec == NULL ? 0 : spec->size; + int size = spec == nullptr ? 0 : spec->size; SetDParam(0, GB(size, HasBit(_selected_object_view, 0) ? 4 : 0, 4)); SetDParam(1, GB(size, HasBit(_selected_object_view, 0) ? 0 : 4, 4)); break; @@ -120,7 +118,7 @@ public: } } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_BO_CLASS_LIST: { @@ -145,7 +143,7 @@ public: case WID_BO_OBJECT_MATRIX: { /* Get the right amount of buttons based on the current spec. */ const ObjectSpec *spec = ObjectClass::Get(_selected_object_class)->GetSpec(_selected_object_index); - if (spec != NULL) { + if (spec != nullptr) { if (spec->views >= 2) size->width += resize->width; if (spec->views >= 4) size->height += resize->height; } @@ -185,7 +183,7 @@ public: /* Get the right size for the single widget based on the current spec. */ const ObjectSpec *spec = ObjectClass::Get(_selected_object_class)->GetSpec(_selected_object_index); - if (spec != NULL) { + if (spec != nullptr) { if (spec->views >= 2) size->width = size->width / 2 - 1; if (spec->views >= 4) size->height = size->height / 2 - 1; } @@ -210,7 +208,7 @@ public: } } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { switch (GB(widget, 0, 16)) { case WID_BO_CLASS_LIST: { @@ -229,7 +227,7 @@ public: case WID_BO_OBJECT_SPRITE: { const ObjectSpec *spec = ObjectClass::Get(_selected_object_class)->GetSpec(_selected_object_index); - if (spec == NULL) break; + if (spec == nullptr) break; /* Height of the selection matrix. * Depending on the number of views, the matrix has a 1x1, 1x2, 2x1 or 2x2 layout. To make the previews @@ -243,7 +241,7 @@ public: 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 (spec->grf_prop.grffile == NULL) { + 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); @@ -260,7 +258,7 @@ public: int obj_index = objclass->GetIndexFromUI(GB(widget, 16, 16)); if (obj_index < 0) break; const ObjectSpec *spec = objclass->GetSpec(obj_index); - if (spec == NULL) break; + if (spec == nullptr) break; if (!spec->IsAvailable()) { GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_BLACK, FILLRECT_CHECKER); @@ -270,7 +268,7 @@ public: 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 (spec->grf_prop.grffile == NULL) { + 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); @@ -285,11 +283,11 @@ public: case WID_BO_INFO: { const ObjectSpec *spec = ObjectClass::Get(_selected_object_class)->GetSpec(_selected_object_index); - if (spec == NULL) break; + if (spec == nullptr) break; /* Get the extra message for the GUI */ if (HasBit(spec->callback_mask, CBM_OBJ_FUND_MORE_TEXT)) { - uint16 callback_res = GetObjectCallback(CBID_OBJECT_FUND_MORE_TEXT, 0, 0, spec, NULL, INVALID_TILE, _selected_object_view); + uint16 callback_res = GetObjectCallback(CBID_OBJECT_FUND_MORE_TEXT, 0, 0, spec, nullptr, INVALID_TILE, _selected_object_view); if (callback_res != CALLBACK_FAILED && callback_res != 0x400) { if (callback_res > 0x400) { ErrorUnknownCallbackResult(spec->grf_prop.grffile->grfid, CBID_OBJECT_FUND_MORE_TEXT, callback_res); @@ -382,12 +380,12 @@ public: this->SetDirty(); } - virtual void OnResize() + void OnResize() override { this->vscroll->SetCapacityFromWidget(this, WID_BO_CLASS_LIST); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (GB(widget, 0, 16)) { case WID_BO_CLASS_LIST: { @@ -415,13 +413,13 @@ public: } } - virtual void OnPlaceObject(Point pt, TileIndex tile) + void OnPlaceObject(Point pt, TileIndex tile) override { DoCommandP(tile, ObjectClass::Get(_selected_object_class)->GetSpec(_selected_object_index)->Index(), _selected_object_view, CMD_BUILD_OBJECT | CMD_MSG(STR_ERROR_CAN_T_BUILD_OBJECT), CcTerraform); } - virtual void OnPlaceObjectAbort() + void OnPlaceObjectAbort() override { this->UpdateButtons(_selected_object_class, -1, _selected_object_view); } diff --git a/src/object_map.h b/src/object_map.h index 1aaf984345..d86bf0690e 100644 --- a/src/object_map.h +++ b/src/object_map.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/object_type.h b/src/object_type.h index 4ead576f38..52aedc6540 100644 --- a/src/object_type.h +++ b/src/object_type.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/openttd.cpp b/src/openttd.cpp index 3d5e51b5a6..01d6f8ff6a 100644 --- a/src/openttd.cpp +++ b/src/openttd.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. @@ -53,6 +51,7 @@ #include "engine_func.h" #include "core/random_func.hpp" #include "rail_gui.h" +#include "road_gui.h" #include "core/backup_type.hpp" #include "hotkeys.h" #include "newgrf.h" @@ -62,12 +61,14 @@ #include "town.h" #include "subsidy_func.h" #include "gfx_layout.h" +#include "viewport_func.h" #include "viewport_sprite_sorter.h" #include "framerate_type.h" #include "linkgraph/linkgraphschedule.h" #include +#include #include "safeguards.h" #ifdef __ANDROID__ @@ -106,7 +107,7 @@ void CDECL usererror(const char *s, ...) va_end(va); ShowOSErrorBox(buf, false); - if (VideoDriver::GetInstance() != NULL) VideoDriver::GetInstance()->Stop(); + if (VideoDriver::GetInstance() != nullptr) VideoDriver::GetInstance()->Stop(); exit(1); } @@ -125,7 +126,7 @@ void CDECL error(const char *s, ...) vseprintf(buf, lastof(buf), s, va); va_end(va); - if (VideoDriver::GetInstance() == NULL || VideoDriver::GetInstance()->HasGUI()) { + if (VideoDriver::GetInstance() == nullptr || VideoDriver::GetInstance()->HasGUI()) { ShowOSErrorBox(buf, true); } @@ -172,16 +173,14 @@ static void ShowHelp() " -e = Start Editor\n" " -g [savegame] = Start new/save game immediately\n" " -G seed = Set random seed\n" -#if defined(ENABLE_NETWORK) " -n [ip:port#company]= Join network game\n" " -p password = Password to join server\n" " -P password = Password to join company\n" " -D [ip][:port] = Start dedicated server\n" " -l ip[:port] = Redirect DEBUG()\n" -#if !defined(__MORPHOS__) && !defined(__AMIGA__) && !defined(_WIN32) +#if !defined(_WIN32) " -f = Fork into the background (dedicated only)\n" #endif -#endif /* ENABLE_NETWORK */ " -I graphics_set = Force the graphics set (see below)\n" " -S sounds_set = Force the sounds set (see below)\n" " -M music_set = Force the music set (see below)\n" @@ -251,7 +250,7 @@ static void WriteSavegameInfo(const char *name) p = strecpy(p, "NewGRFs:\n", lastof(buf)); if (_load_check_data.HasNewGrfs()) { - for (GRFConfig *c = _load_check_data.grfconfig; c != NULL; c = c->next) { + for (GRFConfig *c = _load_check_data.grfconfig; c != nullptr; c = c->next) { char md5sum[33]; md5sumToString(md5sum, lastof(md5sum), HasBit(c->flags, GCF_COMPATIBLE) ? c->original_md5sum : c->ident.md5sum); p += seprintf(p, lastof(buf), "%08X %s %s\n", c->ident.grfid, md5sum, c->filename); @@ -277,13 +276,13 @@ static void WriteSavegameInfo(const char *name) static void ParseResolution(Dimension *res, const char *s) { const char *t = strchr(s, 'x'); - if (t == NULL) { + if (t == nullptr) { ShowInfoF("Invalid resolution '%s'", s); return; } - res->width = max(strtoul(s, NULL, 0), 64UL); - res->height = max(strtoul(t + 1, NULL, 0), 64UL); + res->width = max(strtoul(s, nullptr, 0), 64UL); + res->height = max(strtoul(t + 1, nullptr, 0), 64UL); } @@ -308,9 +307,7 @@ static void ShutdownGame() /* Uninitialize variables that are allocated dynamically */ GamelogReset(); -#ifdef ENABLE_NETWORK free(_config_file); -#endif LinkGraphSchedule::Clear(); PoolBase::Clean(PT_ALL); @@ -347,6 +344,7 @@ static void LoadIntroGame(bool load_newgrfs = true) SetLocalCompany(COMPANY_FIRST); } + FixTitleGameZoom(); _pause_mode = PM_UNPAUSED; _cursor.fix_at = false; @@ -358,11 +356,11 @@ static void LoadIntroGame(bool load_newgrfs = true) void MakeNewgameSettingsLive() { for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) { - if (_settings_game.ai_config[c] != NULL) { + if (_settings_game.ai_config[c] != nullptr) { delete _settings_game.ai_config[c]; } } - if (_settings_game.game_config != NULL) { + if (_settings_game.game_config != nullptr) { delete _settings_game.game_config; } @@ -372,16 +370,16 @@ void MakeNewgameSettingsLive() _old_vds = _settings_client.company.vehicle; for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) { - _settings_game.ai_config[c] = NULL; - if (_settings_newgame.ai_config[c] != NULL) { + _settings_game.ai_config[c] = nullptr; + if (_settings_newgame.ai_config[c] != nullptr) { _settings_game.ai_config[c] = new AIConfig(_settings_newgame.ai_config[c]); if (!AIConfig::GetConfig(c, AIConfig::SSS_FORCE_GAME)->HasScript()) { - AIConfig::GetConfig(c, AIConfig::SSS_FORCE_GAME)->Change(NULL); + AIConfig::GetConfig(c, AIConfig::SSS_FORCE_GAME)->Change(nullptr); } } } - _settings_game.game_config = NULL; - if (_settings_newgame.game_config != NULL) { + _settings_game.game_config = nullptr; + if (_settings_newgame.game_config != nullptr) { _settings_game.game_config = new GameConfig(_settings_newgame.game_config); } } @@ -401,7 +399,7 @@ struct AfterNewGRFScan : NewGRFScanCallback { uint32 generation_seed; ///< Seed for the new game. char *dedicated_host; ///< Hostname for the dedicated server. uint16 dedicated_port; ///< Port for the dedicated server. - char *network_conn; ///< Information about the server to connect to, or NULL. + char *network_conn; ///< Information about the server to connect to, or nullptr. const char *join_server_password; ///< The password to join the server with. const char *join_company_password; ///< The password to join the company with. bool *save_config_ptr; ///< The pointer to the save config setting. @@ -414,8 +412,8 @@ struct AfterNewGRFScan : NewGRFScanCallback { */ AfterNewGRFScan(bool *save_config_ptr) : startyear(INVALID_YEAR), generation_seed(GENERATE_NEW_SEED), - dedicated_host(NULL), dedicated_port(0), network_conn(NULL), - join_server_password(NULL), join_company_password(NULL), + dedicated_host(nullptr), dedicated_port(0), network_conn(nullptr), + join_server_password(nullptr), join_company_password(nullptr), save_config_ptr(save_config_ptr), save_config(true) { /* Visual C++ 2015 fails compiling this line (AfterNewGRFScan::generation_seed undefined symbol) @@ -442,7 +440,6 @@ struct AfterNewGRFScan : NewGRFScanCallback { Game::Uninitialize(true); AI::Uninitialize(true); - CheckConfig(); LoadFromHighScore(); LoadHotkeysFromConfig(); WindowDesc::LoadFromConfig(); @@ -456,13 +453,11 @@ struct AfterNewGRFScan : NewGRFScanCallback { if (startyear != INVALID_YEAR) _settings_newgame.game_creation.starting_year = startyear; if (generation_seed != GENERATE_NEW_SEED) _settings_newgame.game_creation.generation_seed = generation_seed; -#if defined(ENABLE_NETWORK) - if (dedicated_host != NULL) { - _network_bind_list.Clear(); - *_network_bind_list.Append() = stredup(dedicated_host); + if (dedicated_host != nullptr) { + _network_bind_list.clear(); + _network_bind_list.emplace_back(dedicated_host); } if (dedicated_port != 0) _settings_client.network.server_port = dedicated_port; -#endif /* ENABLE_NETWORK */ /* initialize the ingame console */ IConsoleInit(); @@ -472,16 +467,15 @@ struct AfterNewGRFScan : NewGRFScanCallback { /* Make sure _settings is filled with _settings_newgame if we switch to a game directly */ if (_switch_mode != SM_NONE) MakeNewgameSettingsLive(); -#ifdef ENABLE_NETWORK - if (_network_available && network_conn != NULL) { - const char *port = NULL; - const char *company = NULL; + if (_network_available && network_conn != nullptr) { + const char *port = nullptr; + const char *company = nullptr; uint16 rport = NETWORK_DEFAULT_PORT; CompanyID join_as = COMPANY_NEW_COMPANY; ParseConnectionString(&company, &port, network_conn); - if (company != NULL) { + if (company != nullptr) { join_as = (CompanyID)atoi(company); if (join_as != COMPANY_SPECTATOR) { @@ -492,20 +486,19 @@ struct AfterNewGRFScan : NewGRFScanCallback { } } } - if (port != NULL) rport = atoi(port); + if (port != nullptr) rport = atoi(port); LoadIntroGame(); _switch_mode = SM_NONE; NetworkClientConnectGame(NetworkAddress(network_conn, rport), join_as, join_server_password, join_company_password); } -#endif /* ENABLE_NETWORK */ /* After the scan we're not used anymore. */ delete this; } }; -#if defined(UNIX) && !defined(__MORPHOS__) +#if defined(UNIX) extern void DedicatedFork(); #endif @@ -518,16 +511,14 @@ static const OptionData _options[] = { GETOPT_SHORT_VALUE('s'), GETOPT_SHORT_VALUE('v'), GETOPT_SHORT_VALUE('b'), -#if defined(ENABLE_NETWORK) GETOPT_SHORT_OPTVAL('D'), GETOPT_SHORT_OPTVAL('n'), GETOPT_SHORT_VALUE('l'), GETOPT_SHORT_VALUE('p'), GETOPT_SHORT_VALUE('P'), -#if !defined(__MORPHOS__) && !defined(__AMIGA__) && !defined(_WIN32) +#if !defined(_WIN32) GETOPT_SHORT_NOVAL('f'), #endif -#endif /* ENABLE_NETWORK */ GETOPT_SHORT_VALUE('r'), GETOPT_SHORT_VALUE('t'), GETOPT_SHORT_OPTVAL('d'), @@ -549,28 +540,29 @@ static const OptionData _options[] = { */ int openttd_main(int argc, char *argv[]) { - char *musicdriver = NULL; - char *sounddriver = NULL; - char *videodriver = NULL; - char *blitter = NULL; - char *graphics_set = NULL; - char *sounds_set = NULL; - char *music_set = NULL; + char *musicdriver = nullptr; + char *sounddriver = nullptr; + char *videodriver = nullptr; + char *blitter = nullptr; + char *graphics_set = nullptr; + char *sounds_set = nullptr; + char *music_set = nullptr; Dimension resolution = {0, 0}; /* AfterNewGRFScan sets save_config to true after scanning completed. */ bool save_config = false; AfterNewGRFScan *scanner = new AfterNewGRFScan(&save_config); -#if defined(ENABLE_NETWORK) bool dedicated = false; - char *debuglog_conn = NULL; + char *debuglog_conn = nullptr; extern bool _dedicated_forks; _dedicated_forks = false; -#endif /* ENABLE_NETWORK */ + + std::unique_lock modal_work_lock(_modal_progress_work_mutex, std::defer_lock); + std::unique_lock modal_paint_lock(_modal_progress_paint_mutex, std::defer_lock); _game_mode = GM_MENU; _switch_mode = SM_MENU; - _config_file = NULL; + _config_file = nullptr; GetOptData mgo(argc - 1, argv + 1, _options); int ret = 0; @@ -585,7 +577,6 @@ int openttd_main(int argc, char *argv[]) case 's': free(sounddriver); sounddriver = stredup(mgo.opt); break; case 'v': free(videodriver); videodriver = stredup(mgo.opt); break; case 'b': free(blitter); blitter = stredup(mgo.opt); break; -#if defined(ENABLE_NETWORK) case 'D': free(musicdriver); free(sounddriver); @@ -597,19 +588,19 @@ int openttd_main(int argc, char *argv[]) blitter = stredup("null"); dedicated = true; SetDebugString("net=6"); - if (mgo.opt != NULL) { + if (mgo.opt != nullptr) { /* Use the existing method for parsing (openttd -n). * However, we do ignore the #company part. */ - const char *temp = NULL; - const char *port = NULL; + const char *temp = nullptr; + const char *port = nullptr; ParseConnectionString(&temp, &port, mgo.opt); if (!StrEmpty(mgo.opt)) scanner->dedicated_host = mgo.opt; - if (port != NULL) scanner->dedicated_port = atoi(port); + if (port != nullptr) scanner->dedicated_port = atoi(port); } break; case 'f': _dedicated_forks = true; break; case 'n': - scanner->network_conn = mgo.opt; // optional IP parameter, NULL if unset + scanner->network_conn = mgo.opt; // optional IP parameter, nullptr if unset break; case 'l': debuglog_conn = mgo.opt; @@ -620,19 +611,18 @@ int openttd_main(int argc, char *argv[]) case 'P': scanner->join_company_password = mgo.opt; break; -#endif /* ENABLE_NETWORK */ case 'r': ParseResolution(&resolution, mgo.opt); break; case 't': scanner->startyear = atoi(mgo.opt); break; case 'd': { #if defined(_WIN32) CreateConsole(); #endif - if (mgo.opt != NULL) SetDebugString(mgo.opt); + if (mgo.opt != nullptr) SetDebugString(mgo.opt); break; } case 'e': _switch_mode = (_switch_mode == SM_LOAD_GAME || _switch_mode == SM_LOAD_SCENARIO ? SM_LOAD_SCENARIO : SM_EDITOR); break; case 'g': - if (mgo.opt != NULL) { + if (mgo.opt != nullptr) { _file_to_saveload.SetName(mgo.opt); bool is_scenario = _switch_mode == SM_EDITOR || _switch_mode == SM_LOAD_SCENARIO; _switch_mode = is_scenario ? SM_LOAD_SCENARIO : SM_LOAD_GAME; @@ -640,8 +630,8 @@ int openttd_main(int argc, char *argv[]) /* if the file doesn't exist or it is not a valid savegame, let the saveload code show an error */ const char *t = strrchr(_file_to_saveload.name, '.'); - if (t != NULL) { - FiosType ft = FiosGetSavegameListCallback(SLO_LOAD, _file_to_saveload.name, t, NULL, NULL); + if (t != nullptr) { + FiosType ft = FiosGetSavegameListCallback(SLO_LOAD, _file_to_saveload.name, t, nullptr, nullptr); if (ft != FIOS_TYPE_INVALID) _file_to_saveload.SetMode(ft); } @@ -682,7 +672,7 @@ int openttd_main(int argc, char *argv[]) goto exit_noshutdown; } - case 'G': scanner->generation_seed = strtoul(mgo.opt, NULL, 10); break; + case 'G': scanner->generation_seed = strtoul(mgo.opt, nullptr, 10); break; case 'c': free(_config_file); _config_file = stredup(mgo.opt); break; case 'x': scanner->save_config = false; break; case 'h': @@ -711,14 +701,12 @@ int openttd_main(int argc, char *argv[]) DeterminePaths(argv[0]); TarScanner::DoScan(TarScanner::BASESET); -#if defined(ENABLE_NETWORK) if (dedicated) DEBUG(net, 0, "Starting dedicated version %s", _openttd_revision); if (_dedicated_forks && !dedicated) _dedicated_forks = false; -#if defined(UNIX) && !defined(__MORPHOS__) +#if defined(UNIX) /* We must fork here, or we'll end up without some resources we need (like sockets) */ if (_dedicated_forks) DedicatedFork(); -#endif #endif LoadFromConfig(true); @@ -760,10 +748,10 @@ int openttd_main(int argc, char *argv[]) InitWindowSystem(); BaseGraphics::FindSets(); - if (graphics_set == NULL && BaseGraphics::ini_set != NULL) graphics_set = stredup(BaseGraphics::ini_set); + if (graphics_set == nullptr && BaseGraphics::ini_set != nullptr) graphics_set = stredup(BaseGraphics::ini_set); if (!BaseGraphics::SetSet(graphics_set)) { if (!StrEmpty(graphics_set)) { - BaseGraphics::SetSet(NULL); + BaseGraphics::SetSet(nullptr); ErrorMessageData msg(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_BASE_GRAPHICS_NOT_FOUND); msg.SetDParamStr(0, graphics_set); @@ -776,7 +764,7 @@ int openttd_main(int argc, char *argv[]) GfxInitPalettes(); DEBUG(misc, 1, "Loading blitter..."); - if (_ini_blitter != NULL) blitter = stredup(_ini_blitter); + if (_ini_blitter != nullptr) blitter = stredup(_ini_blitter); _blitter_autodetected = StrEmpty(blitter); /* Activate the initial blitter. * This is only some initial guess, after NewGRFs have been loaded SwitchNewGRFBlitter may switch to a different one. @@ -785,9 +773,9 @@ int openttd_main(int argc, char *argv[]) * - Use 8bpp blitter otherwise. */ if (!_blitter_autodetected || - (_support8bpp != S8BPP_NONE && (BaseGraphics::GetUsedSet() == NULL || BaseGraphics::GetUsedSet()->blitter == BLT_8BPP)) || - BlitterFactory::SelectBlitter("32bpp-anim") == NULL) { - if (BlitterFactory::SelectBlitter(blitter) == NULL) { + (_support8bpp != S8BPP_NONE && (BaseGraphics::GetUsedSet() == nullptr || BaseGraphics::GetUsedSet()->blitter == BLT_8BPP)) || + BlitterFactory::SelectBlitter("32bpp-anim") == nullptr) { + if (BlitterFactory::SelectBlitter(blitter) == nullptr) { StrEmpty(blitter) ? usererror("Failed to autoprobe blitter") : usererror("Failed to select requested blitter '%s'; does it exist?", blitter); @@ -795,7 +783,7 @@ int openttd_main(int argc, char *argv[]) } free(blitter); - if (videodriver == NULL && _ini_videodriver != NULL) videodriver = stredup(_ini_videodriver); + if (videodriver == nullptr && _ini_videodriver != nullptr) videodriver = stredup(_ini_videodriver); DriverFactoryBase::SelectDriver(videodriver, Driver::DT_VIDEO); free(videodriver); @@ -806,20 +794,18 @@ int openttd_main(int argc, char *argv[]) NetworkStartUp(); // initialize network-core -#if defined(ENABLE_NETWORK) - if (debuglog_conn != NULL && _network_available) { - const char *not_used = NULL; - const char *port = NULL; + if (debuglog_conn != nullptr && _network_available) { + const char *not_used = nullptr; + const char *port = nullptr; uint16 rport; rport = NETWORK_DEFAULT_DEBUGLOG_PORT; ParseConnectionString(¬_used, &port, debuglog_conn); - if (port != NULL) rport = atoi(port); + if (port != nullptr) rport = atoi(port); NetworkStartDebugLog(NetworkAddress(debuglog_conn, rport)); } -#endif /* ENABLE_NETWORK */ if (!HandleBootstrap()) { ShutdownGame(); @@ -833,10 +819,10 @@ int openttd_main(int argc, char *argv[]) InitializeScreenshotFormats(); BaseSounds::FindSets(); - if (sounds_set == NULL && BaseSounds::ini_set != NULL) sounds_set = stredup(BaseSounds::ini_set); + if (sounds_set == nullptr && BaseSounds::ini_set != nullptr) sounds_set = stredup(BaseSounds::ini_set); if (!BaseSounds::SetSet(sounds_set)) { - if (StrEmpty(sounds_set) || !BaseSounds::SetSet(NULL)) { - usererror("Failed to find a sounds set. Please acquire a sounds set for OpenTTD. See section 4.1 of README.md."); + if (StrEmpty(sounds_set) || !BaseSounds::SetSet(nullptr)) { + usererror("Failed to find a sounds set. Please acquire a sounds set for OpenTTD. See section 1.4 of README.md."); } else { ErrorMessageData msg(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_BASE_SOUNDS_NOT_FOUND); msg.SetDParamStr(0, sounds_set); @@ -846,10 +832,10 @@ int openttd_main(int argc, char *argv[]) free(sounds_set); BaseMusic::FindSets(); - if (music_set == NULL && BaseMusic::ini_set != NULL) music_set = stredup(BaseMusic::ini_set); + if (music_set == nullptr && BaseMusic::ini_set != nullptr) music_set = stredup(BaseMusic::ini_set); if (!BaseMusic::SetSet(music_set)) { - if (StrEmpty(music_set) || !BaseMusic::SetSet(NULL)) { - usererror("Failed to find a music set. Please acquire a music set for OpenTTD. See section 4.1 of README.md."); + if (StrEmpty(music_set) || !BaseMusic::SetSet(nullptr)) { + usererror("Failed to find a music set. Please acquire a music set for OpenTTD. See section 1.4 of README.md."); } else { ErrorMessageData msg(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_BASE_MUSIC_NOT_FOUND); msg.SetDParamStr(0, music_set); @@ -858,17 +844,23 @@ int openttd_main(int argc, char *argv[]) } free(music_set); - if (sounddriver == NULL && _ini_sounddriver != NULL) sounddriver = stredup(_ini_sounddriver); + if (sounddriver == nullptr && _ini_sounddriver != nullptr) sounddriver = stredup(_ini_sounddriver); DriverFactoryBase::SelectDriver(sounddriver, Driver::DT_SOUND); free(sounddriver); - if (musicdriver == NULL && _ini_musicdriver != NULL) musicdriver = stredup(_ini_musicdriver); + if (musicdriver == nullptr && _ini_musicdriver != nullptr) musicdriver = stredup(_ini_musicdriver); DriverFactoryBase::SelectDriver(musicdriver, Driver::DT_MUSIC); free(musicdriver); /* Take our initial lock on whatever we might want to do! */ - _modal_progress_paint_mutex->BeginCritical(); - _modal_progress_work_mutex->BeginCritical(); + try { + modal_work_lock.lock(); + modal_paint_lock.lock(); + } catch (const std::system_error&) { + /* If there is some error we assume that threads aren't usable on the system we run. */ + extern bool _use_threaded_modal_progress; // From progress.cpp + _use_threaded_modal_progress = false; + } GenerateWorld(GWM_EMPTY, 64, 64); // Make the viewport initialization happy WaitTillGeneratedWorld(); @@ -879,7 +871,7 @@ int openttd_main(int argc, char *argv[]) /* ScanNewGRFFiles now has control over the scanner. */ ScanNewGRFFiles(scanner); - scanner = NULL; + scanner = nullptr; try { VideoDriver::GetInstance()->MainLoop(); @@ -892,6 +884,7 @@ int openttd_main(int argc, char *argv[]) } WaitTillSaved(); + WaitTillGeneratedWorld(); // Make sure any generate world threads have been joined. /* only save config if we have to */ if (save_config) { @@ -938,12 +931,10 @@ exit_normal: delete scanner; -#ifdef ENABLE_NETWORK extern FILE *_log_fd; - if (_log_fd != NULL) { + if (_log_fd != nullptr) { fclose(_log_fd); } -#endif /* ENABLE_NETWORK */ return ret; } @@ -991,14 +982,13 @@ static void MakeNewGameDone() SetLocalCompany(COMPANY_FIRST); InitializeRailGUI(); + InitializeRoadGUI(); -#ifdef ENABLE_NETWORK /* We are the server, we start a new company (not dedicated), * so set the default password *if* needed. */ if (_network_server && !StrEmpty(_settings_client.network.default_company_pass)) { NetworkChangeCompanyPassword(_local_company, _settings_client.network.default_company_pass); } -#endif /* ENABLE_NETWORK */ if (_settings_client.gui.pause_on_newgame) DoCommandP(0, PM_PAUSED_NORMAL, 1, CMD_PAUSE); @@ -1040,21 +1030,20 @@ static void MakeNewEditorWorld() * @param fop mode of loading, always SLO_LOAD * @param newgm switch to this mode of loading fails due to some unknown error * @param subdir default directory to look for filename, set to 0 if not needed - * @param lf Load filter to use, if NULL: use filename + subdir. + * @param lf Load filter to use, if nullptr: use filename + subdir. */ -bool SafeLoad(const char *filename, SaveLoadOperation fop, DetailedFileType dft, GameMode newgm, Subdirectory subdir, struct LoadFilter *lf = NULL) +bool SafeLoad(const char *filename, SaveLoadOperation fop, DetailedFileType dft, GameMode newgm, Subdirectory subdir, struct LoadFilter *lf = nullptr) { assert(fop == SLO_LOAD); - assert(dft == DFT_GAME_FILE || (lf == NULL && dft == DFT_OLD_GAME_FILE)); + assert(dft == DFT_GAME_FILE || (lf == nullptr && dft == DFT_OLD_GAME_FILE)); GameMode ogm = _game_mode; _game_mode = newgm; - switch (lf == NULL ? SaveOrLoad(filename, fop, dft, subdir) : LoadWithFilter(lf)) { + switch (lf == nullptr ? SaveOrLoad(filename, fop, dft, subdir) : LoadWithFilter(lf)) { case SL_OK: return true; case SL_REINIT: -#ifdef ENABLE_NETWORK if (_network_dedicated) { /* * We need to reinit a network map... @@ -1070,7 +1059,6 @@ bool SafeLoad(const char *filename, SaveLoadOperation fop, DetailedFileType dft, /* We can't load the intro game as server, so disconnect first. */ NetworkDisconnect(); } -#endif /* ENABLE_NETWORK */ switch (ogm) { default: @@ -1087,7 +1075,6 @@ bool SafeLoad(const char *filename, SaveLoadOperation fop, DetailedFileType dft, void SwitchToMode(SwitchMode new_mode) { -#ifdef ENABLE_NETWORK /* If we are saving something, the network stays in his current state */ if (new_mode != SM_SAVE_GAME) { /* If the network is active, make it not-active */ @@ -1116,7 +1103,7 @@ void SwitchToMode(SwitchMode new_mode) } } } -#endif /* ENABLE_NETWORK */ + /* Make sure all AI controllers are gone at quitting game */ if (new_mode != SM_SAVE_GAME) AI::KillAll(); @@ -1127,11 +1114,9 @@ void SwitchToMode(SwitchMode new_mode) case SM_RESTARTGAME: // Restart --> 'Random game' with current settings case SM_NEWGAME: // New Game --> 'Random game' -#ifdef ENABLE_NETWORK if (_network_server) { seprintf(_network_game_info.map_name, lastof(_network_game_info.map_name), "Random Map"); } -#endif /* ENABLE_NETWORK */ MakeNewGame(false, new_mode == SM_NEWGAME); break; @@ -1154,21 +1139,17 @@ void SwitchToMode(SwitchMode new_mode) IConsoleCmdExec("exec scripts/game_start.scr 0"); /* Decrease pause counter (was increased from opening load dialog) */ DoCommandP(0, PM_PAUSED_SAVELOAD, 0, CMD_PAUSE); -#ifdef ENABLE_NETWORK if (_network_server) { seprintf(_network_game_info.map_name, lastof(_network_game_info.map_name), "%s (Loaded game)", _file_to_saveload.title); } -#endif /* ENABLE_NETWORK */ } break; } case SM_START_HEIGHTMAP: // Load a heightmap and start a new game from it -#ifdef ENABLE_NETWORK if (_network_server) { seprintf(_network_game_info.map_name, lastof(_network_game_info.map_name), "%s (Heightmap)", _file_to_saveload.title); } -#endif /* ENABLE_NETWORK */ MakeNewGame(true, true); break; @@ -1194,7 +1175,7 @@ void SwitchToMode(SwitchMode new_mode) case SM_MENU: // Switch to game intro menu LoadIntroGame(); - if (BaseSounds::ini_set == NULL && BaseSounds::GetUsedSet()->fallback) { + if (BaseSounds::ini_set == nullptr && BaseSounds::GetUsedSet()->fallback) { ShowErrorMessage(STR_WARNING_FALLBACK_SOUNDSET, INVALID_STRING_ID, WL_CRITICAL); BaseSounds::ini_set = stredup(BaseSounds::GetUsedSet()->name); } @@ -1258,10 +1239,9 @@ static void CheckCaches() if (_debug_desync_level <= 1) return; /* Check the town caches. */ - SmallVector old_town_caches; - Town *t; - FOR_ALL_TOWNS(t) { - MemCpyT(old_town_caches.Append(), &t->cache); + std::vector old_town_caches; + for (const Town *t : Town::Iterate()) { + old_town_caches.push_back(t->cache); } extern void RebuildTownCaches(); @@ -1269,32 +1249,30 @@ static void CheckCaches() RebuildSubsidisedSourceAndDestinationCache(); uint i = 0; - FOR_ALL_TOWNS(t) { - if (MemCmpT(old_town_caches.Get(i), &t->cache) != 0) { + for (Town *t : Town::Iterate()) { + if (MemCmpT(old_town_caches.data() + i, &t->cache) != 0) { DEBUG(desync, 2, "town cache mismatch: town %i", (int)t->index); } i++; } /* Check company infrastructure cache. */ - SmallVector old_infrastructure; - Company *c; - FOR_ALL_COMPANIES(c) MemCpyT(old_infrastructure.Append(), &c->infrastructure); + std::vector old_infrastructure; + for (const Company *c : Company::Iterate()) old_infrastructure.push_back(c->infrastructure); extern void AfterLoadCompanyStats(); AfterLoadCompanyStats(); i = 0; - FOR_ALL_COMPANIES(c) { - if (MemCmpT(old_infrastructure.Get(i), &c->infrastructure) != 0) { + for (const Company *c : Company::Iterate()) { + if (MemCmpT(old_infrastructure.data() + i, &c->infrastructure) != 0) { DEBUG(desync, 2, "infrastructure cache mismatch: company %i", (int)c->index); } i++; } /* Strict checking of the road stop cache entries */ - const RoadStop *rs; - FOR_ALL_ROADSTOPS(rs) { + for (const RoadStop *rs : RoadStop::Iterate()) { if (IsStandardRoadStopTile(rs->xy)) continue; assert(rs->GetEntry(DIAGDIR_NE) != rs->GetEntry(DIAGDIR_NW)); @@ -1302,13 +1280,12 @@ static void CheckCaches() rs->GetEntry(DIAGDIR_NW)->CheckIntegrity(rs); } - Vehicle *v; - FOR_ALL_VEHICLES(v) { + 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; - for (const Vehicle *u = v; u != NULL; u = u->Next()) length++; + for (const Vehicle *u = v; u != nullptr; u = u->Next()) length++; NewGRFCache *grf_cache = CallocT(length); VehicleCache *veh_cache = CallocT(length); @@ -1316,7 +1293,7 @@ static void CheckCaches() TrainCache *tra_cache = CallocT(length); length = 0; - for (const Vehicle *u = v; u != NULL; u = u->Next()) { + for (const Vehicle *u = v; u != nullptr; u = u->Next()) { FillNewGRFVehicleCache(u); grf_cache[length] = u->grf_cache; veh_cache[length] = u->vcache; @@ -1343,7 +1320,7 @@ static void CheckCaches() } length = 0; - for (const Vehicle *u = v; u != NULL; u = u->Next()) { + for (const Vehicle *u = v; u != nullptr; u = u->Next()) { FillNewGRFVehicleCache(u); if (memcmp(&grf_cache[length], &u->grf_cache, sizeof(NewGRFCache)) != 0) { DEBUG(desync, 2, "newgrf cache mismatch: type %i, vehicle %i, company %i, unit number %i, wagon %i", (int)v->type, v->index, (int)v->owner, v->unitnumber, length); @@ -1378,15 +1355,14 @@ static void CheckCaches() } /* Check whether the caches are still valid */ - FOR_ALL_VEHICLES(v) { + for (Vehicle *v : Vehicle::Iterate()) { byte buff[sizeof(VehicleCargoList)]; memcpy(buff, &v->cargo, sizeof(VehicleCargoList)); v->cargo.InvalidateCache(); assert(memcmp(&v->cargo, buff, sizeof(VehicleCargoList)) == 0); } - Station *st; - FOR_ALL_STATIONS(st) { + for (Station *st : Station::Iterate()) { for (CargoID c = 0; c < NUM_CARGO; c++) { byte buff[sizeof(StationCargoList)]; memcpy(buff, &st->goods[c].cargo, sizeof(StationCargoList)); @@ -1448,7 +1424,7 @@ void StateGameLoop() /* All these actions has to be done from OWNER_NONE * for multiplayer compatibility */ - Backup cur_company(_current_company, OWNER_NONE, FILE_LINE); + Backup cur_company(_current_company, OWNER_NONE, FILE_LINE); BasePersistentStorageArray::SwitchMode(PSM_ENTER_GAMELOOP); AnimateAnimatedTiles(); @@ -1504,10 +1480,8 @@ static void DoAutosave() void GameLoop() { if (_game_mode == GM_BOOTSTRAP) { -#ifdef ENABLE_NETWORK /* Check for UDP stuff */ if (_network_available) NetworkBackgroundLoop(); -#endif InputLoop(); return; } @@ -1530,7 +1504,6 @@ void GameLoop() IncreaseSpriteLRU(); InteractiveRandom(); -#ifdef ENABLE_NETWORK /* Check for UDP stuff */ if (_network_available) NetworkBackgroundLoop(); @@ -1546,9 +1519,6 @@ void GameLoop() /* Singleplayer */ StateGameLoop(); } -#else - StateGameLoop(); -#endif /* ENABLE_NETWORK */ if (!_pause_mode && HasBit(_display_opt, DO_FULL_ANIMATION)) DoPaletteAnimations(); diff --git a/src/openttd.h b/src/openttd.h index 0a92475f51..27d27b8cdd 100644 --- a/src/openttd.h +++ b/src/openttd.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. @@ -55,7 +53,7 @@ extern bool _exit_game; extern bool _restart_game; /** Modes of pausing we've got */ -enum PauseMode { +enum PauseMode : byte { PM_UNPAUSED = 0, ///< A normal unpaused game PM_PAUSED_NORMAL = 1 << 0, ///< A game normally paused PM_PAUSED_SAVELOAD = 1 << 1, ///< A game paused for saving/loading @@ -68,10 +66,9 @@ enum PauseMode { PMB_PAUSED_NETWORK = PM_PAUSED_ACTIVE_CLIENTS | PM_PAUSED_JOIN, }; DECLARE_ENUM_AS_BIT_SET(PauseMode) -typedef SimpleTinyEnumT PauseModeByte; /** The current pause mode */ -extern PauseModeByte _pause_mode; +extern PauseMode _pause_mode; void AskExitGame(); void AskExitToGameMenu(); diff --git a/src/order_backup.cpp b/src/order_backup.cpp index 58d1b40606..d537d8ce5c 100644 --- a/src/order_backup.cpp +++ b/src/order_backup.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. @@ -30,7 +28,7 @@ OrderBackup::~OrderBackup() if (CleaningPool()) return; Order *o = this->orders; - while (o != NULL) { + while (o != nullptr) { Order *next = o->next; delete o; o = next; @@ -75,11 +73,11 @@ OrderBackup::OrderBackup(const Vehicle *v, uint32 user) void OrderBackup::DoRestore(Vehicle *v) { /* If we had shared orders, recover that */ - if (this->clone != NULL) { + if (this->clone != nullptr) { DoCommand(0, v->index | CO_SHARE << 30, this->clone->index, DC_EXEC, CMD_CLONE_ORDER); - } else if (this->orders != NULL && OrderList::CanAllocateItem()) { + } else if (this->orders != nullptr && OrderList::CanAllocateItem()) { v->orders.list = new OrderList(this->orders, v); - this->orders = NULL; + this->orders = nullptr; /* Make sure buoys/oil rigs are updated in the station list. */ InvalidateWindowClassesData(WC_STATION_LIST, 0); } @@ -104,8 +102,7 @@ void OrderBackup::DoRestore(Vehicle *v) { /* Don't use reset as that broadcasts over the network to reset the variable, * which is what we are doing at the moment. */ - OrderBackup *ob; - FOR_ALL_ORDER_BACKUPS(ob) { + for (OrderBackup *ob : OrderBackup::Iterate()) { if (ob->user == user) delete ob; } if (OrderBackup::CanAllocateItem()) { @@ -121,8 +118,7 @@ void OrderBackup::DoRestore(Vehicle *v) */ /* static */ void OrderBackup::Restore(Vehicle *v, uint32 user) { - OrderBackup *ob; - FOR_ALL_ORDER_BACKUPS(ob) { + for (OrderBackup *ob : OrderBackup::Iterate()) { if (v->tile != ob->tile || ob->user != user) continue; ob->DoRestore(v); @@ -138,8 +134,7 @@ void OrderBackup::DoRestore(Vehicle *v) */ /* static */ void OrderBackup::ResetOfUser(TileIndex tile, uint32 user) { - OrderBackup *ob; - FOR_ALL_ORDER_BACKUPS(ob) { + for (OrderBackup *ob : OrderBackup::Iterate()) { if (ob->user == user && (ob->tile == tile || tile == INVALID_TILE)) delete ob; } } @@ -171,9 +166,8 @@ CommandCost CmdClearOrderBackup(TileIndex tile, DoCommandFlag flags, uint32 p1, { assert(_network_server); - OrderBackup *ob; - FOR_ALL_ORDER_BACKUPS(ob) { - /* If it's not an backup of us, so ignore it. */ + for (OrderBackup *ob : OrderBackup::Iterate()) { + /* If it's not a backup of us, ignore it. */ if (ob->user != user) continue; DoCommandP(0, 0, user, CMD_CLEAR_ORDER_BACKUP); @@ -193,15 +187,10 @@ CommandCost CmdClearOrderBackup(TileIndex tile, DoCommandFlag flags, uint32 p1, * but compiled it. A network client has its own variable for the unique * client/user identifier. Finally if networking isn't compiled in the * default is just plain and simple: 0. */ -#ifdef ENABLE_NETWORK uint32 user = _networking && !_network_server ? _network_own_client_id : CLIENT_ID_SERVER; -#else - uint32 user = 0; -#endif - OrderBackup *ob; - FOR_ALL_ORDER_BACKUPS(ob) { - /* If it's not an backup of us, so ignore it. */ + for (OrderBackup *ob : OrderBackup::Iterate()) { + /* If it's not a backup of us, ignore it. */ if (ob->user != user) continue; /* If it's not for our chosen tile either, ignore it. */ if (t != INVALID_TILE && t != ob->tile) continue; @@ -210,7 +199,7 @@ CommandCost CmdClearOrderBackup(TileIndex tile, DoCommandFlag flags, uint32 p1, /* We need to circumvent the "prevention" from this command being executed * while the game is paused, so use the internal method. Nor do we want * this command to get its cost estimated when shift is pressed. */ - DoCommandPInternal(ob->tile, 0, user, CMD_CLEAR_ORDER_BACKUP, NULL, NULL, true, false); + DoCommandPInternal(ob->tile, 0, user, CMD_CLEAR_ORDER_BACKUP, nullptr, nullptr, true, false); } else { /* The command came from the game logic, i.e. the clearing of a tile. * In that case we have no need to actually sync this, just do it. */ @@ -225,8 +214,7 @@ CommandCost CmdClearOrderBackup(TileIndex tile, DoCommandFlag flags, uint32 p1, */ /* static */ void OrderBackup::ClearGroup(GroupID group) { - OrderBackup *ob; - FOR_ALL_ORDER_BACKUPS(ob) { + for (OrderBackup *ob : OrderBackup::Iterate()) { if (ob->group == group) ob->group = DEFAULT_GROUP; } } @@ -234,20 +222,19 @@ CommandCost CmdClearOrderBackup(TileIndex tile, DoCommandFlag flags, uint32 p1, /** * Clear/update the (clone) vehicle from an order backup. * @param v The vehicle to clear. - * @pre v != NULL + * @pre v != nullptr * @note If it is not possible to set another vehicle as clone * "example", then this backed up order will be removed. */ /* static */ void OrderBackup::ClearVehicle(const Vehicle *v) { - assert(v != NULL); - OrderBackup *ob; - FOR_ALL_ORDER_BACKUPS(ob) { + assert(v != nullptr); + for (OrderBackup *ob : OrderBackup::Iterate()) { if (ob->clone == v) { /* Get another item in the shared list. */ ob->clone = (v->FirstShared() == v) ? v->NextShared() : v->FirstShared(); /* But if that isn't there, remove it. */ - if (ob->clone == NULL) delete ob; + if (ob->clone == nullptr) delete ob; } } } @@ -262,9 +249,8 @@ CommandCost CmdClearOrderBackup(TileIndex tile, DoCommandFlag flags, uint32 p1, */ /* static */ void OrderBackup::RemoveOrder(OrderType type, DestinationID destination, bool hangar) { - OrderBackup *ob; - FOR_ALL_ORDER_BACKUPS(ob) { - for (Order *order = ob->orders; order != NULL; order = order->next) { + for (OrderBackup *ob : OrderBackup::Iterate()) { + for (Order *order = ob->orders; order != nullptr; order = order->next) { OrderType ot = order->GetType(); if (ot == OT_GOTO_DEPOT && (order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) != 0) continue; if (ot == OT_GOTO_DEPOT && hangar && !IsHangarTile(ob->tile)) continue; // Not an aircraft? Can't have a hangar order. diff --git a/src/order_backup.h b/src/order_backup.h index c56bc0ecc6..5d1dcef50e 100644 --- a/src/order_backup.h +++ b/src/order_backup.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. @@ -66,17 +64,4 @@ public: static void RemoveOrder(OrderType type, DestinationID destination, bool hangar); }; -/** - * Iterator over all order backups from a given ID. - * @param var The variable to iterate with. - * @param start The start of the iteration. - */ -#define FOR_ALL_ORDER_BACKUPS_FROM(var, start) FOR_ALL_ITEMS_FROM(OrderBackup, order_backup_index, var, start) - -/** - * Iterator over all order backups. - * @param var The variable to iterate with. - */ -#define FOR_ALL_ORDER_BACKUPS(var) FOR_ALL_ORDER_BACKUPS_FROM(var, 0) - #endif /* ORDER_BACKUP_H */ diff --git a/src/order_base.h b/src/order_base.h index 0def7b0bcd..ba4959c0f3 100644 --- a/src/order_base.h +++ b/src/order_base.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. @@ -48,9 +46,9 @@ private: uint16 max_speed; ///< How fast the vehicle may go on the way to the destination. public: - Order *next; ///< Pointer to next order. If NULL, end of list + Order *next; ///< Pointer to next order. If nullptr, end of list - Order() : refit_cargo(CT_NO_REFIT), max_speed(UINT16_MAX) {} + Order() : flags(0), refit_cargo(CT_NO_REFIT), max_speed(UINT16_MAX) {} ~Order(); Order(uint32 packed); @@ -268,7 +266,7 @@ private: public: /** Default constructor producing an invalid order list. */ OrderList(VehicleOrderID num_orders = INVALID_VEH_ORDER_ID) - : first(NULL), num_orders(num_orders), num_manual_orders(0), num_vehicles(0), first_shared(NULL), + : first(nullptr), num_orders(num_orders), num_manual_orders(0), num_vehicles(0), first_shared(nullptr), timetable_duration(0), total_duration(0) { } /** @@ -283,6 +281,8 @@ public: void Initialize(Order *chain, Vehicle *v); + void RecalculateTimetableDuration(); + /** * Get the first order of the order chain. * @return the first order of the chain. @@ -303,7 +303,7 @@ public: * @param curr Order to find the next one for. * @return Next order. */ - inline const Order *GetNext(const Order *curr) const { return (curr->next == NULL) ? this->GetFirstOrder() : curr->next; } + inline const Order *GetNext(const Order *curr) const { return (curr->next == nullptr) ? this->GetFirstOrder() : curr->next; } /** * Get number of orders in the order list. @@ -317,7 +317,7 @@ public: */ inline VehicleOrderID GetNumManualOrders() const { return this->num_manual_orders; } - StationIDStack GetNextStoppingStation(const Vehicle *v, const Order *first = NULL, uint hops = 0) const; + StationIDStack GetNextStoppingStation(const Vehicle *v, const Order *first = nullptr, uint hops = 0) const; const Order *GetNextDecisionNode(const Order *next, uint hops) const; void InsertOrderAt(Order *new_order, int index); @@ -392,14 +392,6 @@ public: void DebugCheckSanity() const; }; -#define FOR_ALL_ORDERS_FROM(var, start) FOR_ALL_ITEMS_FROM(Order, order_index, var, start) -#define FOR_ALL_ORDERS(var) FOR_ALL_ORDERS_FROM(var, 0) - - -#define FOR_VEHICLE_ORDERS(v, order) for (order = (v->orders.list == NULL) ? NULL : v->orders.list->GetFirstOrder(); order != NULL; order = order->next) - - -#define FOR_ALL_ORDER_LISTS_FROM(var, start) FOR_ALL_ITEMS_FROM(OrderList, orderlist_index, var, start) -#define FOR_ALL_ORDER_LISTS(var) FOR_ALL_ORDER_LISTS_FROM(var, 0) +#define FOR_VEHICLE_ORDERS(v, order) for (order = (v->orders.list == nullptr) ? nullptr : v->orders.list->GetFirstOrder(); order != nullptr; order = order->next) #endif /* ORDER_BASE_H */ diff --git a/src/order_cmd.cpp b/src/order_cmd.cpp index dae6e58ad6..1e9e8f2f3b 100644 --- a/src/order_cmd.cpp +++ b/src/order_cmd.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. @@ -23,7 +21,6 @@ #include "core/random_func.hpp" #include "aircraft.h" #include "roadveh.h" -#include "ship.h" #include "station_base.h" #include "waypoint_base.h" #include "company_base.h" @@ -54,7 +51,7 @@ Order::~Order() * the list of stations. So, we need to invalidate that window if needed. */ if (this->IsType(OT_GOTO_STATION) || this->IsType(OT_GOTO_WAYPOINT)) { BaseStation *bs = BaseStation::GetIfValid(this->GetDestination()); - if (bs != NULL && bs->owner == OWNER_NONE) InvalidateWindowClassesData(WC_STATION_LIST, 0); + if (bs != nullptr && bs->owner == OWNER_NONE) InvalidateWindowClassesData(WC_STATION_LIST, 0); } } @@ -67,7 +64,7 @@ void Order::Free() this->type = OT_NOTHING; this->flags = 0; this->dest = 0; - this->next = NULL; + this->next = nullptr; } /** @@ -238,7 +235,7 @@ Order::Order(uint32 packed) this->type = (OrderType)GB(packed, 0, 8); this->flags = GB(packed, 8, 8); this->dest = GB(packed, 16, 16); - this->next = NULL; + this->next = nullptr; this->refit_cargo = CT_NO_REFIT; this->wait_time = 0; this->travel_time = 0; @@ -299,21 +296,33 @@ void OrderList::Initialize(Order *chain, Vehicle *v) this->num_manual_orders = 0; this->num_vehicles = 1; this->timetable_duration = 0; - this->total_duration = 0; - for (Order *o = this->first; o != NULL; o = o->next) { + for (Order *o = this->first; o != nullptr; o = o->next) { ++this->num_orders; if (!o->IsType(OT_IMPLICIT)) ++this->num_manual_orders; - this->timetable_duration += o->GetTimetabledWait() + o->GetTimetabledTravel(); this->total_duration += o->GetWaitTime() + o->GetTravelTime(); } - for (Vehicle *u = this->first_shared->PreviousShared(); u != NULL; u = u->PreviousShared()) { + this->RecalculateTimetableDuration(); + + for (Vehicle *u = this->first_shared->PreviousShared(); u != nullptr; u = u->PreviousShared()) { ++this->num_vehicles; this->first_shared = u; } - for (const Vehicle *u = v->NextShared(); u != NULL; u = u->NextShared()) ++this->num_vehicles; + for (const Vehicle *u = v->NextShared(); u != nullptr; u = u->NextShared()) ++this->num_vehicles; +} + +/** + * Recomputes Timetable duration. + * Split out into a separate function so it can be used by afterload. + */ +void OrderList::RecalculateTimetableDuration() +{ + this->timetable_duration = 0; + for (Order *o = this->first; o != nullptr; o = o->next) { + this->timetable_duration += o->GetTimetabledWait() + o->GetTimetabledTravel(); + } } /** @@ -324,13 +333,13 @@ void OrderList::Initialize(Order *chain, Vehicle *v) void OrderList::FreeChain(bool keep_orderlist) { Order *next; - for (Order *o = this->first; o != NULL; o = next) { + for (Order *o = this->first; o != nullptr; o = next) { next = o->next; delete o; } if (keep_orderlist) { - this->first = NULL; + this->first = nullptr; this->num_orders = 0; this->num_manual_orders = 0; this->timetable_duration = 0; @@ -346,11 +355,11 @@ void OrderList::FreeChain(bool keep_orderlist) */ Order *OrderList::GetOrderAt(int index) const { - if (index < 0) return NULL; + if (index < 0) return nullptr; Order *order = this->first; - while (order != NULL && index-- > 0) { + while (order != nullptr && index-- > 0) { order = order->next; } return order; @@ -365,11 +374,11 @@ Order *OrderList::GetOrderAt(int index) const * \li a station order * \li a refitting depot order * \li a non-trivial conditional order - * \li NULL if the vehicle won't stop anymore. + * \li nullptr if the vehicle won't stop anymore. */ const Order *OrderList::GetNextDecisionNode(const Order *next, uint hops) const { - if (hops > this->GetNumOrders() || next == NULL) return NULL; + if (hops > this->GetNumOrders() || next == nullptr) return nullptr; if (next->IsType(OT_CONDITIONAL)) { if (next->GetConditionVariable() != OCV_UNCONDITIONALLY) return next; @@ -382,7 +391,7 @@ const Order *OrderList::GetNextDecisionNode(const Order *next, uint hops) const } if (next->IsType(OT_GOTO_DEPOT)) { - if (next->GetDepotActionType() == ODATFB_HALT) return NULL; + if (next->GetDepotActionType() == ODATFB_HALT) return nullptr; if (next->IsRefit()) return next; } @@ -396,9 +405,9 @@ const Order *OrderList::GetNextDecisionNode(const Order *next, uint hops) const /** * Recursively determine the next deterministic station to stop at. * @param v The vehicle we're looking at. - * @param first Order to start searching at or NULL to start at cur_implicit_order_index + 1. + * @param first Order to start searching at or nullptr to start at cur_implicit_order_index + 1. * @param hops Number of orders we have already looked at. - * @return Next stoppping station or INVALID_STATION. + * @return Next stopping station or INVALID_STATION. * @pre The vehicle is currently loading and v->last_station_visited is meaningful. * @note This function may draw a random number. Don't use it from the GUI. */ @@ -406,17 +415,17 @@ StationIDStack OrderList::GetNextStoppingStation(const Vehicle *v, const Order * { const Order *next = first; - if (first == NULL) { + if (first == nullptr) { next = this->GetOrderAt(v->cur_implicit_order_index); - if (next == NULL) { + if (next == nullptr) { next = this->GetFirstOrder(); - if (next == NULL) return INVALID_STATION; + if (next == nullptr) return INVALID_STATION; } else { - /* GetNext never returns NULL if there is a valid station in the list. + /* GetNext never returns nullptr if there is a valid station in the list. * As the given "next" is already valid and a station in the list, we - * don't have to check for NULL here. */ + * don't have to check for nullptr here. */ next = this->GetNext(next); - assert(next != NULL); + assert(next != nullptr); } } @@ -424,16 +433,16 @@ StationIDStack OrderList::GetNextStoppingStation(const Vehicle *v, const Order * next = this->GetNextDecisionNode(next, ++hops); /* Resolve possibly nested conditionals by estimation. */ - while (next != NULL && next->IsType(OT_CONDITIONAL)) { + while (next != nullptr && next->IsType(OT_CONDITIONAL)) { /* We return both options of conditional orders. */ const Order *skip_to = this->GetNextDecisionNode( this->GetOrderAt(next->GetConditionSkipToOrder()), hops); const Order *advance = this->GetNextDecisionNode( this->GetNext(next), hops); - if (advance == NULL || advance == first || skip_to == advance) { - next = (skip_to == first) ? NULL : skip_to; - } else if (skip_to == NULL || skip_to == first) { - next = (advance == first) ? NULL : advance; + if (advance == nullptr || advance == first || skip_to == advance) { + next = (skip_to == first) ? nullptr : skip_to; + } else if (skip_to == nullptr || skip_to == first) { + next = (advance == first) ? nullptr : advance; } else { StationIDStack st1 = this->GetNextStoppingStation(v, skip_to, hops); StationIDStack st2 = this->GetNextStoppingStation(v, advance, hops); @@ -444,7 +453,7 @@ StationIDStack OrderList::GetNextStoppingStation(const Vehicle *v, const Order * } /* Don't return a next stop if the vehicle has to unload everything. */ - if (next == NULL || ((next->IsType(OT_GOTO_STATION) || next->IsType(OT_IMPLICIT)) && + if (next == nullptr || ((next->IsType(OT_GOTO_STATION) || next->IsType(OT_IMPLICIT)) && next->GetDestination() == v->last_station_visited && (next->GetUnloadType() & (OUFB_TRANSFER | OUFB_UNLOAD)) != 0)) { return INVALID_STATION; @@ -461,7 +470,7 @@ StationIDStack OrderList::GetNextStoppingStation(const Vehicle *v, const Order * */ void OrderList::InsertOrderAt(Order *new_order, int index) { - if (this->first == NULL) { + if (this->first == nullptr) { this->first = new_order; } else { if (index == 0) { @@ -567,7 +576,7 @@ void OrderList::RemoveVehicle(Vehicle *v) */ bool OrderList::IsVehicleInSharedOrdersList(const Vehicle *v) const { - for (const Vehicle *v_shared = this->first_shared; v_shared != NULL; v_shared = v_shared->NextShared()) { + for (const Vehicle *v_shared = this->first_shared; v_shared != nullptr; v_shared = v_shared->NextShared()) { if (v_shared == v) return true; } @@ -582,7 +591,7 @@ bool OrderList::IsVehicleInSharedOrdersList(const Vehicle *v) const int OrderList::GetPositionInSharedOrderList(const Vehicle *v) const { int count = 0; - for (const Vehicle *v_shared = v->PreviousShared(); v_shared != NULL; v_shared = v_shared->PreviousShared()) count++; + for (const Vehicle *v_shared = v->PreviousShared(); v_shared != nullptr; v_shared = v_shared->PreviousShared()) count++; return count; } @@ -592,7 +601,7 @@ int OrderList::GetPositionInSharedOrderList(const Vehicle *v) const */ bool OrderList::IsCompleteTimetable() const { - for (Order *o = this->first; o != NULL; o = o->next) { + for (Order *o = this->first; o != nullptr; o = o->next) { /* Implicit orders are, by definition, not timetabled. */ if (o->IsType(OT_IMPLICIT)) continue; if (!o->IsCompletelyTimetabled()) return false; @@ -613,7 +622,7 @@ void OrderList::DebugCheckSanity() const DEBUG(misc, 6, "Checking OrderList %hu for sanity...", this->index); - for (const Order *o = this->first; o != NULL; o = o->next) { + for (const Order *o = this->first; o != nullptr; o = o->next) { ++check_num_orders; if (!o->IsType(OT_IMPLICIT)) ++check_num_manual_orders; check_timetable_duration += o->GetTimetabledWait() + o->GetTimetabledTravel(); @@ -624,7 +633,7 @@ void OrderList::DebugCheckSanity() const assert(this->timetable_duration == check_timetable_duration); assert(this->total_duration == check_total_duration); - for (const Vehicle *v = this->first_shared; v != NULL; v = v->NextShared()) { + for (const Vehicle *v = this->first_shared; v != nullptr; v = v->NextShared()) { ++check_num_vehicles; assert(v->orders.list == this); } @@ -703,7 +712,7 @@ uint GetOrderDistance(const Order *prev, const Order *cur, const Vehicle *v, int conditional_depth++; int dist1 = GetOrderDistance(prev, v->GetOrder(cur->GetConditionSkipToOrder()), v, conditional_depth); - int dist2 = GetOrderDistance(prev, cur->next == NULL ? v->orders.list->GetFirstOrder() : cur->next, v, conditional_depth); + int dist2 = GetOrderDistance(prev, cur->next == nullptr ? v->orders.list->GetFirstOrder() : cur->next, v, conditional_depth); return max(dist1, dist2); } @@ -733,7 +742,7 @@ CommandCost CmdInsertOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 Order new_order(p2); Vehicle *v = Vehicle::GetIfValid(veh); - if (v == NULL || !v->IsPrimaryVehicle()) return CMD_ERROR; + if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR; CommandCost ret = CheckOwnership(v->owner); if (ret.Failed()) return ret; @@ -743,7 +752,7 @@ CommandCost CmdInsertOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 switch (new_order.GetType()) { case OT_GOTO_STATION: { const Station *st = Station::GetIfValid(new_order.GetDestination()); - if (st == NULL) return CMD_ERROR; + if (st == nullptr) return CMD_ERROR; if (st->owner != OWNER_NONE) { CommandCost ret = CheckOwnership(st->owner); @@ -751,7 +760,7 @@ CommandCost CmdInsertOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 } if (!CanVehicleUseStation(v, st)) return_cmd_error(STR_ERROR_CAN_T_ADD_ORDER); - for (Vehicle *u = v->FirstShared(); u != NULL; u = u->NextShared()) { + for (Vehicle *u = v->FirstShared(); u != nullptr; u = u->NextShared()) { if (!CanVehicleUseStation(u, st)) return_cmd_error(STR_ERROR_CAN_T_ADD_ORDER_SHARED); } @@ -790,7 +799,7 @@ CommandCost CmdInsertOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 if (v->type == VEH_AIRCRAFT) { const Station *st = Station::GetIfValid(new_order.GetDestination()); - if (st == NULL) return CMD_ERROR; + if (st == nullptr) return CMD_ERROR; CommandCost ret = CheckOwnership(st->owner); if (ret.Failed()) return ret; @@ -801,7 +810,7 @@ CommandCost CmdInsertOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 } else { const Depot *dp = Depot::GetIfValid(new_order.GetDestination()); - if (dp == NULL) return CMD_ERROR; + if (dp == nullptr) return CMD_ERROR; CommandCost ret = CheckOwnership(GetTileOwner(dp->xy)); if (ret.Failed()) return ret; @@ -833,7 +842,7 @@ CommandCost CmdInsertOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 case OT_GOTO_WAYPOINT: { const Waypoint *wp = Waypoint::GetIfValid(new_order.GetDestination()); - if (wp == NULL) return CMD_ERROR; + if (wp == nullptr) return CMD_ERROR; switch (v->type) { default: return CMD_ERROR; @@ -898,43 +907,7 @@ CommandCost CmdInsertOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 if (v->GetNumOrders() >= MAX_VEH_ORDER_ID) return_cmd_error(STR_ERROR_TOO_MANY_ORDERS); if (!Order::CanAllocateItem()) return_cmd_error(STR_ERROR_NO_MORE_SPACE_FOR_ORDERS); - if (v->orders.list == NULL && !OrderList::CanAllocateItem()) return_cmd_error(STR_ERROR_NO_MORE_SPACE_FOR_ORDERS); - - if (v->type == VEH_SHIP && _settings_game.pf.pathfinder_for_ships != VPF_NPF) { - /* Make sure the new destination is not too far away from the previous */ - const Order *prev = NULL; - uint n = 0; - - /* Find the last goto station or depot order before the insert location. - * If the order is to be inserted at the beginning of the order list this - * finds the last order in the list. */ - const Order *o; - FOR_VEHICLE_ORDERS(v, o) { - switch (o->GetType()) { - case OT_GOTO_STATION: - case OT_GOTO_DEPOT: - case OT_GOTO_WAYPOINT: - prev = o; - break; - - default: break; - } - if (++n == sel_ord && prev != NULL) break; - } - if (prev != NULL) { - uint dist; - if (new_order.IsType(OT_CONDITIONAL)) { - /* The order is not yet inserted, so we have to do the first iteration here. */ - dist = GetOrderDistance(prev, v->GetOrder(new_order.GetConditionSkipToOrder()), v); - } else { - dist = GetOrderDistance(prev, &new_order, v); - } - - if (dist >= SHIP_MAX_ORDER_DISTANCE) { - return_cmd_error(STR_ERROR_TOO_FAR_FROM_PREVIOUS_DESTINATION); - } - } - } + if (v->orders.list == nullptr && !OrderList::CanAllocateItem()) return_cmd_error(STR_ERROR_NO_MORE_SPACE_FOR_ORDERS); if (flags & DC_EXEC) { Order *new_o = new Order(); @@ -954,7 +927,7 @@ CommandCost CmdInsertOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 void InsertOrder(Vehicle *v, Order *new_o, VehicleOrderID sel_ord) { /* Create new order and link in list */ - if (v->orders.list == NULL) { + if (v->orders.list == nullptr) { v->orders.list = new OrderList(new_o, v); } else { v->orders.list->InsertOrderAt(new_o, sel_ord); @@ -962,7 +935,7 @@ void InsertOrder(Vehicle *v, Order *new_o, VehicleOrderID sel_ord) Vehicle *u = v->FirstShared(); DeleteOrderWarnings(u); - for (; u != NULL; u = u->NextShared()) { + for (; u != nullptr; u = u->NextShared()) { assert(v->orders.list == u->orders.list); /* If there is added an order before the current one, we need @@ -1045,7 +1018,7 @@ CommandCost CmdDeleteOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 Vehicle *v = Vehicle::GetIfValid(veh_id); - if (v == NULL || !v->IsPrimaryVehicle()) return CMD_ERROR; + if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR; CommandCost ret = CheckOwnership(v->owner); if (ret.Failed()) return ret; @@ -1053,7 +1026,7 @@ CommandCost CmdDeleteOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 /* If we did not select an order, we maybe want to de-clone the orders */ if (sel_ord >= v->GetNumOrders()) return DecloneOrder(v, flags); - if (v->GetOrder(sel_ord) == NULL) return CMD_ERROR; + if (v->GetOrder(sel_ord) == nullptr) return CMD_ERROR; if (flags & DC_EXEC) DeleteOrder(v, sel_ord); return CommandCost(); @@ -1085,7 +1058,7 @@ void DeleteOrder(Vehicle *v, VehicleOrderID sel_ord) Vehicle *u = v->FirstShared(); DeleteOrderWarnings(u); - for (; u != NULL; u = u->NextShared()) { + for (; u != nullptr; u = u->NextShared()) { assert(v->orders.list == u->orders.list); if (sel_ord == u->cur_real_order_index && u->current_order.IsType(OT_LOADING)) { @@ -1117,7 +1090,7 @@ void DeleteOrder(Vehicle *v, VehicleOrderID sel_ord) /* As we delete an order, the order to skip to will be 'wrong'. */ VehicleOrderID cur_order_id = 0; - Order *order = NULL; + Order *order = nullptr; FOR_VEHICLE_ORDERS(v, order) { if (order->IsType(OT_CONDITIONAL)) { VehicleOrderID order_id = order->GetConditionSkipToOrder(); @@ -1151,7 +1124,7 @@ CommandCost CmdSkipToOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 Vehicle *v = Vehicle::GetIfValid(veh_id); - if (v == NULL || !v->IsPrimaryVehicle() || sel_ord == v->cur_implicit_order_index || sel_ord >= v->GetNumOrders() || v->GetNumOrders() < 2) return CMD_ERROR; + if (v == nullptr || !v->IsPrimaryVehicle() || sel_ord == v->cur_implicit_order_index || sel_ord >= v->GetNumOrders() || v->GetNumOrders() < 2) return CMD_ERROR; CommandCost ret = CheckOwnership(v->owner); if (ret.Failed()) return ret; @@ -1192,7 +1165,7 @@ CommandCost CmdMoveOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 VehicleOrderID target_order = GB(p2, 16, 16); Vehicle *v = Vehicle::GetIfValid(veh); - if (v == NULL || !v->IsPrimaryVehicle()) return CMD_ERROR; + if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR; CommandCost ret = CheckOwnership(v->owner); if (ret.Failed()) return ret; @@ -1203,7 +1176,7 @@ CommandCost CmdMoveOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 Order *moving_one = v->GetOrder(moving_order); /* Don't move an empty order */ - if (moving_one == NULL) return CMD_ERROR; + if (moving_one == nullptr) return CMD_ERROR; if (flags & DC_EXEC) { v->orders.list->MoveOrder(moving_order, target_order); @@ -1213,7 +1186,7 @@ CommandCost CmdMoveOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 DeleteOrderWarnings(u); - for (; u != NULL; u = u->NextShared()) { + for (; u != nullptr; u = u->NextShared()) { /* Update the current order. * There are multiple ways to move orders, which result in cur_implicit_order_index * and cur_real_order_index to not longer make any sense. E.g. moving another @@ -1299,7 +1272,7 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 if (mof >= MOF_END) return CMD_ERROR; Vehicle *v = Vehicle::GetIfValid(veh); - if (v == NULL || !v->IsPrimaryVehicle()) return CMD_ERROR; + if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR; CommandCost ret = CheckOwnership(v->owner); if (ret.Failed()) return ret; @@ -1496,13 +1469,13 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 /* Update the windows and full load flags, also for vehicles that share the same order list */ Vehicle *u = v->FirstShared(); DeleteOrderWarnings(u); - for (; u != NULL; u = u->NextShared()) { + for (; u != nullptr; u = u->NextShared()) { /* Toggle u->current_order "Full load" flag if it changed. * However, as the same flag is used for depot orders, check * whether we are not going to a depot as there are three * cases where the full load flag can be active and only * one case where the flag is used for depot orders. In the - * other cases for the OrderTypeByte the flags are not used, + * other cases for the OrderType the flags are not used, * so do not care and those orders should not be active * when this function is called. */ @@ -1527,17 +1500,17 @@ CommandCost CmdModifyOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 */ static bool CheckAircraftOrderDistance(const Aircraft *v_new, const Vehicle *v_order, const Order *first) { - if (first == NULL || v_new->acache.cached_max_range == 0) return true; + if (first == nullptr || v_new->acache.cached_max_range == 0) return true; /* Iterate over all orders to check the distance between all * 'goto' orders and their respective next order (of any type). */ - for (const Order *o = first; o != NULL; o = o->next) { + for (const Order *o = first; o != nullptr; o = o->next) { switch (o->GetType()) { case OT_GOTO_STATION: case OT_GOTO_DEPOT: case OT_GOTO_WAYPOINT: /* If we don't have a next order, we've reached the end and must check the first order instead. */ - if (GetOrderDistance(o, o->next != NULL ? o->next : first, v_order) > v_new->acache.cached_max_range_sqr) return false; + if (GetOrderDistance(o, o->next != nullptr ? o->next : first, v_order) > v_new->acache.cached_max_range_sqr) return false; break; default: break; @@ -1564,7 +1537,7 @@ CommandCost CmdCloneOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 VehicleID veh_dst = GB(p1, 0, 20); Vehicle *dst = Vehicle::GetIfValid(veh_dst); - if (dst == NULL || !dst->IsPrimaryVehicle()) return CMD_ERROR; + if (dst == nullptr || !dst->IsPrimaryVehicle()) return CMD_ERROR; CommandCost ret = CheckOwnership(dst->owner); if (ret.Failed()) return ret; @@ -1574,7 +1547,7 @@ CommandCost CmdCloneOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 Vehicle *src = Vehicle::GetIfValid(veh_src); /* Sanity checks */ - if (src == NULL || !src->IsPrimaryVehicle() || dst->type != src->type || dst == src) return CMD_ERROR; + if (src == nullptr || !src->IsPrimaryVehicle() || dst->type != src->type || dst == src) return CMD_ERROR; CommandCost ret = CheckOwnership(src->owner); if (ret.Failed()) return ret; @@ -1606,7 +1579,7 @@ CommandCost CmdCloneOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 return_cmd_error(STR_ERROR_AIRCRAFT_NOT_ENOUGH_RANGE); } - if (src->orders.list == NULL && !OrderList::CanAllocateItem()) { + if (src->orders.list == nullptr && !OrderList::CanAllocateItem()) { return_cmd_error(STR_ERROR_NO_MORE_SPACE_FOR_ORDERS); } @@ -1633,7 +1606,7 @@ CommandCost CmdCloneOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 Vehicle *src = Vehicle::GetIfValid(veh_src); /* Sanity checks */ - if (src == NULL || !src->IsPrimaryVehicle() || dst->type != src->type || dst == src) return CMD_ERROR; + if (src == nullptr || !src->IsPrimaryVehicle() || dst->type != src->type || dst == src) return CMD_ERROR; CommandCost ret = CheckOwnership(src->owner); if (ret.Failed()) return ret; @@ -1660,7 +1633,7 @@ CommandCost CmdCloneOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 if (flags & DC_EXEC) { const Order *order; - Order *first = NULL; + Order *first = nullptr; Order **order_dst; /* If the destination vehicle had an order list, destroy the chain but keep the OrderList. @@ -1674,10 +1647,10 @@ CommandCost CmdCloneOrder(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 (*order_dst)->AssignOrder(*order); order_dst = &(*order_dst)->next; } - if (dst->orders.list == NULL) { + if (dst->orders.list == nullptr) { dst->orders.list = new OrderList(first, dst); } else { - assert(dst->orders.list->GetFirstOrder() == NULL); + assert(dst->orders.list->GetFirstOrder() == nullptr); assert(!dst->orders.list->IsShared()); delete dst->orders.list; assert(OrderList::CanAllocateItem()); @@ -1718,13 +1691,13 @@ CommandCost CmdOrderRefit(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 if (cargo >= NUM_CARGO && cargo != CT_NO_REFIT && cargo != CT_AUTO_REFIT) return CMD_ERROR; const Vehicle *v = Vehicle::GetIfValid(veh); - if (v == NULL || !v->IsPrimaryVehicle()) return CMD_ERROR; + if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR; CommandCost ret = CheckOwnership(v->owner); if (ret.Failed()) return ret; Order *order = v->GetOrder(order_number); - if (order == NULL) return CMD_ERROR; + if (order == nullptr) return CMD_ERROR; /* Automatic refit cargo is only supported for goto station orders. */ if (cargo == CT_AUTO_REFIT && !order->IsType(OT_GOTO_STATION)) return CMD_ERROR; @@ -1740,7 +1713,7 @@ CommandCost CmdOrderRefit(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 order->SetDepotActionType((OrderDepotActionFlags)(order->GetDepotActionType() & ~ODATFB_HALT)); } - for (Vehicle *u = v->FirstShared(); u != NULL; u = u->NextShared()) { + for (Vehicle *u = v->FirstShared(); u != nullptr; u = u->NextShared()) { /* Update any possible open window of the vehicle */ InvalidateVehicleOrder(u, VIWD_MODIFY_ORDERS); @@ -1818,7 +1791,7 @@ void CheckOrders(const Vehicle *v) if (n_st < 2 && message == INVALID_STRING_ID) message = STR_NEWS_VEHICLE_HAS_TOO_FEW_ORDERS; #ifndef NDEBUG - if (v->orders.list != NULL) v->orders.list->DebugCheckSanity(); + if (v->orders.list != nullptr) v->orders.list->DebugCheckSanity(); #endif /* We don't have a problem */ @@ -1839,14 +1812,12 @@ void CheckOrders(const Vehicle *v) */ void RemoveOrderFromAllVehicles(OrderType type, DestinationID destination, bool hangar) { - Vehicle *v; - /* Aircraft have StationIDs for depot orders and never use DepotIDs * This fact is handled specially below */ /* Go through all vehicles */ - FOR_ALL_VEHICLES(v) { + for (Vehicle *v : Vehicle::Iterate()) { Order *order; order = &v->current_order; @@ -1873,7 +1844,7 @@ restart: if (order->IsType(OT_IMPLICIT)) { order = order->next; // DeleteOrder() invalidates current order DeleteOrder(v, id); - if (order != NULL) goto restart; + if (order != nullptr) goto restart; break; } @@ -1890,7 +1861,7 @@ restart: order->MakeDummy(); order->SetTravelTimetabled(travel_timetabled); - for (const Vehicle *w = v->FirstShared(); w != NULL; w = w->NextShared()) { + for (const Vehicle *w = v->FirstShared(); w != nullptr; w = w->NextShared()) { /* In GUI, simulate by removing the order and adding it back */ InvalidateVehicleOrder(w, id | (INVALID_VEH_ORDER_ID << 8)); InvalidateVehicleOrder(w, (INVALID_VEH_ORDER_ID << 8) | id); @@ -1933,11 +1904,11 @@ void DeleteVehicleOrders(Vehicle *v, bool keep_orderlist, bool reset_order_indic if (v->IsOrderListShared()) { /* Remove ourself from the shared order list. */ v->RemoveFromShared(); - v->orders.list = NULL; - } else if (v->orders.list != NULL) { + v->orders.list = nullptr; + } else if (v->orders.list != nullptr) { /* Remove the orders */ v->orders.list->FreeChain(keep_orderlist); - if (!keep_orderlist) v->orders.list = NULL; + if (!keep_orderlist) v->orders.list = nullptr; } if (reset_order_indices) { @@ -2019,7 +1990,7 @@ VehicleOrderID ProcessConditionalOrder(const Order *order, const Vehicle *v) uint16 value = order->GetConditionValue(); switch (order->GetConditionVariable()) { - case OCV_LOAD_PERCENTAGE: skip_order = OrderConditionCompare(occ, CalcPercentVehicleFilled(v, NULL), value); break; + case OCV_LOAD_PERCENTAGE: skip_order = OrderConditionCompare(occ, CalcPercentVehicleFilled(v, nullptr), value); break; case OCV_RELIABILITY: skip_order = OrderConditionCompare(occ, ToPercent16(v->reliability), value); break; case OCV_MAX_RELIABILITY: skip_order = OrderConditionCompare(occ, ToPercent16(v->GetEngine()->reliability), value); break; case OCV_MAX_SPEED: skip_order = OrderConditionCompare(occ, v->GetDisplayMaxSpeed() * 10 / 16, value); break; @@ -2146,12 +2117,12 @@ bool UpdateOrderDest(Vehicle *v, const Order *order, int conditional_depth, bool /* Get the current order */ order = v->GetOrder(v->cur_real_order_index); - if (order != NULL && order->IsType(OT_IMPLICIT)) { + if (order != nullptr && order->IsType(OT_IMPLICIT)) { assert(v->GetNumManualOrders() == 0); - order = NULL; + order = nullptr; } - if (order == NULL) { + if (order == nullptr) { v->current_order.Free(); v->SetDestTile(0); return false; @@ -2214,13 +2185,13 @@ bool ProcessOrders(Vehicle *v) v->UpdateRealOrderIndex(); const Order *order = v->GetOrder(v->cur_real_order_index); - if (order != NULL && order->IsType(OT_IMPLICIT)) { + if (order != nullptr && order->IsType(OT_IMPLICIT)) { assert(v->GetNumManualOrders() == 0); - order = NULL; + order = nullptr; } /* If no order, do nothing. */ - if (order == NULL || (v->type == VEH_AIRCRAFT && !CheckForValidOrders(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); @@ -2235,7 +2206,7 @@ bool ProcessOrders(Vehicle *v) /* If it is unchanged, keep it. */ if (order->Equals(v->current_order) && (v->type == VEH_AIRCRAFT || v->dest_tile != 0) && - (v->type != VEH_SHIP || !order->IsType(OT_GOTO_STATION) || Station::Get(order->GetDestination())->dock_tile != INVALID_TILE)) { + (v->type != VEH_SHIP || !order->IsType(OT_GOTO_STATION) || Station::Get(order->GetDestination())->ship_station.tile != INVALID_TILE)) { return false; } diff --git a/src/order_func.h b/src/order_func.h index df99394282..7faeb08429 100644 --- a/src/order_func.h +++ b/src/order_func.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/order_gui.cpp b/src/order_gui.cpp index 91ca244d4d..a71225d99c 100644 --- a/src/order_gui.cpp +++ b/src/order_gui.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. @@ -24,6 +22,7 @@ #include "tilehighlight_func.h" #include "network/network.h" #include "station_base.h" +#include "industry.h" #include "waypoint_base.h" #include "core/geometry_func.hpp" #include "hotkeys.h" @@ -239,7 +238,7 @@ void DrawOrderString(const Vehicle *v, const Order *order, int order_index, int /* Check range for aircraft. */ if (v->type == VEH_AIRCRAFT && Aircraft::From(v)->GetRange() > 0 && order->IsGotoOrder()) { - const Order *next = order->next != NULL ? order->next : v->GetFirstOrder(); + const Order *next = order->next != nullptr ? order->next : v->GetFirstOrder(); if (GetOrderDistance(order, next, v) > Aircraft::From(v)->acache.cached_max_range_sqr) SetDParam(8, STR_ORDER_OUT_OF_RANGE); } @@ -389,19 +388,27 @@ static Order GetOrderCmdFromTile(const Vehicle *v, TileIndex tile) return order; } - if (IsTileType(tile, MP_STATION)) { - StationID st_index = GetStationIndex(tile); - const Station *st = Station::Get(st_index); + /* check for station or industry with neutral station */ + if (IsTileType(tile, MP_STATION) || IsTileType(tile, MP_INDUSTRY)) { + const Station *st = nullptr; - if (st->owner == _local_company || st->owner == OWNER_NONE) { + if (IsTileType(tile, MP_STATION)) { + st = Station::GetByTile(tile); + } else { + const Industry *in = Industry::GetByTile(tile); + st = in->neutral_station; + } + if (st != nullptr && (st->owner == _local_company || st->owner == OWNER_NONE)) { byte facil; - (facil = FACIL_DOCK, v->type == VEH_SHIP) || - (facil = FACIL_TRAIN, v->type == VEH_TRAIN) || - (facil = FACIL_AIRPORT, v->type == VEH_AIRCRAFT) || - (facil = FACIL_BUS_STOP, v->type == VEH_ROAD && RoadVehicle::From(v)->IsBus()) || - (facil = FACIL_TRUCK_STOP, 1); + switch (v->type) { + case VEH_SHIP: facil = FACIL_DOCK; break; + case VEH_TRAIN: facil = FACIL_TRAIN; break; + case VEH_AIRCRAFT: facil = FACIL_AIRPORT; break; + case VEH_ROAD: facil = FACIL_BUS_STOP | FACIL_TRUCK_STOP; break; + default: NOT_REACHED(); + } if (st->facilities & facil) { - order.MakeGoToStation(st_index); + order.MakeGoToStation(st->index); if (_ctrl_pressed) order.SetLoadType(OLF_FULL_LOAD_ANY); if (_settings_client.gui.new_nonstop && v->IsGroundVehicle()) order.SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS); order.SetStopLocation(v->type == VEH_TRAIN ? (OrderStopLocation)(_settings_client.gui.stop_location) : OSL_PLATFORM_FAR_END); @@ -577,7 +584,7 @@ private: VehicleOrderID sel_ord = this->OrderGetSel(); const Order *order = this->vehicle->GetOrder(sel_ord); - if (order == NULL || order->GetLoadType() == load_type) return; + if (order == nullptr || order->GetLoadType() == load_type) return; if (load_type < 0) { load_type = order->GetLoadType() == OLF_LOAD_IF_POSSIBLE ? OLF_FULL_LOAD_ANY : OLF_LOAD_IF_POSSIBLE; @@ -602,7 +609,7 @@ private: if (i < 0) { const Order *order = this->vehicle->GetOrder(sel_ord); - if (order == NULL) return; + if (order == nullptr) return; i = (order->GetDepotOrderType() & ODTFB_SERVICE) ? DA_ALWAYS_GO : DA_SERVICE; } DoCommandP(this->vehicle->tile, this->vehicle->index + (sel_ord << 20), MOF_DEPOT_ACTION | (i << 4), CMD_MODIFY_ORDER | CMD_MSG(STR_ERROR_CAN_T_MODIFY_THIS_ORDER)); @@ -614,7 +621,7 @@ private: void OrderClick_NearestDepot() { Order order; - order.next = NULL; + order.next = nullptr; order.index = 0; order.MakeGoToDepot(0, ODTFB_PART_OF_ORDERS, _settings_client.gui.new_nonstop && this->vehicle->IsGroundVehicle() ? ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS : ONSF_STOP_EVERYWHERE); @@ -631,7 +638,7 @@ private: VehicleOrderID sel_ord = this->OrderGetSel(); const Order *order = this->vehicle->GetOrder(sel_ord); - if (order == NULL || order->GetUnloadType() == unload_type) return; + if (order == nullptr || order->GetUnloadType() == unload_type) return; if (unload_type < 0) { unload_type = order->GetUnloadType() == OUF_UNLOAD_IF_POSSIBLE ? OUFB_UNLOAD : OUF_UNLOAD_IF_POSSIBLE; @@ -673,7 +680,7 @@ private: VehicleOrderID sel_ord = this->OrderGetSel(); const Order *order = this->vehicle->GetOrder(sel_ord); - if (order == NULL || order->GetNonStopType() == non_stop) return; + if (order == nullptr || order->GetNonStopType() == non_stop) return; /* Keypress if negative, so 'toggle' to the next */ if (non_stop < 0) { @@ -761,7 +768,7 @@ private: { this->can_do_refit = false; this->can_do_autorefit = false; - for (const Vehicle *w = this->vehicle; w != NULL; w = w->IsGroundVehicle() ? w->Next() : NULL) { + for (const Vehicle *w = this->vehicle; w != nullptr; w = w->IsGroundVehicle() ? w->Next() : nullptr) { if (IsEngineRefittable(w->engine_type)) this->can_do_refit = true; if (HasBit(Engine::Get(w->engine_type)->info.misc_flags, EF_AUTO_REFIT)) this->can_do_autorefit = true; } @@ -799,7 +806,7 @@ public: this->OnInvalidateData(VIWD_MODIFY_ORDERS); } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_O_ORDER_LIST: @@ -836,7 +843,7 @@ public: * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { VehicleOrderID from = INVALID_VEH_ORDER_ID; VehicleOrderID to = INVALID_VEH_ORDER_ID; @@ -954,11 +961,11 @@ public: NWidgetStacked *right_sel = this->GetWidget(WID_O_SEL_TOP_RIGHT); /* Ship or airplane. */ NWidgetStacked *row_sel = this->GetWidget(WID_O_SEL_TOP_ROW); - assert(row_sel != NULL || (train_row_sel != NULL && left_sel != NULL && middle_sel != NULL && right_sel != NULL)); + assert(row_sel != nullptr || (train_row_sel != nullptr && left_sel != nullptr && middle_sel != nullptr && right_sel != nullptr)); - if (order == NULL) { - if (row_sel != NULL) { + if (order == nullptr) { + if (row_sel != nullptr) { row_sel->SetDisplayedPlane(DP_ROW_LOAD); } else { train_row_sel->SetDisplayedPlane(DP_GROUNDVEHICLE_ROW_NORMAL); @@ -977,7 +984,7 @@ public: switch (order->GetType()) { case OT_GOTO_STATION: - if (row_sel != NULL) { + if (row_sel != nullptr) { row_sel->SetDisplayedPlane(DP_ROW_LOAD); } else { train_row_sel->SetDisplayedPlane(DP_GROUNDVEHICLE_ROW_NORMAL); @@ -999,7 +1006,7 @@ public: break; case OT_GOTO_WAYPOINT: - if (row_sel != NULL) { + if (row_sel != nullptr) { row_sel->SetDisplayedPlane(DP_ROW_LOAD); } else { train_row_sel->SetDisplayedPlane(DP_GROUNDVEHICLE_ROW_NORMAL); @@ -1015,7 +1022,7 @@ public: break; case OT_GOTO_DEPOT: - if (row_sel != NULL) { + if (row_sel != nullptr) { row_sel->SetDisplayedPlane(DP_ROW_DEPOT); } else { train_row_sel->SetDisplayedPlane(DP_GROUNDVEHICLE_ROW_NORMAL); @@ -1034,7 +1041,7 @@ public: break; case OT_CONDITIONAL: { - if (row_sel != NULL) { + if (row_sel != nullptr) { row_sel->SetDisplayedPlane(DP_ROW_CONDITIONAL); } else { train_row_sel->SetDisplayedPlane(DP_GROUNDVEHICLE_ROW_CONDITIONAL); @@ -1049,7 +1056,7 @@ public: } default: // every other order - if (row_sel != NULL) { + if (row_sel != nullptr) { row_sel->SetDisplayedPlane(DP_ROW_LOAD); } else { train_row_sel->SetDisplayedPlane(DP_GROUNDVEHICLE_ROW_NORMAL); @@ -1071,7 +1078,7 @@ public: this->SetDirty(); } - virtual void OnPaint() + void OnPaint() override { if (this->vehicle->owner != _local_company) { this->selected_order = -1; // Disable selection any selected row at a competitor order window. @@ -1081,7 +1088,7 @@ public: this->DrawWidgets(); } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { if (widget != WID_O_ORDER_LIST) return; @@ -1097,7 +1104,7 @@ public: const Order *order = this->vehicle->GetOrder(i); /* First draw the highlighting underground if it exists. */ if (this->order_over != INVALID_VEH_ORDER_ID) { - while (order != NULL) { + while (order != nullptr) { /* Don't draw anything if it extends past the end of the window. */ if (!this->vscroll->IsVisible(i)) break; @@ -1122,7 +1129,7 @@ public: } /* Draw the orders. */ - while (order != NULL) { + while (order != nullptr) { /* Don't draw anything if it extends past the end of the window. */ if (!this->vscroll->IsVisible(i)) break; @@ -1139,14 +1146,14 @@ public: } } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { switch (widget) { case WID_O_COND_VALUE: { VehicleOrderID sel = this->OrderGetSel(); const Order *order = this->vehicle->GetOrder(sel); - if (order != NULL && order->IsType(OT_CONDITIONAL)) { + if (order != nullptr && order->IsType(OT_CONDITIONAL)) { uint value = order->GetConditionValue(); if (order->GetConditionVariable() == OCV_MAX_SPEED) value = ConvertSpeedToDisplaySpeed(value); SetDParam(0, value); @@ -1160,7 +1167,7 @@ public: } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_O_ORDER_LIST: { @@ -1168,7 +1175,7 @@ public: VehicleOrderID order_id = this->GetOrderFromPt(_cursor.pos.y - this->top); if (order_id != INVALID_VEH_ORDER_ID) { Order order; - order.next = NULL; + order.next = nullptr; order.index = 0; order.MakeConditional(order_id); @@ -1296,11 +1303,11 @@ public: break; case WID_O_COND_VARIABLE: { - DropDownList *list = new DropDownList(); + DropDownList list; for (uint i = 0; i < lengthof(_order_conditional_variable); i++) { - *list->Append() = new DropDownListStringItem(STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE + _order_conditional_variable[i], _order_conditional_variable[i], false); + list.emplace_back(new DropDownListStringItem(STR_ORDER_CONDITIONAL_LOAD_PERCENTAGE + _order_conditional_variable[i], _order_conditional_variable[i], false)); } - ShowDropDownList(this, list, this->vehicle->GetOrder(this->OrderGetSel())->GetConditionVariable(), WID_O_COND_VARIABLE); + ShowDropDownList(this, std::move(list), this->vehicle->GetOrder(this->OrderGetSel())->GetConditionVariable(), WID_O_COND_VARIABLE); break; } @@ -1325,7 +1332,7 @@ public: } } - virtual void OnQueryTextFinished(char *str) + void OnQueryTextFinished(char *str) override { if (!StrEmpty(str)) { VehicleOrderID sel = this->OrderGetSel(); @@ -1348,7 +1355,7 @@ public: } } - virtual void OnDropdownSelect(int widget, int index) + void OnDropdownSelect(int widget, int index) override { switch (widget) { case WID_O_NON_STOP: @@ -1391,7 +1398,7 @@ public: } } - virtual void OnDragDrop(Point pt, int widget) + void OnDragDrop(Point pt, int widget) override { switch (widget) { case WID_O_ORDER_LIST: { @@ -1424,7 +1431,7 @@ public: } } - virtual EventState OnHotkey(int hotkey) + EventState OnHotkey(int hotkey) override { if (this->vehicle->owner != _local_company) return ES_NOT_HANDLED; @@ -1445,7 +1452,7 @@ public: return ES_HANDLED; } - virtual void OnPlaceObject(Point pt, TileIndex tile) + void OnPlaceObject(Point pt, TileIndex tile) override { if (this->goto_type == OPOS_GOTO) { const Order cmd = GetOrderCmdFromTile(this->vehicle, tile); @@ -1458,7 +1465,7 @@ public: } } - virtual bool OnVehicleSelect(const Vehicle *v) + bool OnVehicleSelect(const Vehicle *v) override { /* v is vehicle getting orders. Only copy/clone orders if vehicle doesn't have any orders yet. * We disallow copying orders of other vehicles if we already have at least one order entry @@ -1476,7 +1483,7 @@ public: return true; } - virtual void OnPlaceObjectAbort() + void OnPlaceObjectAbort() override { this->goto_type = OPOS_NONE; this->SetWidgetDirty(WID_O_GOTO); @@ -1488,7 +1495,7 @@ public: } } - virtual void OnMouseDrag(Point pt, int widget) + void OnMouseDrag(Point pt, int widget) override { if (this->selected_order != -1 && widget == WID_O_ORDER_LIST) { /* An order is dragged.. */ @@ -1508,7 +1515,7 @@ public: } } - virtual void OnResize() + void OnResize() override { /* Update the scroll bar */ this->vscroll->SetCapacityFromWidget(this, WID_O_ORDER_LIST); @@ -1717,7 +1724,7 @@ void ShowOrdersWindow(const Vehicle *v) { DeleteWindowById(WC_VEHICLE_DETAILS, v->index, false); DeleteWindowById(WC_VEHICLE_TIMETABLE, v->index, false); - if (BringWindowToFrontById(WC_VEHICLE_ORDERS, v->index) != NULL) return; + if (BringWindowToFrontById(WC_VEHICLE_ORDERS, v->index) != nullptr) return; /* Using a different WindowDescs for _local_company causes problems. * Due to this we have to close order windows in ChangeWindowOwner/DeleteCompanyWindows, diff --git a/src/order_type.h b/src/order_type.h index b1e0fad539..9f4d0ba22b 100644 --- a/src/order_type.h +++ b/src/order_type.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. @@ -33,8 +31,8 @@ static const OrderID INVALID_ORDER = 0xFFFFFF; */ static const uint IMPLICIT_ORDER_ONLY_CAP = 32; -/** Order types */ -enum OrderType { +/** Order types. It needs to be 8bits, because we save and load it as such */ +enum OrderType : byte { OT_BEGIN = 0, OT_NOTHING = 0, OT_GOTO_STATION = 1, @@ -44,14 +42,10 @@ enum OrderType { OT_DUMMY = 5, OT_GOTO_WAYPOINT = 6, OT_CONDITIONAL = 7, - OT_IMPLICIT = 8, + OT_IMPLICIT = 8, OT_END }; -/** It needs to be 8bits, because we save and load it as such */ -typedef SimpleTinyEnumT OrderTypeByte; - - /** * Flags related to the unloading order. */ diff --git a/src/os/macosx/G5_detector.cpp b/src/os/macosx/G5_detector.cpp index 53d21c4d4f..cf2aeab0d5 100644 --- a/src/os/macosx/G5_detector.cpp +++ b/src/os/macosx/G5_detector.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. diff --git a/src/os/macosx/crashlog_osx.cpp b/src/os/macosx/crashlog_osx.cpp index ad258bbc91..17686d9e1a 100644 --- a/src/os/macosx/crashlog_osx.cpp +++ b/src/os/macosx/crashlog_osx.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. @@ -14,6 +12,7 @@ #include "../../string_func.h" #include "../../gamelog.h" #include "../../saveload/saveload.h" +#include "../../video/video_driver.hpp" #include "macos.h" #include @@ -52,7 +51,7 @@ class CrashLogOSX : public CrashLog { char filename_save[MAX_PATH]; ///< Path of crash.sav char filename_screenshot[MAX_PATH]; ///< Path of crash.(png|bmp|pcx) - /* virtual */ char *LogOSVersion(char *buffer, const char *last) const + char *LogOSVersion(char *buffer, const char *last) const override { int ver_maj, ver_min, ver_bug; GetMacOSVersion(&ver_maj, &ver_min, &ver_bug); @@ -66,12 +65,12 @@ class CrashLogOSX : public CrashLog { " Machine: %s\n" " Min Ver: %d\n", ver_maj, ver_min, ver_bug, - arch != NULL ? arch->description : "unknown", + arch != nullptr ? arch->description : "unknown", MAC_OS_X_VERSION_MIN_REQUIRED ); } - /* virtual */ char *LogError(char *buffer, const char *last, const char *message) const + char *LogError(char *buffer, const char *last, const char *message) const override { return buffer + seprintf(buffer, last, "Crash reason:\n" @@ -79,11 +78,11 @@ class CrashLogOSX : public CrashLog { " Message: %s\n\n", strsignal(this->signum), this->signum, - message == NULL ? "" : message + message == nullptr ? "" : message ); } - /* virtual */ char *LogStacktrace(char *buffer, const char *last) const + char *LogStacktrace(char *buffer, const char *last) const override { /* As backtrace() is only implemented in 10.5 or later, * we're rolling our own here. Mostly based on @@ -99,14 +98,14 @@ class CrashLogOSX : public CrashLog { frame = (void **)__builtin_frame_address(0); #endif - for (int i = 0; frame != NULL && i < MAX_STACK_FRAMES; i++) { + for (int i = 0; frame != nullptr && i < MAX_STACK_FRAMES; i++) { /* Get IP for current stack frame. */ #if defined(__ppc__) || defined(__ppc64__) void *ip = frame[2]; #else void *ip = frame[1]; #endif - if (ip == NULL) break; + if (ip == nullptr) break; /* Print running index. */ buffer += seprintf(buffer, last, " [%02d]", i); @@ -118,7 +117,7 @@ class CrashLogOSX : public CrashLog { if (dl_valid && dli.dli_fname) { /* Valid image name? Extract filename from the complete path. */ const char *s = strrchr(dli.dli_fname, '/'); - if (s != NULL) { + if (s != nullptr) { fname = s + 1; } else { fname = dli.dli_fname; @@ -128,13 +127,13 @@ class CrashLogOSX : public CrashLog { buffer += seprintf(buffer, last, " %-20s " PRINTF_PTR, fname, (uintptr_t)ip); /* Print function offset if information is available. */ - if (dl_valid && dli.dli_sname != NULL && dli.dli_saddr != NULL) { + if (dl_valid && dli.dli_sname != nullptr && dli.dli_saddr != nullptr) { /* Try to demangle a possible C++ symbol. */ int status = -1; - char *func_name = abi::__cxa_demangle(dli.dli_sname, NULL, 0, &status); + char *func_name = abi::__cxa_demangle(dli.dli_sname, nullptr, 0, &status); long int offset = (intptr_t)ip - (intptr_t)dli.dli_saddr; - buffer += seprintf(buffer, last, " (%s + %ld)", func_name != NULL ? func_name : dli.dli_sname, offset); + buffer += seprintf(buffer, last, " (%s + %ld)", func_name != nullptr ? func_name : dli.dli_sname, offset); free(func_name); } @@ -203,7 +202,7 @@ public: char message[1024]; seprintf(message, lastof(message), "Please send the generated crash information and the last (auto)save to the developers. " - "This will greatly help debugging. The correct place to do this is http://bugs.openttd.org.\n\n" + "This will greatly help debugging. The correct place to do this is https://github.com/OpenTTD/OpenTTD/issues.\n\n" "Generated file(s):\n%s\n%s\n%s", this->filename_log, this->filename_save, this->filename_screenshot); @@ -242,7 +241,9 @@ void CDECL HandleCrash(int signum) CrashLogOSX log(signum); log.MakeCrashLog(); - log.DisplayCrashDialog(); + if (VideoDriver::GetInstance() == nullptr || VideoDriver::GetInstance()->HasGUI()) { + log.DisplayCrashDialog(); + } CrashLog::AfterCrashLogCleanup(); abort(); diff --git a/src/os/macosx/macos.h b/src/os/macosx/macos.h index 4204d93bb6..2a7a12a5fb 100644 --- a/src/os/macosx/macos.h +++ b/src/os/macosx/macos.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. @@ -40,4 +38,17 @@ bool IsMonospaceFont(CFStringRef name); void MacOSSetThreadName(const char *name); + +/** Deleter that calls CFRelease rather than deleting the pointer. */ +template struct CFDeleter { + void operator()(T *p) + { + if (p) ::CFRelease(p); + } +}; + +/** Specialisation of std::unique_ptr for CoreFoundation objects. */ +template +using CFAutoRelease = std::unique_ptr::type, CFDeleter::type>>; + #endif /* MACOS_H */ diff --git a/src/os/macosx/macos.mm b/src/os/macosx/macos.mm index 7fb71fe9ee..33d2ad2192 100644 --- a/src/os/macosx/macos.mm +++ b/src/os/macosx/macos.mm @@ -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. @@ -206,23 +204,6 @@ bool GetClipboardContents(char *buffer, const char *last) } #endif -uint GetCPUCoreCount() -{ - uint count = 1; -#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) - if (MacOSVersionIsAtLeast(10, 5, 0)) { - count = (uint)[ [ NSProcessInfo processInfo ] activeProcessorCount ]; - } else -#endif - { -#if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) - count = MPProcessorsScheduled(); -#endif - } - - return count; -} - /** * Check if a font is a monospace font. * @param name Name of the font. diff --git a/src/os/macosx/osx_stdafx.h b/src/os/macosx/osx_stdafx.h index 70dc8030cc..476362cccd 100644 --- a/src/os/macosx/osx_stdafx.h +++ b/src/os/macosx/osx_stdafx.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. @@ -24,7 +22,7 @@ #define HAVE_OSX_1011_SDK #endif -/* It would seem that to ensure backward compability we have to ensure that we have defined MAC_OS_X_VERSION_10_x everywhere */ +/* It would seem that to ensure backward compatibility we have to ensure that we have defined MAC_OS_X_VERSION_10_x everywhere */ #ifndef MAC_OS_X_VERSION_10_3 #define MAC_OS_X_VERSION_10_3 1030 #endif diff --git a/src/os/macosx/splash.cpp b/src/os/macosx/splash.cpp index eadb785101..ac2f86425b 100644 --- a/src/os/macosx/splash.cpp +++ b/src/os/macosx/splash.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. @@ -54,7 +52,7 @@ static void PNGAPI png_my_warning(png_structp png_ptr, png_const_charp message) void DisplaySplashImage() { FILE *f = FioFOpenFile(SPLASH_IMAGE_FILE, "r", BASESET_DIR); - if (f == NULL) return; + if (f == nullptr) return; png_byte header[8]; fread(header, sizeof(png_byte), 8, f); @@ -63,23 +61,23 @@ void DisplaySplashImage() return; } - png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp) NULL, png_my_error, png_my_warning); + png_structp png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, (png_voidp) nullptr, png_my_error, png_my_warning); - if (png_ptr == NULL) { + if (png_ptr == nullptr) { fclose(f); return; } png_infop info_ptr = png_create_info_struct(png_ptr); - if (info_ptr == NULL) { - png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL); + if (info_ptr == nullptr) { + png_destroy_read_struct(&png_ptr, (png_infopp)nullptr, (png_infopp)nullptr); fclose(f); return; } png_infop end_info = png_create_info_struct(png_ptr); - if (end_info == NULL) { - png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL); + if (end_info == nullptr) { + png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)nullptr); fclose(f); return; } @@ -93,7 +91,7 @@ void DisplaySplashImage() png_init_io(png_ptr, f); png_set_sig_bytes(png_ptr, 8); - png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, NULL); + png_read_png(png_ptr, info_ptr, PNG_TRANSFORM_IDENTITY, nullptr); uint width = png_get_image_width(png_ptr, info_ptr); uint height = png_get_image_height(png_ptr, info_ptr); diff --git a/src/os/macosx/splash.h b/src/os/macosx/splash.h index 90e6638140..8ddb638578 100644 --- a/src/os/macosx/splash.h +++ b/src/os/macosx/splash.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/os/macosx/string_osx.cpp b/src/os/macosx/string_osx.cpp index 1c5d558855..63be4d3ad9 100644 --- a/src/os/macosx/string_osx.cpp +++ b/src/os/macosx/string_osx.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. @@ -22,9 +20,9 @@ #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) /** Cached current locale. */ -static CFLocaleRef _osx_locale = NULL; +static CFAutoRelease _osx_locale; /** CoreText cache for font information, cleared when OTTD changes fonts. */ -static CTFontRef _font_cache[FS_END]; +static CFAutoRelease _font_cache[FS_END]; /** @@ -36,7 +34,7 @@ private: ptrdiff_t length; const FontMap& font_map; - CTTypesetterRef typesetter; + CFAutoRelease typesetter; CFIndex cur_offset = 0; ///< Offset from the start of the current run from where to output. @@ -53,64 +51,59 @@ public: public: CoreTextVisualRun(CTRunRef run, Font *font, const CoreTextParagraphLayoutFactory::CharType *buff); + CoreTextVisualRun(CoreTextVisualRun &&other) = default; - virtual const GlyphID *GetGlyphs() const { return &this->glyphs[0]; } - virtual const float *GetPositions() const { return &this->positions[0]; } - virtual const int *GetGlyphToCharMap() const { return &this->glyph_to_char[0]; } + const GlyphID *GetGlyphs() const override { return &this->glyphs[0]; } + const float *GetPositions() const override { return &this->positions[0]; } + const int *GetGlyphToCharMap() const override { return &this->glyph_to_char[0]; } - virtual const Font *GetFont() const { return this->font; } - virtual int GetLeading() const { return this->font->fc->GetHeight(); } - virtual int GetGlyphCount() const { return (int)this->glyphs.size(); } + const Font *GetFont() const override { return this->font; } + int GetLeading() const override { return this->font->fc->GetHeight(); } + int GetGlyphCount() const override { return (int)this->glyphs.size(); } int GetAdvance() const { return this->total_advance; } }; /** A single line worth of VisualRuns. */ - class CoreTextLine : public AutoDeleteSmallVector, public ParagraphLayouter::Line { + class CoreTextLine : public std::vector, public ParagraphLayouter::Line { public: - CoreTextLine(CTLineRef line, const FontMap &fontMapping, const CoreTextParagraphLayoutFactory::CharType *buff) + CoreTextLine(CFAutoRelease line, const FontMap &fontMapping, const CoreTextParagraphLayoutFactory::CharType *buff) { - CFArrayRef runs = CTLineGetGlyphRuns(line); + CFArrayRef runs = CTLineGetGlyphRuns(line.get()); for (CFIndex i = 0; i < CFArrayGetCount(runs); i++) { CTRunRef run = (CTRunRef)CFArrayGetValueAtIndex(runs, i); /* Extract font information for this run. */ CFRange chars = CTRunGetStringRange(run); - FontMap::const_iterator map = fontMapping.Begin(); - while (map < fontMapping.End() - 1 && map->first <= chars.location) map++; + auto map = fontMapping.begin(); + while (map < fontMapping.end() - 1 && map->first <= chars.location) map++; - *this->Append() = new CoreTextVisualRun(run, map->second, buff); + this->emplace_back(run, map->second, buff); } - CFRelease(line); } - virtual int GetLeading() const; - virtual int GetWidth() const; - virtual int CountRuns() const { return this->Length(); } - virtual const VisualRun *GetVisualRun(int run) const { return *this->Get(run); } + int GetLeading() const override; + int GetWidth() const override; + int CountRuns() const override { return this->size(); } + const VisualRun &GetVisualRun(int run) const override { return this->at(run); } - int GetInternalCharLength(WChar c) const + int GetInternalCharLength(WChar c) const override { /* CoreText uses UTF-16 internally which means we need to account for surrogate pairs. */ return c >= 0x010000U ? 2 : 1; } }; - CoreTextParagraphLayout(CTTypesetterRef typesetter, const CoreTextParagraphLayoutFactory::CharType *buffer, ptrdiff_t len, const FontMap &fontMapping) : text_buffer(buffer), length(len), font_map(fontMapping), typesetter(typesetter) + CoreTextParagraphLayout(CFAutoRelease typesetter, const CoreTextParagraphLayoutFactory::CharType *buffer, ptrdiff_t len, const FontMap &fontMapping) : text_buffer(buffer), length(len), font_map(fontMapping), typesetter(std::move(typesetter)) { this->Reflow(); } - virtual ~CoreTextParagraphLayout() - { - CFRelease(this->typesetter); - } - - virtual void Reflow() + void Reflow() override { this->cur_offset = 0; } - virtual const Line *NextLine(int max_width); + std::unique_ptr NextLine(int max_width) override; }; @@ -124,82 +117,78 @@ static CGFloat SpriteFontGetWidth(void *ref_con) } static CTRunDelegateCallbacks _sprite_font_callback = { - kCTRunDelegateCurrentVersion, NULL, NULL, NULL, + kCTRunDelegateCurrentVersion, nullptr, nullptr, nullptr, &SpriteFontGetWidth }; /* static */ ParagraphLayouter *CoreTextParagraphLayoutFactory::GetParagraphLayout(CharType *buff, CharType *buff_end, FontMap &fontMapping) { - if (!MacOSVersionIsAtLeast(10, 5, 0)) return NULL; + if (!MacOSVersionIsAtLeast(10, 5, 0)) return nullptr; /* Can't layout an empty string. */ ptrdiff_t length = buff_end - buff; - if (length == 0) return NULL; + if (length == 0) return nullptr; /* Can't layout our in-built sprite fonts. */ - for (FontMap::const_iterator i = fontMapping.Begin(); i != fontMapping.End(); i++) { - if (i->second->fc->IsBuiltInFont()) return NULL; + for (const auto &i : fontMapping) { + if (i.second->fc->IsBuiltInFont()) return nullptr; } /* Make attributed string with embedded font information. */ - CFMutableAttributedStringRef str = CFAttributedStringCreateMutable(kCFAllocatorDefault, 0); - CFAttributedStringBeginEditing(str); + CFAutoRelease str(CFAttributedStringCreateMutable(kCFAllocatorDefault, 0)); + CFAttributedStringBeginEditing(str.get()); - CFStringRef base = CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault, buff, length, kCFAllocatorNull); - CFAttributedStringReplaceString(str, CFRangeMake(0, 0), base); - CFRelease(base); + CFAutoRelease base(CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault, buff, length, kCFAllocatorNull)); + CFAttributedStringReplaceString(str.get(), CFRangeMake(0, 0), base.get()); /* Apply font and colour ranges to our string. This is important to make sure * that we get proper glyph boundaries on style changes. */ int last = 0; - for (FontMap::const_iterator i = fontMapping.Begin(); i != fontMapping.End(); i++) { - if (i->first - last == 0) continue; + for (const auto &i : fontMapping) { + if (i.first - last == 0) continue; - if (_font_cache[i->second->fc->GetSize()] == NULL) { + if (!_font_cache[i.second->fc->GetSize()]) { /* Cache font information. */ - CFStringRef font_name = CFStringCreateWithCString(kCFAllocatorDefault, i->second->fc->GetFontName(), kCFStringEncodingUTF8); - _font_cache[i->second->fc->GetSize()] = CTFontCreateWithName(font_name, i->second->fc->GetFontSize(), NULL); - CFRelease(font_name); + CFAutoRelease font_name(CFStringCreateWithCString(kCFAllocatorDefault, i.second->fc->GetFontName(), kCFStringEncodingUTF8)); + _font_cache[i.second->fc->GetSize()].reset(CTFontCreateWithName(font_name.get(), i.second->fc->GetFontSize(), nullptr)); } - CFAttributedStringSetAttribute(str, CFRangeMake(last, i->first - last), kCTFontAttributeName, _font_cache[i->second->fc->GetSize()]); + CFAttributedStringSetAttribute(str.get(), CFRangeMake(last, i.first - last), kCTFontAttributeName, _font_cache[i.second->fc->GetSize()].get()); - CGColorRef color = CGColorCreateGenericGray((uint8)i->second->colour / 255.0f, 1.0f); // We don't care about the real colours, just that they are different. - CFAttributedStringSetAttribute(str, CFRangeMake(last, i->first - last), kCTForegroundColorAttributeName, color); + CGColorRef color = CGColorCreateGenericGray((uint8)i.second->colour / 255.0f, 1.0f); // We don't care about the real colours, just that they are different. + CFAttributedStringSetAttribute(str.get(), CFRangeMake(last, i.first - last), kCTForegroundColorAttributeName, color); CGColorRelease(color); /* Install a size callback for our special sprite glyphs. */ - for (ssize_t c = last; c < i->first; c++) { + for (ssize_t c = last; c < i.first; c++) { if (buff[c] >= SCC_SPRITE_START && buff[c] <= SCC_SPRITE_END) { - CTRunDelegateRef del = CTRunDelegateCreate(&_sprite_font_callback, (void *)(size_t)(buff[c] | (i->second->fc->GetSize() << 24))); - CFAttributedStringSetAttribute(str, CFRangeMake(c, 1), kCTRunDelegateAttributeName, del); - CFRelease(del); + CFAutoRelease del(CTRunDelegateCreate(&_sprite_font_callback, (void *)(size_t)(buff[c] | (i.second->fc->GetSize() << 24)))); + CFAttributedStringSetAttribute(str.get(), CFRangeMake(c, 1), kCTRunDelegateAttributeName, del.get()); } } - last = i->first; + last = i.first; } - CFAttributedStringEndEditing(str); + CFAttributedStringEndEditing(str.get()); /* Create and return typesetter for the string. */ - CTTypesetterRef typesetter = CTTypesetterCreateWithAttributedString(str); - CFRelease(str); + CFAutoRelease typesetter(CTTypesetterCreateWithAttributedString(str.get())); - return typesetter != NULL ? new CoreTextParagraphLayout(typesetter, buff, length, fontMapping) : NULL; + return typesetter ? new CoreTextParagraphLayout(std::move(typesetter), buff, length, fontMapping) : nullptr; } -/* virtual */ const CoreTextParagraphLayout::Line *CoreTextParagraphLayout::NextLine(int max_width) +/* virtual */ std::unique_ptr CoreTextParagraphLayout::NextLine(int max_width) { - if (this->cur_offset >= this->length) return NULL; + if (this->cur_offset >= this->length) return nullptr; /* Get line break position, trying word breaking first and breaking somewhere if that doesn't work. */ - CFIndex len = CTTypesetterSuggestLineBreak(this->typesetter, this->cur_offset, max_width); - if (len <= 0) len = CTTypesetterSuggestClusterBreak(this->typesetter, this->cur_offset, max_width); + CFIndex len = CTTypesetterSuggestLineBreak(this->typesetter.get(), this->cur_offset, max_width); + if (len <= 0) len = CTTypesetterSuggestClusterBreak(this->typesetter.get(), this->cur_offset, max_width); /* Create line. */ - CTLineRef line = CTTypesetterCreateLine(this->typesetter, CFRangeMake(this->cur_offset, len)); + CFAutoRelease line(CTTypesetterCreateLine(this->typesetter.get(), CFRangeMake(this->cur_offset, len))); this->cur_offset += len; - return line != NULL ? new CoreTextLine(line, this->font_map, this->text_buffer) : NULL; + return std::unique_ptr(line ? new CoreTextLine(std::move(line), this->font_map, this->text_buffer) : nullptr); } CoreTextParagraphLayout::CoreTextVisualRun::CoreTextVisualRun(CTRunRef run, Font *font, const CoreTextParagraphLayoutFactory::CharType *buff) : font(font) @@ -232,7 +221,7 @@ CoreTextParagraphLayout::CoreTextVisualRun::CoreTextVisualRun(CTRunRef run, Font this->positions[i * 2 + 1] = pts[i].y; } } - this->total_advance = (int)CTRunGetTypographicBounds(run, CFRangeMake(0, 0), NULL, NULL, NULL); + this->total_advance = (int)CTRunGetTypographicBounds(run, CFRangeMake(0, 0), nullptr, nullptr, nullptr); this->positions[this->glyphs.size() * 2] = this->positions[0] + this->total_advance; } @@ -243,8 +232,8 @@ CoreTextParagraphLayout::CoreTextVisualRun::CoreTextVisualRun(CTRunRef run, Font int CoreTextParagraphLayout::CoreTextLine::GetLeading() const { int leading = 0; - for (const CoreTextVisualRun * const *run = this->Begin(); run != this->End(); run++) { - leading = max(leading, (*run)->GetLeading()); + for (const auto &run : *this) { + leading = max(leading, run.GetLeading()); } return leading; @@ -256,11 +245,11 @@ int CoreTextParagraphLayout::CoreTextLine::GetLeading() const */ int CoreTextParagraphLayout::CoreTextLine::GetWidth() const { - if (this->Length() == 0) return 0; + if (this->size() == 0) return 0; int total_width = 0; - for (const CoreTextVisualRun * const *run = this->Begin(); run != this->End(); run++) { - total_width += (*run)->GetAdvance(); + for (const auto &run : *this) { + total_width += run.GetAdvance(); } return total_width; @@ -270,10 +259,7 @@ int CoreTextParagraphLayout::CoreTextLine::GetWidth() const /** Delete CoreText font reference for a specific font size. */ void MacOSResetScriptCache(FontSize size) { - if (_font_cache[size] != NULL) { - CFRelease(_font_cache[size]); - _font_cache[size] = NULL; - } + _font_cache[size].reset(); } /** Store current language locale as a CoreFounation locale. */ @@ -281,11 +267,8 @@ void MacOSSetCurrentLocaleName(const char *iso_code) { if (!MacOSVersionIsAtLeast(10, 5, 0)) return; - if (_osx_locale != NULL) CFRelease(_osx_locale); - - CFStringRef iso = CFStringCreateWithCString(kCFAllocatorNull, iso_code, kCFStringEncodingUTF8); - _osx_locale = CFLocaleCreate(kCFAllocatorDefault, iso); - CFRelease(iso); + CFAutoRelease iso(CFStringCreateWithCString(kCFAllocatorDefault, iso_code, kCFStringEncodingUTF8)); + _osx_locale.reset(CFLocaleCreate(kCFAllocatorDefault, iso.get())); } /** @@ -302,15 +285,13 @@ int MacOSStringCompare(const char *s1, const char *s2) CFStringCompareFlags flags = kCFCompareCaseInsensitive | kCFCompareNumerically | kCFCompareLocalized | kCFCompareWidthInsensitive | kCFCompareForcedOrdering; - CFStringRef cf1 = CFStringCreateWithCString(kCFAllocatorDefault, s1, kCFStringEncodingUTF8); - CFStringRef cf2 = CFStringCreateWithCString(kCFAllocatorDefault, s2, kCFStringEncodingUTF8); + CFAutoRelease cf1(CFStringCreateWithCString(kCFAllocatorDefault, s1, kCFStringEncodingUTF8)); + CFAutoRelease cf2(CFStringCreateWithCString(kCFAllocatorDefault, s2, kCFStringEncodingUTF8)); - CFComparisonResult res = CFStringCompareWithOptionsAndLocale(cf1, cf2, CFRangeMake(0, CFStringGetLength(cf1)), flags, _osx_locale); + /* If any CFString could not be created (e.g., due to UTF8 invalid chars), return OS unsupported functionality */ + if (cf1 == nullptr || cf2 == nullptr) return 0; - CFRelease(cf1); - CFRelease(cf2); - - return (int)res + 2; + return (int)CFStringCompareWithOptionsAndLocale(cf1.get(), cf2.get(), CFRangeMake(0, CFStringGetLength(cf1.get())), flags, _osx_locale.get()) + 2; } @@ -345,30 +326,27 @@ int MacOSStringCompare(const char *s1, const char *s2) this->str_info.resize(utf16_to_utf8.size()); if (utf16_str.size() > 0) { - CFStringRef str = CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault, &utf16_str[0], utf16_str.size(), kCFAllocatorNull); + CFAutoRelease str(CFStringCreateWithCharactersNoCopy(kCFAllocatorDefault, &utf16_str[0], utf16_str.size(), kCFAllocatorNull)); /* Get cluster breaks. */ - for (CFIndex i = 0; i < CFStringGetLength(str); ) { - CFRange r = CFStringGetRangeOfComposedCharactersAtIndex(str, i); + for (CFIndex i = 0; i < CFStringGetLength(str.get()); ) { + CFRange r = CFStringGetRangeOfComposedCharactersAtIndex(str.get(), i); this->str_info[r.location].char_stop = true; i += r.length; } /* Get word breaks. */ - CFStringTokenizerRef tokenizer = CFStringTokenizerCreate(kCFAllocatorDefault, str, CFRangeMake(0, CFStringGetLength(str)), kCFStringTokenizerUnitWordBoundary, _osx_locale); + CFAutoRelease tokenizer(CFStringTokenizerCreate(kCFAllocatorDefault, str.get(), CFRangeMake(0, CFStringGetLength(str.get())), kCFStringTokenizerUnitWordBoundary, _osx_locale.get())); CFStringTokenizerTokenType tokenType = kCFStringTokenizerTokenNone; - while ((tokenType = CFStringTokenizerAdvanceToNextToken(tokenizer)) != kCFStringTokenizerTokenNone) { + while ((tokenType = CFStringTokenizerAdvanceToNextToken(tokenizer.get())) != kCFStringTokenizerTokenNone) { /* Skip tokens that are white-space or punctuation tokens. */ if ((tokenType & kCFStringTokenizerTokenHasNonLettersMask) != kCFStringTokenizerTokenHasNonLettersMask) { - CFRange r = CFStringTokenizerGetCurrentTokenRange(tokenizer); + CFRange r = CFStringTokenizerGetCurrentTokenRange(tokenizer.get()); this->str_info[r.location].word_stop = true; } } - - CFRelease(tokenizer); - CFRelease(str); } /* End-of-string is always a valid stopping point. */ @@ -424,7 +402,7 @@ int MacOSStringCompare(const char *s1, const char *s2) /* static */ StringIterator *OSXStringIterator::Create() { - if (!MacOSVersionIsAtLeast(10, 5, 0)) return NULL; + if (!MacOSVersionIsAtLeast(10, 5, 0)) return nullptr; return new OSXStringIterator(); } @@ -440,11 +418,11 @@ int MacOSStringCompare(const char *s1, const char *s2) /* static */ StringIterator *OSXStringIterator::Create() { - return NULL; + return nullptr; } /* static */ ParagraphLayouter *CoreTextParagraphLayoutFactory::GetParagraphLayout(CharType *buff, CharType *buff_end, FontMap &fontMapping) { - return NULL; + return nullptr; } #endif /* (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) */ diff --git a/src/os/macosx/string_osx.h b/src/os/macosx/string_osx.h index d632b0a440..39f255b162 100644 --- a/src/os/macosx/string_osx.h +++ b/src/os/macosx/string_osx.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. @@ -30,10 +28,10 @@ class OSXStringIterator : public StringIterator { size_t cur_pos; ///< Current iteration position. public: - virtual void SetString(const char *s); - virtual size_t SetCurPosition(size_t pos); - virtual size_t Next(IterType what); - virtual size_t Prev(IterType what); + void SetString(const char *s) override; + size_t SetCurPosition(size_t pos) override; + size_t Next(IterType what) override; + size_t Prev(IterType what) override; static StringIterator *Create(); }; diff --git a/src/os/os2/os2.cpp b/src/os/os2/os2.cpp index 7b34f528a6..a44c10a3b7 100644 --- a/src/os/os2/os2.cpp +++ b/src/os/os2/os2.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. @@ -18,6 +16,7 @@ #include "../../core/random_func.hpp" #include "../../string_func.h" #include "../../textbuf_gui.h" +#include "../../thread.h" #include "table/strings.h" @@ -101,7 +100,7 @@ bool FiosGetDiskFreeSpace(const char *path, uint64 *tot) struct diskfree_t free; char drive = path[0] - 'A' + 1; - if (tot != NULL && _getdiskfree(drive, &free) == 0) { + if (tot != nullptr && _getdiskfree(drive, &free) == 0) { *tot = free.avail_clusters * free.sectors_per_cluster * free.bytes_per_sector; return true; } @@ -118,7 +117,7 @@ bool FiosGetDiskFreeSpace(const char *path, uint64 *tot) free = (uint64)s.f_frsize * s.f_bavail; } #endif - if (tot != NULL) *tot = free; + if (tot != nullptr) *tot = free; return true; #endif } @@ -172,7 +171,7 @@ void ShowOSErrorBox(const char *buf, bool system) int CDECL main(int argc, char *argv[]) { - SetRandomSeed(time(NULL)); + SetRandomSeed(time(nullptr)); /* Make sure our arguments contain only valid UTF-8 characters. */ for (int i = 0; i < argc; i++) ValidateString(argv[i]); @@ -190,7 +189,7 @@ bool GetClipboardContents(char *buffer, const char *last) { const char *text = (const char*)WinQueryClipbrdData(hab, CF_TEXT); - if (text != NULL) + if (text != nullptr) { strecpy(buffer, text, last); WinCloseClipbrd(hab); @@ -204,25 +203,15 @@ bool GetClipboardContents(char *buffer, const char *last) } -void CSleep(int milliseconds) -{ -#ifndef __INNOTEK_LIBC__ - delay(milliseconds); -#else - usleep(milliseconds * 1000); -#endif -} - const char *FS2OTTD(const char *name) {return name;} const char *OTTD2FS(const char *name) {return name;} -uint GetCPUCoreCount() -{ - return 1; -} - void OSOpenBrowser(const char *url) { // stub only DEBUG(misc, 0, "Failed to open url: %s", url); } + +void SetCurrentThreadName(const char *) +{ +} diff --git a/src/os/unix/crashlog_unix.cpp b/src/os/unix/crashlog_unix.cpp index c0663a6b06..506f616caf 100644 --- a/src/os/unix/crashlog_unix.cpp +++ b/src/os/unix/crashlog_unix.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. @@ -40,7 +38,7 @@ class CrashLogUnix : public CrashLog { /** Signal that has been thrown. */ int signum; - /* virtual */ char *LogOSVersion(char *buffer, const char *last) const + char *LogOSVersion(char *buffer, const char *last) const override { struct utsname name; if (uname(&name) < 0) { @@ -60,7 +58,7 @@ class CrashLogUnix : public CrashLog { ); } - /* virtual */ char *LogError(char *buffer, const char *last, const char *message) const + char *LogError(char *buffer, const char *last, const char *message) const override { return buffer + seprintf(buffer, last, "Crash reason:\n" @@ -68,7 +66,7 @@ class CrashLogUnix : public CrashLog { " Message: %s\n\n", strsignal(this->signum), this->signum, - message == NULL ? "" : message + message == nullptr ? "" : message ); } @@ -105,7 +103,7 @@ class CrashLogUnix : public CrashLog { } #endif - /* virtual */ char *LogStacktrace(char *buffer, const char *last) const + char *LogStacktrace(char *buffer, const char *last) const override { buffer += seprintf(buffer, last, "Stacktrace:\n"); #if defined(__GLIBC__) diff --git a/src/os/unix/unix.cpp b/src/os/unix/unix.cpp index 6a25d9444e..aa79354d06 100644 --- a/src/os/unix/unix.cpp +++ b/src/os/unix/unix.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. @@ -17,6 +15,7 @@ #include "../../debug.h" #include "../../string_func.h" #include "../../fios.h" +#include "../../thread.h" #include @@ -43,26 +42,17 @@ #include #endif - -#ifdef __MORPHOS__ -#include -ULONG __stack = (1024*1024)*2; // maybe not that much is needed actually ;) - -/* The system supplied definition of SIG_IGN does not match */ -#undef SIG_IGN -#define SIG_IGN (void (*)(int))1 -#endif /* __MORPHOS__ */ - -#ifdef __AMIGA__ -#warning add stack symbol to avoid that user needs to set stack manually (tokai) -// ULONG __stack = +#ifndef NO_THREADS +#include #endif #if defined(__APPLE__) - #if defined(WITH_SDL) +# if defined(WITH_SDL) /* the mac implementation needs this file included in the same file as main() */ - #include - #endif +# include +# endif + +# include "../macosx/macos.h" #endif #ifdef __ANDROID__ @@ -73,13 +63,7 @@ ULONG __stack = (1024*1024)*2; // maybe not that much is needed actually ;) bool FiosIsRoot(const char *path) { -#if !defined(__MORPHOS__) && !defined(__AMIGAOS__) return path[1] == '\0'; -#else - /* On MorphOS or AmigaOS paths look like: "Volume:directory/subdirectory" */ - const char *s = strchr(path, ':'); - return s != NULL && s[1] == '\0'; -#endif } void FiosGetDrives(FileList &file_list) @@ -102,7 +86,7 @@ bool FiosGetDiskFreeSpace(const char *path, uint64 *tot) if (statvfs(path, &s) != 0) return false; free = (uint64)s.f_frsize * s.f_bavail; #endif - if (tot != NULL) *tot = free; + if (tot != nullptr) *tot = free; return true; } @@ -110,15 +94,8 @@ bool FiosIsValidFile(const char *path, const struct dirent *ent, struct stat *sb { char filename[MAX_PATH]; int res; -#if defined(__MORPHOS__) || defined(__AMIGAOS__) - /* On MorphOS or AmigaOS paths look like: "Volume:directory/subdirectory" */ - if (FiosIsRoot(path)) { - res = seprintf(filename, lastof(filename), "%s:%s", path, ent->d_name); - } else // XXX - only next line! -#else assert(path[strlen(path) - 1] == PATHSEPCHAR); if (strlen(path) > 2) assert(path[strlen(path) - 2] != PATHSEPCHAR); -#endif res = seprintf(filename, lastof(filename), "%s%s", path, ent->d_name); /* Could we fully concatenate the path and filename? */ @@ -155,9 +132,9 @@ static const char *GetLocalCode() #else /* Strip locale (eg en_US.UTF-8) to only have UTF-8 */ const char *locale = GetCurrentLocale("LC_CTYPE"); - if (locale != NULL) locale = strchr(locale, '.'); + if (locale != nullptr) locale = strchr(locale, '.'); - return (locale == NULL) ? "" : locale + 1; + return (locale == nullptr) ? "" : locale + 1; #endif } @@ -183,7 +160,7 @@ static const char *convert_tofrom_fs(iconv_t convd, const char *name) strecpy(outbuf, name, outbuf + outlen); - iconv(convd, NULL, NULL, NULL, NULL); + iconv(convd, nullptr, nullptr, nullptr, nullptr); if (iconv(convd, &inbuf, &inlen, &outbuf, &outlen) == (size_t)(-1)) { DEBUG(misc, 0, "[iconv] error converting '%s'. Errno %d", name, errno); } @@ -279,13 +256,13 @@ int CDECL main(int argc, char *argv[]) cocoaSetupAutoreleasePool(); /* This is passed if we are launched by double-clicking */ if (argc >= 2 && strncmp(argv[1], "-psn", 4) == 0) { - argv[1] = NULL; + argv[1] = nullptr; argc = 1; } #endif CrashLog::InitialiseCrashLog(); - SetRandomSeed(time(NULL)); + SetRandomSeed(time(nullptr)); signal(SIGPIPE, SIG_IGN); @@ -306,74 +283,7 @@ bool GetClipboardContents(char *buffer, const char *last) #endif -/* multi os compatible sleep function */ - -#ifdef __AMIGA__ -/* usleep() implementation */ -# include -# include - - extern struct Device *TimerBase = NULL; - extern struct MsgPort *TimerPort = NULL; - extern struct timerequest *TimerRequest = NULL; -#endif /* __AMIGA__ */ - -void CSleep(int milliseconds) -{ - #if defined(__BEOS__) - snooze(milliseconds * 1000); - #elif defined(__AMIGA__) - { - ULONG signals; - ULONG TimerSigBit = 1 << TimerPort->mp_SigBit; - - /* send IORequest */ - TimerRequest->tr_node.io_Command = TR_ADDREQUEST; - TimerRequest->tr_time.tv_secs = (milliseconds * 1000) / 1000000; - TimerRequest->tr_time.tv_micro = (milliseconds * 1000) % 1000000; - SendIO((struct IORequest *)TimerRequest); - - if (!((signals = Wait(TimerSigBit | SIGBREAKF_CTRL_C)) & TimerSigBit) ) { - AbortIO((struct IORequest *)TimerRequest); - } - WaitIO((struct IORequest *)TimerRequest); - } - #else - usleep(milliseconds * 1000); - #endif -} - - #ifndef __APPLE__ -uint GetCPUCoreCount() -{ - uint count = 1; -#ifdef HAS_SYSCTL - int ncpu = 0; - size_t len = sizeof(ncpu); - -#ifdef OPENBSD - int name[2]; - name[0] = CTL_HW; - name[1] = HW_NCPU; - if (sysctl(name, 2, &ncpu, &len, NULL, 0) < 0) { - ncpu = 0; - } -#else - if (sysctlbyname("hw.availcpu", &ncpu, &len, NULL, 0) < 0) { - sysctlbyname("hw.ncpu", &ncpu, &len, NULL, 0); - } -#endif /* #ifdef OPENBSD */ - - if (ncpu > 0) count = ncpu; -#elif defined(_SC_NPROCESSORS_ONLN) - long res = sysconf(_SC_NPROCESSORS_ONLN); - if (res > 0) count = res; -#endif - - return count; -} - void OSOpenBrowser(const char *url) { pid_t child_pid = fork(); @@ -394,10 +304,21 @@ void OSOpenBrowser(const char *url) const char *args[3]; args[0] = "xdg-open"; args[1] = url; - args[2] = NULL; + args[2] = nullptr; #endif execvp(args[0], const_cast(args)); DEBUG(misc, 0, "Failed to open url: %s", url); exit(0); } -#endif +#endif /* __APPLE__ */ + +void SetCurrentThreadName(const char *threadName) { +#if !defined(NO_THREADS) && defined(__GLIBC__) +#if __GLIBC_PREREQ(2, 12) + if (threadName) pthread_setname_np(pthread_self(), threadName); +#endif /* __GLIBC_PREREQ(2, 12) */ +#endif /* !defined(NO_THREADS) && defined(__GLIBC__) */ +#if defined(__APPLE__) + MacOSSetThreadName(threadName); +#endif /* defined(__APPLE__) */ +} diff --git a/src/os/windows/crashlog_win.cpp b/src/os/windows/crashlog_win.cpp index 1abb0e725c..9585bdf20f 100644 --- a/src/os/windows/crashlog_win.cpp +++ b/src/os/windows/crashlog_win.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. @@ -26,9 +24,6 @@ #include "../../safeguards.h" -static const uint MAX_SYMBOL_LEN = 512; -static const uint MAX_FRAMES = 64; - /* printf format specification for 32/64-bit addresses. */ #ifdef _M_AMD64 #define PRINTF_PTR "0x%016IX" @@ -43,14 +38,14 @@ class CrashLogWindows : public CrashLog { /** Information about the encountered exception */ EXCEPTION_POINTERS *ep; - /* virtual */ char *LogOSVersion(char *buffer, const char *last) const; - /* virtual */ char *LogError(char *buffer, const char *last, const char *message) const; - /* virtual */ char *LogStacktrace(char *buffer, const char *last) const; - /* virtual */ char *LogRegisters(char *buffer, const char *last) const; - /* virtual */ char *LogModules(char *buffer, const char *last) const; + char *LogOSVersion(char *buffer, const char *last) const override; + char *LogError(char *buffer, const char *last, const char *message) const override; + char *LogStacktrace(char *buffer, const char *last) const override; + char *LogRegisters(char *buffer, const char *last) const override; + char *LogModules(char *buffer, const char *last) const override; public: #if defined(_MSC_VER) - /* virtual */ int WriteCrashDump(char *filename, const char *filename_last) const; + int WriteCrashDump(char *filename, const char *filename_last) const override; char *AppendDecodedStacktrace(char *buffer, const char *last) const; #else char *AppendDecodedStacktrace(char *buffer, const char *last) const { return buffer; } @@ -69,7 +64,7 @@ public: * A crash log is always generated when it's generated. * @param ep the data related to the exception. */ - CrashLogWindows(EXCEPTION_POINTERS *ep = NULL) : + CrashLogWindows(EXCEPTION_POINTERS *ep = nullptr) : ep(ep) { this->crashlog[0] = '\0'; @@ -84,7 +79,7 @@ public: static CrashLogWindows *current; }; -/* static */ CrashLogWindows *CrashLogWindows::current = NULL; +/* static */ CrashLogWindows *CrashLogWindows::current = nullptr; /* virtual */ char *CrashLogWindows::LogOSVersion(char *buffer, const char *last) const { @@ -117,7 +112,7 @@ public: " Message: %s\n\n", (int)ep->ExceptionRecord->ExceptionCode, (size_t)ep->ExceptionRecord->ExceptionAddress, - message == NULL ? "" : message + message == nullptr ? "" : message ); } @@ -159,7 +154,7 @@ static void GetFileInfo(DebugFileInfo *dfi, const TCHAR *filename) HANDLE file; memset(dfi, 0, sizeof(*dfi)); - file = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, 0, 0); + file = CreateFile(filename, GENERIC_READ, FILE_SHARE_READ, nullptr, OPEN_EXISTING, 0, 0); if (file != INVALID_HANDLE_VALUE) { byte buffer[1024]; DWORD numread; @@ -168,7 +163,7 @@ static void GetFileInfo(DebugFileInfo *dfi, const TCHAR *filename) uint32 crc = (uint32)-1; for (;;) { - if (ReadFile(file, buffer, sizeof(buffer), &numread, NULL) == 0 || numread == 0) { + if (ReadFile(file, buffer, sizeof(buffer), &numread, nullptr) == 0 || numread == 0) { break; } filesize += numread; @@ -177,7 +172,7 @@ static void GetFileInfo(DebugFileInfo *dfi, const TCHAR *filename) dfi->size = filesize; dfi->crc32 = crc ^ (uint32)-1; - if (GetFileTime(file, NULL, NULL, &write_time)) { + if (GetFileTime(file, nullptr, nullptr, &write_time)) { FileTimeToSystemTime(&write_time, &dfi->file_time); } CloseHandle(file); @@ -220,7 +215,7 @@ static char *PrintModuleInfo(char *output, const char *last, HMODULE mod) BOOL res; HANDLE proc = OpenProcess(PROCESS_ALL_ACCESS, FALSE, GetCurrentProcessId()); - if (proc != NULL) { + if (proc != nullptr) { res = EnumProcessModules(proc, modules, sizeof(modules), &needed); CloseHandle(proc); if (res) { @@ -231,7 +226,7 @@ static char *PrintModuleInfo(char *output, const char *last, HMODULE mod) } } } - output = PrintModuleInfo(output, last, NULL); + output = PrintModuleInfo(output, last, nullptr); return output + seprintf(output, last, "\n"); } @@ -264,7 +259,7 @@ static char *PrintModuleInfo(char *output, const char *last, HMODULE mod) ep->ContextRecord->Rip, ep->ContextRecord->EFlags ); -#else +#elif defined(_M_IX86) buffer += seprintf(buffer, last, " EAX: %.8X EBX: %.8X ECX: %.8X EDX: %.8X\n" " ESI: %.8X EDI: %.8X EBP: %.8X ESP: %.8X\n" @@ -280,13 +275,57 @@ static char *PrintModuleInfo(char *output, const char *last, HMODULE mod) (int)ep->ContextRecord->Eip, (int)ep->ContextRecord->EFlags ); +#elif defined(_M_ARM64) + buffer += seprintf(buffer, last, + " X0: %.16I64X X1: %.16I64X X2: %.16I64X X3: %.16I64X\n" + " X4: %.16I64X X5: %.16I64X X6: %.16I64X X7: %.16I64X\n" + " X8: %.16I64X X9: %.16I64X X10: %.16I64X X11: %.16I64X\n" + " X12: %.16I64X X13: %.16I64X X14: %.16I64X X15: %.16I64X\n" + " X16: %.16I64X X17: %.16I64X X18: %.16I64X X19: %.16I64X\n" + " X20: %.16I64X X21: %.16I64X X22: %.16I64X X23: %.16I64X\n" + " X24: %.16I64X X25: %.16I64X X26: %.16I64X X27: %.16I64X\n" + " X28: %.16I64X Fp: %.16I64X Lr: %.16I64X\n", + ep->ContextRecord->X0, + ep->ContextRecord->X1, + ep->ContextRecord->X2, + ep->ContextRecord->X3, + ep->ContextRecord->X4, + ep->ContextRecord->X5, + ep->ContextRecord->X6, + ep->ContextRecord->X7, + ep->ContextRecord->X8, + ep->ContextRecord->X9, + ep->ContextRecord->X10, + ep->ContextRecord->X11, + ep->ContextRecord->X12, + ep->ContextRecord->X13, + ep->ContextRecord->X14, + ep->ContextRecord->X15, + ep->ContextRecord->X16, + ep->ContextRecord->X17, + ep->ContextRecord->X18, + ep->ContextRecord->X19, + ep->ContextRecord->X20, + ep->ContextRecord->X21, + ep->ContextRecord->X22, + ep->ContextRecord->X23, + ep->ContextRecord->X24, + ep->ContextRecord->X25, + ep->ContextRecord->X26, + ep->ContextRecord->X27, + ep->ContextRecord->X28, + ep->ContextRecord->Fp, + ep->ContextRecord->Lr + ); #endif buffer += seprintf(buffer, last, "\n Bytes at instruction pointer:\n"); #ifdef _M_AMD64 byte *b = (byte*)ep->ContextRecord->Rip; -#else +#elif defined(_M_IX86) byte *b = (byte*)ep->ContextRecord->Eip; +#elif defined(_M_ARM64) + byte *b = (byte*)ep->ContextRecord->Pc; #endif for (int i = 0; i != 24; i++) { if (IsBadReadPtr(b, 1)) { @@ -304,8 +343,10 @@ static char *PrintModuleInfo(char *output, const char *last, HMODULE mod) buffer += seprintf(buffer, last, "Stack trace:\n"); #ifdef _M_AMD64 uint32 *b = (uint32*)ep->ContextRecord->Rsp; -#else +#elif defined(_M_IX86) uint32 *b = (uint32*)ep->ContextRecord->Esp; +#elif defined(_M_ARM64) + uint32 *b = (uint32*)ep->ContextRecord->Sp; #endif for (int j = 0; j != 24; j++) { for (int i = 0; i != 8; i++) { @@ -322,6 +363,9 @@ static char *PrintModuleInfo(char *output, const char *last, HMODULE mod) } #if defined(_MSC_VER) +static const uint MAX_SYMBOL_LEN = 512; +static const uint MAX_FRAMES = 64; + #pragma warning(disable:4091) #include #pragma warning(default:4091) @@ -362,7 +406,7 @@ char *CrashLogWindows::AppendDecodedStacktrace(char *buffer, const char *last) c if (LoadLibraryList((Function*)&proc, dbg_import)) { /* Initialize symbol handler. */ HANDLE hCur = GetCurrentProcess(); - proc.pSymInitialize(hCur, NULL, TRUE); + proc.pSymInitialize(hCur, nullptr, TRUE); /* Load symbols only when needed, fail silently on errors, demangle symbol names. */ proc.pSymSetOptions(SYMOPT_DEFERRED_LOADS | SYMOPT_FAIL_CRITICAL_ERRORS | SYMOPT_UNDNAME); @@ -373,10 +417,14 @@ char *CrashLogWindows::AppendDecodedStacktrace(char *buffer, const char *last) c frame.AddrPC.Offset = ep->ContextRecord->Rip; frame.AddrFrame.Offset = ep->ContextRecord->Rbp; frame.AddrStack.Offset = ep->ContextRecord->Rsp; -#else +#elif defined(_M_IX86) frame.AddrPC.Offset = ep->ContextRecord->Eip; frame.AddrFrame.Offset = ep->ContextRecord->Ebp; frame.AddrStack.Offset = ep->ContextRecord->Esp; +#elif defined(_M_ARM64) + frame.AddrPC.Offset = ep->ContextRecord->Pc; + frame.AddrFrame.Offset = ep->ContextRecord->Fp; + frame.AddrStack.Offset = ep->ContextRecord->Sp; #endif frame.AddrPC.Mode = AddrModeFlat; frame.AddrFrame.Mode = AddrModeFlat; @@ -399,7 +447,7 @@ char *CrashLogWindows::AppendDecodedStacktrace(char *buffer, const char *last) c #else IMAGE_FILE_MACHINE_I386, #endif - hCur, GetCurrentThread(), &frame, &ctx, NULL, proc.pSymFunctionTableAccess64, proc.pSymGetModuleBase64, NULL)) break; + hCur, GetCurrentThread(), &frame, &ctx, nullptr, proc.pSymFunctionTableAccess64, proc.pSymGetModuleBase64, nullptr)) break; if (frame.AddrPC.Offset == frame.AddrReturn.Offset) { buffer += seprintf(buffer, last, " \n"); @@ -443,16 +491,16 @@ char *CrashLogWindows::AppendDecodedStacktrace(char *buffer, const char *last) c { int ret = 0; HMODULE dbghelp = LoadLibrary(_T("dbghelp.dll")); - if (dbghelp != NULL) { + if (dbghelp != nullptr) { typedef BOOL (WINAPI *MiniDumpWriteDump_t)(HANDLE, DWORD, HANDLE, MINIDUMP_TYPE, CONST PMINIDUMP_EXCEPTION_INFORMATION, CONST PMINIDUMP_USER_STREAM_INFORMATION, CONST PMINIDUMP_CALLBACK_INFORMATION); MiniDumpWriteDump_t funcMiniDumpWriteDump = (MiniDumpWriteDump_t)GetProcAddress(dbghelp, "MiniDumpWriteDump"); - if (funcMiniDumpWriteDump != NULL) { + if (funcMiniDumpWriteDump != nullptr) { seprintf(filename, filename_last, "%scrash.dmp", _personal_dir); - HANDLE file = CreateFile(OTTD2FS(filename), GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, 0, 0); + HANDLE file = CreateFile(OTTD2FS(filename), GENERIC_WRITE, 0, nullptr, CREATE_ALWAYS, 0, 0); HANDLE proc = GetCurrentProcess(); DWORD procid = GetCurrentProcessId(); MINIDUMP_EXCEPTION_INFORMATION mdei; @@ -470,7 +518,7 @@ char *CrashLogWindows::AppendDecodedStacktrace(char *buffer, const char *last) c mdei.ExceptionPointers = ep; mdei.ClientPointers = false; - funcMiniDumpWriteDump(proc, procid, file, MiniDumpWithDataSegs, &mdei, &musi, NULL); + funcMiniDumpWriteDump(proc, procid, file, MiniDumpWithDataSegs, &mdei, &musi, nullptr); ret = 1; } else { ret = -1; @@ -488,11 +536,11 @@ static void ShowCrashlogWindow(); * Stack pointer for use when 'starting' the crash handler. * Not static as gcc's inline assembly needs it that way. */ -void *_safe_esp = NULL; +void *_safe_esp = nullptr; static LONG WINAPI ExceptionHandler(EXCEPTION_POINTERS *ep) { - if (CrashLogWindows::current != NULL) { + if (CrashLogWindows::current != nullptr) { CrashLog::AfterCrashLogCleanup(); ExitProcess(2); } @@ -501,7 +549,7 @@ static LONG WINAPI ExceptionHandler(EXCEPTION_POINTERS *ep) static const TCHAR _emergency_crash[] = _T("A serious fault condition occurred in the game. The game will shut down.\n") _T("As you loaded an emergency savegame no crash information will be generated.\n"); - MessageBox(NULL, _emergency_crash, _T("Fatal Application Failure"), MB_ICONERROR); + MessageBox(nullptr, _emergency_crash, _T("Fatal Application Failure"), MB_ICONERROR); ExitProcess(3); } @@ -510,7 +558,7 @@ static LONG WINAPI ExceptionHandler(EXCEPTION_POINTERS *ep) _T("A serious fault condition occurred in the game. The game will shut down.\n") _T("As you loaded an savegame for which you do not have the required NewGRFs\n") _T("no crash information will be generated.\n"); - MessageBox(NULL, _saveload_crash, _T("Fatal Application Failure"), MB_ICONERROR); + MessageBox(nullptr, _saveload_crash, _T("Fatal Application Failure"), MB_ICONERROR); ExitProcess(3); } @@ -525,13 +573,16 @@ static LONG WINAPI ExceptionHandler(EXCEPTION_POINTERS *ep) /* Close any possible log files */ CloseConsoleLogIfActive(); - if ((VideoDriver::GetInstance() == NULL || VideoDriver::GetInstance()->HasGUI()) && _safe_esp != NULL) { + if ((VideoDriver::GetInstance() == nullptr || VideoDriver::GetInstance()->HasGUI()) && _safe_esp != nullptr) { #ifdef _M_AMD64 ep->ContextRecord->Rip = (DWORD64)ShowCrashlogWindow; ep->ContextRecord->Rsp = (DWORD64)_safe_esp; -#else +#elif defined(_M_IX86) ep->ContextRecord->Eip = (DWORD)ShowCrashlogWindow; ep->ContextRecord->Esp = (DWORD)_safe_esp; +#elif defined(_M_ARM64) + ep->ContextRecord->Pc = (DWORD64)ShowCrashlogWindow; + ep->ContextRecord->Sp = (DWORD64)_safe_esp; #endif return EXCEPTION_CONTINUE_EXECUTION; } @@ -542,12 +593,12 @@ static LONG WINAPI ExceptionHandler(EXCEPTION_POINTERS *ep) static void CDECL CustomAbort(int signal) { - RaiseException(0xE1212012, 0, 0, NULL); + RaiseException(0xE1212012, 0, 0, nullptr); } /* static */ void CrashLog::InitialiseCrashLog() { -#ifdef _M_AMD64 +#if defined(_M_AMD64) || defined(_M_ARM64) CONTEXT ctx; RtlCaptureContext(&ctx); @@ -555,7 +606,11 @@ static void CDECL CustomAbort(int signal) * function. As we are simulating a function call with the safe ESP value, * we need to subtract 8 for the imaginary return address otherwise stack * alignment would be wrong in the called function. */ +#if defined(_M_ARM64) + _safe_esp = (void *)(ctx.Sp - 8); +#else _safe_esp = (void *)(ctx.Rsp - 8); +#endif #else #if defined(_MSC_VER) _asm { @@ -582,7 +637,7 @@ static bool _expanded; static const TCHAR _crash_desc[] = _T("A serious fault condition occurred in the game. The game will shut down.\n") _T("Please send the crash information and the crash.dmp file (if any) to the developers.\n") - _T("This will greatly help debugging. The correct place to do this is http://bugs.openttd.org. ") + _T("This will greatly help debugging. The correct place to do this is https://github.com/OpenTTD/OpenTTD/issues. ") _T("The information contained in the report is displayed below.\n") _T("Press \"Emergency save\" to attempt saving the game. Generated file(s):\n") _T("%s"); @@ -693,5 +748,5 @@ static void ShowCrashlogWindow() { ShowCursor(TRUE); ShowWindow(GetActiveWindow(), FALSE); - DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(100), NULL, CrashDialogFunc); + DialogBox(GetModuleHandle(nullptr), MAKEINTRESOURCE(100), nullptr, CrashDialogFunc); } diff --git a/src/os/windows/ottdres.rc.in b/src/os/windows/ottdres.rc.in index ebf0cc4afb..5b375790a3 100644 --- a/src/os/windows/ottdres.rc.in +++ b/src/os/windows/ottdres.rc.in @@ -1,6 +1,4 @@ //Microsoft Developer Studio generated resource script. -// $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. // 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. @@ -79,8 +77,8 @@ END // VS_VERSION_INFO VERSIONINFO - FILEVERSION 1,9,0,!!ISODATE!! - PRODUCTVERSION 1,9,0,!!ISODATE!! + FILEVERSION 1,10,0,!!ISODATE!! + PRODUCTVERSION 1,10,0,!!ISODATE!! FILEFLAGSMASK 0x3fL #ifdef _DEBUG FILEFLAGS 0x1L diff --git a/src/os/windows/string_uniscribe.cpp b/src/os/windows/string_uniscribe.cpp index ce61537b2b..ce433364a1 100644 --- a/src/os/windows/string_uniscribe.cpp +++ b/src/os/windows/string_uniscribe.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. @@ -86,34 +84,35 @@ public: int num_glyphs; Font *font; - mutable int *glyph_to_char = NULL; + mutable int *glyph_to_char = nullptr; public: UniscribeVisualRun(const UniscribeRun &range, int x); - virtual ~UniscribeVisualRun() + UniscribeVisualRun(UniscribeVisualRun &&other) noexcept; + ~UniscribeVisualRun() override { free(this->glyph_to_char); } - virtual const GlyphID *GetGlyphs() const { return &this->glyphs[0]; } - virtual const float *GetPositions() const { return &this->positions[0]; } - virtual const int *GetGlyphToCharMap() const; + const GlyphID *GetGlyphs() const override { return &this->glyphs[0]; } + const float *GetPositions() const override { return &this->positions[0]; } + const int *GetGlyphToCharMap() const override; - virtual const Font *GetFont() const { return this->font; } - virtual int GetLeading() const { return this->font->fc->GetHeight(); } - virtual int GetGlyphCount() const { return this->num_glyphs; } + const Font *GetFont() const override { return this->font; } + int GetLeading() const override { return this->font->fc->GetHeight(); } + int GetGlyphCount() const override { return this->num_glyphs; } int GetAdvance() const { return this->total_advance; } }; /** A single line worth of VisualRuns. */ - class UniscribeLine : public AutoDeleteSmallVector, public ParagraphLayouter::Line { + class UniscribeLine : public std::vector, public ParagraphLayouter::Line { public: - virtual int GetLeading() const; - virtual int GetWidth() const; - virtual int CountRuns() const { return this->Length(); } - virtual const VisualRun *GetVisualRun(int run) const { return *this->Get(run); } + int GetLeading() const override; + int GetWidth() const override; + int CountRuns() const override { return (uint)this->size(); } + const VisualRun &GetVisualRun(int run) const override { return this->at(run); } - int GetInternalCharLength(WChar c) const + int GetInternalCharLength(WChar c) const override { /* Uniscribe uses UTF-16 internally which means we need to account for surrogate pairs. */ return c >= 0x010000U ? 2 : 1; @@ -125,28 +124,30 @@ public: this->Reflow(); } - virtual ~UniscribeParagraphLayout() {} + ~UniscribeParagraphLayout() override {} - virtual void Reflow() + void Reflow() override { this->cur_range = this->ranges.begin(); this->cur_range_offset = 0; } - virtual const Line *NextLine(int max_width); + std::unique_ptr NextLine(int max_width) override; }; void UniscribeResetScriptCache(FontSize size) { - if (_script_cache[size] != NULL) { + if (_script_cache[size] != nullptr) { ScriptFreeCache(&_script_cache[size]); - _script_cache[size] = NULL; + _script_cache[size] = nullptr; } } /** Load the matching native Windows font. */ static HFONT HFontFromFont(Font *font) { + if (font->fc->GetOSHandle() != nullptr) return CreateFontIndirect((PLOGFONT)font->fc->GetOSHandle()); + LOGFONT logfont; ZeroMemory(&logfont, sizeof(LOGFONT)); logfont.lfHeight = font->fc->GetHeight(); @@ -167,9 +168,9 @@ static bool UniscribeShapeRun(const UniscribeParagraphLayoutFactory::CharType *b /* The char-to-glyph array is the same size as the input. */ range.char_to_glyph.resize(range.len); - HDC temp_dc = NULL; - HFONT old_font = NULL; - HFONT cur_font = NULL; + HDC temp_dc = nullptr; + HFONT old_font = nullptr; + HFONT cur_font = nullptr; while (true) { /* Shape the text run by determining the glyphs needed for display. */ @@ -194,15 +195,19 @@ static bool UniscribeShapeRun(const UniscribeParagraphLayoutFactory::CharType *b } for (int i = 0; i < range.len; i++) { if (buff[range.pos + i] >= SCC_SPRITE_START && buff[range.pos + i] <= SCC_SPRITE_END) { - range.ft_glyphs[range.char_to_glyph[i]] = range.font->fc->MapCharToGlyph(buff[range.pos + i]); - range.offsets[range.char_to_glyph[i]].dv = range.font->fc->GetAscender() - range.font->fc->GetGlyph(range.ft_glyphs[range.char_to_glyph[i]])->height - 1; // Align sprite glyphs to font baseline. + 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.advances[pos] = range.font->fc->GetGlyphWidth(range.ft_glyphs[pos]); } } - /* FreeType and GDI/Uniscribe seems to occasionally disagree over the width of a glyph. */ range.total_advance = 0; for (size_t i = 0; i < range.advances.size(); i++) { +#ifdef WITH_FREETYPE + /* FreeType and GDI/Uniscribe seems to occasionally disagree over the width of a glyph. */ if (range.advances[i] > 0 && range.ft_glyphs[i] != 0xFFFF) range.advances[i] = range.font->fc->GetGlyphWidth(range.ft_glyphs[i]); +#endif range.total_advance += range.advances[i]; } break; @@ -216,9 +221,9 @@ static bool UniscribeShapeRun(const UniscribeParagraphLayoutFactory::CharType *b } else if (hr == E_PENDING) { /* Glyph data is not in cache, load native font. */ cur_font = HFontFromFont(range.font); - if (cur_font == NULL) return false; // Sorry, no dice. + if (cur_font == nullptr) return false; // Sorry, no dice. - temp_dc = CreateCompatibleDC(NULL); + temp_dc = CreateCompatibleDC(nullptr); SetMapMode(temp_dc, MM_TEXT); old_font = (HFONT)SelectObject(temp_dc, cur_font); } else if (hr == USP_E_SCRIPT_NOT_IN_FONT && range.sa.eScript != SCRIPT_UNDEFINED) { @@ -226,19 +231,19 @@ static bool UniscribeShapeRun(const UniscribeParagraphLayoutFactory::CharType *b range.sa.eScript = SCRIPT_UNDEFINED; } else { /* Some unknown other error. */ - if (temp_dc != NULL) { + if (temp_dc != nullptr) { SelectObject(temp_dc, old_font); DeleteObject(cur_font); - ReleaseDC(NULL, temp_dc); + ReleaseDC(nullptr, temp_dc); } return false; } } - if (temp_dc != NULL) { + if (temp_dc != nullptr) { SelectObject(temp_dc, old_font); DeleteObject(cur_font); - ReleaseDC(NULL, temp_dc); + ReleaseDC(nullptr, temp_dc); } return true; @@ -279,16 +284,16 @@ static std::vector UniscribeItemizeString(UniscribeParagraphLayoutF { int32 length = buff_end - buff; /* Can't layout an empty string. */ - if (length == 0) return NULL; + if (length == 0) return nullptr; /* Can't layout our in-built sprite fonts. */ - for (FontMap::const_iterator i = fontMapping.Begin(); i != fontMapping.End(); i++) { - if (i->second->fc->IsBuiltInFont()) return NULL; + for (auto const &pair : fontMapping) { + if (pair.second->fc->IsBuiltInFont()) return nullptr; } /* Itemize text. */ std::vector items = UniscribeItemizeString(buff, length); - if (items.size() == 0) return NULL; + if (items.size() == 0) return nullptr; /* Build ranges from the items and the font map. A range is a run of text * that is part of a single item and formatted using a single font style. */ @@ -296,16 +301,16 @@ static std::vector UniscribeItemizeString(UniscribeParagraphLayoutF int cur_pos = 0; std::vector::iterator cur_item = items.begin(); - for (FontMap::const_iterator i = fontMapping.Begin(); i != fontMapping.End(); i++) { - while (cur_pos < i->first && cur_item != items.end() - 1) { + for (auto const &i : fontMapping) { + while (cur_pos < i.first && cur_item != items.end() - 1) { /* Add a range that spans the intersection of the remaining item and font run. */ - int stop_pos = min(i->first, (cur_item + 1)->iCharPos); + int stop_pos = min(i.first, (cur_item + 1)->iCharPos); assert(stop_pos - cur_pos > 0); - ranges.push_back(UniscribeRun(cur_pos, stop_pos - cur_pos, i->second, cur_item->a)); + ranges.push_back(UniscribeRun(cur_pos, stop_pos - cur_pos, i.second, cur_item->a)); /* Shape the range. */ if (!UniscribeShapeRun(buff, ranges.back())) { - return NULL; + return nullptr; } /* If we are at the end of the current item, advance to the next item. */ @@ -317,12 +322,12 @@ static std::vector UniscribeItemizeString(UniscribeParagraphLayoutF return new UniscribeParagraphLayout(ranges, buff); } -/* virtual */ const ParagraphLayouter::Line *UniscribeParagraphLayout::NextLine(int max_width) +/* virtual */ std::unique_ptr UniscribeParagraphLayout::NextLine(int max_width) { std::vector::iterator start_run = this->cur_range; std::vector::iterator last_run = this->cur_range; - if (start_run == this->ranges.end()) return NULL; + if (start_run == this->ranges.end()) return nullptr; /* Add remaining width of the first run if it is a broken run. */ int cur_width = 0; @@ -354,7 +359,7 @@ static std::vector UniscribeItemizeString(UniscribeParagraphLayoutF int last_cluster = this->cur_range_offset + 1; for (std::vector::iterator r = start_run; r != last_run; r++) { log_attribs.resize(r->pos - start_run->pos + r->len); - if (FAILED(ScriptBreak(this->text_buffer + r->pos + start_offs, r->len - start_offs, &r->sa, &log_attribs[r->pos - start_run->pos + start_offs]))) return NULL; + if (FAILED(ScriptBreak(this->text_buffer + r->pos + start_offs, r->len - start_offs, &r->sa, &log_attribs[r->pos - start_run->pos + start_offs]))) return nullptr; std::vector dx(r->len); ScriptGetLogicalWidths(&r->sa, r->len, (int)r->glyphs.size(), &r->advances[0], &r->char_to_glyph[0], &r->vis_attribs[0], &dx[0]); @@ -400,10 +405,10 @@ static std::vector UniscribeItemizeString(UniscribeParagraphLayoutF bidi_level.push_back(r->sa.s.uBidiLevel); } std::vector vis_to_log(bidi_level.size()); - if (FAILED(ScriptLayout((int)bidi_level.size(), &bidi_level[0], &vis_to_log[0], NULL))) return NULL; + if (FAILED(ScriptLayout((int)bidi_level.size(), &bidi_level[0], &vis_to_log[0], nullptr))) return nullptr; /* Create line. */ - UniscribeLine *line = new UniscribeLine(); + std::unique_ptr line(new UniscribeLine()); int cur_pos = 0; for (std::vector::iterator l = vis_to_log.begin(); l != vis_to_log.end(); l++) { @@ -414,17 +419,17 @@ static std::vector UniscribeItemizeString(UniscribeParagraphLayoutF if (i_run == last_run - 1 && remaing_offset < (last_run - 1)->len) { run.len = remaing_offset - 1; - if (!UniscribeShapeRun(this->text_buffer, run)) return NULL; + if (!UniscribeShapeRun(this->text_buffer, run)) return nullptr; } if (i_run == start_run && this->cur_range_offset > 0) { assert(run.len - this->cur_range_offset > 0); run.pos += this->cur_range_offset; run.len -= this->cur_range_offset; - if (!UniscribeShapeRun(this->text_buffer, run)) return NULL; + if (!UniscribeShapeRun(this->text_buffer, run)) return nullptr; } - *line->Append() = new UniscribeVisualRun(run, cur_pos); + line->emplace_back(run, cur_pos); cur_pos += run.total_advance; } @@ -448,8 +453,8 @@ static std::vector UniscribeItemizeString(UniscribeParagraphLayoutF int UniscribeParagraphLayout::UniscribeLine::GetLeading() const { int leading = 0; - for (const UniscribeVisualRun * const *run = this->Begin(); run != this->End(); run++) { - leading = max(leading, (*run)->GetLeading()); + for (const auto &run : *this) { + leading = max(leading, run.GetLeading()); } return leading; @@ -462,8 +467,8 @@ int UniscribeParagraphLayout::UniscribeLine::GetLeading() const int UniscribeParagraphLayout::UniscribeLine::GetWidth() const { int length = 0; - for (const UniscribeVisualRun * const *run = this->Begin(); run != this->End(); run++) { - length += (*run)->GetAdvance(); + for (const auto &run : *this) { + length += run.GetAdvance(); } return length; @@ -484,9 +489,17 @@ UniscribeParagraphLayout::UniscribeVisualRun::UniscribeVisualRun(const Uniscribe this->positions[this->num_glyphs * 2] = advance + x; } +UniscribeParagraphLayout::UniscribeVisualRun::UniscribeVisualRun(UniscribeVisualRun&& other) noexcept + : glyphs(std::move(other.glyphs)), positions(std::move(other.positions)), char_to_glyph(std::move(other.char_to_glyph)), + start_pos(other.start_pos), total_advance(other.total_advance), num_glyphs(other.num_glyphs), font(other.font) +{ + this->glyph_to_char = other.glyph_to_char; + other.glyph_to_char = nullptr; +} + const int *UniscribeParagraphLayout::UniscribeVisualRun::GetGlyphToCharMap() const { - if (this->glyph_to_char == NULL) { + if (this->glyph_to_char == nullptr) { this->glyph_to_char = CallocT(this->GetGlyphCount()); /* The char to glyph array contains the first glyph index of the cluster that is associated diff --git a/src/os/windows/string_uniscribe.h b/src/os/windows/string_uniscribe.h index 6af858a88f..9470b44b0c 100644 --- a/src/os/windows/string_uniscribe.h +++ b/src/os/windows/string_uniscribe.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. @@ -81,10 +79,10 @@ class UniscribeStringIterator : public StringIterator { size_t cur_pos; ///< Current iteration position. public: - virtual void SetString(const char *s); - virtual size_t SetCurPosition(size_t pos); - virtual size_t Next(IterType what); - virtual size_t Prev(IterType what); + void SetString(const char *s) override; + size_t SetCurPosition(size_t pos) override; + size_t Next(IterType what) override; + size_t Prev(IterType what) override; }; #endif /* defined(WITH_UNISCRIBE) */ diff --git a/src/os/windows/win32.cpp b/src/os/windows/win32.cpp index 4a49555492..1bdbc3c2a8 100644 --- a/src/os/windows/win32.cpp +++ b/src/os/windows/win32.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. @@ -30,6 +28,7 @@ #include #include #include "../../language.h" +#include "../../thread.h" #include "../../safeguards.h" @@ -60,14 +59,14 @@ bool LoadLibraryList(Function proc[], const char *dll) HMODULE lib; lib = LoadLibrary(MB_TO_WIDE(dll)); - if (lib == NULL) return false; + if (lib == nullptr) return false; for (;;) { FARPROC p; while (*dll++ != '\0') { /* Nothing */ } if (*dll == '\0') break; p = GetProcAddress(lib, dll); - if (p == NULL) return false; + if (p == nullptr) return false; *proc++ = (Function)p; } dll++; @@ -78,12 +77,12 @@ bool LoadLibraryList(Function proc[], const char *dll) void ShowOSErrorBox(const char *buf, bool system) { MyShowCursor(true); - MessageBox(GetActiveWindow(), OTTD2FS(buf), _T("Error!"), MB_ICONSTOP); + MessageBox(GetActiveWindow(), OTTD2FS(buf), _T("Error!"), MB_ICONSTOP | MB_TASKMODAL); } void OSOpenBrowser(const char *url) { - ShellExecute(GetActiveWindow(), _T("open"), OTTD2FS(url), NULL, NULL, SW_SHOWNORMAL); + ShellExecute(GetActiveWindow(), _T("open"), OTTD2FS(url), nullptr, nullptr, SW_SHOWNORMAL); } /* Code below for windows version of opendir/readdir/closedir copied and @@ -141,7 +140,7 @@ DIR *opendir(const TCHAR *path) if ((fa != INVALID_FILE_ATTRIBUTES) && (fa & FILE_ATTRIBUTE_DIRECTORY)) { d = dir_calloc(); - if (d != NULL) { + if (d != nullptr) { TCHAR search_path[MAX_PATH]; bool slash = path[_tcslen(path) - 1] == '\\'; @@ -157,14 +156,14 @@ DIR *opendir(const TCHAR *path) d->at_first_entry = true; } else { dir_free(d); - d = NULL; + d = nullptr; } } else { errno = ENOMEM; } } else { /* path not found or not a directory */ - d = NULL; + d = nullptr; errno = ENOENT; } @@ -178,11 +177,11 @@ struct dirent *readdir(DIR *d) if (d->at_first_entry) { /* the directory was empty when opened */ - if (d->hFind == INVALID_HANDLE_VALUE) return NULL; + if (d->hFind == INVALID_HANDLE_VALUE) return nullptr; d->at_first_entry = false; } else if (!FindNextFile(d->hFind, &d->fd)) { // determine cause and bail if (GetLastError() == ERROR_NO_MORE_FILES) SetLastError(prev_err); - return NULL; + return nullptr; } /* This entry has passed all checks; return information about it. @@ -250,7 +249,7 @@ bool FiosGetDiskFreeSpace(const char *path, uint64 *tot) DWORD spc, bps, nfc, tnc; _sntprintf(root, lengthof(root), _T("%c:") _T(PATHSEP), path[0]); - if (tot != NULL && GetDiskFreeSpace(root, &spc, &bps, &nfc, &tnc)) { + if (tot != nullptr && GetDiskFreeSpace(root, &spc, &bps, &nfc, &tnc)) { *tot = ((spc * bps) * (uint64)nfc); retval = true; } @@ -338,9 +337,9 @@ void CreateConsole() *stderr = *fdopen(2, "w" ); #endif - setvbuf(stdin, NULL, _IONBF, 0); - setvbuf(stdout, NULL, _IONBF, 0); - setvbuf(stderr, NULL, _IONBF, 0); + setvbuf(stdin, nullptr, _IONBF, 0); + setvbuf(stdout, nullptr, _IONBF, 0); + setvbuf(stderr, nullptr, _IONBF, 0); } /** Temporary pointer to get the help message to the window */ @@ -397,7 +396,7 @@ void ShowInfo(const char *str) * ShowInfo are much shorter, or so long they need this way of displaying * them anyway. */ _help_msg = str; - DialogBox(GetModuleHandle(NULL), MAKEINTRESOURCE(101), NULL, HelpDialogFunc); + DialogBox(GetModuleHandle(nullptr), MAKEINTRESOURCE(101), nullptr, HelpDialogFunc); } else { /* We need to put the text in a separate buffer because the default * buffer in OTTD2FS might not be large enough (512 chars). */ @@ -458,28 +457,28 @@ void DetermineBasePaths(const char *exe) char tmp[MAX_PATH]; TCHAR path[MAX_PATH]; #ifdef WITH_PERSONAL_DIR - if (SUCCEEDED(OTTDSHGetFolderPath(NULL, CSIDL_PERSONAL, NULL, SHGFP_TYPE_CURRENT, path))) { + if (SUCCEEDED(OTTDSHGetFolderPath(nullptr, CSIDL_PERSONAL, nullptr, SHGFP_TYPE_CURRENT, path))) { strecpy(tmp, FS2OTTD(path), lastof(tmp)); AppendPathSeparator(tmp, lastof(tmp)); strecat(tmp, PERSONAL_DIR, lastof(tmp)); AppendPathSeparator(tmp, lastof(tmp)); _searchpaths[SP_PERSONAL_DIR] = stredup(tmp); } else { - _searchpaths[SP_PERSONAL_DIR] = NULL; + _searchpaths[SP_PERSONAL_DIR] = nullptr; } - if (SUCCEEDED(OTTDSHGetFolderPath(NULL, CSIDL_COMMON_DOCUMENTS, NULL, SHGFP_TYPE_CURRENT, path))) { + if (SUCCEEDED(OTTDSHGetFolderPath(nullptr, CSIDL_COMMON_DOCUMENTS, nullptr, SHGFP_TYPE_CURRENT, path))) { strecpy(tmp, FS2OTTD(path), lastof(tmp)); AppendPathSeparator(tmp, lastof(tmp)); strecat(tmp, PERSONAL_DIR, lastof(tmp)); AppendPathSeparator(tmp, lastof(tmp)); _searchpaths[SP_SHARED_DIR] = stredup(tmp); } else { - _searchpaths[SP_SHARED_DIR] = NULL; + _searchpaths[SP_SHARED_DIR] = nullptr; } #else - _searchpaths[SP_PERSONAL_DIR] = NULL; - _searchpaths[SP_SHARED_DIR] = NULL; + _searchpaths[SP_PERSONAL_DIR] = nullptr; + _searchpaths[SP_SHARED_DIR] = nullptr; #endif /* Get the path to working directory of OpenTTD */ @@ -487,15 +486,15 @@ void DetermineBasePaths(const char *exe) AppendPathSeparator(tmp, lastof(tmp)); _searchpaths[SP_WORKING_DIR] = stredup(tmp); - if (!GetModuleFileName(NULL, path, lengthof(path))) { + if (!GetModuleFileName(nullptr, path, lengthof(path))) { DEBUG(misc, 0, "GetModuleFileName failed (%lu)\n", GetLastError()); - _searchpaths[SP_BINARY_DIR] = NULL; + _searchpaths[SP_BINARY_DIR] = nullptr; } else { TCHAR exec_dir[MAX_PATH]; _tcsncpy(path, convert_to_fs(exe, path, lengthof(path)), lengthof(path)); - if (!GetFullPathName(path, lengthof(exec_dir), exec_dir, NULL)) { + if (!GetFullPathName(path, lengthof(exec_dir), exec_dir, nullptr)) { DEBUG(misc, 0, "GetFullPathName failed (%lu)\n", GetLastError()); - _searchpaths[SP_BINARY_DIR] = NULL; + _searchpaths[SP_BINARY_DIR] = nullptr; } else { strecpy(tmp, convert_from_fs(exec_dir, tmp, lengthof(tmp)), lastof(tmp)); char *s = strrchr(tmp, PATHSEPCHAR); @@ -504,8 +503,8 @@ void DetermineBasePaths(const char *exe) } } - _searchpaths[SP_INSTALLATION_DIR] = NULL; - _searchpaths[SP_APPLICATION_BUNDLE_DIR] = NULL; + _searchpaths[SP_INSTALLATION_DIR] = nullptr; + _searchpaths[SP_APPLICATION_BUNDLE_DIR] = nullptr; } @@ -515,18 +514,18 @@ bool GetClipboardContents(char *buffer, const char *last) const char *ptr; if (IsClipboardFormatAvailable(CF_UNICODETEXT)) { - OpenClipboard(NULL); + OpenClipboard(nullptr); cbuf = GetClipboardData(CF_UNICODETEXT); ptr = (const char*)GlobalLock(cbuf); - int out_len = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)ptr, -1, buffer, (last - buffer) + 1, NULL, NULL); + int out_len = WideCharToMultiByte(CP_UTF8, 0, (LPCWSTR)ptr, -1, buffer, (last - buffer) + 1, nullptr, nullptr); GlobalUnlock(cbuf); CloseClipboard(); if (out_len == 0) return false; #if !defined(UNICODE) } else if (IsClipboardFormatAvailable(CF_TEXT)) { - OpenClipboard(NULL); + OpenClipboard(nullptr); cbuf = GetClipboardData(CF_TEXT); ptr = (const char*)GlobalLock(cbuf); @@ -543,12 +542,6 @@ bool GetClipboardContents(char *buffer, const char *last) } -void CSleep(int milliseconds) -{ - Sleep(milliseconds); -} - - /** * Convert to OpenTTD's encoding from that of the local environment. * When the project is built in UNICODE, the system codepage is irrelevant and @@ -601,7 +594,7 @@ char *convert_from_fs(const TCHAR *name, char *utf8_buf, size_t buflen) const WCHAR *wide_buf = name; #else /* Convert string from the local codepage to UTF-16. */ - int wide_len = MultiByteToWideChar(CP_ACP, 0, name, -1, NULL, 0); + int wide_len = MultiByteToWideChar(CP_ACP, 0, name, -1, nullptr, 0); if (wide_len == 0) { utf8_buf[0] = '\0'; return utf8_buf; @@ -612,7 +605,7 @@ char *convert_from_fs(const TCHAR *name, char *utf8_buf, size_t buflen) #endif /* Convert UTF-16 string to UTF-8. */ - int len = WideCharToMultiByte(CP_UTF8, 0, wide_buf, -1, utf8_buf, (int)buflen, NULL, NULL); + int len = WideCharToMultiByte(CP_UTF8, 0, wide_buf, -1, utf8_buf, (int)buflen, nullptr, nullptr); if (len == 0) utf8_buf[0] = '\0'; return utf8_buf; @@ -635,7 +628,7 @@ TCHAR *convert_to_fs(const char *name, TCHAR *system_buf, size_t buflen, bool co int len = MultiByteToWideChar(CP_UTF8, 0, name, -1, system_buf, (int)buflen); if (len == 0) system_buf[0] = '\0'; #else - int len = MultiByteToWideChar(CP_UTF8, 0, name, -1, NULL, 0); + int len = MultiByteToWideChar(CP_UTF8, 0, name, -1, nullptr, 0); if (len == 0) { system_buf[0] = '\0'; return system_buf; @@ -644,7 +637,7 @@ TCHAR *convert_to_fs(const char *name, TCHAR *system_buf, size_t buflen, bool co WCHAR *wide_buf = AllocaM(WCHAR, len); MultiByteToWideChar(CP_UTF8, 0, name, -1, wide_buf, len); - len = WideCharToMultiByte(console_cp ? CP_OEMCP : CP_ACP, 0, wide_buf, len, system_buf, (int)buflen, NULL, NULL); + len = WideCharToMultiByte(console_cp ? CP_OEMCP : CP_ACP, 0, wide_buf, len, system_buf, (int)buflen, nullptr, nullptr); if (len == 0) system_buf[0] = '\0'; #endif @@ -659,7 +652,7 @@ TCHAR *convert_to_fs(const char *name, TCHAR *system_buf, size_t buflen, bool co */ HRESULT OTTDSHGetFolderPath(HWND hwnd, int csidl, HANDLE hToken, DWORD dwFlags, LPTSTR pszPath) { - static HRESULT (WINAPI *SHGetFolderPath)(HWND, int, HANDLE, DWORD, LPTSTR) = NULL; + static HRESULT (WINAPI *SHGetFolderPath)(HWND, int, HANDLE, DWORD, LPTSTR) = nullptr; static bool first_time = true; /* We only try to load the library one time; if it fails, it fails */ @@ -679,7 +672,7 @@ HRESULT OTTDSHGetFolderPath(HWND hwnd, int csidl, HANDLE hToken, DWORD dwFlags, first_time = false; } - if (SHGetFolderPath != NULL) return SHGetFolderPath(hwnd, csidl, hToken, dwFlags, pszPath); + if (SHGetFolderPath != nullptr) return SHGetFolderPath(hwnd, csidl, hToken, dwFlags, pszPath); /* SHGetFolderPath doesn't exist, try a more conservative approach, * eg environment variables. This is only included for legacy modes @@ -703,7 +696,7 @@ HRESULT OTTDSHGetFolderPath(HWND hwnd, int csidl, HANDLE hToken, DWORD dwFlags, HKEY key; if (RegOpenKeyEx(csidl == CSIDL_PERSONAL ? HKEY_CURRENT_USER : HKEY_LOCAL_MACHINE, REGSTR_PATH_SPECIAL_FOLDERS, 0, KEY_READ, &key) != ERROR_SUCCESS) break; DWORD len = MAX_PATH; - ret = RegQueryValueEx(key, csidl == CSIDL_PERSONAL ? _T("Personal") : _T("Common Documents"), NULL, NULL, (LPBYTE)pszPath, &len); + ret = RegQueryValueEx(key, csidl == CSIDL_PERSONAL ? _T("Personal") : _T("Common Documents"), nullptr, nullptr, (LPBYTE)pszPath, &len); RegCloseKey(key); if (ret == ERROR_SUCCESS) return (HRESULT)0; break; @@ -723,21 +716,13 @@ const char *GetCurrentLocale(const char *) if (GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SISO639LANGNAME, lang, lengthof(lang)) == 0 || GetLocaleInfoA(LOCALE_USER_DEFAULT, LOCALE_SISO3166CTRYNAME, country, lengthof(country)) == 0) { /* Unable to retrieve the locale. */ - return NULL; + return nullptr; } /* Format it as 'en_us'. */ static char retbuf[6] = {lang[0], lang[1], '_', country[0], country[1], 0}; return retbuf; } -uint GetCPUCoreCount() -{ - SYSTEM_INFO info; - - GetSystemInfo(&info); - return info.dwNumberOfProcessors; -} - static WCHAR _cur_iso_locale[16] = L""; @@ -763,7 +748,7 @@ void Win32SetCurrentLocaleName(const char *iso_code) int OTTDStringCompare(const char *s1, const char *s2) { typedef int (WINAPI *PFNCOMPARESTRINGEX)(LPCWSTR, DWORD, LPCWCH, int, LPCWCH, int, LPVOID, LPVOID, LPARAM); - static PFNCOMPARESTRINGEX _CompareStringEx = NULL; + static PFNCOMPARESTRINGEX _CompareStringEx = nullptr; static bool first_time = true; #ifndef SORT_DIGITSASNUMBERS @@ -778,10 +763,10 @@ int OTTDStringCompare(const char *s1, const char *s2) first_time = false; } - if (_CompareStringEx != NULL) { + if (_CompareStringEx != nullptr) { /* CompareStringEx takes UTF-16 strings, even in ANSI-builds. */ - int len_s1 = MultiByteToWideChar(CP_UTF8, 0, s1, -1, NULL, 0); - int len_s2 = MultiByteToWideChar(CP_UTF8, 0, s2, -1, NULL, 0); + int len_s1 = MultiByteToWideChar(CP_UTF8, 0, s1, -1, nullptr, 0); + int len_s2 = MultiByteToWideChar(CP_UTF8, 0, s2, -1, nullptr, 0); if (len_s1 != 0 && len_s2 != 0) { LPWSTR str_s1 = AllocaM(WCHAR, len_s1); @@ -790,7 +775,7 @@ int OTTDStringCompare(const char *s1, const char *s2) MultiByteToWideChar(CP_UTF8, 0, s1, -1, str_s1, len_s1); MultiByteToWideChar(CP_UTF8, 0, s2, -1, str_s2, len_s2); - int result = _CompareStringEx(_cur_iso_locale, LINGUISTIC_IGNORECASE | SORT_DIGITSASNUMBERS, str_s1, -1, str_s2, -1, NULL, NULL, 0); + int result = _CompareStringEx(_cur_iso_locale, LINGUISTIC_IGNORECASE | SORT_DIGITSASNUMBERS, str_s1, -1, str_s2, -1, nullptr, nullptr, 0); if (result != 0) return result; } } @@ -816,12 +801,12 @@ PACK_N(struct THREADNAME_INFO { /** * Signal thread name to any attached debuggers. */ -void SetWin32ThreadName(DWORD dwThreadID, const char* threadName) +void SetCurrentThreadName(const char *threadName) { THREADNAME_INFO info; info.dwType = 0x1000; info.szName = threadName; - info.dwThreadID = dwThreadID; + info.dwThreadID = -1; info.dwFlags = 0; #pragma warning(push) @@ -832,4 +817,6 @@ void SetWin32ThreadName(DWORD dwThreadID, const char* threadName) } #pragma warning(pop) } +#else +void SetCurrentThreadName(const char *) {} #endif diff --git a/src/os/windows/win32.h b/src/os/windows/win32.h index 4f813c4a6f..8ffe8ae7b5 100644 --- a/src/os/windows/win32.h +++ b/src/os/windows/win32.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. @@ -39,12 +37,6 @@ HRESULT OTTDSHGetFolderPath(HWND, int, HANDLE, DWORD, LPTSTR); #define SHGFP_TYPE_CURRENT 0 #endif /* __MINGW32__ */ -#ifdef _MSC_VER -void SetWin32ThreadName(DWORD dwThreadID, const char* threadName); -#else -static inline void SetWin32ThreadName(DWORD dwThreadID, const char* threadName) {} -#endif - void Win32SetCurrentLocaleName(const char *iso_code); int OTTDStringCompare(const char *s1, const char *s2); diff --git a/src/osk_gui.cpp b/src/osk_gui.cpp index 4ef27f7561..d90c9d9114 100644 --- a/src/osk_gui.cpp +++ b/src/osk_gui.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. @@ -46,10 +44,10 @@ struct OskWindow : public Window { OskWindow(WindowDesc *desc, Window *parent, int button) : Window(desc) { this->parent = parent; - assert(parent != NULL); + assert(parent != nullptr); NWidgetCore *par_wid = parent->GetWidget(button); - assert(par_wid != NULL); + assert(par_wid != nullptr); assert(parent->querystrings.Contains(button)); this->qs = parent->querystrings.Find(button)->second; @@ -94,12 +92,12 @@ struct OskWindow : public Window { this->SetWidgetLoweredState(WID_OSK_CAPS, HasBit(_keystate, KEYS_CAPS)); } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { if (widget == WID_OSK_CAPTION) SetDParam(0, this->caption); } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { if (widget < WID_OSK_LETTERS) return; @@ -110,7 +108,7 @@ struct OskWindow : public Window { TC_BLACK); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { /* clicked a letter */ if (widget >= WID_OSK_LETTERS) { @@ -166,7 +164,7 @@ struct OskWindow : public Window { break; case WID_OSK_OK: - if (this->qs->orig == NULL || strcmp(this->qs->text.buf, this->qs->orig) != 0) { + if (this->qs->orig == nullptr || strcmp(this->qs->text.buf, this->qs->orig) != 0) { /* pass information by simulating a button press on parent window */ if (this->qs->ok_button >= 0) { this->parent->OnClick(pt, this->qs->ok_button, 1); @@ -192,21 +190,21 @@ struct OskWindow : public Window { } } - virtual void OnEditboxChanged(int widget) + void OnEditboxChanged(int widget) override { this->SetWidgetDirty(WID_OSK_TEXT); this->parent->OnEditboxChanged(this->text_btn); this->parent->SetWidgetDirty(this->text_btn); } - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; this->SetWidgetDirty(WID_OSK_TEXT); this->parent->SetWidgetDirty(this->text_btn); } - virtual void OnFocusLost() + void OnFocusLost() override { VideoDriver::GetInstance()->EditBoxLostFocus(); delete this; @@ -422,13 +420,13 @@ void ShowOnScreenKeyboard(Window *parent, int button) * Updates the original text of the OSK so when the 'parent' changes the * original and you press on cancel you won't get the 'old' original text * but the updated one. - * @param parent window that just updated its orignal text + * @param parent window that just updated its original text * @param button widget number of parent's textbox to update */ void UpdateOSKOriginalText(const Window *parent, int button) { OskWindow *osk = dynamic_cast(FindWindowById(WC_OSK, 0)); - if (osk == NULL || osk->parent != parent || osk->text_btn != button) return; + if (osk == nullptr || osk->parent != parent || osk->text_btn != button) return; free(osk->orig_str_buf); osk->orig_str_buf = stredup(osk->qs->text.buf); @@ -445,5 +443,5 @@ void UpdateOSKOriginalText(const Window *parent, int button) bool IsOSKOpenedFor(const Window *w, int button) { OskWindow *osk = dynamic_cast(FindWindowById(WC_OSK, 0)); - return osk != NULL && osk->parent == w && osk->text_btn == button; + return osk != nullptr && osk->parent == w && osk->text_btn == button; } diff --git a/src/pathfinder/follow_track.hpp b/src/pathfinder/follow_track.hpp index 9b4377248e..2cfe4d9e4a 100644 --- a/src/pathfinder/follow_track.hpp +++ b/src/pathfinder/follow_track.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. @@ -32,7 +30,7 @@ struct CFollowTrackT enum ErrorCode { EC_NONE, EC_OWNER, - EC_RAIL_TYPE, + EC_RAIL_ROAD_TYPE, EC_90DEG, EC_NO_WAY, EC_RESERVED, @@ -53,27 +51,28 @@ struct CFollowTrackT CPerformanceTimer *m_pPerf; RailTypes m_railtypes; - inline CFollowTrackT(const VehicleType *v = NULL, RailTypes railtype_override = INVALID_RAILTYPES, CPerformanceTimer *pPerf = NULL) + inline CFollowTrackT(const VehicleType *v = nullptr, RailTypes railtype_override = INVALID_RAILTYPES, CPerformanceTimer *pPerf = nullptr) { Init(v, railtype_override, pPerf); } - inline CFollowTrackT(Owner o, RailTypes railtype_override = INVALID_RAILTYPES, CPerformanceTimer *pPerf = NULL) + inline CFollowTrackT(Owner o, RailTypes railtype_override = INVALID_RAILTYPES, CPerformanceTimer *pPerf = nullptr) { - m_veh = NULL; + assert(IsRailTT()); + m_veh = nullptr; Init(o, railtype_override, pPerf); } inline void Init(const VehicleType *v, RailTypes railtype_override, CPerformanceTimer *pPerf) { - assert(!IsRailTT() || (v != NULL && v->type == VEH_TRAIN)); + assert(!IsRailTT() || (v != nullptr && v->type == VEH_TRAIN)); m_veh = v; - Init(v != NULL ? v->owner : INVALID_OWNER, IsRailTT() && railtype_override == INVALID_RAILTYPES ? Train::From(v)->compatible_railtypes : railtype_override, pPerf); + Init(v != nullptr ? v->owner : INVALID_OWNER, IsRailTT() && railtype_override == INVALID_RAILTYPES ? Train::From(v)->compatible_railtypes : railtype_override, pPerf); } inline void Init(Owner o, RailTypes railtype_override, CPerformanceTimer *pPerf) { - assert(!IsRoadTT() || m_veh != NULL); + assert(!IsRoadTT() || m_veh != nullptr); assert(!IsRailTT() || railtype_override != INVALID_RAILTYPES); m_veh_owner = o; m_pPerf = pPerf; @@ -92,7 +91,7 @@ struct CFollowTrackT inline static TransportType TT() { return Ttr_type_; } inline static bool IsWaterTT() { return TT() == TRANSPORT_WATER; } inline static bool IsRailTT() { return TT() == TRANSPORT_RAIL; } - inline bool IsTram() { return IsRoadTT() && HasBit(RoadVehicle::From(m_veh)->compatible_roadtypes, ROADTYPE_TRAM); } + inline bool IsTram() { return IsRoadTT() && RoadTypeIsTram(RoadVehicle::From(m_veh)->roadtype); } inline static bool IsRoadTT() { return TT() == TRANSPORT_ROAD; } inline static bool Allow90degTurns() { return T90deg_turns_allowed_; } inline static bool DoTrackMasking() { return Tmask_reserved_tracks; } @@ -103,7 +102,7 @@ struct CFollowTrackT assert(IsTram()); // this function shouldn't be called in other cases if (IsNormalRoadTile(tile)) { - RoadBits rb = GetRoadBits(tile, ROADTYPE_TRAM); + RoadBits rb = GetRoadBits(tile, RTT_TRAM); switch (rb) { case ROAD_NW: return DIAGDIR_NW; case ROAD_SW: return DIAGDIR_SW; @@ -126,7 +125,7 @@ struct CFollowTrackT m_err = EC_NONE; assert( ((TrackStatusToTrackdirBits( - GetTileTrackStatus(m_old_tile, TT(), (IsRoadTT() && m_veh != NULL) ? RoadVehicle::From(m_veh)->compatible_roadtypes : 0) + GetTileTrackStatus(m_old_tile, TT(), (IsRoadTT() && m_veh != nullptr) ? (this->IsTram() ? RTT_TRAM : RTT_ROAD) : 0) ) & TrackdirToTrackdirBits(m_old_td)) != 0) || (IsTram() && GetSingleTramBit(m_old_tile) != INVALID_DIAGDIR) // Disable the assertion for single tram bits ); @@ -151,13 +150,13 @@ struct CFollowTrackT if (IsRoadTT() && !IsTram() && TryReverse()) return true; /* CanEnterNewTile already set a reason. - * Do NOT overwrite it (important for example for EC_RAIL_TYPE). + * Do NOT overwrite it (important for example for EC_RAIL_ROAD_TYPE). * Only set a reason if CanEnterNewTile was not called */ if (m_new_td_bits == TRACKDIR_BIT_NONE) m_err = EC_NO_WAY; return false; } - if (!Allow90degTurns()) { + if ((!IsRailTT() && !Allow90degTurns()) || (IsRailTT() && Rail90DegTurnDisallowed(GetTileRailType(m_old_tile), GetTileRailType(m_new_tile), !Allow90degTurns()))) { m_new_td_bits &= (TrackdirBits)~(int)TrackdirCrossesTrackdirs(m_old_td); if (m_new_td_bits == TRACKDIR_BIT_NONE) { m_err = EC_90DEG; @@ -241,7 +240,7 @@ protected: if (IsRailTT() && IsPlainRailTile(m_new_tile)) { m_new_td_bits = (TrackdirBits)(GetTrackBits(m_new_tile) * 0x101); } else { - m_new_td_bits = TrackStatusToTrackdirBits(GetTileTrackStatus(m_new_tile, TT(), IsRoadTT() ? RoadVehicle::From(m_veh)->compatible_roadtypes : 0)); + m_new_td_bits = TrackStatusToTrackdirBits(GetTileTrackStatus(m_new_tile, TT(), IsRoadTT() ? (this->IsTram() ? RTT_TRAM : RTT_ROAD) : 0)); if (IsTram() && m_new_td_bits == TRACKDIR_BIT_NONE) { /* GetTileTrackStatus() returns 0 for single tram bits. @@ -350,7 +349,18 @@ protected: RailType rail_type = GetTileRailType(m_new_tile); if (!HasBit(m_railtypes, rail_type)) { /* incompatible rail type */ - m_err = EC_RAIL_TYPE; + m_err = EC_RAIL_ROAD_TYPE; + return false; + } + } + + /* road transport is possible only on compatible road types */ + if (IsRoadTT()) { + const RoadVehicle *v = RoadVehicle::From(m_veh); + RoadType roadtype = GetRoadType(m_new_tile, GetRoadTramType(v->roadtype)); + if (!HasBit(v->compatible_roadtypes, roadtype)) { + /* incompatible road type */ + m_err = EC_RAIL_ROAD_TYPE; return false; } } @@ -447,7 +457,7 @@ protected: public: /** Helper for pathfinders - get min/max speed on the m_old_tile/m_old_td */ - int GetSpeedLimit(int *pmin_speed = NULL) const + int GetSpeedLimit(int *pmin_speed = nullptr) const { int min_speed = 0; int max_speed = INT_MAX; // no limit @@ -465,7 +475,7 @@ public: } /* if min speed was requested, return it */ - if (pmin_speed != NULL) *pmin_speed = min_speed; + if (pmin_speed != nullptr) *pmin_speed = min_speed; return max_speed; } }; @@ -474,8 +484,6 @@ typedef CFollowTrackT CFollowTrackWater; typedef CFollowTrackT CFollowTrackRoad; typedef CFollowTrackT CFollowTrackRail; -typedef CFollowTrackT CFollowTrackWaterNo90; -typedef CFollowTrackT CFollowTrackRoadNo90; typedef CFollowTrackT CFollowTrackRailNo90; typedef CFollowTrackT CFollowTrackFreeRail; diff --git a/src/pathfinder/npf/aystar.cpp b/src/pathfinder/npf/aystar.cpp index beac06291f..b14053b7c0 100644 --- a/src/pathfinder/npf/aystar.cpp +++ b/src/pathfinder/npf/aystar.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. @@ -32,7 +30,7 @@ /** * This looks in the hash whether a node exists in the closed list. * @param node Node to search. - * @return The #PathNode if it is available, else \c NULL + * @return The #PathNode if it is available, else \c nullptr */ PathNode *AyStar::ClosedListIsInList(const AyStarNode *node) { @@ -55,7 +53,7 @@ void AyStar::ClosedListAdd(const PathNode *node) /** * Check whether a node is in the open list. * @param node Node to search. - * @return If the node is available, it is returned, else \c NULL is returned. + * @return If the node is available, it is returned, else \c nullptr is returned. */ OpenListNode *AyStar::OpenListIsInList(const AyStarNode *node) { @@ -65,13 +63,13 @@ OpenListNode *AyStar::OpenListIsInList(const AyStarNode *node) /** * Gets the best node from the open list. * It deletes the returned node from the open list. - * @returns the best node available, or \c NULL of none is found. + * @returns the best node available, or \c nullptr of none is found. */ OpenListNode *AyStar::OpenListPop() { /* Return the item the Queue returns.. the best next OpenList item. */ OpenListNode *res = (OpenListNode*)this->openlist_queue.Pop(); - if (res != NULL) { + if (res != nullptr) { this->openlist_hash.DeleteValue(res->path.node.tile, res->path.node.direction); } @@ -105,7 +103,7 @@ void AyStar::CheckTile(AyStarNode *current, OpenListNode *parent) OpenListNode *check; /* Check the new node against the ClosedList */ - if (this->ClosedListIsInList(current) != NULL) return; + if (this->ClosedListIsInList(current) != nullptr) return; /* Calculate the G-value for this node */ new_g = this->CalculateG(this, current, parent); @@ -131,7 +129,7 @@ void AyStar::CheckTile(AyStarNode *current, OpenListNode *parent) /* Check if this item is already in the OpenList */ check = this->OpenListIsInList(current); - if (check != NULL) { + if (check != nullptr) { uint i; /* Yes, check if this g value is lower.. */ if (new_g > check->g) return; @@ -167,11 +165,11 @@ int AyStar::Loop() /* Get the best node from OpenList */ OpenListNode *current = this->OpenListPop(); /* If empty, drop an error */ - if (current == NULL) return AYSTAR_EMPTY_OPENLIST; + if (current == nullptr) return AYSTAR_EMPTY_OPENLIST; /* Check for end node and if found, return that code */ if (this->EndNodeCheck(this, current) == AYSTAR_FOUND_END_NODE && !CheckIgnoreFirstTile(¤t->path)) { - if (this->FoundEndNode != NULL) { + if (this->FoundEndNode != nullptr) { this->FoundEndNode(this, current); } free(current); @@ -285,7 +283,7 @@ void AyStar::AddStartNode(AyStarNode *start_node, uint g) printf("[AyStar] Starting A* Algorithm from node (%d, %d, %d)\n", TileX(start_node->tile), TileY(start_node->tile), start_node->direction); #endif - this->OpenListAdd(NULL, start_node, 0, g); + this->OpenListAdd(nullptr, start_node, 0, g); } /** diff --git a/src/pathfinder/npf/aystar.h b/src/pathfinder/npf/aystar.h index 890b023e83..cbbe8a4157 100644 --- a/src/pathfinder/npf/aystar.h +++ b/src/pathfinder/npf/aystar.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/pathfinder/npf/npf.cpp b/src/pathfinder/npf/npf.cpp index 7d19d4ef1d..34b85791bd 100644 --- a/src/pathfinder/npf/npf.cpp +++ b/src/pathfinder/npf/npf.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. @@ -14,6 +12,7 @@ #include "../../viewport_func.h" #include "../../ship.h" #include "../../roadstop_base.h" +#include "../../vehicle_func.h" #include "../pathfinder_func.h" #include "../pathfinder_type.h" #include "../follow_track.hpp" @@ -43,6 +42,7 @@ struct AyStarUserData { TransportType type; RailTypes railtypes; RoadTypes roadtypes; + uint subtype; }; /** Indices into AyStarNode.userdata[] */ @@ -103,7 +103,7 @@ static inline void NPFSetFlag(AyStarNode *node, NPFNodeFlag flag, bool value) bool CheckIgnoreFirstTile(const PathNode *node) { - return (node->parent == NULL && HasBit(node->node.user_data[NPF_NODE_FLAGS], NPF_FLAG_IGNORE_START_TILE)); + return (node->parent == nullptr && HasBit(node->node.user_data[NPF_NODE_FLAGS], NPF_FLAG_IGNORE_START_TILE)); } /** @@ -164,8 +164,8 @@ static int32 NPFCalcStationOrTileHeuristic(AyStar *as, AyStarNode *current, Open uint dist; AyStarUserData *user = (AyStarUserData *)as->user_data; - /* for train-stations, we are going to aim for the closest station tile */ - if (user->type != TRANSPORT_WATER && fstd->station_index != INVALID_STATION) { + /* aim for the closest station tile */ + if (fstd->station_index != INVALID_STATION) { to = CalcClosestStationTile(fstd->station_index, from, fstd->station_type); } @@ -192,7 +192,7 @@ static int32 NPFCalcStationOrTileHeuristic(AyStar *as, AyStarNode *current, Open * choice */ static void NPFFillTrackdirChoice(AyStarNode *current, OpenListNode *parent) { - if (parent->path.parent == NULL) { + if (parent->path.parent == nullptr) { Trackdir trackdir = current->direction; /* This is a first order decision, so we'd better save the * direction we chose */ @@ -302,6 +302,15 @@ static void NPFMarkTile(TileIndex tile) } } +static Vehicle *CountShipProc(Vehicle *v, void *data) +{ + uint *count = (uint *)data; + /* Ignore other vehicles (aircraft) and ships inside depot. */ + if (v->type == VEH_SHIP && (v->vehstatus & VS_HIDDEN) == 0) (*count)++; + + return nullptr; +} + static int32 NPFWaterPathCost(AyStar *as, AyStarNode *current, OpenListNode *parent) { /* TileIndex tile = current->tile; */ @@ -318,6 +327,13 @@ static int32 NPFWaterPathCost(AyStar *as, AyStarNode *current, OpenListNode *par cost += _settings_game.pf.npf.npf_water_curve_penalty; } + if (IsDockingTile(current->tile)) { + /* Check docking tile for occupancy */ + uint count = 1; + HasVehicleOnPos(current->tile, &count, &CountShipProc); + cost += count * 3 * _trackdir_length[trackdir]; + } + /* @todo More penalties? */ return cost; @@ -562,6 +578,12 @@ static int32 NPFFindStationOrTile(const AyStar *as, const OpenListNode *current) if (fstd->station_index == INVALID_STATION && tile == fstd->dest_coords) return AYSTAR_FOUND_END_NODE; + if (fstd->v->type == VEH_SHIP) { + /* Ships do not actually reach the destination station, so we check for a docking tile instead. */ + if (IsDockingTile(tile) && IsShipDestinationTile(tile, fstd->station_index)) return AYSTAR_FOUND_END_NODE; + return AYSTAR_DONE; + } + if (IsTileType(tile, MP_STATION) && GetStationIndex(tile) == fstd->station_index) { if (fstd->v->type == VEH_TRAIN) return AYSTAR_FOUND_END_NODE; @@ -584,7 +606,7 @@ static const PathNode *FindSafePosition(PathNode *path, const Train *v) /* If there is no signal, reserve the whole path. */ PathNode *sig = path; - for (; path->parent != NULL; path = path->parent) { + for (; path->parent != nullptr; path = path->parent) { if (IsSafeWaitingPosition(v, path->node.tile, path->node.direction, true, _settings_game.pf.forbid_90_deg)) { sig = path; } @@ -625,7 +647,7 @@ static void NPFSaveTargetData(AyStar *as, OpenListNode *current) ftd->node = current->path.node; ftd->res_okay = false; - if (as->user_target != NULL && ((NPFFindStationOrTileData*)as->user_target)->reserve_path && user->type == TRANSPORT_RAIL) { + if (as->user_target != nullptr && ((NPFFindStationOrTileData*)as->user_target)->reserve_path && user->type == TRANSPORT_RAIL) { /* Path reservation is requested. */ const Train *v = Train::From(((NPFFindStationOrTileData *)as->user_target)->v); @@ -647,7 +669,7 @@ static void NPFSaveTargetData(AyStar *as, OpenListNode *current) if (!IsWaitingPositionFree(v, target->node.tile, target->node.direction, _settings_game.pf.forbid_90_deg)) return; } - for (const PathNode *cur = target; cur->parent != NULL; cur = cur->parent) { + for (const PathNode *cur = target; cur->parent != nullptr; cur = cur->parent) { if (!TryReserveRailTrack(cur->node.tile, TrackdirToTrack(cur->node.direction))) { /* Reservation failed, undo. */ ClearPathReservation(target, cur); @@ -719,7 +741,7 @@ static DiagDirection GetDepotDirection(TileIndex tile, TransportType type) static DiagDirection GetSingleTramBit(TileIndex tile) { if (IsNormalRoadTile(tile)) { - RoadBits rb = GetRoadBits(tile, ROADTYPE_TRAM); + RoadBits rb = GetRoadBits(tile, RTT_TRAM); switch (rb) { case ROAD_NW: return DIAGDIR_NW; case ROAD_SW: return DIAGDIR_SW; @@ -747,7 +769,7 @@ static DiagDirection GetTileSingleEntry(TileIndex tile, TransportType type, uint if (type == TRANSPORT_ROAD) { if (IsStandardRoadStopTile(tile)) return GetRoadStopDir(tile); - if (HasBit(subtype, ROADTYPE_TRAM)) return GetSingleTramBit(tile); + if ((RoadTramType)subtype == RTT_TRAM) return GetSingleTramBit(tile); } return INVALID_DIAGDIR; @@ -785,13 +807,24 @@ static bool CanEnterTile(TileIndex tile, DiagDirection dir, AyStarUserData *user if (!CanEnterTileOwnerCheck(user->owner, tile, dir)) return false; /* check correct rail type (mono, maglev, etc) */ - if (user->type == TRANSPORT_RAIL) { - RailType rail_type = GetTileRailType(tile); - if (!HasBit(user->railtypes, rail_type)) return false; + switch (user->type) { + case TRANSPORT_RAIL: { + RailType rail_type = GetTileRailType(tile); + if (!HasBit(user->railtypes, rail_type)) return false; + break; + } + + case TRANSPORT_ROAD: { + RoadType road_type = GetRoadType(tile, (RoadTramType)user->subtype); + if (!HasBit(user->roadtypes, road_type)) return false; + break; + } + + default: break; } /* Depots, standard roadstops and single tram bits can only be entered from one direction */ - DiagDirection single_entry = GetTileSingleEntry(tile, user->type, user->roadtypes); + DiagDirection single_entry = GetTileSingleEntry(tile, user->type, user->subtype); if (single_entry != INVALID_DIAGDIR && single_entry != ReverseDiagDir(dir)) return false; return true; @@ -803,16 +836,17 @@ static bool CanEnterTile(TileIndex tile, DiagDirection dir, AyStarUserData *user * One-way-roads are taken into account. Signals are not tested. * * @param dst_tile The tile of interest. + * @param src_tile The originating tile. * @param src_trackdir The direction the vehicle is currently moving. * @param type The transporttype of the vehicle. * @param subtype For TRANSPORT_ROAD the compatible RoadTypes of the vehicle. * @return The Trackdirs the vehicle can continue moving on. */ -static TrackdirBits GetDriveableTrackdirBits(TileIndex dst_tile, Trackdir src_trackdir, TransportType type, uint subtype) +static TrackdirBits GetDriveableTrackdirBits(TileIndex dst_tile, TileIndex src_tile, Trackdir src_trackdir, TransportType type, uint subtype) { TrackdirBits trackdirbits = TrackStatusToTrackdirBits(GetTileTrackStatus(dst_tile, type, subtype)); - if (trackdirbits == TRACKDIR_BIT_NONE && type == TRANSPORT_ROAD && HasBit(subtype, ROADTYPE_TRAM)) { + if (trackdirbits == TRACKDIR_BIT_NONE && type == TRANSPORT_ROAD && (RoadTramType)subtype == RTT_TRAM) { /* GetTileTrackStatus() returns 0 for single tram bits. * As we cannot change it there (easily) without breaking something, change it here */ switch (GetSingleTramBit(dst_tile)) { @@ -836,7 +870,9 @@ static TrackdirBits GetDriveableTrackdirBits(TileIndex dst_tile, Trackdir src_tr trackdirbits &= TrackdirReachesTrackdirs(src_trackdir); /* Filter out trackdirs that would make 90 deg turns for trains */ - if (_settings_game.pf.forbid_90_deg && (type == TRANSPORT_RAIL || type == TRANSPORT_WATER)) trackdirbits &= ~TrackdirCrossesTrackdirs(src_trackdir); + if (type == TRANSPORT_RAIL && Rail90DegTurnDisallowed(GetTileRailType(src_tile), GetTileRailType(dst_tile))) { + trackdirbits &= ~TrackdirCrossesTrackdirs(src_trackdir); + } DEBUG(npf, 6, "After filtering: (%d, %d), possible trackdirs: 0x%X", TileX(dst_tile), TileY(dst_tile), trackdirbits); @@ -860,7 +896,7 @@ static void NPFFollowTrack(AyStar *aystar, OpenListNode *current) /* Information about the vehicle: TransportType (road/rail/water) and SubType (compatible rail/road types) */ TransportType type = user->type; - uint subtype = user->roadtypes; + uint subtype = user->subtype; /* Initialize to 0, so we can jump out (return) somewhere an have no neighbours */ aystar->num_neighbours = 0; @@ -877,7 +913,7 @@ static void NPFFollowTrack(AyStar *aystar, OpenListNode *current) if (CheckIgnoreFirstTile(¤t->path)) { /* Do not perform any checks that involve src_tile */ dst_tile = src_tile + TileOffsByDiagDir(src_exitdir); - trackdirbits = GetDriveableTrackdirBits(dst_tile, src_trackdir, type, subtype); + trackdirbits = GetDriveableTrackdirBits(dst_tile, src_tile, src_trackdir, type, subtype); } else if (IsTileType(src_tile, MP_TUNNELBRIDGE) && GetTunnelBridgeDirection(src_tile) == src_exitdir) { /* We drive through the wormhole and arrive on the other side */ dst_tile = GetOtherTunnelBridgeEnd(src_tile); @@ -891,26 +927,26 @@ static void NPFFollowTrack(AyStar *aystar, OpenListNode *current) /* We leave src_tile in src_exitdir and reach dst_tile */ dst_tile = AddTileIndexDiffCWrap(src_tile, TileIndexDiffCByDiagDir(src_exitdir)); - if (dst_tile != INVALID_TILE && !CanEnterTile(dst_tile, src_exitdir, user)) dst_tile = INVALID_TILE; + if (dst_tile != INVALID_TILE && IsNormalRoadTile(dst_tile) && !CanEnterTile(dst_tile, src_exitdir, user)) dst_tile = INVALID_TILE; if (dst_tile == INVALID_TILE) { /* We cannot enter the next tile. Road vehicles can reverse, others reach dead end */ - if (type != TRANSPORT_ROAD || HasBit(subtype, ROADTYPE_TRAM)) return; + if (type != TRANSPORT_ROAD || (RoadTramType)subtype == RTT_TRAM) return; dst_tile = src_tile; src_trackdir = ReverseTrackdir(src_trackdir); } - trackdirbits = GetDriveableTrackdirBits(dst_tile, src_trackdir, type, subtype); + trackdirbits = GetDriveableTrackdirBits(dst_tile, src_tile, src_trackdir, type, subtype); if (trackdirbits == TRACKDIR_BIT_NONE) { /* We cannot enter the next tile. Road vehicles can reverse, others reach dead end */ - if (type != TRANSPORT_ROAD || HasBit(subtype, ROADTYPE_TRAM)) return; + if (type != TRANSPORT_ROAD || (RoadTramType)subtype == RTT_TRAM) return; dst_tile = src_tile; src_trackdir = ReverseTrackdir(src_trackdir); - trackdirbits = GetDriveableTrackdirBits(dst_tile, src_trackdir, type, subtype); + trackdirbits = GetDriveableTrackdirBits(dst_tile, src_tile, src_trackdir, type, subtype); } } @@ -954,13 +990,13 @@ static void NPFFollowTrack(AyStar *aystar, OpenListNode *current) /* * Plan a route to the specified target (which is checked by target_proc), - * from start1 and if not NULL, from start2 as well. The type of transport we + * from start1 and if not nullptr, from start2 as well. The type of transport we * are checking is in type. reverse_penalty is applied to all routes that * originate from the second start node. * When we are looking for one specific target (optionally multiple tiles), we * should use a good heuristic to perform aystar search. When we search for * multiple targets that are spread around, we should perform a breadth first - * search by specifiying CalcZero as our heuristic. + * search by specifying CalcZero as our heuristic. */ static NPFFoundTargetData NPFRouteInternal(AyStarNode *start1, bool ignore_start_tile1, AyStarNode *start2, bool ignore_start_tile2, NPFFindStationOrTileData *target, AyStar_EndNodeCheck target_proc, AyStar_CalculateH heuristic_proc, AyStarUserData *user, uint reverse_penalty, bool ignore_reserved = false, int max_penalty = 0) { @@ -986,7 +1022,7 @@ static NPFFoundTargetData NPFRouteInternal(AyStarNode *start1, bool ignore_start NPFSetFlag(start1, NPF_FLAG_IGNORE_START_TILE, ignore_start_tile1); NPFSetFlag(start1, NPF_FLAG_IGNORE_RESERVED, ignore_reserved); _npf_aystar.AddStartNode(start1, 0); - if (start2 != NULL) { + if (start2 != nullptr) { start2->user_data[NPF_TRACKDIR_CHOICE] = INVALID_TRACKDIR; start2->user_data[NPF_NODE_FLAGS] = 0; NPFSetFlag(start2, NPF_FLAG_IGNORE_START_TILE, ignore_start_tile2); @@ -1014,10 +1050,10 @@ static NPFFoundTargetData NPFRouteInternal(AyStarNode *start1, bool ignore_start assert(r != AYSTAR_STILL_BUSY); if (result.best_bird_dist != 0) { - if (target != NULL) { + if (target != nullptr) { DEBUG(npf, 1, "Could not find route to tile 0x%X from 0x%X.", target->dest_coords, start1->tile); } else { - /* Assumption: target == NULL, so we are looking for a depot */ + /* Assumption: target == nullptr, so we are looking for a depot */ DEBUG(npf, 1, "Could not find route to a depot from tile 0x%X.", start1->tile); } @@ -1038,7 +1074,7 @@ static NPFFoundTargetData NPFRouteToStationOrTileTwoWay(TileIndex tile1, Trackdi start1.direction = trackdir1; start2.direction = trackdir2; - return NPFRouteInternal(&start1, ignore_start_tile1, (IsValidTile(tile2) ? &start2 : NULL), ignore_start_tile2, target, NPFFindStationOrTile, NPFCalcStationOrTileHeuristic, user, 0); + return NPFRouteInternal(&start1, ignore_start_tile1, (IsValidTile(tile2) ? &start2 : nullptr), ignore_start_tile2, target, NPFFindStationOrTile, NPFCalcStationOrTileHeuristic, user, 0); } /* Will search from the given tile and direction, for a route to the given @@ -1066,9 +1102,9 @@ static NPFFoundTargetData NPFRouteToDepotBreadthFirstTwoWay(TileIndex tile1, Tra start1.direction = trackdir1; start2.direction = trackdir2; - /* perform a breadth first search. Target is NULL, + /* perform a breadth first search. Target is nullptr, * since we are just looking for any depot...*/ - return NPFRouteInternal(&start1, ignore_start_tile1, (IsValidTile(tile2) ? &start2 : NULL), ignore_start_tile2, target, NPFFindDepot, NPFCalcZero, user, reverse_penalty, false, max_penalty); + return NPFRouteInternal(&start1, ignore_start_tile1, (IsValidTile(tile2) ? &start2 : nullptr), ignore_start_tile2, target, NPFFindDepot, NPFCalcZero, user, reverse_penalty, false, max_penalty); } void InitializeNPF() @@ -1096,10 +1132,16 @@ static void NPFFillWithOrderData(NPFFindStationOrTileData *fstd, const Vehicle * * dest_tile, not just any stop of that station. * So only for train orders to stations we fill fstd->station_index, for all * others only dest_coords */ - if (v->type != VEH_SHIP && (v->current_order.IsType(OT_GOTO_STATION) || v->current_order.IsType(OT_GOTO_WAYPOINT))) { - assert(v->IsGroundVehicle()); + if (v->current_order.IsType(OT_GOTO_STATION) || v->current_order.IsType(OT_GOTO_WAYPOINT)) { fstd->station_index = v->current_order.GetDestination(); - fstd->station_type = (v->type == VEH_TRAIN) ? (v->current_order.IsType(OT_GOTO_STATION) ? STATION_RAIL : STATION_WAYPOINT) : (RoadVehicle::From(v)->IsBus() ? STATION_BUS : STATION_TRUCK); + if (v->type == VEH_TRAIN) { + fstd->station_type = v->current_order.IsType(OT_GOTO_STATION) ? STATION_RAIL : STATION_WAYPOINT; + } else if (v->type == VEH_ROAD) { + fstd->station_type = RoadVehicle::From(v)->IsBus() ? STATION_BUS : STATION_TRUCK; + } else if (v->type == VEH_SHIP) { + fstd->station_type = v->current_order.IsType(OT_GOTO_STATION) ? STATION_DOCK : STATION_BUOY; + } + fstd->not_articulated = v->type == VEH_ROAD && !RoadVehicle::From(v)->HasArticulatedPart(); /* Let's take the closest tile of the station as our target for vehicles */ fstd->dest_coords = CalcClosestStationTile(fstd->station_index, v->tile, fstd->station_type); @@ -1117,8 +1159,8 @@ FindDepotData NPFRoadVehicleFindNearestDepot(const RoadVehicle *v, int max_penal { Trackdir trackdir = v->GetVehicleTrackdir(); - AyStarUserData user = { v->owner, TRANSPORT_ROAD, INVALID_RAILTYPES, v->compatible_roadtypes }; - NPFFoundTargetData ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, false, INVALID_TILE, INVALID_TRACKDIR, false, NULL, &user, 0, max_penalty); + AyStarUserData user = { v->owner, TRANSPORT_ROAD, RAILTYPES_NONE, v->compatible_roadtypes, GetRoadTramType(v->roadtype) }; + NPFFoundTargetData ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, false, INVALID_TILE, INVALID_TRACKDIR, false, nullptr, &user, 0, max_penalty); if (ftd.best_bird_dist != 0) return FindDepotData(); @@ -1137,7 +1179,7 @@ Trackdir NPFRoadVehicleChooseTrack(const RoadVehicle *v, TileIndex tile, DiagDir NPFFillWithOrderData(&fstd, v); Trackdir trackdir = DiagDirToDiagTrackdir(enterdir); - AyStarUserData user = { v->owner, TRANSPORT_ROAD, INVALID_RAILTYPES, v->compatible_roadtypes }; + AyStarUserData user = { v->owner, TRANSPORT_ROAD, RAILTYPES_NONE, v->compatible_roadtypes, GetRoadTramType(v->roadtype) }; NPFFoundTargetData ftd = NPFRouteToStationOrTile(tile - TileOffsByDiagDir(enterdir), trackdir, true, &fstd, &user); assert(ftd.best_trackdir != INVALID_TRACKDIR); @@ -1160,7 +1202,7 @@ Track NPFShipChooseTrack(const Ship *v, bool &path_found) NPFFillWithOrderData(&fstd, v); - AyStarUserData user = { v->owner, TRANSPORT_WATER, INVALID_RAILTYPES, ROADTYPES_NONE }; + AyStarUserData user = { v->owner, TRANSPORT_WATER, RAILTYPES_NONE, ROADTYPES_NONE, 0 }; NPFFoundTargetData ftd = NPFRouteToStationOrTile(v->tile, trackdir, true, &fstd, &user); assert(ftd.best_trackdir != INVALID_TRACKDIR); @@ -1185,7 +1227,7 @@ bool NPFShipCheckReverse(const Ship *v) assert(trackdir != INVALID_TRACKDIR); assert(trackdir_rev != INVALID_TRACKDIR); - AyStarUserData user = { v->owner, TRANSPORT_WATER, INVALID_RAILTYPES, ROADTYPES_NONE }; + AyStarUserData user = { v->owner, TRANSPORT_WATER, RAILTYPES_NONE, ROADTYPES_NONE, 0 }; ftd = NPFRouteToStationOrTileTwoWay(v->tile, trackdir, false, v->tile, trackdir_rev, false, &fstd, &user); /* If we didn't find anything, just keep on going straight ahead, otherwise take the reverse flag */ return ftd.best_bird_dist == 0 && NPFGetFlag(&ftd.node, NPF_FLAG_REVERSE); @@ -1203,7 +1245,7 @@ FindDepotData NPFTrainFindNearestDepot(const Train *v, int max_penalty) fstd.reserve_path = false; assert(trackdir != INVALID_TRACKDIR); - AyStarUserData user = { v->owner, TRANSPORT_RAIL, v->compatible_railtypes, ROADTYPES_NONE }; + AyStarUserData user = { v->owner, TRANSPORT_RAIL, v->compatible_railtypes, ROADTYPES_NONE, 0 }; NPFFoundTargetData ftd = NPFRouteToDepotBreadthFirstTwoWay(v->tile, trackdir, false, last->tile, trackdir_rev, false, &fstd, &user, NPF_INFINITE_PENALTY, max_penalty); if (ftd.best_bird_dist != 0) return FindDepotData(); @@ -1230,10 +1272,10 @@ bool NPFTrainFindNearestSafeTile(const Train *v, TileIndex tile, Trackdir trackd RailTypes railtypes = v->compatible_railtypes; if (override_railtype) railtypes |= GetRailTypeInfo(v->railtype)->compatible_railtypes; - /* perform a breadth first search. Target is NULL, + /* perform a breadth first search. Target is nullptr, * since we are just looking for any safe tile...*/ - AyStarUserData user = { v->owner, TRANSPORT_RAIL, railtypes, ROADTYPES_NONE }; - return NPFRouteInternal(&start1, true, NULL, false, &fstd, NPFFindSafeTile, NPFCalcZero, &user, 0, true).res_okay; + AyStarUserData user = { v->owner, TRANSPORT_RAIL, railtypes, ROADTYPES_NONE, 0 }; + return NPFRouteInternal(&start1, true, nullptr, false, &fstd, NPFFindSafeTile, NPFCalcZero, &user, 0, true).res_okay; } bool NPFTrainCheckReverse(const Train *v) @@ -1249,7 +1291,7 @@ bool NPFTrainCheckReverse(const Train *v) assert(trackdir != INVALID_TRACKDIR); assert(trackdir_rev != INVALID_TRACKDIR); - AyStarUserData user = { v->owner, TRANSPORT_RAIL, v->compatible_railtypes, ROADTYPES_NONE }; + AyStarUserData user = { v->owner, TRANSPORT_RAIL, v->compatible_railtypes, ROADTYPES_NONE, 0 }; ftd = NPFRouteToStationOrTileTwoWay(v->tile, trackdir, false, last->tile, trackdir_rev, false, &fstd, &user); /* If we didn't find anything, just keep on going straight ahead, otherwise take the reverse flag */ return ftd.best_bird_dist == 0 && NPFGetFlag(&ftd.node, NPF_FLAG_REVERSE); @@ -1263,10 +1305,10 @@ Track NPFTrainChooseTrack(const Train *v, bool &path_found, bool reserve_track, PBSTileInfo origin = FollowTrainReservation(v); assert(IsValidTrackdir(origin.trackdir)); - AyStarUserData user = { v->owner, TRANSPORT_RAIL, v->compatible_railtypes, ROADTYPES_NONE }; + AyStarUserData user = { v->owner, TRANSPORT_RAIL, v->compatible_railtypes, ROADTYPES_NONE, 0 }; NPFFoundTargetData ftd = NPFRouteToStationOrTile(origin.tile, origin.trackdir, true, &fstd, &user); - if (target != NULL) { + if (target != nullptr) { target->tile = ftd.node.tile; target->trackdir = (Trackdir)ftd.node.direction; target->okay = ftd.res_okay; diff --git a/src/pathfinder/npf/npf_func.h b/src/pathfinder/npf/npf_func.h index 2429989ab9..036caf9bb0 100644 --- a/src/pathfinder/npf/npf_func.h +++ b/src/pathfinder/npf/npf_func.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/pathfinder/npf/queue.cpp b/src/pathfinder/npf/queue.cpp index 2afb413918..64ea3bfcae 100644 --- a/src/pathfinder/npf/queue.cpp +++ b/src/pathfinder/npf/queue.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. @@ -37,7 +35,7 @@ void BinaryHeap::Clear(bool free_values) uint j; for (i = 0; i < this->blocks; i++) { - if (this->elements[i] == NULL) { + if (this->elements[i] == nullptr) { /* No more allocated blocks */ break; } @@ -55,7 +53,7 @@ void BinaryHeap::Clear(bool free_values) if (i != 0) { /* Leave the first block of memory alone */ free(this->elements[i]); - this->elements[i] = NULL; + this->elements[i] = nullptr; } } this->size = 0; @@ -73,7 +71,7 @@ void BinaryHeap::Free(bool free_values) this->Clear(free_values); for (i = 0; i < this->blocks; i++) { - if (this->elements[i] == NULL) break; + if (this->elements[i] == nullptr) break; free(this->elements[i]); } free(this->elements); @@ -88,7 +86,7 @@ bool BinaryHeap::Push(void *item, int priority) if (this->size == this->max_size) return false; assert(this->size < this->max_size); - if (this->elements[this->size >> BINARY_HEAP_BLOCKSIZE_BITS] == NULL) { + if (this->elements[this->size >> BINARY_HEAP_BLOCKSIZE_BITS] == nullptr) { /* The currently allocated blocks are full, allocate a new one */ assert((this->size & BINARY_HEAP_BLOCKSIZE_MASK) == 0); this->elements[this->size >> BINARY_HEAP_BLOCKSIZE_BITS] = MallocT(BINARY_HEAP_BLOCKSIZE); @@ -195,7 +193,7 @@ void *BinaryHeap::Pop() { void *result; - if (this->size == 0) return NULL; + if (this->size == 0) return nullptr; /* The best item is always on top, so give that as result */ result = this->GetElement(1).item; @@ -264,7 +262,7 @@ void Hash::Delete(bool free_values) /* Free the first value */ if (free_values) free(this->buckets[i].value); node = this->buckets[i].next; - while (node != NULL) { + while (node != nullptr) { HashNode *prev = node; node = node->next; @@ -296,7 +294,7 @@ void Hash::PrintStatistics() const const HashNode *node; used_buckets++; - for (node = &this->buckets[i]; node != NULL; node = node->next) collision++; + for (node = &this->buckets[i]; node != nullptr; node = node->next) collision++; if (collision > max_collision) max_collision = collision; } if (collision >= lengthof(usage)) collision = lengthof(usage) - 1; @@ -351,7 +349,7 @@ void Hash::Clear(bool free_values) /* Free the first value */ if (free_values) free(this->buckets[i].value); node = this->buckets[i].next; - while (node != NULL) { + while (node != nullptr) { HashNode *prev = node; node = node->next; @@ -365,32 +363,32 @@ void Hash::Clear(bool free_values) /** * Finds the node that that saves this key pair. If it is not - * found, returns NULL. If it is found, *prev is set to the + * found, returns nullptr. If it is found, *prev is set to the * node before the one found, or if the node found was the first in the bucket - * to NULL. If it is not found, *prev is set to the last HashNode in the - * bucket, or NULL if it is empty. prev can also be NULL, in which case it is + * to nullptr. If it is not found, *prev is set to the last HashNode in the + * bucket, or nullptr if it is empty. prev can also be nullptr, in which case it is * not used for output. */ HashNode *Hash::FindNode(uint key1, uint key2, HashNode** prev_out) const { uint hash = this->hash(key1, key2); - HashNode *result = NULL; + HashNode *result = nullptr; /* Check if the bucket is empty */ if (!this->buckets_in_use[hash]) { - if (prev_out != NULL) *prev_out = NULL; - result = NULL; + if (prev_out != nullptr) *prev_out = nullptr; + result = nullptr; /* Check the first node specially */ } else if (this->buckets[hash].key1 == key1 && this->buckets[hash].key2 == key2) { /* Save the value */ result = this->buckets + hash; - if (prev_out != NULL) *prev_out = NULL; + if (prev_out != nullptr) *prev_out = nullptr; /* Check all other nodes */ } else { HashNode *prev = this->buckets + hash; HashNode *node; - for (node = prev->next; node != NULL; node = node->next) { + for (node = prev->next; node != nullptr; node = node->next) { if (node->key1 == key1 && node->key2 == key2) { /* Found it */ result = node; @@ -398,14 +396,14 @@ HashNode *Hash::FindNode(uint key1, uint key2, HashNode** prev_out) const } prev = node; } - if (prev_out != NULL) *prev_out = prev; + if (prev_out != nullptr) *prev_out = prev; } return result; } /** * Deletes the value with the specified key pair from the hash and returns - * that value. Returns NULL when the value was not present. The value returned + * that value. Returns nullptr when the value was not present. The value returned * is _not_ free()'d! */ void *Hash::DeleteValue(uint key1, uint key2) @@ -414,15 +412,15 @@ void *Hash::DeleteValue(uint key1, uint key2) HashNode *prev; // Used as output var for below function call HashNode *node = this->FindNode(key1, key2, &prev); - if (node == NULL) { + if (node == nullptr) { /* not found */ - result = NULL; - } else if (prev == NULL) { + result = nullptr; + } else if (prev == nullptr) { /* It is in the first node, we can't free that one, so we free * the next one instead (if there is any)*/ /* Save the value */ result = node->value; - if (node->next != NULL) { + if (node->next != nullptr) { HashNode *next = node->next; /* Copy the second to the first */ *node = *next; @@ -443,20 +441,20 @@ void *Hash::DeleteValue(uint key1, uint key2) /* Free the node */ free(node); } - if (result != NULL) this->size--; + if (result != nullptr) this->size--; return result; } /** * Sets the value associated with the given key pair to the given value. - * Returns the old value if the value was replaced, NULL when it was not yet present. + * Returns the old value if the value was replaced, nullptr when it was not yet present. */ void *Hash::Set(uint key1, uint key2, void *value) { HashNode *prev; HashNode *node = this->FindNode(key1, key2, &prev); - if (node != NULL) { + if (node != nullptr) { /* Found it */ void *result = node->value; @@ -464,7 +462,7 @@ void *Hash::Set(uint key1, uint key2, void *value) return result; } /* It is not yet present, let's add it */ - if (prev == NULL) { + if (prev == nullptr) { /* The bucket is still empty */ uint hash = this->hash(key1, key2); this->buckets_in_use[hash] = true; @@ -474,21 +472,21 @@ void *Hash::Set(uint key1, uint key2, void *value) node = MallocT(1); prev->next = node; } - node->next = NULL; + node->next = nullptr; node->key1 = key1; node->key2 = key2; node->value = value; this->size++; - return NULL; + return nullptr; } /** - * Gets the value associated with the given key pair, or NULL when it is not + * Gets the value associated with the given key pair, or nullptr when it is not * present. */ void *Hash::Get(uint key1, uint key2) const { - HashNode *node = this->FindNode(key1, key2, NULL); + HashNode *node = this->FindNode(key1, key2, nullptr); - return (node != NULL) ? node->value : NULL; + return (node != nullptr) ? node->value : nullptr; } diff --git a/src/pathfinder/npf/queue.h b/src/pathfinder/npf/queue.h index 3a5bd1ce92..c65131aec9 100644 --- a/src/pathfinder/npf/queue.h +++ b/src/pathfinder/npf/queue.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/pathfinder/opf/opf_ship.cpp b/src/pathfinder/opf/opf_ship.cpp deleted file mode 100644 index c993f82033..0000000000 --- a/src/pathfinder/opf/opf_ship.cpp +++ /dev/null @@ -1,222 +0,0 @@ -/* $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. - * 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 opf_ship.cpp Implementation of the oldest supported ship pathfinder. */ - -#include "../../stdafx.h" -#include "../../tunnelbridge_map.h" -#include "../../tunnelbridge.h" -#include "../../ship.h" -#include "../../core/random_func.hpp" - -#include "../../safeguards.h" - -struct RememberData { - uint16 cur_length; - byte depth; - Track last_choosen_track; -}; - -struct TrackPathFinder { - TileIndex skiptile; - TileIndex dest_coords; - uint best_bird_dist; - uint best_length; - RememberData rd; - TrackdirByte the_dir; -}; - -static bool ShipTrackFollower(TileIndex tile, TrackPathFinder *pfs, uint length) -{ - /* Found dest? */ - if (tile == pfs->dest_coords) { - pfs->best_bird_dist = 0; - - pfs->best_length = minu(pfs->best_length, length); - return true; - } - - /* Skip this tile in the calculation */ - if (tile != pfs->skiptile) { - pfs->best_bird_dist = minu(pfs->best_bird_dist, DistanceMaxPlusManhattan(pfs->dest_coords, tile)); - } - - return false; -} - -static void TPFModeShip(TrackPathFinder *tpf, TileIndex tile, DiagDirection direction) -{ - if (IsTileType(tile, MP_TUNNELBRIDGE)) { - /* wrong track type */ - if (GetTunnelBridgeTransportType(tile) != TRANSPORT_WATER) return; - - DiagDirection dir = GetTunnelBridgeDirection(tile); - /* entering tunnel / bridge? */ - if (dir == direction) { - TileIndex endtile = GetOtherTunnelBridgeEnd(tile); - - tpf->rd.cur_length += GetTunnelBridgeLength(tile, endtile) + 1; - - tile = endtile; - } else { - /* leaving tunnel / bridge? */ - if (ReverseDiagDir(dir) != direction) return; - } - } - - /* This addition will sometimes overflow by a single tile. - * The use of TILE_MASK here makes sure that we still point at a valid - * tile, and then this tile will be in the sentinel row/col, so GetTileTrackStatus will fail. */ - tile = TILE_MASK(tile + TileOffsByDiagDir(direction)); - - if (++tpf->rd.cur_length > 50) return; - - TrackBits bits = TrackStatusToTrackBits(GetTileTrackStatus(tile, TRANSPORT_WATER, 0)) & DiagdirReachesTracks(direction); - if (bits == TRACK_BIT_NONE) return; - - assert(TileX(tile) != MapMaxX() && TileY(tile) != MapMaxY()); - - bool only_one_track = true; - do { - Track track = RemoveFirstTrack(&bits); - if (bits != TRACK_BIT_NONE) only_one_track = false; - RememberData rd = tpf->rd; - - /* Change direction 4 times only */ - if (!only_one_track && track != tpf->rd.last_choosen_track) { - if (++tpf->rd.depth > 4) { - tpf->rd = rd; - return; - } - tpf->rd.last_choosen_track = track; - } - - tpf->the_dir = TrackEnterdirToTrackdir(track, direction); - - if (!ShipTrackFollower(tile, tpf, tpf->rd.cur_length)) { - TPFModeShip(tpf, tile, TrackdirToExitdir(tpf->the_dir)); - } - - tpf->rd = rd; - } while (bits != TRACK_BIT_NONE); -} - -static void OPFShipFollowTrack(TileIndex tile, DiagDirection direction, TrackPathFinder *tpf) -{ - assert(IsValidDiagDirection(direction)); - - /* initialize path finder variables */ - tpf->rd.cur_length = 0; - tpf->rd.depth = 0; - tpf->rd.last_choosen_track = INVALID_TRACK; - - ShipTrackFollower(tile, tpf, 0); - TPFModeShip(tpf, tile, direction); -} - -/** Directions to search towards given track bits and the ship's enter direction. */ -static const DiagDirection _ship_search_directions[6][4] = { - { DIAGDIR_NE, INVALID_DIAGDIR, DIAGDIR_SW, INVALID_DIAGDIR }, - { INVALID_DIAGDIR, DIAGDIR_SE, INVALID_DIAGDIR, DIAGDIR_NW }, - { INVALID_DIAGDIR, DIAGDIR_NE, DIAGDIR_NW, INVALID_DIAGDIR }, - { DIAGDIR_SE, INVALID_DIAGDIR, INVALID_DIAGDIR, DIAGDIR_SW }, - { DIAGDIR_NW, DIAGDIR_SW, INVALID_DIAGDIR, INVALID_DIAGDIR }, - { INVALID_DIAGDIR, INVALID_DIAGDIR, DIAGDIR_SE, DIAGDIR_NE }, -}; - -/** Track to "direction (& 3)" mapping. */ -static const byte _pick_shiptrack_table[6] = {DIR_NE, DIR_SE, DIR_E, DIR_E, DIR_N, DIR_N}; - -static uint FindShipTrack(const Ship *v, TileIndex tile, DiagDirection dir, TrackBits bits, TileIndex skiptile, Track *track) -{ - TrackPathFinder pfs; - uint best_bird_dist = 0; - uint best_length = 0; - byte ship_dir = v->direction & 3; - - pfs.dest_coords = v->dest_tile; - pfs.skiptile = skiptile; - - Track best_track = INVALID_TRACK; - - assert(bits != TRACK_BIT_NONE); - do { - Track i = RemoveFirstTrack(&bits); - - pfs.best_bird_dist = UINT_MAX; - pfs.best_length = UINT_MAX; - - OPFShipFollowTrack(tile, _ship_search_directions[i][dir], &pfs); - - if (best_track != INVALID_TRACK) { - if (pfs.best_bird_dist != 0) { - /* neither reached the destination, pick the one with the smallest bird dist */ - if (pfs.best_bird_dist > best_bird_dist) goto bad; - if (pfs.best_bird_dist < best_bird_dist) goto good; - } else { - if (pfs.best_length > best_length) goto bad; - if (pfs.best_length < best_length) goto good; - } - - /* if we reach this position, there's two paths of equal value so far. - * pick one randomly. */ - uint r = GB(Random(), 0, 8); - if (_pick_shiptrack_table[i] == ship_dir) r += 80; - if (_pick_shiptrack_table[best_track] == ship_dir) r -= 80; - if (r <= 127) goto bad; - } -good:; - best_track = i; - best_bird_dist = pfs.best_bird_dist; - best_length = pfs.best_length; -bad:; - - } while (bits != TRACK_BIT_NONE); - - *track = best_track; - return best_bird_dist; -} - -/** - * Finds the best track to choose on the next tile and - * returns INVALID_TRACK when it is better to reverse. - * @param v The ship. - * @param tile The tile we are about to enter. - * @param enterdir The direction entering the tile. - * @param tracks The tracks available on new tile. - * @param[out] path_found Whether a path has been found. - * @return Best track on next tile or INVALID_TRACK when better to reverse. - */ -Track OPFShipChooseTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found) -{ - assert(IsValidDiagDirection(enterdir)); - - TileIndex tile2 = TILE_ADD(tile, -TileOffsByDiagDir(enterdir)); - Track track; - - /* Let's find out how far it would be if we would reverse first */ - uint rev_dist = UINT_MAX; // distance if we reverse - Track cur_track = TrackdirToTrack(v->GetVehicleTrackdir()); // track on the current tile - DiagDirection rev_enterdir = ReverseDiagDir(enterdir); - TrackBits rev_tracks = TrackStatusToTrackBits(GetTileTrackStatus(tile2, TRANSPORT_WATER, 0)) & - DiagdirReachesTracks(rev_enterdir); - - if (HasTrack(rev_tracks, cur_track)) { - rev_dist = FindShipTrack(v, tile2, rev_enterdir, TrackToTrackBits(cur_track), tile, &track); - if (rev_dist != UINT_MAX) rev_dist++; // penalty for reversing - } - - /* And if we would not reverse? */ - uint dist = FindShipTrack(v, tile, enterdir, tracks, 0, &track); - - /* Due to the way this pathfinder works we cannot determine whether we're lost or not. */ - path_found = true; - if (dist <= rev_dist) return track; - return INVALID_TRACK; // We could better reverse -} diff --git a/src/pathfinder/opf/opf_ship.h b/src/pathfinder/opf/opf_ship.h deleted file mode 100644 index 62668b206a..0000000000 --- a/src/pathfinder/opf/opf_ship.h +++ /dev/null @@ -1,31 +0,0 @@ -/* $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. - * 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 opf_ship.h Original pathfinder for ships; very simple. */ - -#ifndef OPF_SHIP_H -#define OPF_SHIP_H - -#include "../../direction_type.h" -#include "../../tile_type.h" -#include "../../track_type.h" -#include "../../vehicle_type.h" - -/** - * Finds the best path for given ship using OPF. - * @param v the ship that needs to find a path - * @param tile the tile to find the path from (should be next tile the ship is about to enter) - * @param enterdir diagonal direction which the ship will enter this new tile from - * @param tracks available tracks on the new tile (to choose from) - * @param path_found [out] Whether a path has been found (true) or has been guessed (false) - * @return the best trackdir for next turn or INVALID_TRACK if the path could not be found - */ -Track OPFShipChooseTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found); - -#endif /* OPF_SHIP_H */ diff --git a/src/pathfinder/pathfinder_func.h b/src/pathfinder/pathfinder_func.h index 4c0671941c..03edf6995b 100644 --- a/src/pathfinder/pathfinder_func.h +++ b/src/pathfinder/pathfinder_func.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/pathfinder/pathfinder_type.h b/src/pathfinder/pathfinder_type.h index 0ecf00bbd2..eb0381d8a3 100644 --- a/src/pathfinder/pathfinder_type.h +++ b/src/pathfinder/pathfinder_type.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. @@ -43,6 +41,12 @@ static const int YAPF_INFINITE_PENALTY = 1000 * YAPF_TILE_LENGTH; /** Maximum length of ship path cache */ static const int YAPF_SHIP_PATH_CACHE_LENGTH = 32; +/** Maximum segments of road vehicle path cache */ +static const int YAPF_ROADVEH_PATH_CACHE_SEGMENTS = 8; + +/** Distance from destination road stops to not cache any further */ +static const int YAPF_ROADVEH_PATH_CACHE_DESTINATION_LIMIT = 8; + /** * Helper container to find a depot */ diff --git a/src/pathfinder/pf_performance_timer.hpp b/src/pathfinder/pf_performance_timer.hpp index 808542d25a..66ec9695f8 100644 --- a/src/pathfinder/pf_performance_timer.hpp +++ b/src/pathfinder/pf_performance_timer.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. @@ -53,7 +51,7 @@ struct CPerfStartReal inline CPerfStartReal(CPerformanceTimer& perf) : m_pperf(&perf) { - if (m_pperf != NULL) m_pperf->Start(); + if (m_pperf != nullptr) m_pperf->Start(); } inline ~CPerfStartReal() @@ -63,9 +61,9 @@ struct CPerfStartReal inline void Stop() { - if (m_pperf != NULL) { + if (m_pperf != nullptr) { m_pperf->Stop(); - m_pperf = NULL; + m_pperf = nullptr; } } }; diff --git a/src/pathfinder/yapf/nodelist.hpp b/src/pathfinder/yapf/nodelist.hpp index 87e65fd26e..e4d91c6ee0 100644 --- a/src/pathfinder/yapf/nodelist.hpp +++ b/src/pathfinder/yapf/nodelist.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. @@ -42,7 +40,7 @@ public: /** default constructor */ CNodeList_HashTableT() : m_open_queue(2048) { - m_new_node = NULL; + m_new_node = nullptr; } /** destructor */ @@ -65,7 +63,7 @@ public: /** allocate new data item from m_arr */ inline Titem_ *CreateNewNode() { - if (m_new_node == NULL) m_new_node = m_arr.AppendC(); + if (m_new_node == nullptr) m_new_node = m_arr.AppendC(); return m_new_node; } @@ -74,7 +72,7 @@ public: { /* for now it is enough to invalidate m_new_node if it is our given node */ if (&item == m_new_node) { - m_new_node = NULL; + m_new_node = nullptr; } /* TODO: do we need to store best nodes found in some extra list/array? Probably not now. */ } @@ -82,11 +80,11 @@ public: /** insert given item as open node (into m_open and m_open_queue) */ inline void InsertOpenNode(Titem_ &item) { - assert(m_closed.Find(item.GetKey()) == NULL); + assert(m_closed.Find(item.GetKey()) == nullptr); m_open.Push(item); m_open_queue.Include(&item); if (&item == m_new_node) { - m_new_node = NULL; + m_new_node = nullptr; } } @@ -96,7 +94,7 @@ public: if (!m_open_queue.IsEmpty()) { return m_open_queue.Begin(); } - return NULL; + return nullptr; } /** remove and return the best open node */ @@ -107,10 +105,10 @@ public: m_open.Pop(*item); return item; } - return NULL; + return nullptr; } - /** return the open node specified by a key or NULL if not found */ + /** return the open node specified by a key or nullptr if not found */ inline Titem_ *FindOpenNode(const Key &key) { Titem_ *item = m_open.Find(key); @@ -129,11 +127,11 @@ public: /** close node */ inline void InsertClosedNode(Titem_ &item) { - assert(m_open.Find(item.GetKey()) == NULL); + assert(m_open.Find(item.GetKey()) == nullptr); m_closed.Push(item); } - /** return the closed node specified by a key or NULL if not found */ + /** return the closed node specified by a key or nullptr if not found */ inline Titem_ *FindClosedNode(const Key &key) { Titem_ *item = m_closed.Find(key); diff --git a/src/pathfinder/yapf/yapf.h b/src/pathfinder/yapf/yapf.h index 84bd35c8b0..af5e966e7f 100644 --- a/src/pathfinder/yapf/yapf.h +++ b/src/pathfinder/yapf/yapf.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. @@ -16,6 +14,7 @@ #include "../../track_type.h" #include "../../vehicle_type.h" #include "../../ship.h" +#include "../../roadveh.h" #include "../pathfinder_type.h" /** @@ -45,7 +44,7 @@ bool YapfShipCheckReverse(const Ship *v); * @param path_found [out] Whether a path has been found (true) or has been guessed (false) * @return the best trackdir for next turn or INVALID_TRACKDIR if the path could not be found */ -Trackdir YapfRoadVehicleChooseTrack(const RoadVehicle *v, TileIndex tile, DiagDirection enterdir, TrackdirBits trackdirs, bool &path_found); +Trackdir YapfRoadVehicleChooseTrack(const RoadVehicle *v, TileIndex tile, DiagDirection enterdir, TrackdirBits trackdirs, bool &path_found, RoadVehPathCache &path_cache); /** * Finds the best path for given train using YAPF. diff --git a/src/pathfinder/yapf/yapf.hpp b/src/pathfinder/yapf/yapf.hpp index fda79287d8..867c6188ff 100644 --- a/src/pathfinder/yapf/yapf.hpp +++ b/src/pathfinder/yapf/yapf.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/pathfinder/yapf/yapf_base.hpp b/src/pathfinder/yapf/yapf_base.hpp index 6360567bb2..0bdd81dffe 100644 --- a/src/pathfinder/yapf/yapf_base.hpp +++ b/src/pathfinder/yapf/yapf_base.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. @@ -81,11 +79,11 @@ public: public: /** default constructor */ inline CYapfBaseT() - : m_pBestDestNode(NULL) - , m_pBestIntermediateNode(NULL) + : m_pBestDestNode(nullptr) + , m_pBestIntermediateNode(nullptr) , m_settings(&_settings_game.pf.yapf) , m_max_search_nodes(PfGetSettings().max_search_nodes) - , m_veh(NULL) + , m_veh(nullptr) , m_stats_cost_calcs(0) , m_stats_cache_hits(0) , m_num_steps(0) @@ -131,12 +129,12 @@ public: for (;;) { m_num_steps++; Node *n = m_nodes.GetBestOpenNode(); - if (n == NULL) { + if (n == nullptr) { break; } /* if the best open node was worse than the best path found, we can finish */ - if (m_pBestDestNode != NULL && m_pBestDestNode->GetCost() < n->GetCostEstimate()) { + if (m_pBestDestNode != nullptr && m_pBestDestNode->GetCost() < n->GetCostEstimate()) { break; } @@ -150,7 +148,7 @@ public: } } - bDestFound &= (m_pBestDestNode != NULL); + bDestFound &= (m_pBestDestNode != nullptr); perf.Stop(); if (_debug_yapf_level >= 2) { @@ -158,7 +156,7 @@ public: _total_pf_time_us += t; if (_debug_yapf_level >= 3) { - UnitID veh_idx = (m_veh != NULL) ? m_veh->unitnumber : 0; + UnitID veh_idx = (m_veh != nullptr) ? m_veh->unitnumber : 0; char ttc = Yapf().TransportTypeChar(); float cache_hit_ratio = (m_stats_cache_hits == 0) ? 0.0f : ((float)m_stats_cache_hits / (float)(m_stats_cache_hits + m_stats_cost_calcs) * 100.0f); int cost = bDestFound ? m_pBestDestNode->m_cost : -1; @@ -180,7 +178,7 @@ public: */ inline Node *GetBestNode() { - return (m_pBestDestNode != NULL) ? m_pBestDestNode : m_pBestIntermediateNode; + return (m_pBestDestNode != nullptr) ? m_pBestDestNode : m_pBestIntermediateNode; } /** @@ -198,7 +196,7 @@ public: { Yapf().PfNodeCacheFetch(n); /* insert the new node only if it is not there */ - if (m_nodes.FindOpenNode(n.m_key) == NULL) { + if (m_nodes.FindOpenNode(n.m_key) == nullptr) { m_nodes.InsertOpenNode(n); } else { /* if we are here, it means that node is already there - how it is possible? @@ -229,7 +227,7 @@ public: */ void PruneIntermediateNodeBranch() { - while (Yapf().m_pBestIntermediateNode != NULL && (Yapf().m_pBestIntermediateNode->m_segment->m_end_segment_reason & ESRB_CHOICE_FOLLOWS) == 0) { + while (Yapf().m_pBestIntermediateNode != nullptr && (Yapf().m_pBestIntermediateNode->m_segment->m_end_segment_reason & ESRB_CHOICE_FOLLOWS) == 0) { Yapf().m_pBestIntermediateNode = Yapf().m_pBestIntermediateNode->m_parent; } } @@ -262,20 +260,20 @@ public: /* detect the destination */ bool bDestination = Yapf().PfDetectDestination(n); if (bDestination) { - if (m_pBestDestNode == NULL || n < *m_pBestDestNode) { + if (m_pBestDestNode == nullptr || n < *m_pBestDestNode) { m_pBestDestNode = &n; } m_nodes.FoundBestNode(n); return; } - if (m_max_search_nodes > 0 && (m_pBestIntermediateNode == NULL || (m_pBestIntermediateNode->GetCostEstimate() - m_pBestIntermediateNode->GetCost()) > (n.GetCostEstimate() - n.GetCost()))) { + if (m_max_search_nodes > 0 && (m_pBestIntermediateNode == nullptr || (m_pBestIntermediateNode->GetCostEstimate() - m_pBestIntermediateNode->GetCost()) > (n.GetCostEstimate() - n.GetCost()))) { m_pBestIntermediateNode = &n; } /* check new node against open list */ Node *openNode = m_nodes.FindOpenNode(n.GetKey()); - if (openNode != NULL) { + if (openNode != nullptr) { /* another node exists with the same key in the open list * is it better than new one? */ if (n.GetCostEstimate() < openNode->GetCostEstimate()) { @@ -290,7 +288,7 @@ public: /* check new node against closed list */ Node *closedNode = m_nodes.FindClosedNode(n.GetKey()); - if (closedNode != NULL) { + if (closedNode != nullptr) { /* another node exists with the same key in the closed list * is it better than new one? */ int node_est = n.GetCostEstimate(); diff --git a/src/pathfinder/yapf/yapf_cache.h b/src/pathfinder/yapf/yapf_cache.h index 1660a21c02..a66cbc9e25 100644 --- a/src/pathfinder/yapf/yapf_cache.h +++ b/src/pathfinder/yapf/yapf_cache.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/pathfinder/yapf/yapf_common.hpp b/src/pathfinder/yapf/yapf_common.hpp index 8ff69b3f6b..c6f7e6e5fb 100644 --- a/src/pathfinder/yapf/yapf_common.hpp +++ b/src/pathfinder/yapf/yapf_common.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. @@ -46,7 +44,7 @@ public: for (TrackdirBits tdb = m_orgTrackdirs; tdb != TRACKDIR_BIT_NONE; tdb = KillFirstBit(tdb)) { Trackdir td = (Trackdir)FindFirstBit2x64(tdb); Node &n1 = Yapf().CreateNewNode(); - n1.Set(NULL, m_orgTile, td, is_choice); + n1.Set(nullptr, m_orgTile, td, is_choice); Yapf().AddStartupNode(n1); } } @@ -92,12 +90,12 @@ public: { if (m_orgTile != INVALID_TILE && m_orgTd != INVALID_TRACKDIR) { Node &n1 = Yapf().CreateNewNode(); - n1.Set(NULL, m_orgTile, m_orgTd, false); + n1.Set(nullptr, m_orgTile, m_orgTd, false); Yapf().AddStartupNode(n1); } if (m_revTile != INVALID_TILE && m_revTd != INVALID_TRACKDIR) { Node &n2 = Yapf().CreateNewNode(); - n2.Set(NULL, m_revTile, m_revTd, false); + n2.Set(nullptr, m_revTile, m_revTd, false); n2.m_cost = m_reverse_penalty; Yapf().AddStartupNode(n2); } diff --git a/src/pathfinder/yapf/yapf_costbase.hpp b/src/pathfinder/yapf/yapf_costbase.hpp index 6b55585a83..8da9257d91 100644 --- a/src/pathfinder/yapf/yapf_costbase.hpp +++ b/src/pathfinder/yapf/yapf_costbase.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/pathfinder/yapf/yapf_costcache.hpp b/src/pathfinder/yapf/yapf_costcache.hpp index f16d4054c6..c56c47b5f2 100644 --- a/src/pathfinder/yapf/yapf_costcache.hpp +++ b/src/pathfinder/yapf/yapf_costcache.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. @@ -143,7 +141,7 @@ struct CSegmentCostCacheT : public CSegmentCostCacheBase { inline Tsegment& Get(Key &key, bool *found) { Tsegment *item = m_map.Find(key); - if (item == NULL) { + if (item == nullptr) { *found = false; item = new (m_heap.Append()) Tsegment(key); m_map.Push(*item); diff --git a/src/pathfinder/yapf/yapf_costrail.hpp b/src/pathfinder/yapf/yapf_costrail.hpp index 022b9a1678..e6422dc240 100644 --- a/src/pathfinder/yapf/yapf_costrail.hpp +++ b/src/pathfinder/yapf/yapf_costrail.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. @@ -47,14 +45,6 @@ protected: this->tile_type = GetTileType(tile); this->rail_type = GetTileRailType(tile); } - - TILE(const TILE &src) - { - tile = src.tile; - td = src.td; - tile_type = src.tile_type; - rail_type = src.rail_type; - } }; protected: @@ -251,7 +241,7 @@ public: { int cost = 0; const Train *v = Yapf().GetVehicle(); - assert(v != NULL); + assert(v != nullptr); assert(v->type == VEH_TRAIN); assert(v->gcache.cached_total_length != 0); int missing_platform_length = CeilDiv(v->gcache.cached_total_length, TILE_SIZE) - platform_length; @@ -285,7 +275,7 @@ public: CPerfStart perf_cost(Yapf().m_perf_cost); /* Does the node have some parent node? */ - bool has_parent = (n.m_parent != NULL); + bool has_parent = (n.m_parent != nullptr); /* Do we already have a cached segment? */ CachedData &segment = *n.m_segment; @@ -496,7 +486,7 @@ no_entry_cost: // jump here at the beginning if the node has no parent (it is th if (!tf_local.Follow(cur.tile, cur.td)) { assert(tf_local.m_err != TrackFollower::EC_NONE); /* Can't move to the next tile (EOL?). */ - if (tf_local.m_err == TrackFollower::EC_RAIL_TYPE) { + if (tf_local.m_err == TrackFollower::EC_RAIL_ROAD_TYPE) { end_segment_reason |= ESRB_RAIL_TYPE; } else { end_segment_reason |= ESRB_DEAD_END; @@ -606,7 +596,7 @@ no_entry_cost: // jump here at the beginning if the node has no parent (it is th /* Station platform-length penalty. */ if ((end_segment_reason & ESRB_STATION) != ESRB_NONE) { const BaseStation *st = BaseStation::GetByTile(n.GetLastTile()); - assert(st != NULL); + assert(st != nullptr); uint platform_length = st->GetPlatformLength(n.GetLastTile(), ReverseDiagDir(TrackdirToExitdir(n.GetLastTrackdir()))); /* Reduce the extra cost caused by passing-station penalty (each station receives it in the segment cost). */ extra_cost -= Yapf().PfGetSettings().rail_station_penalty * platform_length; @@ -624,7 +614,7 @@ no_entry_cost: // jump here at the beginning if the node has no parent (it is th inline bool CanUseGlobalCache(Node &n) const { return !m_disable_cache - && (n.m_parent != NULL) + && (n.m_parent != nullptr) && (n.m_parent->m_num_signals_passed >= m_sig_look_ahead_costs.Size()); } diff --git a/src/pathfinder/yapf/yapf_destrail.hpp b/src/pathfinder/yapf/yapf_destrail.hpp index 1d1833fbfd..05a1235778 100644 --- a/src/pathfinder/yapf/yapf_destrail.hpp +++ b/src/pathfinder/yapf/yapf_destrail.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/pathfinder/yapf/yapf_node.hpp b/src/pathfinder/yapf/yapf_node.hpp index b3021096b3..689a8e9752 100644 --- a/src/pathfinder/yapf/yapf_node.hpp +++ b/src/pathfinder/yapf/yapf_node.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. @@ -67,14 +65,16 @@ struct CYapfNodeT { Node *m_parent; int m_cost; int m_estimate; + bool m_is_choice; inline void Set(Node *parent, TileIndex tile, Trackdir td, bool is_choice) { m_key.Set(tile, td); - m_hash_next = NULL; + m_hash_next = nullptr; m_parent = parent; m_cost = 0; m_estimate = 0; + m_is_choice = is_choice; } inline Node *GetHashNext() @@ -112,6 +112,11 @@ struct CYapfNodeT { return m_estimate; } + inline bool GetIsChoice() const + { + return m_is_choice; + } + inline bool operator<(const Node &other) const { return m_estimate < other.m_estimate; diff --git a/src/pathfinder/yapf/yapf_node_rail.hpp b/src/pathfinder/yapf/yapf_node_rail.hpp index 180c894392..fce909ac9b 100644 --- a/src/pathfinder/yapf/yapf_node_rail.hpp +++ b/src/pathfinder/yapf/yapf_node_rail.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. @@ -83,7 +81,7 @@ struct CYapfRailSegment , m_last_signal_tile(INVALID_TILE) , m_last_signal_td(INVALID_TRACKDIR) , m_end_segment_reason(ESRB_NONE) - , m_hash_next(NULL) + , m_hash_next(nullptr) {} inline const Key& GetKey() const @@ -142,8 +140,8 @@ struct CYapfRailNodeT inline void Set(CYapfRailNodeT *parent, TileIndex tile, Trackdir td, bool is_choice) { base::Set(parent, tile, td, is_choice); - m_segment = NULL; - if (parent == NULL) { + m_segment = nullptr; + if (parent == nullptr) { m_num_signals_passed = 0; flags_u.m_inherited_flags = 0; m_last_red_signal_type = SIGTYPE_NORMAL; @@ -169,19 +167,19 @@ struct CYapfRailNodeT inline TileIndex GetLastTile() const { - assert(m_segment != NULL); + assert(m_segment != nullptr); return m_segment->m_last_tile; } inline Trackdir GetLastTrackdir() const { - assert(m_segment != NULL); + assert(m_segment != nullptr); return m_segment->m_last_td; } inline void SetLastTileTrackdir(TileIndex tile, Trackdir td) { - assert(m_segment != NULL); + assert(m_segment != nullptr); m_segment->m_last_tile = tile; m_segment->m_last_td = td; } diff --git a/src/pathfinder/yapf/yapf_node_road.hpp b/src/pathfinder/yapf/yapf_node_road.hpp index 9a392f088f..cf5fda95c9 100644 --- a/src/pathfinder/yapf/yapf_node_road.hpp +++ b/src/pathfinder/yapf/yapf_node_road.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/pathfinder/yapf/yapf_node_ship.hpp b/src/pathfinder/yapf/yapf_node_ship.hpp index df4254fd98..63e21987a3 100644 --- a/src/pathfinder/yapf/yapf_node_ship.hpp +++ b/src/pathfinder/yapf/yapf_node_ship.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. @@ -14,7 +12,19 @@ /** Yapf Node for ships */ template -struct CYapfShipNodeT : CYapfNodeT > { }; +struct CYapfShipNodeT : CYapfNodeT > { + typedef CYapfNodeT > base; + + TileIndex m_segment_last_tile; + Trackdir m_segment_last_td; + + void Set(CYapfShipNodeT *parent, TileIndex tile, Trackdir td, bool is_choice) + { + base::Set(parent, tile, td, is_choice); + m_segment_last_tile = tile; + m_segment_last_td = td; + } +}; /* now define two major node types (that differ by key type) */ typedef CYapfShipNodeT CYapfShipNodeExitDir; diff --git a/src/pathfinder/yapf/yapf_rail.cpp b/src/pathfinder/yapf/yapf_rail.cpp index d3f8e8aeee..6922c0b89d 100644 --- a/src/pathfinder/yapf/yapf_rail.cpp +++ b/src/pathfinder/yapf/yapf_rail.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. @@ -28,8 +26,8 @@ template void DumpState(Tpf &pf1, Tpf &pf2) pf2.DumpBase(dmp2); FILE *f1 = fopen("yapf1.txt", "wt"); FILE *f2 = fopen("yapf2.txt", "wt"); - assert(f1 != NULL); - assert(f2 != NULL); + assert(f1 != nullptr); + assert(f2 != nullptr); fwrite(dmp1.m_out.Data(), 1, dmp1.m_out.Size(), f1); fwrite(dmp2.m_out.Data(), 1, dmp2.m_out.Size(), f2); fclose(f1); @@ -84,7 +82,7 @@ private: tile = TILE_ADD(tile, diff); } while (IsCompatibleTrainStationTile(tile, start) && tile != m_origin_tile); - TriggerStationRandomisation(NULL, start, SRT_PATH_RESERVATION); + TriggerStationRandomisation(nullptr, start, SRT_PATH_RESERVATION); return true; } @@ -138,7 +136,7 @@ public: /** Check the node for a possible reservation target. */ inline void FindSafePositionOnNode(Node *node) { - assert(node->m_parent != NULL); + assert(node->m_parent != nullptr); /* We will never pass more than two signals, no need to check for a safe tile. */ if (node->m_parent->m_num_signals_passed >= 2) return; @@ -154,7 +152,7 @@ public: m_res_fail_tile = INVALID_TILE; m_origin_tile = origin; - if (target != NULL) { + if (target != nullptr) { target->tile = m_res_dest; target->trackdir = m_res_dest_td; target->okay = false; @@ -163,7 +161,7 @@ public: /* Don't bother if the target is reserved. */ if (!IsWaitingPositionFree(Yapf().GetVehicle(), m_res_dest, m_res_dest_td)) return false; - for (Node *node = m_res_node; node->m_parent != NULL; node = node->m_parent) { + for (Node *node = m_res_node; node->m_parent != nullptr; node = node->m_parent) { node->IterateTiles(Yapf().GetVehicle(), Yapf(), *this, &CYapfReserveTrack::ReserveSingleTrack); if (m_res_fail_tile != INVALID_TILE) { /* Reservation failed, undo. */ @@ -173,13 +171,13 @@ public: /* If this is the node that failed, stop at the failed tile. */ m_res_fail_tile = fail_node == node ? stop_tile : INVALID_TILE; fail_node->IterateTiles(Yapf().GetVehicle(), Yapf(), *this, &CYapfReserveTrack::UnreserveSingleTrack); - } while (fail_node != node && (fail_node = fail_node->m_parent) != NULL); + } while (fail_node != node && (fail_node = fail_node->m_parent) != nullptr); return false; } } - if (target != NULL) target->okay = true; + if (target != nullptr) target->okay = true; if (Yapf().CanUseGlobalCache(*m_res_node)) { YapfNotifyTrackLayoutChange(INVALID_TILE, INVALID_TRACK); @@ -270,7 +268,7 @@ public: /* walk through the path back to the origin */ Node *pNode = n; - while (pNode->m_parent != NULL) { + while (pNode->m_parent != nullptr) { pNode = pNode->m_parent; } @@ -351,15 +349,15 @@ public: this->SetReservationTarget(pNode, pNode->GetLastTile(), pNode->GetLastTrackdir()); /* Walk through the path back to the origin. */ - Node *pPrev = NULL; - while (pNode->m_parent != NULL) { + Node *pPrev = nullptr; + while (pNode->m_parent != nullptr) { pPrev = pNode; pNode = pNode->m_parent; this->FindSafePositionOnNode(pPrev); } - return dont_reserve || this->TryReservePath(NULL, pNode->GetLastTile()); + return dont_reserve || this->TryReservePath(nullptr, pNode->GetLastTile()); } }; @@ -408,7 +406,7 @@ public: if (_debug_desync_level < 2) { result1 = pf1.ChooseRailTrack(v, tile, enterdir, tracks, path_found, reserve_track, target); } else { - result1 = pf1.ChooseRailTrack(v, tile, enterdir, tracks, path_found, false, NULL); + result1 = pf1.ChooseRailTrack(v, tile, enterdir, tracks, path_found, false, nullptr); Tpf pf2; pf2.DisableCache(true); Trackdir result2 = pf2.ChooseRailTrack(v, tile, enterdir, tracks, path_found, reserve_track, target); @@ -423,7 +421,7 @@ public: inline Trackdir ChooseRailTrack(const Train *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found, bool reserve_track, PBSTileInfo *target) { - if (target != NULL) target->tile = INVALID_TILE; + if (target != nullptr) target->tile = INVALID_TILE; /* set origin and destination nodes */ PBSTileInfo origin = FollowTrainReservation(v); @@ -436,14 +434,14 @@ public: /* if path not found - return INVALID_TRACKDIR */ Trackdir next_trackdir = INVALID_TRACKDIR; Node *pNode = Yapf().GetBestNode(); - if (pNode != NULL) { + if (pNode != nullptr) { /* reserve till end of path */ this->SetReservationTarget(pNode, pNode->GetLastTile(), pNode->GetLastTrackdir()); /* path was found or at least suggested * walk through the path back to the origin */ - Node *pPrev = NULL; - while (pNode->m_parent != NULL) { + Node *pPrev = nullptr; + while (pNode->m_parent != nullptr) { pPrev = pNode; pNode = pNode->m_parent; @@ -494,7 +492,7 @@ public: /* path was found * walk through the path back to the origin */ Node *pNode = Yapf().GetBestNode(); - while (pNode->m_parent != NULL) { + while (pNode->m_parent != nullptr) { pNode = pNode->m_parent; } diff --git a/src/pathfinder/yapf/yapf_road.cpp b/src/pathfinder/yapf/yapf_road.cpp index 0240eb9366..1b85c8d4ec 100644 --- a/src/pathfinder/yapf/yapf_road.cpp +++ b/src/pathfinder/yapf/yapf_road.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. @@ -118,7 +116,7 @@ public: /* start at n.m_key.m_tile / n.m_key.m_td and walk to the end of segment */ TileIndex tile = n.m_key.m_tile; Trackdir trackdir = n.m_key.m_td; - int parent_cost = (n.m_parent != NULL) ? n.m_parent->m_cost : 0; + int parent_cost = (n.m_parent != nullptr) ? n.m_parent->m_cost : 0; for (;;) { /* base tile cost depending on distance between edges */ @@ -249,10 +247,15 @@ public: } else { m_dest_station = INVALID_STATION; m_destTile = v->dest_tile; - m_destTrackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(v->dest_tile, TRANSPORT_ROAD, v->compatible_roadtypes)); + m_destTrackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(v->dest_tile, TRANSPORT_ROAD, GetRoadTramType(v->roadtype))); } } + const Station *GetDestinationStation() const + { + return m_dest_station != INVALID_STATION ? Station::GetIfValid(m_dest_station) : nullptr; + } + protected: /** to access inherited path finder */ Tpf& Yapf() @@ -348,13 +351,13 @@ public: return 'r'; } - static Trackdir stChooseRoadTrack(const RoadVehicle *v, TileIndex tile, DiagDirection enterdir, bool &path_found) + static Trackdir stChooseRoadTrack(const RoadVehicle *v, TileIndex tile, DiagDirection enterdir, bool &path_found, RoadVehPathCache &path_cache) { Tpf pf; - return pf.ChooseRoadTrack(v, tile, enterdir, path_found); + return pf.ChooseRoadTrack(v, tile, enterdir, path_found, path_cache); } - inline Trackdir ChooseRoadTrack(const RoadVehicle *v, TileIndex tile, DiagDirection enterdir, bool &path_found) + inline Trackdir ChooseRoadTrack(const RoadVehicle *v, TileIndex tile, DiagDirection enterdir, bool &path_found, RoadVehPathCache &path_cache) { /* Handle special case - when next tile is destination tile. * However, when going to a station the (initial) destination @@ -367,7 +370,7 @@ public: /* our source tile will be the next vehicle tile (should be the given one) */ TileIndex src_tile = tile; /* get available trackdirs on the start tile */ - TrackdirBits src_trackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(tile, TRANSPORT_ROAD, v->compatible_roadtypes)); + TrackdirBits src_trackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(tile, TRANSPORT_ROAD, GetRoadTramType(v->roadtype))); /* select reachable trackdirs only */ src_trackdirs &= DiagdirReachesTrackdirs(enterdir); @@ -381,16 +384,45 @@ public: /* if path not found - return INVALID_TRACKDIR */ Trackdir next_trackdir = INVALID_TRACKDIR; Node *pNode = Yapf().GetBestNode(); - if (pNode != NULL) { + if (pNode != nullptr) { + uint steps = 0; + for (Node *n = pNode; n->m_parent != nullptr; n = n->m_parent) steps++; + /* path was found or at least suggested * walk through the path back to its origin */ - while (pNode->m_parent != NULL) { + while (pNode->m_parent != nullptr) { + steps--; + if (pNode->GetIsChoice() && steps < YAPF_ROADVEH_PATH_CACHE_SEGMENTS) { + path_cache.td.push_front(pNode->GetTrackdir()); + path_cache.tile.push_front(pNode->GetTile()); + } pNode = pNode->m_parent; } /* return trackdir from the best origin node (one of start nodes) */ Node &best_next_node = *pNode; assert(best_next_node.GetTile() == tile); next_trackdir = best_next_node.GetTrackdir(); + /* remove last element for the special case when tile == dest_tile */ + if (path_found && !path_cache.empty() && tile == v->dest_tile) { + path_cache.td.pop_back(); + path_cache.tile.pop_back(); + } + + /* Check if target is a station, and cached path ends within 8 tiles of the dest tile */ + const Station *st = Yapf().GetDestinationStation(); + if (st) { + const RoadStop *stop = st->GetPrimaryRoadStop(v); + if (stop != nullptr && (IsDriveThroughStopTile(stop->xy) || stop->GetNextRoadStop(v) != nullptr)) { + /* Destination station has at least 2 usable road stops, or first is a drive-through stop, + * trim end of path cache within a number of tiles of road stop tile area */ + TileArea non_cached_area = v->IsBus() ? st->bus_station : st->truck_station; + non_cached_area.Expand(YAPF_ROADVEH_PATH_CACHE_DESTINATION_LIMIT); + while (!path_cache.empty() && non_cached_area.Contains(path_cache.tile.back())) { + path_cache.td.pop_back(); + path_cache.tile.pop_back(); + } + } + } } return next_trackdir; } @@ -421,7 +453,7 @@ public: if (!Yapf().FindPath(v)) return dist; Node *pNode = Yapf().GetBestNode(); - if (pNode != NULL) { + if (pNode != nullptr) { /* path was found * get the path cost estimate */ dist = pNode->GetCostEstimate(); @@ -436,7 +468,7 @@ public: /* set origin (tile, trackdir) */ TileIndex src_tile = v->tile; Trackdir src_td = v->GetVehicleTrackdir(); - if (!HasTrackdir(TrackStatusToTrackdirBits(GetTileTrackStatus(src_tile, TRANSPORT_ROAD, v->compatible_roadtypes)), src_td)) { + if (!HasTrackdir(TrackStatusToTrackdirBits(GetTileTrackStatus(src_tile, TRANSPORT_ROAD, this->IsTram() ? RTT_TRAM : RTT_ROAD)), src_td)) { /* sometimes the roadveh is not on the road (it resides on non-existing track) * how should we handle that situation? */ return false; @@ -497,18 +529,18 @@ struct CYapfRoadAnyDepot1 : CYapfT > {}; -Trackdir YapfRoadVehicleChooseTrack(const RoadVehicle *v, TileIndex tile, DiagDirection enterdir, TrackdirBits trackdirs, bool &path_found) +Trackdir YapfRoadVehicleChooseTrack(const RoadVehicle *v, TileIndex tile, DiagDirection enterdir, TrackdirBits trackdirs, bool &path_found, RoadVehPathCache &path_cache) { /* default is YAPF type 2 */ - typedef Trackdir (*PfnChooseRoadTrack)(const RoadVehicle*, TileIndex, DiagDirection, bool &path_found); + typedef Trackdir (*PfnChooseRoadTrack)(const RoadVehicle*, TileIndex, DiagDirection, bool &path_found, RoadVehPathCache &path_cache); PfnChooseRoadTrack pfnChooseRoadTrack = &CYapfRoad2::stChooseRoadTrack; // default: ExitDir, allow 90-deg /* check if non-default YAPF type should be used */ if (_settings_game.pf.yapf.disable_node_optimization) { - pfnChooseRoadTrack = &CYapfRoad1::stChooseRoadTrack; // Trackdir, allow 90-deg + pfnChooseRoadTrack = &CYapfRoad1::stChooseRoadTrack; // Trackdir } - Trackdir td_ret = pfnChooseRoadTrack(v, tile, enterdir, path_found); + Trackdir td_ret = pfnChooseRoadTrack(v, tile, enterdir, path_found, path_cache); return (td_ret != INVALID_TRACKDIR) ? td_ret : (Trackdir)FindFirstBit2x64(trackdirs); } @@ -516,7 +548,7 @@ FindDepotData YapfRoadVehicleFindNearestDepot(const RoadVehicle *v, int max_dist { TileIndex tile = v->tile; Trackdir trackdir = v->GetVehicleTrackdir(); - if (!HasTrackdir(TrackStatusToTrackdirBits(GetTileTrackStatus(tile, TRANSPORT_ROAD, v->compatible_roadtypes)), trackdir)) { + if (!HasTrackdir(TrackStatusToTrackdirBits(GetTileTrackStatus(tile, TRANSPORT_ROAD, GetRoadTramType(v->roadtype))), trackdir)) { return FindDepotData(); } @@ -526,7 +558,7 @@ FindDepotData YapfRoadVehicleFindNearestDepot(const RoadVehicle *v, int max_dist /* check if non-default YAPF type should be used */ if (_settings_game.pf.yapf.disable_node_optimization) { - pfnFindNearestDepot = &CYapfRoadAnyDepot1::stFindNearestDepot; // Trackdir, allow 90-deg + pfnFindNearestDepot = &CYapfRoadAnyDepot1::stFindNearestDepot; // Trackdir } return pfnFindNearestDepot(v, tile, trackdir, max_distance); diff --git a/src/pathfinder/yapf/yapf_ship.cpp b/src/pathfinder/yapf/yapf_ship.cpp index c6e484feaa..2f2ed7e441 100644 --- a/src/pathfinder/yapf/yapf_ship.cpp +++ b/src/pathfinder/yapf/yapf_ship.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. @@ -11,12 +9,96 @@ #include "../../stdafx.h" #include "../../ship.h" +#include "../../industry.h" +#include "../../vehicle_func.h" #include "yapf.hpp" #include "yapf_node_ship.hpp" #include "../../safeguards.h" +template +class CYapfDestinationTileWaterT +{ +public: + typedef typename Types::Tpf Tpf; ///< the pathfinder class (derived from THIS class) + typedef typename Types::TrackFollower TrackFollower; + typedef typename Types::NodeList::Titem Node; ///< this will be our node type + typedef typename Node::Key Key; ///< key to hash tables + +protected: + TileIndex m_destTile; + TrackdirBits m_destTrackdirs; + StationID m_destStation; + +public: + void SetDestination(const Ship *v) + { + if (v->current_order.IsType(OT_GOTO_STATION)) { + m_destStation = v->current_order.GetDestination(); + m_destTile = CalcClosestStationTile(m_destStation, v->tile, STATION_DOCK); + m_destTrackdirs = INVALID_TRACKDIR_BIT; + } else { + m_destStation = INVALID_STATION; + m_destTile = v->dest_tile; + m_destTrackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(v->dest_tile, TRANSPORT_WATER, 0)); + } + } + +protected: + /** to access inherited path finder */ + inline Tpf& Yapf() + { + return *static_cast(this); + } + +public: + /** Called by YAPF to detect if node ends in the desired destination */ + inline bool PfDetectDestination(Node& n) + { + return PfDetectDestinationTile(n.m_segment_last_tile, n.m_segment_last_td); + } + + inline bool PfDetectDestinationTile(TileIndex tile, Trackdir trackdir) + { + if (m_destStation != INVALID_STATION) { + return IsDockingTile(tile) && IsShipDestinationTile(tile, m_destStation); + } + + return tile == m_destTile && ((m_destTrackdirs & TrackdirToTrackdirBits(trackdir)) != TRACKDIR_BIT_NONE); + } + + /** + * Called by YAPF to calculate cost estimate. Calculates distance to the destination + * adds it to the actual cost from origin and stores the sum to the Node::m_estimate + */ + inline bool PfCalcEstimate(Node& n) + { + static const int dg_dir_to_x_offs[] = {-1, 0, 1, 0}; + static const int dg_dir_to_y_offs[] = {0, 1, 0, -1}; + if (PfDetectDestination(n)) { + n.m_estimate = n.m_cost; + return true; + } + + TileIndex tile = n.m_segment_last_tile; + DiagDirection exitdir = TrackdirToExitdir(n.m_segment_last_td); + int x1 = 2 * TileX(tile) + dg_dir_to_x_offs[(int)exitdir]; + int y1 = 2 * TileY(tile) + dg_dir_to_y_offs[(int)exitdir]; + int x2 = 2 * TileX(m_destTile); + int y2 = 2 * TileY(m_destTile); + int dx = abs(x1 - x2); + int dy = abs(y1 - y2); + int dmin = min(dx, dy); + int dxy = abs(dx - dy); + int d = dmin * YAPF_TILE_CORNER_LENGTH + (dxy - 1) * (YAPF_TILE_LENGTH / 2); + n.m_estimate = n.m_cost + d; + assert(n.m_estimate >= n.m_parent->m_estimate); + return true; + } +}; + + /** Node Follower module of YAPF for ships */ template class CYapfFollowShipT @@ -75,31 +157,32 @@ public: /* convert origin trackdir to TrackdirBits */ TrackdirBits trackdirs = TrackdirToTrackdirBits(trackdir); - /* get available trackdirs on the destination tile */ - TrackdirBits dest_trackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(v->dest_tile, TRANSPORT_WATER, 0)); /* create pathfinder instance */ Tpf pf; /* set origin and destination nodes */ pf.SetOrigin(src_tile, trackdirs); - pf.SetDestination(v->dest_tile, dest_trackdirs); + pf.SetDestination(v); /* find best path */ path_found = pf.FindPath(v); Trackdir next_trackdir = INVALID_TRACKDIR; // this would mean "path not found" Node *pNode = pf.GetBestNode(); - if (pNode != NULL) { + if (pNode != nullptr) { uint steps = 0; - for (Node *n = pNode; n->m_parent != NULL; n = n->m_parent) steps++; + for (Node *n = pNode; n->m_parent != nullptr; n = n->m_parent) steps++; + uint skip = 0; + if (path_found) skip = YAPF_SHIP_PATH_CACHE_LENGTH / 2; /* walk through the path back to the origin */ - Node *pPrevNode = NULL; - while (pNode->m_parent != NULL) { - if (steps > 1 && --steps < YAPF_SHIP_PATH_CACHE_LENGTH) { - TrackdirByte td; - td = pNode->GetTrackdir(); - path_cache.push_front(td); + Node *pPrevNode = nullptr; + while (pNode->m_parent != nullptr) { + steps--; + /* Skip tiles at end of path near destination. */ + if (skip > 0) skip--; + if (skip == 0 && steps > 0 && steps < YAPF_SHIP_PATH_CACHE_LENGTH) { + path_cache.push_front(pNode->GetTrackdir()); } pPrevNode = pNode; pNode = pNode->m_parent; @@ -125,23 +208,20 @@ public: */ static bool CheckShipReverse(const Ship *v, TileIndex tile, Trackdir td1, Trackdir td2) { - /* get available trackdirs on the destination tile */ - TrackdirBits dest_trackdirs = TrackStatusToTrackdirBits(GetTileTrackStatus(v->dest_tile, TRANSPORT_WATER, 0)); - /* create pathfinder instance */ Tpf pf; /* set origin and destination nodes */ pf.SetOrigin(tile, TrackdirToTrackdirBits(td1) | TrackdirToTrackdirBits(td2)); - pf.SetDestination(v->dest_tile, dest_trackdirs); + pf.SetDestination(v); /* find best path */ if (!pf.FindPath(v)) return false; Node *pNode = pf.GetBestNode(); - if (pNode == NULL) return false; + if (pNode == nullptr) return false; /* path was found * walk through the path back to the origin */ - while (pNode->m_parent != NULL) { + while (pNode->m_parent != nullptr) { pNode = pNode->m_parent; } @@ -169,6 +249,30 @@ protected: } public: + inline int CurveCost(Trackdir td1, Trackdir td2) + { + assert(IsValidTrackdir(td1)); + assert(IsValidTrackdir(td2)); + + if (HasTrackdir(TrackdirCrossesTrackdirs(td1), td2)) { + /* 90-deg curve penalty */ + return Yapf().PfGetSettings().ship_curve90_penalty; + } else if (td2 != NextTrackdir(td1)) { + /* 45-deg curve penalty */ + return Yapf().PfGetSettings().ship_curve45_penalty; + } + return 0; + } + + static Vehicle *CountShipProc(Vehicle *v, void *data) + { + uint *count = (uint *)data; + /* Ignore other vehicles (aircraft) and ships inside depot. */ + if (v->type == VEH_SHIP && (v->vehstatus & VS_HIDDEN) == 0) (*count)++; + + return nullptr; + } + /** * Called by YAPF to calculate the cost from the origin to the given node. * Calculates only the cost of given node, adds it to the parent node cost @@ -179,9 +283,13 @@ public: /* base tile cost depending on distance */ int c = IsDiagonalTrackdir(n.GetTrackdir()) ? YAPF_TILE_LENGTH : YAPF_TILE_CORNER_LENGTH; /* additional penalty for curves */ - if (n.GetTrackdir() != NextTrackdir(n.m_parent->GetTrackdir())) { - /* new trackdir does not match the next one when going straight */ - c += YAPF_TILE_LENGTH; + c += CurveCost(n.m_parent->GetTrackdir(), n.GetTrackdir()); + + if (IsDockingTile(n.GetTile())) { + /* Check docking tile for occupancy */ + uint count = 1; + HasVehicleOnPos(n.GetTile(), &count, &CountShipProc); + c += count * 3 * YAPF_TILE_LENGTH; } /* Skipped tile cost for aqueducts. */ @@ -219,30 +327,36 @@ struct CYapfShip_TypesT typedef CYapfBaseT PfBase; // base pathfinder class typedef CYapfFollowShipT PfFollow; // node follower typedef CYapfOriginTileT PfOrigin; // origin provider - typedef CYapfDestinationTileT PfDestination; // destination/distance provider + typedef CYapfDestinationTileWaterT PfDestination; // destination/distance provider typedef CYapfSegmentCostCacheNoneT PfCache; // segment cost cache provider typedef CYapfCostShipT PfCost; // cost provider }; -/* YAPF type 1 - uses TileIndex/Trackdir as Node key, allows 90-deg turns */ +/* YAPF type 1 - uses TileIndex/Trackdir as Node key */ struct CYapfShip1 : CYapfT > {}; -/* YAPF type 2 - uses TileIndex/DiagDirection as Node key, allows 90-deg turns */ +/* YAPF type 2 - uses TileIndex/DiagDirection as Node key */ struct CYapfShip2 : CYapfT > {}; -/* YAPF type 3 - uses TileIndex/Trackdir as Node key, forbids 90-deg turns */ -struct CYapfShip3 : CYapfT > {}; + +static inline bool RequireTrackdirKey() +{ + /* If the two curve penalties are not equal, then it is not possible to use the + * ExitDir keyed node list, as it there will be key overlap. Using Trackdir keyed + * nodes means potentially more paths are tested, which would be wasteful if it's + * not necessary. + */ + return _settings_game.pf.yapf.ship_curve45_penalty != _settings_game.pf.yapf.ship_curve90_penalty; +} /** Ship controller helper - path finder invoker */ Track YapfShipChooseTrack(const Ship *v, TileIndex tile, DiagDirection enterdir, TrackBits tracks, bool &path_found, ShipPathCache &path_cache) { /* default is YAPF type 2 */ typedef Trackdir (*PfnChooseShipTrack)(const Ship*, TileIndex, DiagDirection, TrackBits, bool &path_found, ShipPathCache &path_cache); - PfnChooseShipTrack pfnChooseShipTrack = CYapfShip2::ChooseShipTrack; // default: ExitDir, allow 90-deg + PfnChooseShipTrack pfnChooseShipTrack = CYapfShip2::ChooseShipTrack; // default: ExitDir /* check if non-default YAPF type needed */ - if (_settings_game.pf.forbid_90_deg) { - pfnChooseShipTrack = &CYapfShip3::ChooseShipTrack; // Trackdir, forbid 90-deg - } else if (_settings_game.pf.yapf.disable_node_optimization) { - pfnChooseShipTrack = &CYapfShip1::ChooseShipTrack; // Trackdir, allow 90-deg + if (_settings_game.pf.yapf.disable_node_optimization || RequireTrackdirKey()) { + pfnChooseShipTrack = &CYapfShip1::ChooseShipTrack; // Trackdir } Trackdir td_ret = pfnChooseShipTrack(v, tile, enterdir, tracks, path_found, path_cache); @@ -256,13 +370,11 @@ bool YapfShipCheckReverse(const Ship *v) TileIndex tile = v->tile; typedef bool (*PfnCheckReverseShip)(const Ship*, TileIndex, Trackdir, Trackdir); - PfnCheckReverseShip pfnCheckReverseShip = CYapfShip2::CheckShipReverse; // default: ExitDir, allow 90-deg + PfnCheckReverseShip pfnCheckReverseShip = CYapfShip2::CheckShipReverse; // default: ExitDir /* check if non-default YAPF type needed */ - if (_settings_game.pf.forbid_90_deg) { - pfnCheckReverseShip = &CYapfShip3::CheckShipReverse; // Trackdir, forbid 90-deg - } else if (_settings_game.pf.yapf.disable_node_optimization) { - pfnCheckReverseShip = &CYapfShip1::CheckShipReverse; // Trackdir, allow 90-deg + if (_settings_game.pf.yapf.disable_node_optimization || RequireTrackdirKey()) { + pfnCheckReverseShip = &CYapfShip1::CheckShipReverse; // Trackdir } bool reverse = pfnCheckReverseShip(v, tile, td, td_rev); diff --git a/src/pathfinder/yapf/yapf_type.hpp b/src/pathfinder/yapf/yapf_type.hpp index 8d24eee5e2..ff63c1304a 100644 --- a/src/pathfinder/yapf/yapf_type.hpp +++ b/src/pathfinder/yapf/yapf_type.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/pbs.cpp b/src/pbs.cpp index 6bb35a6964..c4dfcbce54 100644 --- a/src/pbs.cpp +++ b/src/pbs.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. @@ -116,7 +114,7 @@ bool TryReserveRailTrack(TileIndex tile, Track t, bool trigger_stations) case MP_STATION: if (HasStationRail(tile) && !HasStationReservation(tile)) { SetRailStationReservation(tile, true); - if (trigger_stations && IsRailStation(tile)) TriggerStationRandomisation(NULL, tile, SRT_PATH_RESERVATION); + if (trigger_stations && IsRailStation(tile)) TriggerStationRandomisation(nullptr, tile, SRT_PATH_RESERVATION); MarkTileDirtyByTile(tile); // some GRFs need redraw after reserving track return true; } @@ -258,8 +256,8 @@ struct FindTrainOnTrackInfo { PBSTileInfo res; ///< Information about the track. Train *best; ///< The currently "best" vehicle we have found. - /** Init the best location to NULL always! */ - FindTrainOnTrackInfo() : best(NULL) {} + /** Init the best location to nullptr always! */ + FindTrainOnTrackInfo() : best(nullptr) {} }; /** Callback for Has/FindVehicleOnPos to find a train on a specific track. */ @@ -267,18 +265,18 @@ static Vehicle *FindTrainOnTrackEnum(Vehicle *v, void *data) { FindTrainOnTrackInfo *info = (FindTrainOnTrackInfo *)data; - if (v->type != VEH_TRAIN || (v->vehstatus & VS_CRASHED)) return NULL; + if (v->type != VEH_TRAIN || (v->vehstatus & VS_CRASHED)) return nullptr; Train *t = Train::From(v); if (t->track == TRACK_BIT_WORMHOLE || HasBit((TrackBits)t->track, TrackdirToTrack(info->res.trackdir))) { t = t->First(); /* ALWAYS return the lowest ID (anti-desync!) */ - if (info->best == NULL || t->index < info->best->index) info->best = t; + if (info->best == nullptr || t->index < info->best->index) info->best = t; return t; } - return NULL; + return nullptr; } /** @@ -300,24 +298,24 @@ PBSTileInfo FollowTrainReservation(const Train *v, Vehicle **train_on_res) FindTrainOnTrackInfo ftoti; ftoti.res = FollowReservation(v->owner, GetRailTypeInfo(v->railtype)->compatible_railtypes, tile, trackdir); ftoti.res.okay = IsSafeWaitingPosition(v, ftoti.res.tile, ftoti.res.trackdir, true, _settings_game.pf.forbid_90_deg); - if (train_on_res != NULL) { + if (train_on_res != nullptr) { FindVehicleOnPos(ftoti.res.tile, &ftoti, FindTrainOnTrackEnum); - if (ftoti.best != NULL) *train_on_res = ftoti.best->First(); - if (*train_on_res == NULL && IsRailStationTile(ftoti.res.tile)) { + if (ftoti.best != nullptr) *train_on_res = ftoti.best->First(); + if (*train_on_res == nullptr && IsRailStationTile(ftoti.res.tile)) { /* The target tile is a rail station. The track follower * has stopped on the last platform tile where we haven't * found a train. Also check all previous platform tiles * for a possible train. */ TileIndexDiff diff = TileOffsByDiagDir(TrackdirToExitdir(ReverseTrackdir(ftoti.res.trackdir))); - for (TileIndex st_tile = ftoti.res.tile + diff; *train_on_res == NULL && IsCompatibleTrainStationTile(st_tile, ftoti.res.tile); st_tile += diff) { + for (TileIndex st_tile = ftoti.res.tile + diff; *train_on_res == nullptr && IsCompatibleTrainStationTile(st_tile, ftoti.res.tile); st_tile += diff) { FindVehicleOnPos(st_tile, &ftoti, FindTrainOnTrackEnum); - if (ftoti.best != NULL) *train_on_res = ftoti.best->First(); + if (ftoti.best != nullptr) *train_on_res = ftoti.best->First(); } } - if (*train_on_res == NULL && IsTileType(ftoti.res.tile, MP_TUNNELBRIDGE)) { + if (*train_on_res == nullptr && IsTileType(ftoti.res.tile, MP_TUNNELBRIDGE)) { /* The target tile is a bridge/tunnel, also check the other end tile. */ FindVehicleOnPos(GetOtherTunnelBridgeEnd(ftoti.res.tile), &ftoti, FindTrainOnTrackEnum); - if (ftoti.best != NULL) *train_on_res = ftoti.best->First(); + if (ftoti.best != nullptr) *train_on_res = ftoti.best->First(); } } return ftoti.res; @@ -328,7 +326,7 @@ PBSTileInfo FollowTrainReservation(const Train *v, Vehicle **train_on_res) * * @param tile A tile on the path. * @param track A reserved track on the tile. - * @return The vehicle holding the reservation or NULL if the path is stray. + * @return The vehicle holding the reservation or nullptr if the path is stray. */ Train *GetTrainForReservation(TileIndex tile, Track track) { @@ -349,25 +347,25 @@ Train *GetTrainForReservation(TileIndex tile, Track track) ftoti.res = FollowReservation(GetTileOwner(tile), rts, tile, trackdir, true); FindVehicleOnPos(ftoti.res.tile, &ftoti, FindTrainOnTrackEnum); - if (ftoti.best != NULL) return ftoti.best; + if (ftoti.best != nullptr) return ftoti.best; /* Special case for stations: check the whole platform for a vehicle. */ if (IsRailStationTile(ftoti.res.tile)) { TileIndexDiff diff = TileOffsByDiagDir(TrackdirToExitdir(ReverseTrackdir(ftoti.res.trackdir))); for (TileIndex st_tile = ftoti.res.tile + diff; IsCompatibleTrainStationTile(st_tile, ftoti.res.tile); st_tile += diff) { FindVehicleOnPos(st_tile, &ftoti, FindTrainOnTrackEnum); - if (ftoti.best != NULL) return ftoti.best; + if (ftoti.best != nullptr) return ftoti.best; } } /* Special case for bridges/tunnels: check the other end as well. */ if (IsTileType(ftoti.res.tile, MP_TUNNELBRIDGE)) { FindVehicleOnPos(GetOtherTunnelBridgeEnd(ftoti.res.tile), &ftoti, FindTrainOnTrackEnum); - if (ftoti.best != NULL) return ftoti.best; + if (ftoti.best != nullptr) return ftoti.best; } } - return NULL; + return nullptr; } /** @@ -400,7 +398,7 @@ bool IsSafeWaitingPosition(const Train *v, TileIndex tile, Trackdir trackdir, bo /* Check for reachable tracks. */ ft.m_new_td_bits &= DiagdirReachesTrackdirs(ft.m_exitdir); - if (forbid_90deg) ft.m_new_td_bits &= ~TrackdirCrossesTrackdirs(trackdir); + if (Rail90DegTurnDisallowed(GetTileRailType(ft.m_old_tile), GetTileRailType(ft.m_new_tile), forbid_90deg)) ft.m_new_td_bits &= ~TrackdirCrossesTrackdirs(trackdir); if (ft.m_new_td_bits == TRACKDIR_BIT_NONE) return include_line_end; if (ft.m_new_td_bits != TRACKDIR_BIT_NONE && KillFirstBit(ft.m_new_td_bits) == TRACKDIR_BIT_NONE) { @@ -445,7 +443,7 @@ bool IsWaitingPositionFree(const Train *v, TileIndex tile, Trackdir trackdir, bo /* Check for reachable tracks. */ ft.m_new_td_bits &= DiagdirReachesTrackdirs(ft.m_exitdir); - if (forbid_90deg) ft.m_new_td_bits &= ~TrackdirCrossesTrackdirs(trackdir); + if (Rail90DegTurnDisallowed(GetTileRailType(ft.m_old_tile), GetTileRailType(ft.m_new_tile), forbid_90deg)) ft.m_new_td_bits &= ~TrackdirCrossesTrackdirs(trackdir); return !HasReservedTracks(ft.m_new_tile, TrackdirBitsToTrackBits(ft.m_new_td_bits)); } diff --git a/src/pbs.h b/src/pbs.h index a02d4d06e1..a7af4e373e 100644 --- a/src/pbs.h +++ b/src/pbs.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. @@ -44,7 +42,7 @@ struct PBSTileInfo { PBSTileInfo(TileIndex _t, Trackdir _td, bool _okay) : tile(_t), trackdir(_td), okay(_okay) {} }; -PBSTileInfo FollowTrainReservation(const Train *v, Vehicle **train_on_res = NULL); +PBSTileInfo FollowTrainReservation(const Train *v, Vehicle **train_on_res = nullptr); bool IsSafeWaitingPosition(const Train *v, TileIndex tile, Trackdir trackdir, bool include_line_end, bool forbid_90deg = false); bool IsWaitingPositionFree(const Train *v, TileIndex tile, Trackdir trackdir, bool forbid_90deg = false); diff --git a/src/progress.cpp b/src/progress.cpp index b498be109b..e45e5db078 100644 --- a/src/progress.cpp +++ b/src/progress.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. @@ -10,17 +8,19 @@ /** @file progress.cpp Functions for modal progress windows. */ #include "stdafx.h" -#include "thread/thread.h" +#include "progress.h" #include "safeguards.h" /** Are we in a modal progress or not? */ bool _in_modal_progress = false; bool _first_in_modal_loop = false; +/** Threading usable for modal progress? */ +bool _use_threaded_modal_progress = true; /** Rights for the performing work. */ -ThreadMutex *_modal_progress_work_mutex = ThreadMutex::New(); +std::mutex _modal_progress_work_mutex; /** Rights for the painting. */ -ThreadMutex *_modal_progress_paint_mutex = ThreadMutex::New(); +std::mutex _modal_progress_paint_mutex; /** * Set the modal progress state. diff --git a/src/progress.h b/src/progress.h index eec369b23c..59a61c678e 100644 --- a/src/progress.h +++ b/src/progress.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. @@ -12,7 +10,7 @@ #ifndef PROGRESS_H #define PROGRESS_H -#include "thread/thread.h" +#include static const uint MODAL_PROGRESS_REDRAW_TIMEOUT = 200; ///< Timeout between redraws @@ -26,10 +24,20 @@ static inline bool HasModalProgress() return _in_modal_progress; } +/** + * Check if we can use a thread for modal progress. + * @return Threading usable? + */ +static inline bool UseThreadedModelProgress() +{ + extern bool _use_threaded_modal_progress; + return _use_threaded_modal_progress; +} + bool IsFirstModalProgressLoop(); void SetModalProgress(bool state); -extern class ThreadMutex *_modal_progress_work_mutex; -extern class ThreadMutex *_modal_progress_paint_mutex; +extern std::mutex _modal_progress_work_mutex; +extern std::mutex _modal_progress_paint_mutex; #endif /* PROGRESS_H */ diff --git a/src/querystring_gui.h b/src/querystring_gui.h index a1f3896dd1..1556334c3d 100644 --- a/src/querystring_gui.h +++ b/src/querystring_gui.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. @@ -37,7 +35,7 @@ struct QueryString { * @param size Maximum size in bytes. * @param chars Maximum size in chars. */ - QueryString(uint16 size, uint16 chars = UINT16_MAX) : ok_button(ACTION_NOTHING), cancel_button(ACTION_DESELECT), text(size, chars), orig(NULL) + QueryString(uint16 size, uint16 chars = UINT16_MAX) : ok_button(ACTION_NOTHING), cancel_button(ACTION_DESELECT), text(size, chars), orig(nullptr) { } @@ -79,11 +77,11 @@ public: /** * Get the currently marked text. * @param[out] length Length of the marked text. - * @return Begining of the marked area or NULL if no text is marked. + * @return Beginning of the marked area or nullptr if no text is marked. */ const char *GetMarkedText(size_t *length) const { - if (this->text.markend == 0) return NULL; + if (this->text.markend == 0) return nullptr; *length = this->text.markend - this->text.markpos; return this->text.buf + this->text.markpos; diff --git a/src/rail.cpp b/src/rail.cpp index 8bd7aa5181..63afa379e0 100644 --- a/src/rail.cpp +++ b/src/rail.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. @@ -210,21 +208,6 @@ bool ValParamRailtype(const RailType rail) return rail < RAILTYPE_END && HasRailtypeAvail(_current_company, rail); } -/** - * Returns the "best" railtype a company can build. - * As the AI doesn't know what the BEST one is, we have our own priority list - * here. When adding new railtypes, modify this function - * @param company the company "in action" - * @return The "best" railtype a company has available - */ -RailType GetBestRailtype(const CompanyID company) -{ - if (HasRailtypeAvail(company, RAILTYPE_MAGLEV)) return RAILTYPE_MAGLEV; - if (HasRailtypeAvail(company, RAILTYPE_MONO)) return RAILTYPE_MONO; - if (HasRailtypeAvail(company, RAILTYPE_ELECTRIC)) return RAILTYPE_ELECTRIC; - return RAILTYPE_RAIL; -} - /** * Add the rail types that are to be introduced at the given date. * @param current The currently available railtypes. @@ -262,14 +245,14 @@ RailTypes AddDateIntroducedRailTypes(RailTypes current, Date date) /** * Get the rail types the given company can build. * @param company the company to get the rail types for. + * @param introduces If true, include rail types introduced by other rail types * @return the rail types. */ -RailTypes GetCompanyRailtypes(CompanyID company) +RailTypes GetCompanyRailtypes(CompanyID company, bool introduces) { RailTypes rts = RAILTYPES_NONE; - Engine *e; - FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) { + for (const Engine *e : Engine::IterateType(VEH_TRAIN)) { const EngineInfo *ei = &e->info; if (HasBit(ei->climates, _settings_game.game_creation.landscape) && @@ -278,12 +261,45 @@ RailTypes GetCompanyRailtypes(CompanyID company) if (rvi->railveh_type != RAILVEH_WAGON) { assert(rvi->railtype < RAILTYPE_END); - rts |= GetRailTypeInfo(rvi->railtype)->introduces_railtypes; + if (introduces) { + rts |= GetRailTypeInfo(rvi->railtype)->introduces_railtypes; + } else { + SetBit(rts, rvi->railtype); + } } } } - return AddDateIntroducedRailTypes(rts, _date); + if (introduces) return AddDateIntroducedRailTypes(rts, _date); + return rts; +} + +/** + * Get list of rail types, regardless of company availability. + * @param introduces If true, include rail types introduced by other rail types + * @return the rail types. + */ +RailTypes GetRailTypes(bool introduces) +{ + RailTypes rts = RAILTYPES_NONE; + + for (const Engine *e : Engine::IterateType(VEH_TRAIN)) { + const EngineInfo *ei = &e->info; + if (!HasBit(ei->climates, _settings_game.game_creation.landscape)) continue; + + const RailVehicleInfo *rvi = &e->u.rail; + if (rvi->railveh_type != RAILVEH_WAGON) { + assert(rvi->railtype < RAILTYPE_END); + if (introduces) { + rts |= GetRailTypeInfo(rvi->railtype)->introduces_railtypes; + } else { + SetBit(rts, rvi->railtype); + } + } + } + + if (introduces) return AddDateIntroducedRailTypes(rts, MAX_DAY); + return rts; } /** @@ -304,7 +320,7 @@ RailType GetRailTypeByLabel(RailTypeLabel label, bool allow_alternate_labels) /* Test if any rail type defines the label as an alternate. */ for (RailType r = RAILTYPE_BEGIN; r != RAILTYPE_END; r++) { const RailtypeInfo *rti = GetRailTypeInfo(r); - if (rti->alternate_labels.Contains(label)) return r; + if (std::find(rti->alternate_labels.begin(), rti->alternate_labels.end(), label) != rti->alternate_labels.end()) return r; } } diff --git a/src/rail.h b/src/rail.h index 83d1d9b7af..d9121d545a 100644 --- a/src/rail.h +++ b/src/rail.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. @@ -21,17 +19,24 @@ #include "strings_type.h" #include "date_type.h" #include "signal_type.h" +#include "settings_type.h" /** Railtype flags. */ enum RailTypeFlags { RTF_CATENARY = 0, ///< Bit number for drawing a catenary. RTF_NO_LEVEL_CROSSING = 1, ///< Bit number for disallowing level crossings. RTF_HIDDEN = 2, ///< Bit number for hiding from selection. + RTF_NO_SPRITE_COMBINE = 3, ///< Bit number for using non-combined junctions. + RTF_ALLOW_90DEG = 4, ///< Bit number for always allowed 90 degree turns, regardless of setting. + RTF_DISALLOW_90DEG = 5, ///< Bit number for never allowed 90 degree turns, regardless of setting. RTFB_NONE = 0, ///< All flags cleared. RTFB_CATENARY = 1 << RTF_CATENARY, ///< Value for drawing a catenary. RTFB_NO_LEVEL_CROSSING = 1 << RTF_NO_LEVEL_CROSSING, ///< Value for disallowing level crossings. RTFB_HIDDEN = 1 << RTF_HIDDEN, ///< Value for hiding from selection. + RTFB_NO_SPRITE_COMBINE = 1 << RTF_NO_SPRITE_COMBINE, ///< Value for using non-combined junctions. + RTFB_ALLOW_90DEG = 1 << RTF_ALLOW_90DEG, ///< Value for always allowed 90 degree turns, regardless of setting. + RTFB_DISALLOW_90DEG = 1 << RTF_DISALLOW_90DEG, ///< Value for never allowed 90 degree turns, regardless of setting. }; DECLARE_ENUM_AS_BIT_SET(RailTypeFlags) @@ -51,6 +56,7 @@ enum RailTypeSpriteGroup { RTSG_FENCES, ///< Fence images RTSG_TUNNEL_PORTAL, ///< Tunnel portal overlay RTSG_SIGNALS, ///< Signal images + RTSG_GROUND_COMPLETE, ///< Complete ground images RTSG_END, }; @@ -110,7 +116,7 @@ enum RailFenceOffset { }; /** List of rail type labels. */ -typedef SmallVector RailTypeLabelList; +typedef std::vector RailTypeLabelList; /** * This struct contains all the info that is needed to draw and construct tracks. @@ -262,7 +268,7 @@ public: byte sorting_order; /** - * NewGRF providing the Action3 for the railtype. NULL if not available. + * NewGRF providing the Action3 for the railtype. nullptr if not available. */ const GRFFile *grffile[RTSG_END]; @@ -273,7 +279,7 @@ public: inline bool UsesOverlay() const { - return this->group[RTSG_GROUND] != NULL; + return this->group[RTSG_GROUND] != nullptr; } /** @@ -338,6 +344,26 @@ static inline bool RailNoLevelCrossings(RailType rt) return HasBit(GetRailTypeInfo(rt)->flags, RTF_NO_LEVEL_CROSSING); } +/** + * Test if 90 degree turns are disallowed between two railtypes. + * @param rt1 First railtype to test for. + * @param rt2 Second railtype to test for. + * @param def Default value to use if the rail type doesn't specify anything. + * @return True if 90 degree turns are disallowed between the two rail types. + */ +static inline bool Rail90DegTurnDisallowed(RailType rt1, RailType rt2, bool def = _settings_game.pf.forbid_90_deg) +{ + if (rt1 == INVALID_RAILTYPE || rt2 == INVALID_RAILTYPE) return def; + + const RailtypeInfo *rti1 = GetRailTypeInfo(rt1); + const RailtypeInfo *rti2 = GetRailTypeInfo(rt2); + + bool rt1_90deg = HasBit(rti1->flags, RTF_DISALLOW_90DEG) || (!HasBit(rti1->flags, RTF_ALLOW_90DEG) && def); + bool rt2_90deg = HasBit(rti2->flags, RTF_DISALLOW_90DEG) || (!HasBit(rti2->flags, RTF_ALLOW_90DEG) && def); + + return rt1_90deg || rt2_90deg; +} + /** * Returns the cost of building the specified railtype. * @param railtype The railtype being built. @@ -426,8 +452,8 @@ bool ValParamRailtype(const RailType rail); RailTypes AddDateIntroducedRailTypes(RailTypes current, Date date); -RailType GetBestRailtype(const CompanyID company); -RailTypes GetCompanyRailtypes(const CompanyID c); +RailTypes GetCompanyRailtypes(CompanyID company, bool introduces = true); +RailTypes GetRailTypes(bool introduces); RailType GetRailTypeByLabel(RailTypeLabel label, bool allow_alternate_labels = true); @@ -435,14 +461,13 @@ void ResetRailTypes(); void InitRailTypes(); RailType AllocateRailType(RailTypeLabel label); -extern RailType _sorted_railtypes[RAILTYPE_END]; -extern uint8 _sorted_railtypes_size; +extern std::vector _sorted_railtypes; extern RailTypes _railtypes_hidden_mask; /** * Loop header for iterating over railtypes, sorted by sortorder. * @param var Railtype. */ -#define FOR_ALL_SORTED_RAILTYPES(var) for (uint8 index = 0; index < _sorted_railtypes_size && (var = _sorted_railtypes[index], true) ; index++) +#define FOR_ALL_SORTED_RAILTYPES(var) for (uint8 index = 0; index < _sorted_railtypes.size() && (var = _sorted_railtypes[index], true) ; index++) #endif /* RAIL_H */ diff --git a/src/rail_cmd.cpp b/src/rail_cmd.cpp index 3230d9bf22..7de00327eb 100644 --- a/src/rail_cmd.cpp +++ b/src/rail_cmd.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. @@ -41,11 +39,10 @@ #include "safeguards.h" /** Helper type for lists/vectors of trains */ -typedef SmallVector TrainList; +typedef std::vector TrainList; RailtypeInfo _railtypes[RAILTYPE_END]; -RailType _sorted_railtypes[RAILTYPE_END]; -uint8 _sorted_railtypes_size; +std::vector _sorted_railtypes; RailTypes _railtypes_hidden_mask; /** Enum holding the signal offset in the sprite sheet according to the side it is representing. */ @@ -130,9 +127,9 @@ void ResolveRailTypeGUISprites(RailtypeInfo *rti) * @param second The railtype to compare. * @return True iff the first should be sorted before the second. */ -static int CDECL CompareRailTypes(const RailType *first, const RailType *second) +static bool CompareRailTypes(const RailType &first, const RailType &second) { - return GetRailTypeInfo(*first)->sorting_order - GetRailTypeInfo(*second)->sorting_order; + return GetRailTypeInfo(first)->sorting_order < GetRailTypeInfo(second)->sorting_order; } /** @@ -146,13 +143,13 @@ void InitRailTypes() if (HasBit(rti->flags, RTF_HIDDEN)) SetBit(_railtypes_hidden_mask, rt); } - _sorted_railtypes_size = 0; + _sorted_railtypes.clear(); for (RailType rt = RAILTYPE_BEGIN; rt != RAILTYPE_END; rt++) { if (_railtypes[rt].label != 0 && !HasBit(_railtypes_hidden_mask, rt)) { - _sorted_railtypes[_sorted_railtypes_size++] = rt; + _sorted_railtypes.push_back(rt); } } - QSortT(_sorted_railtypes, _sorted_railtypes_size, CompareRailTypes); + std::sort(_sorted_railtypes.begin(), _sorted_railtypes.end(), CompareRailTypes); } /** @@ -167,7 +164,7 @@ RailType AllocateRailType(RailTypeLabel label) /* Set up new rail type */ *rti = _original_railtypes[RAILTYPE_RAIL]; rti->label = label; - rti->alternate_labels.Clear(); + rti->alternate_labels.clear(); /* Make us compatible with ourself. */ rti->powered_railtypes = (RailTypes)(1LL << rt); @@ -513,41 +510,48 @@ CommandCost CmdBuildSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, u if (GetDisallowedRoadDirections(tile) != DRD_NONE) return_cmd_error(STR_ERROR_CROSSING_ON_ONEWAY_ROAD); - if (RailNoLevelCrossings(railtype)) return_cmd_error(STR_ERROR_CROSSING_DISALLOWED); + if (RailNoLevelCrossings(railtype)) return_cmd_error(STR_ERROR_CROSSING_DISALLOWED_RAIL); - RoadTypes roadtypes = GetRoadTypes(tile); - RoadBits road = GetRoadBits(tile, ROADTYPE_ROAD); - RoadBits tram = GetRoadBits(tile, ROADTYPE_TRAM); + RoadType roadtype_road = GetRoadTypeRoad(tile); + RoadType roadtype_tram = GetRoadTypeTram(tile); + + if (roadtype_road != INVALID_ROADTYPE && RoadNoLevelCrossing(roadtype_road)) return_cmd_error(STR_ERROR_CROSSING_DISALLOWED_ROAD); + if (roadtype_tram != INVALID_ROADTYPE && RoadNoLevelCrossing(roadtype_tram)) return_cmd_error(STR_ERROR_CROSSING_DISALLOWED_ROAD); + + RoadBits road = GetRoadBits(tile, RTT_ROAD); + RoadBits tram = GetRoadBits(tile, RTT_TRAM); if ((track == TRACK_X && ((road | tram) & ROAD_X) == 0) || (track == TRACK_Y && ((road | tram) & ROAD_Y) == 0)) { - Owner road_owner = GetRoadOwner(tile, ROADTYPE_ROAD); - Owner tram_owner = GetRoadOwner(tile, ROADTYPE_TRAM); + Owner road_owner = GetRoadOwner(tile, RTT_ROAD); + Owner tram_owner = GetRoadOwner(tile, RTT_TRAM); /* 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); if (ret.Failed()) return ret; } - /* Crossings must always have a road... */ - uint num_new_road_pieces = 2 - CountBits(road); - if (road == ROAD_NONE) road_owner = _current_company; - roadtypes |= ROADTYPES_ROAD; - /* ...but tram is not required. */ - uint num_new_tram_pieces = (tram != ROAD_NONE) ? 2 - CountBits(tram) : 0; - cost.AddCost((num_new_road_pieces + num_new_tram_pieces) * _price[PR_BUILD_ROAD]); + uint num_new_road_pieces = (road != ROAD_NONE) ? 2 - CountBits(road) : 0; + if (num_new_road_pieces > 0) { + cost.AddCost(num_new_road_pieces * RoadBuildCost(roadtype_road)); + } + + uint num_new_tram_pieces = (tram != ROAD_NONE) ? 2 - CountBits(tram) : 0; + if (num_new_tram_pieces > 0) { + cost.AddCost(num_new_tram_pieces * RoadBuildCost(roadtype_tram)); + } if (flags & DC_EXEC) { - MakeRoadCrossing(tile, road_owner, tram_owner, _current_company, (track == TRACK_X ? AXIS_Y : AXIS_X), railtype, roadtypes, GetTownIndex(tile)); + 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); Company::Get(_current_company)->infrastructure.rail[railtype] += LEVELCROSSING_TRACKBIT_FACTOR; DirtyCompanyInfrastructureWindows(_current_company); if (num_new_road_pieces > 0 && Company::IsValidID(road_owner)) { - Company::Get(road_owner)->infrastructure.road[ROADTYPE_ROAD] += num_new_road_pieces; + Company::Get(road_owner)->infrastructure.road[roadtype_road] += num_new_road_pieces; DirtyCompanyInfrastructureWindows(road_owner); } if (num_new_tram_pieces > 0 && Company::IsValidID(tram_owner)) { - Company::Get(tram_owner)->infrastructure.road[ROADTYPE_TRAM] += num_new_tram_pieces; + Company::Get(tram_owner)->infrastructure.road[roadtype_tram] += num_new_tram_pieces; DirtyCompanyInfrastructureWindows(tram_owner); } } @@ -564,6 +568,7 @@ CommandCost CmdBuildSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, u default: { /* Will there be flat water on the lower halftile? */ bool water_ground = IsTileType(tile, MP_WATER) && IsSlopeWithOneCornerRaised(tileh); + bool docking = IsPossibleDockingTile(tile) && IsDockingTile(tile); CommandCost ret = CheckRailSlope(tileh, trackbit, TRACK_BIT_NONE, tile); if (ret.Failed()) return ret; @@ -580,7 +585,10 @@ CommandCost CmdBuildSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, u if (flags & DC_EXEC) { MakeRailNormal(tile, _current_company, trackbit, railtype); - if (water_ground) SetRailGroundType(tile, RAIL_GROUND_WATER); + if (water_ground) { + SetRailGroundType(tile, RAIL_GROUND_WATER); + SetDockingTile(tile, docking); + } Company::Get(_current_company)->infrastructure.rail[railtype]++; DirtyCompanyInfrastructureWindows(_current_company); } @@ -622,7 +630,7 @@ CommandCost CmdRemoveSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, * so do not call GetTileOwner(tile) in any case here */ Owner owner = INVALID_OWNER; - Train *v = NULL; + Train *v = nullptr; switch (GetTileType(tile)) { case MP_ROAD: { @@ -643,12 +651,13 @@ CommandCost CmdRemoveSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, if (flags & DC_EXEC) { if (HasReservedTracks(tile, trackbit)) { v = GetTrainForReservation(tile, track); - if (v != NULL) FreeTrainTrackReservation(v); + if (v != nullptr) FreeTrainTrackReservation(v); } + owner = GetTileOwner(tile); Company::Get(owner)->infrastructure.rail[GetRailType(tile)] -= LEVELCROSSING_TRACKBIT_FACTOR; DirtyCompanyInfrastructureWindows(owner); - MakeRoadNormal(tile, GetCrossingRoadBits(tile), GetRoadTypes(tile), GetTownIndex(tile), GetRoadOwner(tile, ROADTYPE_ROAD), GetRoadOwner(tile, ROADTYPE_TRAM)); + MakeRoadNormal(tile, GetCrossingRoadBits(tile), GetRoadTypeRoad(tile), GetRoadTypeTram(tile), GetTownIndex(tile), GetRoadOwner(tile, RTT_ROAD), GetRoadOwner(tile, RTT_TRAM)); DeleteNewGRFInspectWindow(GSF_RAILTYPES, tile); } break; @@ -681,7 +690,7 @@ CommandCost CmdRemoveSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, if (flags & DC_EXEC) { if (HasReservedTracks(tile, trackbit)) { v = GetTrainForReservation(tile, track); - if (v != NULL) FreeTrainTrackReservation(v); + if (v != nullptr) FreeTrainTrackReservation(v); } owner = GetTileOwner(tile); @@ -701,7 +710,9 @@ CommandCost CmdRemoveSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, Slope tileh = GetTileSlope(tile); /* If there is flat water on the lower halftile, convert the tile to shore so the water remains */ if (GetRailGroundType(tile) == RAIL_GROUND_WATER && IsSlopeWithOneCornerRaised(tileh)) { + bool docking = IsDockingTile(tile); MakeShore(tile); + SetDockingTile(tile, docking); } else { DoClearSquare(tile); } @@ -736,7 +747,7 @@ CommandCost CmdRemoveSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, YapfNotifyTrackLayoutChange(tile, track); } - if (v != NULL) TryPathReserve(v, true); + if (v != nullptr) TryPathReserve(v, true); } return cost; @@ -765,7 +776,7 @@ bool FloodHalftile(TileIndex t) TrackBits to_remove = lower_track & rail_bits; if (to_remove != 0) { - Backup cur_company(_current_company, OWNER_WATER, FILE_LINE); + Backup cur_company(_current_company, OWNER_WATER, FILE_LINE); flooded = DoCommand(t, 0, FIND_FIRST_BIT(to_remove), DC_EXEC, CMD_REMOVE_SINGLE_RAIL).Succeeded(); cur_company.Restore(); if (!flooded) return flooded; // not yet floodable @@ -1095,13 +1106,13 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1, } if (flags & DC_EXEC) { - Train *v = NULL; + Train *v = nullptr; /* The new/changed signal could block our path. As this can lead to * stale reservations, we clear the path reservation here and try * to redo it later on. */ if (HasReservedTracks(tile, TrackToTrackBits(track))) { v = GetTrainForReservation(tile, track); - if (v != NULL) FreeTrainTrackReservation(v); + if (v != nullptr) FreeTrainTrackReservation(v); } if (!HasSignals(tile)) { @@ -1177,7 +1188,7 @@ CommandCost CmdBuildSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1, MarkTileDirtyByTile(tile); AddTrackToSignalBuffer(tile, track, _current_company); YapfNotifyTrackLayoutChange(tile, track); - if (v != NULL) { + if (v != nullptr) { /* Extend the train's path if it's not stopped or loading, or not at a safe position. */ if (!(((v->vehstatus & VS_STOPPED) && v->cur_speed == 0) || v->current_order.IsType(OT_LOADING)) || !IsSafeWaitingPosition(v, v->tile, v->GetVehicleTrackdir(), true, _settings_game.pf.forbid_90_deg)) { @@ -1467,13 +1478,13 @@ CommandCost CmdRemoveSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1 /* Do it? */ if (flags & DC_EXEC) { - Train *v = NULL; + Train *v = nullptr; if (HasReservedTracks(tile, TrackToTrackBits(track))) { v = GetTrainForReservation(tile, track); } else if (IsPbsSignal(GetSignalType(tile, track))) { /* PBS signal, might be the end of a path reservation. */ Trackdir td = TrackToTrackdir(track); - for (int i = 0; v == NULL && i < 2; i++, td = ReverseTrackdir(td)) { + for (int i = 0; v == nullptr && i < 2; i++, td = ReverseTrackdir(td)) { /* Only test the active signal side. */ if (!HasSignalOnTrackdir(tile, ReverseTrackdir(td))) continue; TileIndex next = TileAddByDiagDir(tile, TrackdirToExitdir(td)); @@ -1497,7 +1508,7 @@ CommandCost CmdRemoveSingleSignal(TileIndex tile, DoCommandFlag flags, uint32 p1 AddTrackToSignalBuffer(tile, track, GetTileOwner(tile)); YapfNotifyTrackLayoutChange(tile, track); - if (v != NULL) TryPathReserve(v, false); + if (v != nullptr) TryPathReserve(v, false); MarkTileDirtyByTile(tile); } @@ -1531,12 +1542,12 @@ CommandCost CmdRemoveSignalTrack(TileIndex tile, DoCommandFlag flags, uint32 p1, /** Update power of train under which is the railtype being converted */ static Vehicle *UpdateTrainPowerProc(Vehicle *v, void *data) { - if (v->type != VEH_TRAIN) return NULL; + if (v->type != VEH_TRAIN) return nullptr; TrainList *affected_trains = static_cast(data); - affected_trains->Include(Train::From(v)->First()); + include(*affected_trains, Train::From(v)->First()); - return NULL; + return nullptr; } /** @@ -1565,6 +1576,7 @@ CommandCost CmdConvertRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 CommandCost cost(EXPENSES_CONSTRUCTION); 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); for (; (tile = *iter) != INVALID_TILE; ++(*iter)) { @@ -1580,7 +1592,7 @@ CommandCost CmdConvertRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 case MP_ROAD: if (!IsLevelCrossing(tile)) continue; if (RailNoLevelCrossings(totype)) { - error.MakeError(STR_ERROR_CROSSING_DISALLOWED); + error.MakeError(STR_ERROR_CROSSING_DISALLOWED_RAIL); continue; } break; @@ -1603,7 +1615,7 @@ CommandCost CmdConvertRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 continue; } - SmallVector vehicles_affected; + std::vector vehicles_affected; /* Vehicle on the tile when not converting Rail <-> ElRail * Tunnels and bridges have special check later */ @@ -1620,10 +1632,10 @@ CommandCost CmdConvertRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 Track track; while ((track = RemoveFirstTrack(&reserved)) != INVALID_TRACK) { Train *v = GetTrainForReservation(tile, track); - if (v != NULL && !HasPowerOnRail(v->railtype, totype)) { + if (v != nullptr && !HasPowerOnRail(v->railtype, totype)) { /* No power on new rail type, reroute. */ FreeTrainTrackReservation(v); - *vehicles_affected.Append() = v; + vehicles_affected.push_back(v); } } @@ -1660,6 +1672,7 @@ CommandCost CmdConvertRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 InvalidateWindowData(WC_VEHICLE_DEPOT, tile); InvalidateWindowData(WC_BUILD_VEHICLE, tile); } + found_convertible_track = true; cost.AddCost(RailConvertCost(type, totype)); break; @@ -1671,6 +1684,7 @@ CommandCost CmdConvertRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 YapfNotifyTrackLayoutChange(tile, RemoveFirstTrack(&tracks)); } } + found_convertible_track = true; cost.AddCost(RailConvertCost(type, totype) * CountBits(GetTrackBits(tile))); break; } @@ -1702,10 +1716,10 @@ CommandCost CmdConvertRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 Track track = DiagDirToDiagTrack(GetTunnelBridgeDirection(tile)); if (HasTunnelBridgeReservation(tile)) { Train *v = GetTrainForReservation(tile, track); - if (v != NULL && !HasPowerOnRail(v->railtype, totype)) { + if (v != nullptr && !HasPowerOnRail(v->railtype, totype)) { /* No power on new rail type, reroute. */ FreeTrainTrackReservation(v); - *vehicles_affected.Append() = v; + vehicles_affected.push_back(v); } } @@ -1733,6 +1747,7 @@ CommandCost CmdConvertRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 } } + found_convertible_track = true; cost.AddCost((GetTunnelBridgeLength(tile, endtile) + 2) * RailConvertCost(type, totype)); break; } @@ -1743,24 +1758,25 @@ CommandCost CmdConvertRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 YapfNotifyTrackLayoutChange(tile, track); } + found_convertible_track = true; cost.AddCost(RailConvertCost(type, totype)); break; } - for (uint i = 0; i < vehicles_affected.Length(); ++i) { + for (uint i = 0; i < vehicles_affected.size(); ++i) { TryPathReserve(vehicles_affected[i], true); } } if (flags & DC_EXEC) { /* Railtype changed, update trains as when entering different track */ - for (Train **v = affected_trains.Begin(); v != affected_trains.End(); v++) { - (*v)->ConsistChanged(CCF_TRACK); + for (Train *v : affected_trains) { + v->ConsistChanged(CCF_TRACK); } } delete iter; - return (cost.GetCost() == 0) ? error : cost; + return found_convertible_track ? cost : error; } static CommandCost RemoveTrainDepot(TileIndex tile, DoCommandFlag flags) @@ -1777,11 +1793,11 @@ static CommandCost RemoveTrainDepot(TileIndex tile, DoCommandFlag flags) /* read variables before the depot is removed */ DiagDirection dir = GetRailDepotDirection(tile); Owner owner = GetTileOwner(tile); - Train *v = NULL; + Train *v = nullptr; if (HasDepotReservation(tile)) { v = GetTrainForReservation(tile, DiagDirToDiagTrack(dir)); - if (v != NULL) FreeTrainTrackReservation(v); + if (v != nullptr) FreeTrainTrackReservation(v); } Company::Get(owner)->infrastructure.rail[GetRailType(tile)]--; @@ -1791,7 +1807,7 @@ static CommandCost RemoveTrainDepot(TileIndex tile, DoCommandFlag flags) DoClearSquare(tile); AddSideToSignalBuffer(tile, dir, owner); YapfNotifyTrackLayoutChange(tile, DiagDirToDiagTrack(dir)); - if (v != NULL) TryPathReserve(v, true); + if (v != nullptr) TryPathReserve(v, true); } return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_CLEAR_DEPOT_TRAIN]); @@ -2064,7 +2080,7 @@ static const SubSprite _halftile_sub_sprite[4] = { static inline void DrawTrackSprite(SpriteID sprite, PaletteID pal, const TileInfo *ti, Slope s) { - DrawGroundSprite(sprite, pal, NULL, 0, (ti->tileh & s) ? -8 : 0); + DrawGroundSprite(sprite, pal, nullptr, 0, (ti->tileh & s) ? -8 : 0); } static void DrawTrackBitsOverlay(TileInfo *ti, TrackBits track, const RailtypeInfo *rti) @@ -2107,12 +2123,25 @@ static void DrawTrackBitsOverlay(TileInfo *ti, TrackBits track, const RailtypeIn DrawGroundSprite(image, PAL_NONE); } + bool no_combine = ti->tileh == SLOPE_FLAT && HasBit(rti->flags, RTF_NO_SPRITE_COMBINE); SpriteID overlay = GetCustomRailSprite(rti, ti->tile, RTSG_OVERLAY); - SpriteID ground = GetCustomRailSprite(rti, ti->tile, RTSG_GROUND); + SpriteID ground = GetCustomRailSprite(rti, ti->tile, no_combine ? RTSG_GROUND_COMPLETE : RTSG_GROUND); TrackBits pbs = _settings_client.gui.show_track_reservation ? GetRailReservationTrackBits(ti->tile) : TRACK_BIT_NONE; if (track == TRACK_BIT_NONE) { /* Half-tile foundation, no track here? */ + } else if (no_combine) { + /* Use trackbits as direct index from ground sprite, subtract 1 + * because there is no sprite for no bits. */ + DrawGroundSprite(ground + track - 1, PAL_NONE); + + /* Draw reserved track bits */ + if (pbs & TRACK_BIT_X) DrawGroundSprite(overlay + RTO_X, PALETTE_CRASH); + if (pbs & TRACK_BIT_Y) DrawGroundSprite(overlay + RTO_Y, PALETTE_CRASH); + if (pbs & TRACK_BIT_UPPER) DrawTrackSprite(overlay + RTO_N, PALETTE_CRASH, ti, SLOPE_N); + if (pbs & TRACK_BIT_LOWER) DrawTrackSprite(overlay + RTO_S, PALETTE_CRASH, ti, SLOPE_S); + if (pbs & TRACK_BIT_RIGHT) DrawTrackSprite(overlay + RTO_E, PALETTE_CRASH, ti, SLOPE_E); + if (pbs & TRACK_BIT_LEFT) DrawTrackSprite(overlay + RTO_W, PALETTE_CRASH, ti, SLOPE_W); } else if (ti->tileh == SLOPE_NW && track == TRACK_BIT_Y) { DrawGroundSprite(ground + RTO_SLOPE_NW, PAL_NONE); if (pbs != TRACK_BIT_NONE) DrawGroundSprite(overlay + RTO_SLOPE_NW, PALETTE_CRASH); @@ -2245,7 +2274,7 @@ static void DrawTrackBits(TileInfo *ti, TrackBits track) SpriteID image; PaletteID pal = PAL_NONE; - const SubSprite *sub = NULL; + const SubSprite *sub = nullptr; bool junction = false; /* Select the sprite to use. */ @@ -2272,23 +2301,30 @@ static void DrawTrackBits(TileInfo *ti, TrackBits track) image = _track_sloped_sprites[ti->tileh - 1] + rti->base_sprites.track_y; } else { /* track on flat ground */ - (image = rti->base_sprites.track_y, track == TRACK_BIT_Y) || - (image++, track == TRACK_BIT_X) || - (image++, track == TRACK_BIT_UPPER) || - (image++, track == TRACK_BIT_LOWER) || - (image++, track == TRACK_BIT_RIGHT) || - (image++, track == TRACK_BIT_LEFT) || - (image++, track == TRACK_BIT_CROSS) || + switch (track) { + /* single track, select combined track + ground sprite*/ + case TRACK_BIT_Y: image = rti->base_sprites.track_y; break; + case TRACK_BIT_X: image = rti->base_sprites.track_y + 1; break; + case TRACK_BIT_UPPER: image = rti->base_sprites.track_y + 2; break; + case TRACK_BIT_LOWER: image = rti->base_sprites.track_y + 3; break; + case TRACK_BIT_RIGHT: image = rti->base_sprites.track_y + 4; break; + case TRACK_BIT_LEFT: image = rti->base_sprites.track_y + 5; break; + case TRACK_BIT_CROSS: image = rti->base_sprites.track_y + 6; break; - (image = rti->base_sprites.track_ns, track == TRACK_BIT_HORZ) || - (image++, track == TRACK_BIT_VERT) || + /* double diagonal track, select combined track + ground sprite*/ + case TRACK_BIT_HORZ: image = rti->base_sprites.track_ns; break; + case TRACK_BIT_VERT: image = rti->base_sprites.track_ns + 1; break; - (junction = true, false) || - (image = rti->base_sprites.ground, (track & TRACK_BIT_3WAY_NE) == 0) || - (image++, (track & TRACK_BIT_3WAY_SW) == 0) || - (image++, (track & TRACK_BIT_3WAY_NW) == 0) || - (image++, (track & TRACK_BIT_3WAY_SE) == 0) || - (image++, true); + /* junction, select only ground sprite, handle track sprite later */ + default: + junction = true; + if ((track & TRACK_BIT_3WAY_NE) == 0) { image = rti->base_sprites.ground; break; } + if ((track & TRACK_BIT_3WAY_SW) == 0) { image = rti->base_sprites.ground + 1; break; } + if ((track & TRACK_BIT_3WAY_NW) == 0) { image = rti->base_sprites.ground + 2; break; } + if ((track & TRACK_BIT_3WAY_SE) == 0) { image = rti->base_sprites.ground + 3; break; } + image = rti->base_sprites.ground + 4; + break; + } } switch (rgt) { @@ -2335,10 +2371,10 @@ static void DrawTrackBits(TileInfo *ti, TrackBits track) DrawGroundSprite(_track_sloped_sprites[ti->tileh - 1] + rti->base_sprites.single_sloped - 20, PALETTE_CRASH); } } - if (pbs & TRACK_BIT_UPPER) DrawGroundSprite(rti->base_sprites.single_n, PALETTE_CRASH, NULL, 0, ti->tileh & SLOPE_N ? -(int)TILE_HEIGHT : 0); - if (pbs & TRACK_BIT_LOWER) DrawGroundSprite(rti->base_sprites.single_s, PALETTE_CRASH, NULL, 0, ti->tileh & SLOPE_S ? -(int)TILE_HEIGHT : 0); - if (pbs & TRACK_BIT_LEFT) DrawGroundSprite(rti->base_sprites.single_w, PALETTE_CRASH, NULL, 0, ti->tileh & SLOPE_W ? -(int)TILE_HEIGHT : 0); - if (pbs & TRACK_BIT_RIGHT) DrawGroundSprite(rti->base_sprites.single_e, PALETTE_CRASH, NULL, 0, ti->tileh & SLOPE_E ? -(int)TILE_HEIGHT : 0); + if (pbs & TRACK_BIT_UPPER) DrawGroundSprite(rti->base_sprites.single_n, PALETTE_CRASH, nullptr, 0, ti->tileh & SLOPE_N ? -(int)TILE_HEIGHT : 0); + if (pbs & TRACK_BIT_LOWER) DrawGroundSprite(rti->base_sprites.single_s, PALETTE_CRASH, nullptr, 0, ti->tileh & SLOPE_S ? -(int)TILE_HEIGHT : 0); + if (pbs & TRACK_BIT_LEFT) DrawGroundSprite(rti->base_sprites.single_w, PALETTE_CRASH, nullptr, 0, ti->tileh & SLOPE_W ? -(int)TILE_HEIGHT : 0); + if (pbs & TRACK_BIT_RIGHT) DrawGroundSprite(rti->base_sprites.single_e, PALETTE_CRASH, nullptr, 0, ti->tileh & SLOPE_E ? -(int)TILE_HEIGHT : 0); } if (IsValidCorner(halftile_corner)) { @@ -2358,7 +2394,7 @@ static void DrawTrackBits(TileInfo *ti, TrackBits track) if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation && HasReservedTracks(ti->tile, CornerToTrackBits(halftile_corner))) { static const byte _corner_to_track_sprite[] = {3, 1, 2, 0}; - DrawGroundSprite(_corner_to_track_sprite[halftile_corner] + rti->base_sprites.single_n, PALETTE_CRASH, NULL, 0, -(int)TILE_HEIGHT); + DrawGroundSprite(_corner_to_track_sprite[halftile_corner] + rti->base_sprites.single_n, PALETTE_CRASH, nullptr, 0, -(int)TILE_HEIGHT); } } } @@ -2434,9 +2470,8 @@ static void DrawTile_Track(TileInfo *ti) if (image != SPR_FLAT_GRASS_TILE) image += rti->GetRailtypeSpriteOffset(); } - /* adjust ground tile for desert - * don't adjust for snow, because snow in depots looks weird */ - if (IsSnowRailGround(ti->tile) && _settings_game.game_creation.landscape == LT_TROPIC) { + /* Adjust ground tile for desert and snow. */ + if (IsSnowRailGround(ti->tile)) { if (image != SPR_FLAT_GRASS_TILE) { image += rti->snow_offset; // tile with tracks } else { @@ -2938,7 +2973,7 @@ static VehicleEnterTileStatus VehicleEnter_Track(Vehicle *u, TileIndex tile, int if (fract_coord_leave == fract_coord) { /* Leave the depot. */ - if ((v = v->Next()) != NULL) { + if ((v = v->Next()) != nullptr) { v->vehstatus &= ~VS_HIDDEN; v->track = (DiagDirToAxis(dir) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y); } @@ -2949,7 +2984,7 @@ static VehicleEnterTileStatus VehicleEnter_Track(Vehicle *u, TileIndex tile, int v->track = TRACK_BIT_DEPOT, v->vehstatus |= VS_HIDDEN; v->direction = ReverseDir(v->direction); - if (v->Next() == NULL) VehicleEnterDepot(v->First()); + if (v->Next() == nullptr) VehicleEnterDepot(v->First()); v->tile = tile; InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile); @@ -3014,7 +3049,7 @@ static CommandCost TestAutoslopeOnRailTile(TileIndex tile, uint flags, int z_old */ static Vehicle *EnsureNoShipProc(Vehicle *v, void *data) { - return v->type == VEH_SHIP ? v : NULL; + return v->type == VEH_SHIP ? v : nullptr; } static CommandCost TerraformTile_Track(TileIndex tile, DoCommandFlag flags, int z_new, Slope tileh_new) @@ -3027,7 +3062,7 @@ static CommandCost TerraformTile_Track(TileIndex tile, DoCommandFlag flags, int bool was_water = (GetRailGroundType(tile) == RAIL_GROUND_WATER && IsSlopeWithOneCornerRaised(tileh_old)); /* Allow clearing the water only if there is no ship */ - if (was_water && HasVehicleOnPos(tile, NULL, &EnsureNoShipProc)) return_cmd_error(STR_ERROR_SHIP_IN_THE_WAY); + if (was_water && HasVehicleOnPos(tile, nullptr, &EnsureNoShipProc)) return_cmd_error(STR_ERROR_SHIP_IN_THE_WAY); /* First test autoslope. However if it succeeds we still have to test the rest, because non-autoslope terraforming is cheaper. */ CommandCost autoslope_result = TestAutoslopeOnRailTile(tile, flags, z_old, tileh_old, z_new, tileh_new, rail_bits); @@ -3070,14 +3105,14 @@ extern const TileTypeProcs _tile_type_rail_procs = { DrawTile_Track, // draw_tile_proc GetSlopePixelZ_Track, // get_slope_z_proc ClearTile_Track, // clear_tile_proc - NULL, // add_accepted_cargo_proc + nullptr, // add_accepted_cargo_proc GetTileDesc_Track, // get_tile_desc_proc GetTileTrackStatus_Track, // get_tile_track_status_proc ClickTile_Track, // click_tile_proc - NULL, // animate_tile_proc + nullptr, // animate_tile_proc TileLoop_Track, // tile_loop_proc ChangeTileOwner_Track, // change_tile_owner_proc - NULL, // add_produced_cargo_proc + nullptr, // add_produced_cargo_proc VehicleEnter_Track, // vehicle_enter_tile_proc GetFoundation_Track, // get_foundation_proc TerraformTile_Track, // terraform_tile_proc diff --git a/src/rail_gui.cpp b/src/rail_gui.cpp index a1ae370f97..5b552be2c3 100644 --- a/src/rail_gui.cpp +++ b/src/rail_gui.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. @@ -79,15 +77,15 @@ static void ShowSignalBuilder(Window *parent); */ static bool IsStationAvailable(const StationSpec *statspec) { - if (statspec == NULL || !HasBit(statspec->callback_mask, CBM_STATION_AVAIL)) return true; + if (statspec == nullptr || !HasBit(statspec->callback_mask, CBM_STATION_AVAIL)) return true; - uint16 cb_res = GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE); + uint16 cb_res = GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, nullptr, INVALID_TILE); if (cb_res == CALLBACK_FAILED) return true; return Convert8bitBooleanCallback(statspec->grf_prop.grffile, CBID_STATION_AVAILABILITY, cb_res); } -void CcPlaySound_SPLAT_RAIL(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) +void CcPlaySound_SPLAT_RAIL(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) { if (result.Succeeded() && _settings_client.sound.confirm) SndPlayTileFx(SND_20_SPLAT_RAIL, tile); } @@ -130,7 +128,7 @@ static const DiagDirection _place_depot_extra_dir[12] = { DIAGDIR_NW, DIAGDIR_NE, DIAGDIR_NW, DIAGDIR_NE, }; -void CcRailDepot(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) +void CcRailDepot(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) { if (result.Failed()) return; @@ -171,7 +169,7 @@ static void PlaceRail_Waypoint(TileIndex tile) } } -void CcStation(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) +void CcStation(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) { if (result.Failed()) return; @@ -227,7 +225,7 @@ static void GenericPlaceSignals(TileIndex tile) /* various bitstuffed elements for CmdBuildSingleSignal() */ uint32 p1 = track; - if (w != NULL) { + if (w != nullptr) { /* signal GUI is used */ SB(p1, 3, 1, _ctrl_pressed); SB(p1, 4, 1, _cur_signal_variant); @@ -243,13 +241,13 @@ static void GenericPlaceSignals(TileIndex tile) } DoCommandP(tile, p1, 0, CMD_BUILD_SIGNALS | - CMD_MSG((w != NULL && _convert_signal_button) ? STR_ERROR_SIGNAL_CAN_T_CONVERT_SIGNALS_HERE : STR_ERROR_CAN_T_BUILD_SIGNALS_HERE), + CMD_MSG((w != nullptr && _convert_signal_button) ? STR_ERROR_SIGNAL_CAN_T_CONVERT_SIGNALS_HERE : STR_ERROR_CAN_T_BUILD_SIGNALS_HERE), CcPlaySound_SPLAT_RAIL); } } /** Command callback for building a tunnel */ -void CcBuildRailTunnel(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) +void CcBuildRailTunnel(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) { if (result.Succeeded()) { if (_settings_client.sound.confirm) SndPlayTileFx(SND_20_SPLAT_RAIL, tile); @@ -368,7 +366,7 @@ static void HandleAutoSignalPlacement() const Window *w = FindWindowById(WC_BUILD_SIGNAL, 0); - if (w != NULL) { + if (w != nullptr) { /* signal GUI is used */ SB(p2, 3, 1, 0); SB(p2, 4, 1, _cur_signal_variant); @@ -415,6 +413,7 @@ struct BuildRailToolbarWindow : Window { ~BuildRailToolbarWindow() { if (_thd.GetCallbackWnd() == this) this->OnPlaceObjectAbort(); + if (this->IsWidgetLowered(WID_RAT_BUILD_STATION)) SetViewportCatchmentStation(nullptr, true); if (_settings_client.gui.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0, false); } @@ -423,7 +422,7 @@ struct BuildRailToolbarWindow : Window { * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; @@ -490,7 +489,7 @@ struct BuildRailToolbarWindow : Window { } } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { if (widget == WID_RAT_CAPTION) { const RailtypeInfo *rti = GetRailTypeInfo(this->railtype); @@ -504,7 +503,7 @@ struct BuildRailToolbarWindow : Window { } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { if (widget < WID_RAT_BUILD_NS) return; @@ -596,13 +595,13 @@ struct BuildRailToolbarWindow : Window { if (_ctrl_pressed) RailToolbar_CtrlChanged(this); } - virtual EventState OnHotkey(int hotkey) + EventState OnHotkey(int hotkey) override { MarkTileDirtyByTile(TileVirtXY(_thd.pos.x, _thd.pos.y)); // redraw tile selection return Window::OnHotkey(hotkey); } - virtual void OnPlaceObject(Point pt, TileIndex tile) + void OnPlaceObject(Point pt, TileIndex tile) override { switch (this->last_user_action) { case WID_RAT_BUILD_NS: @@ -662,10 +661,10 @@ struct BuildRailToolbarWindow : Window { MoveAllWindowsOffScreen(); } - virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) + void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) override { /* no dragging if you have pressed the convert button */ - if (FindWindowById(WC_BUILD_SIGNAL, 0) != NULL && _convert_signal_button && this->IsWidgetLowered(WID_RAT_BUILD_SIGNALS)) return; + if (FindWindowById(WC_BUILD_SIGNAL, 0) != nullptr && _convert_signal_button && this->IsWidgetLowered(WID_RAT_BUILD_SIGNALS)) return; switch (this->last_user_action) { case WID_RAT_BUILD_TUNNEL: @@ -678,7 +677,7 @@ struct BuildRailToolbarWindow : Window { VpSelectTilesWithMethod(pt.x, pt.y, select_method); } - virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) + void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) override { if (pt.x != -1) { this->last_user_action_remove = _remove_button_clicked; @@ -765,8 +764,10 @@ struct BuildRailToolbarWindow : Window { } } - virtual void OnPlaceObjectAbort() + void OnPlaceObjectAbort() override { + if (this->IsWidgetLowered(WID_RAT_BUILD_STATION)) SetViewportCatchmentStation(nullptr, true); + MoveAllHiddenWindowsBackToScreen(); this->RaiseButtons(); this->DisableWidget(WID_RAT_REMOVE); @@ -781,7 +782,7 @@ struct BuildRailToolbarWindow : Window { DeleteWindowByClass(WC_BUILD_BRIDGE); } - virtual void SelectLastTool() + void SelectLastTool() override { // User misplaced something - activate last selected tool again if (this->last_user_action == WIDGET_LIST_END) @@ -792,7 +793,7 @@ struct BuildRailToolbarWindow : Window { if (this->last_user_action_remove) BuildRailClick_Remove(this); } - virtual void OnPlacePresize(Point pt, TileIndex tile_from) + void OnPlacePresize(Point pt, TileIndex tile) override { TileIndex tile_to = tile_from; @@ -807,7 +808,7 @@ struct BuildRailToolbarWindow : Window { VpSetPresizeRange(tile_from, tile_to); } - virtual EventState OnCTRLStateChange() + EventState OnCTRLStateChange() override { /* do not toggle Remove button by Ctrl when placing station */ if (!this->IsWidgetLowered(WID_RAT_BUILD_STATION) && !this->IsWidgetLowered(WID_RAT_BUILD_WAYPOINT) && RailToolbar_CtrlChanged(this)) return ES_HANDLED; @@ -827,7 +828,7 @@ static EventState RailToolbarGlobalHotkeys(int hotkey) if (_game_mode != GM_NORMAL || !CanBuildVehicleInfrastructure(VEH_TRAIN)) return ES_NOT_HANDLED; extern RailType _last_built_railtype; Window *w = ShowBuildRailToolbar(_last_built_railtype); - if (w == NULL) return ES_NOT_HANDLED; + if (w == nullptr) return ES_NOT_HANDLED; return w->OnHotkey(hotkey); } @@ -908,12 +909,12 @@ static WindowDesc _build_rail_desc( * If the terraform toolbar is linked to the toolbar, that window is also opened. * * @param railtype Rail type to open the window for - * @return newly opened rail toolbar, or NULL if the toolbar could not be opened. + * @return newly opened rail toolbar, or nullptr if the toolbar could not be opened. */ Window *ShowBuildRailToolbar(RailType railtype) { - if (!Company::IsValidID(_local_company)) return NULL; - if (!ValParamRailtype(railtype)) return NULL; + if (!Company::IsValidID(_local_company)) return nullptr; + if (!ValParamRailtype(railtype)) return nullptr; DeleteToolbarLinkedWindows(); _cur_railtype = railtype; @@ -953,7 +954,7 @@ private: */ void CheckSelectedSize(const StationSpec *statspec) { - if (statspec == NULL || _settings_client.gui.station_dragdrop) return; + if (statspec == nullptr || _settings_client.gui.station_dragdrop) return; /* If current number of tracks is not allowed, make it as big as possible */ if (HasBit(statspec->disallowed_platforms, _settings_client.gui.station_numtracks - 1)) { @@ -983,7 +984,7 @@ public: BuildRailStationWindow(WindowDesc *desc, Window *parent, bool newstation) : PickerWindowBase(desc, parent) { this->coverage_height = 2 * FONT_HEIGHT_NORMAL + 3 * WD_PAR_VSEP_NORMAL; - this->vscroll = NULL; + this->vscroll = nullptr; _railstation.newstations = newstation; this->CreateNestedTree(); @@ -1016,7 +1017,7 @@ public: * type is 'selected'. */ _railstation.station_class = STAT_CLASS_DFLT; _railstation.station_type = 0; - this->vscroll2 = NULL; + this->vscroll2 = nullptr; } if (newstation) { _railstation.station_count = StationClass::Get(_railstation.station_class)->GetSpecCount(); @@ -1042,10 +1043,10 @@ public: DeleteWindowById(WC_SELECT_STATION, 0); } - virtual void OnPaint() + void OnPaint() override { bool newstations = _railstation.newstations; - const StationSpec *statspec = newstations ? StationClass::Get(_railstation.station_class)->GetSpec(_railstation.station_type) : NULL; + const StationSpec *statspec = newstations ? StationClass::Get(_railstation.station_class)->GetSpec(_railstation.station_type) : nullptr; if (_settings_client.gui.station_dragdrop) { SetTileSelectSize(1, 1); @@ -1064,7 +1065,7 @@ public: for (uint bits = 0; bits < 7; bits++) { bool disable = bits >= _settings_game.station.station_spread; - if (statspec == NULL) { + if (statspec == nullptr) { this->SetWidgetDisabledState(bits + WID_BRAS_PLATFORM_NUM_1, disable); this->SetWidgetDisabledState(bits + WID_BRAS_PLATFORM_LEN_1, disable); } else { @@ -1075,6 +1076,7 @@ public: this->DrawWidgets(); + 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; @@ -1092,7 +1094,7 @@ public: } } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_BRAS_NEWST_LIST: { @@ -1123,7 +1125,7 @@ public: StationClass *stclass = StationClass::Get(statclass); for (uint16 j = 0; j < stclass->GetSpecCount(); j++) { const StationSpec *statspec = stclass->GetSpec(j); - SetDParam(0, (statspec != NULL && statspec->name != 0) ? statspec->name : STR_STATION_CLASS_DFLT); + SetDParam(0, (statspec != nullptr && statspec->name != 0) ? statspec->name : STR_STATION_CLASS_DFLT); d = maxdim(d, GetStringBoundingBox(str)); } } @@ -1156,7 +1158,7 @@ public: } } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { DrawPixelInfo tmp_dpi; @@ -1231,22 +1233,22 @@ public: } } - virtual void OnResize() + void OnResize() override { - if (this->vscroll != NULL) { // New stations available. + if (this->vscroll != nullptr) { // New stations available. this->vscroll->SetCapacityFromWidget(this, WID_BRAS_NEWST_LIST); } } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { if (widget == WID_BRAS_SHOW_NEWST_TYPE) { const StationSpec *statspec = StationClass::Get(_railstation.station_class)->GetSpec(_railstation.station_type); - SetDParam(0, (statspec != NULL && statspec->name != 0) ? statspec->name : STR_STATION_CLASS_DFLT); + SetDParam(0, (statspec != nullptr && statspec->name != 0) ? statspec->name : STR_STATION_CLASS_DFLT); } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (GB(widget, 0, 16)) { case WID_BRAS_PLATFORM_DIR_X: @@ -1274,8 +1276,8 @@ public: _settings_client.gui.station_dragdrop = false; - const StationSpec *statspec = _railstation.newstations ? StationClass::Get(_railstation.station_class)->GetSpec(_railstation.station_type) : NULL; - if (statspec != NULL && HasBit(statspec->disallowed_lengths, _settings_client.gui.station_platlength - 1)) { + const StationSpec *statspec = _railstation.newstations ? StationClass::Get(_railstation.station_class)->GetSpec(_railstation.station_type) : nullptr; + if (statspec != nullptr && HasBit(statspec->disallowed_lengths, _settings_client.gui.station_platlength - 1)) { /* The previously selected number of platforms in invalid */ for (uint i = 0; i < 7; i++) { if (!HasBit(statspec->disallowed_lengths, i)) { @@ -1309,8 +1311,8 @@ public: _settings_client.gui.station_dragdrop = false; - const StationSpec *statspec = _railstation.newstations ? StationClass::Get(_railstation.station_class)->GetSpec(_railstation.station_type) : NULL; - if (statspec != NULL && HasBit(statspec->disallowed_platforms, _settings_client.gui.station_numtracks - 1)) { + const StationSpec *statspec = _railstation.newstations ? StationClass::Get(_railstation.station_class)->GetSpec(_railstation.station_type) : nullptr; + if (statspec != nullptr && HasBit(statspec->disallowed_platforms, _settings_client.gui.station_numtracks - 1)) { /* The previously selected number of tracks in invalid */ for (uint i = 0; i < 7; i++) { if (!HasBit(statspec->disallowed_platforms, i)) { @@ -1335,8 +1337,8 @@ public: this->ToggleWidgetLoweredState(WID_BRAS_PLATFORM_DRAG_N_DROP); /* get the first allowed length/number of platforms */ - const StationSpec *statspec = _railstation.newstations ? StationClass::Get(_railstation.station_class)->GetSpec(_railstation.station_type) : NULL; - if (statspec != NULL && HasBit(statspec->disallowed_lengths, _settings_client.gui.station_platlength - 1)) { + const StationSpec *statspec = _railstation.newstations ? StationClass::Get(_railstation.station_class)->GetSpec(_railstation.station_type) : nullptr; + if (statspec != nullptr && HasBit(statspec->disallowed_lengths, _settings_client.gui.station_platlength - 1)) { for (uint i = 0; i < 7; i++) { if (!HasBit(statspec->disallowed_lengths, i)) { this->RaiseWidget(_settings_client.gui.station_platlength + WID_BRAS_PLATFORM_LEN_BEGIN); @@ -1345,7 +1347,7 @@ public: } } } - if (statspec != NULL && HasBit(statspec->disallowed_platforms, _settings_client.gui.station_numtracks - 1)) { + if (statspec != nullptr && HasBit(statspec->disallowed_platforms, _settings_client.gui.station_numtracks - 1)) { for (uint i = 0; i < 7; i++) { if (!HasBit(statspec->disallowed_platforms, i)) { this->RaiseWidget(_settings_client.gui.station_numtracks + WID_BRAS_PLATFORM_NUM_BEGIN); @@ -1422,7 +1424,7 @@ public: } } - virtual void OnRealtimeTick(uint delta_ms) + void OnRealtimeTick(uint delta_ms) override { CheckRedrawStationCoverage(this); } @@ -1432,6 +1434,7 @@ static const NWidgetPart _nested_station_builder_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_STATION_BUILD_RAIL_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), + NWidget(WWT_SHADEBOX, COLOUR_DARK_GREEN), NWidget(NWID_SELECTION, INVALID_COLOUR, WID_BRAS_SHOW_NEWST_DEFSIZE), NWidget(WWT_DEFSIZEBOX, COLOUR_DARK_GREEN), EndContainer(), @@ -1590,7 +1593,7 @@ public: _convert_signal_button = false; } - virtual void OnInit() + void OnInit() override { /* Calculate maximum signal sprite size. */ this->sig_sprite_size.width = 0; @@ -1610,7 +1613,7 @@ public: } } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { if (widget == WID_BS_DRAG_SIGNALS_DENSITY_LABEL) { /* Two digits for signals density. */ @@ -1621,7 +1624,7 @@ public: } } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { switch (widget) { case WID_BS_DRAG_SIGNALS_DENSITY_LABEL: @@ -1630,7 +1633,7 @@ public: } } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { if (IsInsideMM(widget, WID_BS_SEMAPHORE_NORM, WID_BS_ELECTRIC_PBS_OWAY + 1)) { /* Extract signal from widget number. */ @@ -1642,7 +1645,7 @@ public: } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_BS_SEMAPHORE_NORM: @@ -1665,7 +1668,7 @@ public: /* If 'remove' button of rail build toolbar is active, disable it. */ if (_remove_button_clicked) { Window *w = FindWindowById(WC_BUILD_TOOLBAR, TRANSPORT_RAIL); - if (w != NULL) ToggleRailButton_Remove(w); + if (w != nullptr) ToggleRailButton_Remove(w); } break; @@ -1699,7 +1702,7 @@ public: * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; this->LowerWidget((_cur_signal_variant == SIG_ELECTRIC ? WID_BS_ELECTRIC_NORM : WID_BS_SEMAPHORE_NORM) + _cur_signal_type); @@ -1770,7 +1773,7 @@ struct BuildRailDepotWindow : public PickerWindowBase { this->LowerWidget(_build_depot_direction + WID_BRAD_DEPOT_NE); } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { if (!IsInsideMM(widget, WID_BRAD_DEPOT_NE, WID_BRAD_DEPOT_NW + 1)) return; @@ -1778,14 +1781,14 @@ struct BuildRailDepotWindow : public PickerWindowBase { size->height = ScaleGUITrad(48) + 2; } - virtual void DrawWidget(const Rect &r, int widget) const + 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); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_BRAD_DEPOT_NE: @@ -1834,7 +1837,7 @@ static const NWidgetPart _nested_build_depot_widgets[] = { }; static WindowDesc _build_depot_desc( - WDP_AUTO, NULL, 0, 0, + WDP_AUTO, nullptr, 0, 0, WC_BUILD_DEPOT, WC_BUILD_TOOLBAR, WDF_CONSTRUCTION, _nested_build_depot_widgets, lengthof(_nested_build_depot_widgets) @@ -1859,7 +1862,7 @@ struct BuildRailWaypointWindow : PickerWindowBase { matrix->SetClicked(_cur_waypoint_type); } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_BRW_WAYPOINT_MATRIX: @@ -1878,7 +1881,7 @@ struct BuildRailWaypointWindow : PickerWindowBase { } } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { switch (GB(widget, 0, 16)) { case WID_BRW_WAYPOINT: { @@ -1893,7 +1896,7 @@ struct BuildRailWaypointWindow : PickerWindowBase { } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (GB(widget, 0, 16)) { case WID_BRW_WAYPOINT: { @@ -1962,7 +1965,7 @@ void ReinitGuiAfterToggleElrail(bool disable) if (disable && _last_built_railtype == RAILTYPE_ELECTRIC) { _last_built_railtype = _cur_railtype = RAILTYPE_RAIL; BuildRailToolbarWindow *w = dynamic_cast(FindWindowById(WC_BUILD_TOOLBAR, TRANSPORT_RAIL)); - if (w != NULL) w->ModifyRailType(_cur_railtype); + if (w != nullptr) w->ModifyRailType(_cur_railtype); } MarkWholeScreenDirty(); } @@ -1973,43 +1976,46 @@ static void SetDefaultRailGui() if (_local_company == COMPANY_SPECTATOR || !Company::IsValidID(_local_company)) return; extern RailType _last_built_railtype; - RailType rt = (RailType)(_settings_client.gui.default_rail_type + RAILTYPE_END); - if (rt == DEF_RAILTYPE_MOST_USED) { - /* Find the most used rail type */ - uint count[RAILTYPE_END]; - memset(count, 0, sizeof(count)); - for (TileIndex t = 0; t < MapSize(); t++) { - if (IsTileType(t, MP_RAILWAY) || IsLevelCrossingTile(t) || HasStationTileRail(t) || - (IsTileType(t, MP_TUNNELBRIDGE) && GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL)) { - count[GetRailType(t)]++; + RailType rt; + switch (_settings_client.gui.default_rail_type) { + case 2: { + /* Find the most used rail type */ + uint count[RAILTYPE_END]; + memset(count, 0, sizeof(count)); + for (TileIndex t = 0; t < MapSize(); t++) { + if (IsTileType(t, MP_RAILWAY) || IsLevelCrossingTile(t) || HasStationTileRail(t) || + (IsTileType(t, MP_TUNNELBRIDGE) && GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL)) { + count[GetRailType(t)]++; + } } + + rt = static_cast(std::max_element(count + RAILTYPE_BEGIN, count + RAILTYPE_END) - count); + if (count[rt] > 0) break; + + /* No rail, just get the first available one */ + FALLTHROUGH; } - - rt = RAILTYPE_RAIL; - for (RailType r = RAILTYPE_ELECTRIC; r < RAILTYPE_END; r++) { - if (count[r] >= count[rt]) rt = r; + case 0: { + /* Use first available type */ + std::vector::const_iterator it = std::find_if(_sorted_railtypes.begin(), _sorted_railtypes.end(), + [](RailType r){ return HasRailtypeAvail(_local_company, r); }); + rt = it != _sorted_railtypes.end() ? *it : RAILTYPE_BEGIN; + break; } - - /* No rail, just get the first available one */ - if (count[rt] == 0) rt = DEF_RAILTYPE_FIRST; - } - switch (rt) { - case DEF_RAILTYPE_FIRST: - rt = RAILTYPE_RAIL; - while (rt < RAILTYPE_END && !HasRailtypeAvail(_local_company, rt)) rt++; + case 1: { + /* Use last available type */ + std::vector::const_reverse_iterator it = std::find_if(_sorted_railtypes.rbegin(), _sorted_railtypes.rend(), + [](RailType r){ return HasRailtypeAvail(_local_company, r); }); + rt = it != _sorted_railtypes.rend() ? *it : RAILTYPE_BEGIN; break; - - case DEF_RAILTYPE_LAST: - rt = GetBestRailtype(_local_company); - break; - + } default: - break; + NOT_REACHED(); } _last_built_railtype = _cur_railtype = rt; BuildRailToolbarWindow *w = dynamic_cast(FindWindowById(WC_BUILD_TOOLBAR, TRANSPORT_RAIL)); - if (w != NULL) w->ModifyRailType(_cur_railtype); + if (w != nullptr) w->ModifyRailType(_cur_railtype); } /** @@ -2024,7 +2030,7 @@ bool ResetSignalVariant(int32 p) if (new_variant != _cur_signal_variant) { Window *w = FindWindowById(WC_BUILD_SIGNAL, 0); - if (w != NULL) { + if (w != nullptr) { w->SetDirty(); w->RaiseWidget((_cur_signal_variant == SIG_ELECTRIC ? WID_BS_ELECTRIC_NORM : WID_BS_SEMAPHORE_NORM) + _cur_signal_type); } @@ -2053,30 +2059,39 @@ void InitializeRailGUI() * @param all_option Whether to add an 'all types' item. * @return The populated and sorted #DropDownList. */ -DropDownList *GetRailTypeDropDownList(bool for_replacement, bool all_option) +DropDownList GetRailTypeDropDownList(bool for_replacement, bool all_option) { - RailTypes used_railtypes = RAILTYPES_NONE; - - /* Find the used railtypes. */ - Engine *e; - FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) { - if (!HasBit(e->info.climates, _settings_game.game_creation.landscape)) continue; - - used_railtypes |= GetRailTypeInfo(e->u.rail.railtype)->introduces_railtypes; - } - - /* Get the date introduced railtypes as well. */ - used_railtypes = AddDateIntroducedRailTypes(used_railtypes, MAX_DAY); + RailTypes used_railtypes; + RailTypes avail_railtypes; const Company *c = Company::Get(_local_company); - DropDownList *list = new DropDownList(); - if (all_option) { - DropDownListStringItem *item = new DropDownListStringItem(STR_REPLACE_ALL_RAILTYPE, INVALID_RAILTYPE, false); - *list->Append() = item; + /* Find the used railtypes. */ + if (for_replacement) { + avail_railtypes = GetCompanyRailtypes(c->index, false); + used_railtypes = GetRailTypes(false); + } else { + avail_railtypes = c->avail_railtypes; + used_railtypes = GetRailTypes(true); } + DropDownList list; + + if (all_option) { + list.emplace_back(new DropDownListStringItem(STR_REPLACE_ALL_RAILTYPE, INVALID_RAILTYPE, false)); + } + + Dimension d = { 0, 0 }; RailType rt; + /* Get largest icon size, to ensure text is aligned on each menu item. */ + if (!for_replacement) { + FOR_ALL_SORTED_RAILTYPES(rt) { + if (!HasBit(used_railtypes, rt)) continue; + const RailtypeInfo *rti = GetRailTypeInfo(rt); + d = maxdim(d, GetSpriteSize(rti->gui_sprites.build_x_rail)); + } + } + FOR_ALL_SORTED_RAILTYPES(rt) { /* If it's not used ever, don't show it to the user. */ if (!HasBit(used_railtypes, rt)) continue; @@ -2084,10 +2099,23 @@ DropDownList *GetRailTypeDropDownList(bool for_replacement, bool all_option) const RailtypeInfo *rti = GetRailTypeInfo(rt); StringID str = for_replacement ? rti->strings.replace_text : (rti->max_speed > 0 ? STR_TOOLBAR_RAILTYPE_VELOCITY : STR_JUST_STRING); - DropDownListParamStringItem *item = new DropDownListParamStringItem(str, rt, !HasBit(c->avail_railtypes, rt)); + DropDownListParamStringItem *item; + if (for_replacement) { + item = new DropDownListParamStringItem(str, rt, !HasBit(avail_railtypes, rt)); + } else { + DropDownListIconItem *iconitem = new DropDownListIconItem(rti->gui_sprites.build_x_rail, PAL_NONE, str, rt, !HasBit(avail_railtypes, rt)); + iconitem->SetDimension(d); + item = iconitem; + } item->SetParam(0, rti->strings.menu_text); item->SetParam(1, rti->max_speed); - *list->Append() = item; + list.emplace_back(item); } + + if (list.size() == 0) { + /* Empty dropdowns are not allowed */ + list.emplace_back(new DropDownListStringItem(STR_NONE, INVALID_RAILTYPE, true)); + } + return list; } diff --git a/src/rail_gui.h b/src/rail_gui.h index e7a03b9120..29a1b9b161 100644 --- a/src/rail_gui.h +++ b/src/rail_gui.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. @@ -19,6 +17,6 @@ struct Window *ShowBuildRailToolbar(RailType railtype); void ReinitGuiAfterToggleElrail(bool disable); bool ResetSignalVariant(int32 = 0); void InitializeRailGUI(); -DropDownList *GetRailTypeDropDownList(bool for_replacement = false, bool all_option = false); +DropDownList GetRailTypeDropDownList(bool for_replacement = false, bool all_option = false); #endif /* RAIL_GUI_H */ diff --git a/src/rail_map.h b/src/rail_map.h index 74afe5ace5..bd1d3c7492 100644 --- a/src/rail_map.h +++ b/src/rail_map.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. @@ -17,6 +15,7 @@ #include "signal_func.h" #include "track_func.h" #include "tile_map.h" +#include "water_map.h" #include "signal_type.h" @@ -521,6 +520,7 @@ static inline void MakeRailNormal(TileIndex 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; @@ -535,6 +535,7 @@ static inline void MakeRailDepot(TileIndex t, Owner o, DepotID did, DiagDirectio { SetTileType(t, MP_RAILWAY); SetTileOwner(t, o); + SetDockingTile(t, false); _m[t].m2 = did; _m[t].m3 = 0; _m[t].m4 = 0; diff --git a/src/rail_type.h b/src/rail_type.h index 2bd602a37e..874a8ebbb6 100644 --- a/src/rail_type.h +++ b/src/rail_type.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. @@ -26,7 +24,7 @@ static const RailTypeLabel RAILTYPE_MAGLEV_LABEL = 'MGLV'; * * This enumeration defines all 4 possible railtypes. */ -enum RailType { +enum RailType : byte { RAILTYPE_BEGIN = 0, ///< Used for iterations RAILTYPE_RAIL = 0, ///< Standard non-electric rails RAILTYPE_ELECTRIC = 1, ///< Electric rails @@ -34,17 +32,12 @@ enum RailType { RAILTYPE_MAGLEV = 3, ///< Maglev RAILTYPE_END = 64, ///< Used for iterations INVALID_RAILTYPE = 0xFF, ///< Flag for invalid railtype - - DEF_RAILTYPE_FIRST = RAILTYPE_END, ///< Default railtype: first available - DEF_RAILTYPE_LAST, ///< Default railtype: last available - DEF_RAILTYPE_MOST_USED, ///< Default railtype: most used }; /** Allow incrementing of Track variables */ DECLARE_POSTFIX_INCREMENT(RailType) /** Define basic enum properties */ template <> struct EnumPropsT : MakeEnumPropsT {}; -typedef TinyEnumT RailTypeByte; /** * The different railtypes we support, but then a bitmask of them. diff --git a/src/rev.cpp.in b/src/rev.cpp.in index 2d58bb152d..003fb5556e 100644 --- a/src/rev.cpp.in +++ b/src/rev.cpp.in @@ -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. @@ -82,11 +80,4 @@ const byte _openttd_revision_tagged = !!ISTAG!!; * final release will always have a lower version number than the released * version, thus making comparisons on specific revisions easy. */ -const uint32 _openttd_newgrf_version = 1 << 28 | 9 << 24 | 0 << 20 | !!ISSTABLETAG!! << 19 | 28004; - -#ifdef __MORPHOS__ -/** - * Variable used by MorphOS to show the version. - */ -extern const char morphos_versions_tag[] = "$VER: OpenTTD !!VERSION!! (!!DATE!!) OpenTTD Team [MorphOS, PowerPC]"; -#endif +const uint32 _openttd_newgrf_version = 1 << 28 | 10 << 24 | 0 << 20 | !!ISSTABLETAG!! << 19 | 28004; diff --git a/src/rev.h b/src/rev.h index 55674cc805..f1e669aa56 100644 --- a/src/rev.h +++ b/src/rev.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/road.cpp b/src/road.cpp index f51597538d..486dc0044c 100644 --- a/src/road.cpp +++ b/src/road.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. @@ -19,6 +17,9 @@ #include "engine_base.h" #include "date_func.h" #include "landscape.h" +#include "road.h" +#include "road_func.h" +#include "roadveh.h" #include "safeguards.h" @@ -38,9 +39,9 @@ static bool IsPossibleCrossing(const TileIndex tile, Axis ax) } /** - * Clean up unnecessary RoadBits of a planed tile. + * Clean up unnecessary RoadBits of a planned tile. * @param tile current tile - * @param org_rb planed RoadBits + * @param org_rb planned RoadBits * @return optimised RoadBits */ RoadBits CleanUpRoadBits(const TileIndex tile, RoadBits org_rb) @@ -72,7 +73,7 @@ RoadBits CleanUpRoadBits(const TileIndex tile, RoadBits org_rb) /* Always connective */ connective = true; } else { - const RoadBits neighbor_rb = GetAnyRoadBits(neighbor_tile, ROADTYPE_ROAD) | GetAnyRoadBits(neighbor_tile, ROADTYPE_TRAM); + const RoadBits neighbor_rb = GetAnyRoadBits(neighbor_tile, RTT_ROAD) | GetAnyRoadBits(neighbor_tile, RTT_TRAM); /* Accept only connective tiles */ connective = (neighbor_rb & mirrored_rb) != ROAD_NONE; @@ -93,7 +94,7 @@ RoadBits CleanUpRoadBits(const TileIndex tile, RoadBits org_rb) } } - /* If the neighbor tile is inconnective, remove the planed road connection to it */ + /* If the neighbor tile is inconnective, remove the planned road connection to it */ if (!connective) org_rb ^= target_rb; } } @@ -102,53 +103,231 @@ RoadBits CleanUpRoadBits(const TileIndex tile, RoadBits org_rb) } /** - * Finds out, whether given company has all given RoadTypes available + * Finds out, whether given company has a given RoadType available for construction. * @param company ID of company - * @param rts RoadTypes to test - * @return true if company has all requested RoadTypes available + * @param roadtypet RoadType to test + * @return true if company has the requested RoadType available */ -bool HasRoadTypesAvail(const CompanyID company, const RoadTypes rts) +bool HasRoadTypeAvail(const CompanyID company, RoadType roadtype) { - RoadTypes avail_roadtypes; - if (company == OWNER_DEITY || company == OWNER_TOWN || _game_mode == GM_EDITOR || _generating_world) { - avail_roadtypes = ROADTYPES_ROAD; + return true; // TODO: should there be a proper check? } else { - Company *c = Company::GetIfValid(company); - if (c == NULL) return false; - avail_roadtypes = (RoadTypes)c->avail_roadtypes | ROADTYPES_ROAD; // road is available for always for everybody + const Company *c = Company::GetIfValid(company); + if (c == nullptr) return false; + return HasBit(c->avail_roadtypes & ~_roadtypes_hidden_mask, roadtype); } - return (rts & ~avail_roadtypes) == 0; +} + +static RoadTypes GetMaskForRoadTramType(RoadTramType rtt) +{ + return rtt == RTT_TRAM ? _roadtypes_type : ~_roadtypes_type; +} + +/** + * Test if any buildable RoadType is available for a company. + * @param company the company in question + * @return true if company has any RoadTypes available + */ +bool HasAnyRoadTypesAvail(CompanyID company, RoadTramType rtt) +{ + return (Company::Get(company)->avail_roadtypes & ~_roadtypes_hidden_mask & GetMaskForRoadTramType(rtt)) != ROADTYPES_NONE; } /** * Validate functions for rail building. - * @param rt road type to check. + * @param roadtype road type to check. * @return true if the current company may build the road. */ -bool ValParamRoadType(const RoadType rt) +bool ValParamRoadType(RoadType roadtype) { - return HasRoadTypesAvail(_current_company, RoadTypeToRoadTypes(rt)); + return roadtype != INVALID_ROADTYPE && HasRoadTypeAvail(_current_company, roadtype); +} + +/** + * Add the road types that are to be introduced at the given date. + * @param rt Roadtype + * @param current The currently available roadtypes. + * @param date The date for the introduction comparisons. + * @return The road types that should be available when date + * introduced road types are taken into account as well. + */ +RoadTypes AddDateIntroducedRoadTypes(RoadTypes current, Date date) +{ + RoadTypes rts = current; + + for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) { + const RoadTypeInfo *rti = GetRoadTypeInfo(rt); + /* Unused road type. */ + if (rti->label == 0) continue; + + /* Not date introduced. */ + if (!IsInsideMM(rti->introduction_date, 0, MAX_DAY)) continue; + + /* Not yet introduced at this date. */ + if (rti->introduction_date > date) continue; + + /* Have we introduced all required roadtypes? */ + RoadTypes required = rti->introduction_required_roadtypes; + if ((rts & required) != required) continue; + + rts |= rti->introduces_roadtypes; + } + + /* When we added roadtypes we need to run this method again; the added + * roadtypes might enable more rail types to become introduced. */ + return rts == current ? rts : AddDateIntroducedRoadTypes(rts, date); } /** * Get the road types the given company can build. - * @param company the company to get the roadtypes for. + * @param company the company to get the road types for. + * @param introduces If true, include road types introduced by other road types * @return the road types. */ -RoadTypes GetCompanyRoadtypes(CompanyID company) +RoadTypes GetCompanyRoadTypes(CompanyID company, bool introduces) { - RoadTypes rt = ROADTYPES_NONE; + RoadTypes rts = ROADTYPES_NONE; - Engine *e; - FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) { + for (const Engine *e : Engine::IterateType(VEH_ROAD)) { const EngineInfo *ei = &e->info; if (HasBit(ei->climates, _settings_game.game_creation.landscape) && (HasBit(e->company_avail, company) || _date >= e->intro_date + DAYS_IN_YEAR)) { - SetBit(rt, HasBit(ei->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD); + const RoadVehicleInfo *rvi = &e->u.road; + assert(rvi->roadtype < ROADTYPE_END); + if (introduces) { + rts |= GetRoadTypeInfo(rvi->roadtype)->introduces_roadtypes; + } else { + SetBit(rts, rvi->roadtype); + } } } - return rt; + if (introduces) return AddDateIntroducedRoadTypes(rts, _date); + return rts; +} + +/** + * Get list of road types, regardless of company availability. + * @param introduces If true, include road types introduced by other road types + * @return the road types. + */ +RoadTypes GetRoadTypes(bool introduces) +{ + RoadTypes rts = ROADTYPES_NONE; + + for (const Engine *e : Engine::IterateType(VEH_ROAD)) { + const EngineInfo *ei = &e->info; + if (!HasBit(ei->climates, _settings_game.game_creation.landscape)) continue; + + const RoadVehicleInfo *rvi = &e->u.road; + assert(rvi->roadtype < ROADTYPE_END); + if (introduces) { + rts |= GetRoadTypeInfo(rvi->roadtype)->introduces_roadtypes; + } else { + SetBit(rts, rvi->roadtype); + } + } + + if (introduces) return AddDateIntroducedRoadTypes(rts, MAX_DAY); + return rts; +} + +/** + * Get the road type for a given label. + * @param label the roadtype label. + * @param allow_alternate_labels Search in the alternate label lists as well. + * @return the roadtype. + */ +RoadType GetRoadTypeByLabel(RoadTypeLabel label, bool allow_alternate_labels) +{ + /* Loop through each road type until the label is found */ + for (RoadType r = ROADTYPE_BEGIN; r != ROADTYPE_END; r++) { + const RoadTypeInfo *rti = GetRoadTypeInfo(r); + if (rti->label == label) return r; + } + + if (allow_alternate_labels) { + /* Test if any road type defines the label as an alternate. */ + for (RoadType r = ROADTYPE_BEGIN; r != ROADTYPE_END; r++) { + const RoadTypeInfo *rti = GetRoadTypeInfo(r); + if (std::find(rti->alternate_labels.begin(), rti->alternate_labels.end(), label) != rti->alternate_labels.end()) return r; + } + } + + /* No matching label was found, so it is invalid */ + return INVALID_ROADTYPE; +} + +/** + * Returns the available RoadSubTypes for the provided RoadType + * If the given company is valid then will be returned a list of the available sub types at the current date, while passing + * a deity company will make all the sub types available + * @param rt the RoadType to filter + * @param c the company ID to check the roadtype against + * @param any_date whether to return only currently introduced roadtypes or also future ones + * @returns the existing RoadSubTypes + */ +RoadTypes ExistingRoadTypes(CompanyID c) +{ + /* Check only players which can actually own vehicles, editor and gamescripts are considered deities */ + if (c < OWNER_END) { + const Company *company = Company::GetIfValid(c); + if (company != nullptr) return company->avail_roadtypes; + } + + RoadTypes known_roadtypes = ROADTYPES_NONE; + + /* Find used roadtypes */ + for (Engine *e : Engine::IterateType(VEH_ROAD)) { + /* Check if the roadtype can be used in the current climate */ + if (!HasBit(e->info.climates, _settings_game.game_creation.landscape)) continue; + + /* Check whether available for all potential companies */ + if (e->company_avail != (CompanyMask)-1) continue; + + known_roadtypes |= GetRoadTypeInfo(e->u.road.roadtype)->introduces_roadtypes; + } + + /* Get the date introduced roadtypes as well. */ + known_roadtypes = AddDateIntroducedRoadTypes(known_roadtypes, MAX_DAY); + + return known_roadtypes; +} + +/** + * Check whether we can build infrastructure for the given RoadType. This to disable building stations etc. when + * you are not allowed/able to have the RoadType yet. + * @param roadtype the roadtype to check this for + * @param company the company id to check this for + * @param any_date to check only existing vehicles or if it is possible to build them in the future + * @return true if there is any reason why you may build the infrastructure for the given roadtype + */ +bool CanBuildRoadTypeInfrastructure(RoadType roadtype, CompanyID company) +{ + if (_game_mode != GM_EDITOR && !Company::IsValidID(company)) return false; + if (!_settings_client.gui.disable_unsuitable_building) return true; + if (!HasAnyRoadTypesAvail(company, GetRoadTramType(roadtype))) return false; + + RoadTypes roadtypes = ExistingRoadTypes(company); + + /* Check if the filtered roadtypes does have the roadtype we are checking for + * and if we can build new ones */ + if (_settings_game.vehicle.max_roadveh > 0 && HasBit(roadtypes, roadtype)) { + /* Can we actually build the vehicle type? */ + for (const Engine *e : Engine::IterateType(VEH_ROAD)) { + if (!HasBit(e->company_avail, company)) continue; + if (HasPowerOnRoad(e->u.road.roadtype, roadtype) || HasPowerOnRoad(roadtype, e->u.road.roadtype)) return true; + } + return false; + } + + /* We should be able to build infrastructure when we have the actual vehicle type */ + for (const Vehicle *v : Vehicle::Iterate()) { + if (v->type == VEH_ROAD && (company == OWNER_DEITY || v->owner == company) && + HasBit(roadtypes, RoadVehicle::From(v)->roadtype) && HasPowerOnRoad(RoadVehicle::From(v)->roadtype, roadtype)) return true; + } + + return false; } diff --git a/src/road.h b/src/road.h new file mode 100644 index 0000000000..1082ab2729 --- /dev/null +++ b/src/road.h @@ -0,0 +1,314 @@ +/* + * 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 road.h Road specific functions. */ + +#ifndef ROAD_H +#define ROAD_H + +#include "road_type.h" +#include "gfx_type.h" +#include "core/bitmath_func.hpp" +#include "strings_type.h" +#include "date_type.h" +#include "core/enum_type.hpp" +#include "newgrf.h" +#include "economy_func.h" + +#include + +enum RoadTramType : bool { + RTT_ROAD, + RTT_TRAM, +}; + +enum RoadTramTypes : uint8 { + RTTB_ROAD = 1 << RTT_ROAD, + RTTB_TRAM = 1 << RTT_TRAM, +}; +DECLARE_ENUM_AS_BIT_SET(RoadTramTypes) + +#define FOR_ALL_ROADTRAMTYPES(x) for (RoadTramType x : { RTT_ROAD, RTT_TRAM }) + +/** Roadtype flags. Starts with RO instead of R because R is used for rails */ +enum RoadTypeFlags { + ROTF_CATENARY = 0, ///< Bit number for adding catenary + 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. + + 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. +}; +DECLARE_ENUM_AS_BIT_SET(RoadTypeFlags) + +struct SpriteGroup; + +/** Sprite groups for a roadtype. */ +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_CATENARY_FRONT, ///< Optional: Catenary front + ROTSG_CATENARY_BACK, ///< Optional: Catenary back + ROTSG_BRIDGE, ///< Required: Bridge surface images + ROTSG_reserved2, ///< Placeholder, if we need specific level crossing sprites. + ROTSG_DEPOT, ///< Optional: Depot images + ROTSG_reserved3, ///< Placeholder, if we add road fences (for highways). + ROTSG_ROADSTOP, ///< Required: Drive-in stop surface + ROTSG_END, +}; + +/** List of road type labels. */ +typedef std::vector RoadTypeLabelList; + +class RoadTypeInfo { +public: + /** + * struct containing the sprites for the road GUI. @note only sprites referred to + * directly in the code are listed + */ + struct { + SpriteID build_x_road; ///< button for building single rail in X direction + SpriteID build_y_road; ///< button for building single rail in Y direction + SpriteID auto_road; ///< button for the autoroad construction + SpriteID build_depot; ///< button for building depots + SpriteID build_tunnel; ///< button for building a tunnel + SpriteID convert_road; ///< button for converting road types + } gui_sprites; + + struct { + CursorID road_swne; ///< Cursor for building rail in X direction + CursorID road_nwse; ///< Cursor for building rail in Y direction + CursorID autoroad; ///< Cursor for autorail tool + CursorID depot; ///< Cursor for building a depot + CursorID tunnel; ///< Cursor for building a tunnel + SpriteID convert_road; ///< Cursor for converting road types + } cursor; ///< Cursors associated with the road type. + + struct { + StringID name; ///< Name of this rail type. + StringID toolbar_caption; ///< Caption in the construction toolbar GUI for this rail type. + StringID menu_text; ///< Name of this rail type in the main toolbar dropdown. + StringID build_caption; ///< Caption of the build vehicle GUI for this rail type. + StringID replace_text; ///< Text used in the autoreplace GUI. + StringID new_engine; ///< Name of an engine for this type of road in the engine preview GUI. + + StringID err_build_road; ///< Building a normal piece of road + StringID err_remove_road; ///< Removing a normal piece of road + StringID err_depot; ///< Building a depot + StringID err_build_station[2]; ///< Building a bus or truck station + StringID err_remove_station[2]; ///< Removing of a bus or truck station + StringID err_convert_road; ///< Converting a road type + + StringID picker_title[2]; ///< Title for the station picker for bus or truck stations + StringID picker_tooltip[2]; ///< Tooltip for the station picker for bus or truck stations + } strings; ///< Strings associated with the rail type. + + /** bitmask to the OTHER roadtypes on which a vehicle of THIS roadtype generates power */ + RoadTypes powered_roadtypes; + + /** + * Bit mask of road type flags + */ + RoadTypeFlags flags; + + /** + * Cost multiplier for building this road type + */ + uint16 cost_multiplier; + + /** + * Cost multiplier for maintenance of this road type + */ + uint16 maintenance_multiplier; + + /** + * Maximum speed for vehicles travelling on this road type + */ + uint16 max_speed; + + /** + * Unique 32 bit road type identifier + */ + RoadTypeLabel label; + + /** + * Road type labels this type provides in addition to the main label. + */ + RoadTypeLabelList alternate_labels; + + /** + * Colour on mini-map + */ + byte map_colour; + + /** + * Introduction date. + * When #INVALID_DATE or a vehicle using this roadtype gets introduced earlier, + * the vehicle's introduction date will be used instead for this roadtype. + * The introduction at this date is furthermore limited by the + * #introduction_required_types. + */ + Date introduction_date; + + /** + * Bitmask of roadtypes that are required for this roadtype to be introduced + * at a given #introduction_date. + */ + RoadTypes introduction_required_roadtypes; + + /** + * Bitmask of which other roadtypes are introduced when this roadtype is introduced. + */ + RoadTypes introduces_roadtypes; + + /** + * The sorting order of this roadtype for the toolbar dropdown. + */ + byte sorting_order; + + /** + * NewGRF providing the Action3 for the roadtype. nullptr if not available. + */ + const GRFFile *grffile[ROTSG_END]; + + /** + * Sprite groups for resolving sprites + */ + const SpriteGroup *group[ROTSG_END]; + + inline bool UsesOverlay() const + { + return this->group[ROTSG_GROUND] != nullptr; + } +}; + +extern RoadTypes _roadtypes_type; + +static inline bool RoadTypeIsRoad(RoadType roadtype) +{ + return !HasBit(_roadtypes_type, roadtype); +} + +static inline bool RoadTypeIsTram(RoadType roadtype) +{ + return HasBit(_roadtypes_type, roadtype); +} + +static inline RoadTramType GetRoadTramType(RoadType roadtype) +{ + return RoadTypeIsTram(roadtype) ? RTT_TRAM : RTT_ROAD; +} + +static inline RoadTramType OtherRoadTramType(RoadTramType rtt) +{ + return rtt == RTT_ROAD ? RTT_TRAM : RTT_ROAD; +} + +/** + * Returns a pointer to the Roadtype information for a given roadtype + * @param roadtype the road type which the information is requested for + * @return The pointer to the RoadTypeInfo + */ +static inline const RoadTypeInfo *GetRoadTypeInfo(RoadType roadtype) +{ + extern RoadTypeInfo _roadtypes[ROADTYPE_END]; + assert(roadtype < ROADTYPE_END); + return &_roadtypes[roadtype]; +} + +/** + * Checks if an engine of the given RoadType got power on a tile with a given + * RoadType. This would normally just be an equality check, but for electrified + * roads (which also support non-electric vehicles). + * @return Whether the engine got power on this tile. + * @param enginetype The RoadType of the engine we are considering. + * @param tiletype The RoadType of the tile we are considering. + */ +static inline bool HasPowerOnRoad(RoadType enginetype, RoadType tiletype) +{ + return HasBit(GetRoadTypeInfo(enginetype)->powered_roadtypes, tiletype); +} + +/** + * Returns the cost of building the specified roadtype. + * @param roadtype The roadtype being built. + * @return The cost multiplier. + */ +static inline Money RoadBuildCost(RoadType roadtype) +{ + assert(roadtype < ROADTYPE_END); + return (_price[PR_BUILD_ROAD] * GetRoadTypeInfo(roadtype)->cost_multiplier) >> 3; +} + +/** + * Returns the cost of clearing the specified roadtype. + * @param roadtype The roadtype being removed. + * @return The cost. + */ +static inline Money RoadClearCost(RoadType roadtype) +{ + assert(roadtype < ROADTYPE_END); + + /* Flat fee for removing road. */ + if (RoadTypeIsRoad(roadtype)) return _price[PR_CLEAR_ROAD]; + + /* Clearing tram earns a little money, but also incurs the standard clear road cost, + * so no profit can be made. */ + return _price[PR_CLEAR_ROAD] - RoadBuildCost(roadtype) * 3 / 4; +} + +/** + * Calculates the cost of road conversion + * @param from The roadtype we are converting from + * @param to The roadtype we are converting to + * @return Cost per RoadBit + */ +static inline Money RoadConvertCost(RoadType from, RoadType to) +{ + /* Don't apply convert costs when converting to the same roadtype (ex. building a roadstop over existing road) */ + if (from == to) return (Money)0; + + /* Same cost as removing and then building. */ + return RoadBuildCost(to) + RoadClearCost(from); +} + +/** + * Test if road disallows level crossings + * @param roadtype The roadtype we are testing + * @return True iff the roadtype disallows level crossings + */ +static inline bool RoadNoLevelCrossing(RoadType roadtype) +{ + assert(roadtype < ROADTYPE_END); + return HasBit(GetRoadTypeInfo(roadtype)->flags, ROTF_NO_LEVEL_CROSSING); +} + +RoadType GetRoadTypeByLabel(RoadTypeLabel label, bool allow_alternate_labels = true); + +void ResetRoadTypes(); +void InitRoadTypes(); +RoadType AllocateRoadType(RoadTypeLabel label, RoadTramType rtt); +bool HasAnyRoadTypesAvail(CompanyID company, RoadTramType rtt); + +extern std::vector _sorted_roadtypes; +extern RoadTypes _roadtypes_hidden_mask; + +/** + * Loop header for iterating over roadtypes, sorted by sortorder. + * @param var Roadtype. + */ +#define FOR_ALL_SORTED_ROADTYPES(var) for (uint8 index = 0; index < _sorted_roadtypes.size() && (var = _sorted_roadtypes[index], true) ; index++) + +#endif /* ROAD_H */ diff --git a/src/road_cmd.cpp b/src/road_cmd.cpp index d9825c9bfa..5a9efb8567 100644 --- a/src/road_cmd.cpp +++ b/src/road_cmd.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. @@ -11,6 +9,7 @@ #include "stdafx.h" #include "cmd_helper.h" +#include "road.h" #include "road_internal.h" #include "viewport_func.h" #include "command_func.h" @@ -31,25 +30,176 @@ #include "town.h" #include "company_base.h" #include "core/random_func.hpp" +#include "newgrf_debug.h" #include "newgrf_railtype.h" +#include "newgrf_roadtype.h" #include "date_func.h" #include "genworld.h" #include "company_gui.h" +#include "road_func.h" #include "table/strings.h" +#include "table/roadtypes.h" #include "safeguards.h" +/** Helper type for lists/vectors of road vehicles */ +typedef std::vector RoadVehicleList; + +RoadTypeInfo _roadtypes[ROADTYPE_END]; +std::vector _sorted_roadtypes; +RoadTypes _roadtypes_hidden_mask; + +/** + * Bitmap of road/tram types. + * Bit if set if a roadtype is tram. + */ +RoadTypes _roadtypes_type; + +/** + * Reset all road type information to its default values. + */ +void ResetRoadTypes() +{ + assert_compile(lengthof(_original_roadtypes) <= lengthof(_roadtypes)); + + uint i = 0; + for (; i < lengthof(_original_roadtypes); i++) _roadtypes[i] = _original_roadtypes[i]; + + static const RoadTypeInfo empty_roadtype = { + { 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0, 0, {}, {}, 0, {}, {} }, + ROADTYPES_NONE, ROTFB_NONE, 0, 0, 0, 0, + RoadTypeLabelList(), 0, 0, ROADTYPES_NONE, ROADTYPES_NONE, 0, + {}, {} }; + for (; i < lengthof(_roadtypes); i++) _roadtypes[i] = empty_roadtype; + + _roadtypes_hidden_mask = ROADTYPES_NONE; + _roadtypes_type = ROADTYPES_TRAM; +} + +void ResolveRoadTypeGUISprites(RoadTypeInfo *rti) +{ + SpriteID cursors_base = GetCustomRoadSprite(rti, INVALID_TILE, ROTSG_CURSORS); + if (cursors_base != 0) { + rti->gui_sprites.build_y_road = cursors_base + 0; + rti->gui_sprites.build_x_road = cursors_base + 1; + rti->gui_sprites.auto_road = cursors_base + 2; + rti->gui_sprites.build_depot = cursors_base + 3; + rti->gui_sprites.build_tunnel = cursors_base + 4; + rti->gui_sprites.convert_road = cursors_base + 5; + rti->cursor.road_swne = cursors_base + 6; + rti->cursor.road_nwse = cursors_base + 7; + rti->cursor.autoroad = cursors_base + 8; + rti->cursor.depot = cursors_base + 9; + rti->cursor.tunnel = cursors_base + 10; + rti->cursor.convert_road = cursors_base + 11; + } +} + +/** + * Compare roadtypes based on their sorting order. + * @param first The roadtype to compare to. + * @param second The roadtype to compare. + * @return True iff the first should be sorted before the second. + */ +static bool CompareRoadTypes(const RoadType &first, const RoadType &second) +{ + if (RoadTypeIsRoad(first) == RoadTypeIsRoad(second)) { + return GetRoadTypeInfo(first)->sorting_order < GetRoadTypeInfo(second)->sorting_order; + } + return RoadTypeIsTram(first) < RoadTypeIsTram(second); +} + +/** + * Resolve sprites of custom road types + */ +void InitRoadTypes() +{ + for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) { + RoadTypeInfo *rti = &_roadtypes[rt]; + ResolveRoadTypeGUISprites(rti); + if (HasBit(rti->flags, ROTF_HIDDEN)) SetBit(_roadtypes_hidden_mask, rt); + } + + _sorted_roadtypes.clear(); + for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) { + if (_roadtypes[rt].label != 0 && !HasBit(_roadtypes_hidden_mask, rt)) { + _sorted_roadtypes.push_back(rt); + } + } + std::sort(_sorted_roadtypes.begin(), _sorted_roadtypes.end(), CompareRoadTypes); +} + +/** + * Allocate a new road type label + */ +RoadType AllocateRoadType(RoadTypeLabel label, RoadTramType rtt) +{ + for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) { + RoadTypeInfo *rti = &_roadtypes[rt]; + + if (rti->label == 0) { + /* Set up new road type */ + *rti = _original_roadtypes[(rtt == RTT_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD]; + rti->label = label; + rti->alternate_labels.clear(); + rti->flags = ROTFB_NONE; + rti->introduction_date = INVALID_DATE; + + /* Make us compatible with ourself. */ + rti->powered_roadtypes = (RoadTypes)(1ULL << rt); + + /* We also introduce ourself. */ + rti->introduces_roadtypes = (RoadTypes)(1ULL << rt); + + /* Default sort order; order of allocation, but with some + * offsets so it's easier for NewGRF to pick a spot without + * changing the order of other (original) road types. + * The << is so you can place other roadtypes in between the + * other roadtypes, the 7 is to be able to place something + * before the first (default) road type. */ + rti->sorting_order = rt << 2 | 7; + + /* Set bitmap of road/tram types */ + if (rtt == RTT_TRAM) { + SetBit(_roadtypes_type, rt); + } else { + ClrBit(_roadtypes_type, rt); + } + + return rt; + } + } + + return INVALID_ROADTYPE; +} + /** * Verify whether a road vehicle is available. * @return \c true if at least one road vehicle is available, \c false if not */ bool RoadVehiclesAreBuilt() { - const RoadVehicle *rv; - FOR_ALL_ROADVEHICLES(rv) return true; + return !RoadVehicle::Iterate().empty(); +} - return false; +/** + * Update road infrastructure counts for a company. + * @param rt Road type to update count of. + * @param o Owner of road piece. + * @param count Number of road pieces to adjust. + */ +void UpdateCompanyRoadInfrastructure(RoadType rt, Owner o, int count) +{ + if (rt == INVALID_ROADTYPE) return; + + Company *c = Company::GetIfValid(o); + if (c == nullptr) return; + + c->infrastructure.road[rt] += count; + DirtyCompanyInfrastructureWindows(c->index); } /** Invalid RoadBits on slopes. */ @@ -113,7 +263,7 @@ static Foundation GetRoadFoundation(Slope tileh, RoadBits bits); * @param town_check Shall the town rating checked/affected * @return A succeeded command when it is allowed to remove the road bits, a failed command otherwise. */ -CommandCost CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, Owner owner, RoadType rt, DoCommandFlag flags, bool town_check) +CommandCost CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, Owner owner, RoadTramType rtt, DoCommandFlag flags, bool town_check) { if (_game_mode == GM_EDITOR || remove == ROAD_NONE) return CommandCost(); @@ -121,7 +271,7 @@ CommandCost CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, Owner owner, R * Towns are not be allowed to remove non "normal" road pieces, like tram * tracks as that would result in trams that cannot turn. */ if (_current_company == OWNER_WATER || - (rt == ROADTYPE_ROAD && !Company::IsValidID(_current_company))) return CommandCost(); + (rtt == RTT_ROAD && !Company::IsValidID(_current_company))) return CommandCost(); /* Only do the special processing if the road is owned * by a town */ @@ -136,7 +286,7 @@ CommandCost CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, Owner owner, R if (_cheats.magic_bulldozer.value) return CommandCost(); Town *t = ClosestTownFromTile(tile, UINT_MAX); - if (t == NULL) return CommandCost(); + if (t == nullptr) return CommandCost(); /* check if you're allowed to remove the street owned by a town * removal allowance depends on difficulty setting */ @@ -145,11 +295,11 @@ CommandCost CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, Owner owner, R /* Get a bitmask of which neighbouring roads has a tile */ RoadBits n = ROAD_NONE; - RoadBits present = GetAnyRoadBits(tile, rt); - if ((present & ROAD_NE) && (GetAnyRoadBits(TILE_ADDXY(tile, -1, 0), rt) & ROAD_SW)) n |= ROAD_NE; - if ((present & ROAD_SE) && (GetAnyRoadBits(TILE_ADDXY(tile, 0, 1), rt) & ROAD_NW)) n |= ROAD_SE; - if ((present & ROAD_SW) && (GetAnyRoadBits(TILE_ADDXY(tile, 1, 0), rt) & ROAD_NE)) n |= ROAD_SW; - if ((present & ROAD_NW) && (GetAnyRoadBits(TILE_ADDXY(tile, 0, -1), rt) & ROAD_SE)) n |= ROAD_NW; + RoadBits present = GetAnyRoadBits(tile, rtt); + if ((present & ROAD_NE) && (GetAnyRoadBits(TILE_ADDXY(tile, -1, 0), rtt) & ROAD_SW)) n |= ROAD_NE; + if ((present & ROAD_SE) && (GetAnyRoadBits(TILE_ADDXY(tile, 0, 1), rtt) & ROAD_NW)) n |= ROAD_SE; + if ((present & ROAD_SW) && (GetAnyRoadBits(TILE_ADDXY(tile, 1, 0), rtt) & ROAD_NE)) n |= ROAD_SW; + if ((present & ROAD_NW) && (GetAnyRoadBits(TILE_ADDXY(tile, 0, -1), rtt) & ROAD_SE)) n |= ROAD_NW; int rating_decrease = RATING_ROAD_DOWN_STEP_EDGE; /* If 0 or 1 bits are set in n, or if no bits that match the bits to remove, @@ -177,11 +327,13 @@ CommandCost CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, Owner owner, R * @param crossing_check should we check if there is a tram track when we are removing road from crossing? * @param town_check should we check if the town allows removal? */ -static CommandCost RemoveRoad(TileIndex tile, DoCommandFlag flags, RoadBits pieces, RoadType rt, bool crossing_check, bool town_check = true) +static CommandCost RemoveRoad(TileIndex tile, DoCommandFlag flags, RoadBits pieces, RoadTramType rtt, bool crossing_check, bool town_check = true) { - RoadTypes rts = GetRoadTypes(tile); + assert(pieces != ROAD_NONE); + + RoadType existing_rt = MayHaveRoad(tile) ? GetRoadType(tile, rtt) : INVALID_ROADTYPE; /* The tile doesn't have the given road type */ - if (!HasBit(rts, rt)) return_cmd_error(rt == ROADTYPE_TRAM ? STR_ERROR_THERE_IS_NO_TRAMWAY : STR_ERROR_THERE_IS_NO_ROAD); + if (existing_rt == INVALID_ROADTYPE) return_cmd_error((rtt == RTT_TRAM) ? STR_ERROR_THERE_IS_NO_TRAMWAY : STR_ERROR_THERE_IS_NO_ROAD); switch (GetTileType(tile)) { case MP_ROAD: { @@ -209,37 +361,32 @@ static CommandCost RemoveRoad(TileIndex tile, DoCommandFlag flags, RoadBits piec return CMD_ERROR; } - CommandCost ret = CheckAllowRemoveRoad(tile, pieces, GetRoadOwner(tile, rt), rt, flags, town_check); + CommandCost ret = CheckAllowRemoveRoad(tile, pieces, GetRoadOwner(tile, rtt), rtt, flags, town_check); if (ret.Failed()) return ret; if (!IsTileType(tile, MP_ROAD)) { /* If it's the last roadtype, just clear the whole tile */ - if (rts == RoadTypeToRoadTypes(rt)) return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + if (GetRoadType(tile, OtherRoadTramType(rtt)) == INVALID_ROADTYPE) return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); CommandCost cost(EXPENSES_CONSTRUCTION); if (IsTileType(tile, MP_TUNNELBRIDGE)) { /* Removing any roadbit in the bridge axis removes the roadtype (that's the behaviour remove-long-roads needs) */ - if ((AxisToRoadBits(DiagDirToAxis(GetTunnelBridgeDirection(tile))) & pieces) == ROAD_NONE) return_cmd_error(rt == ROADTYPE_TRAM ? STR_ERROR_THERE_IS_NO_TRAMWAY : STR_ERROR_THERE_IS_NO_ROAD); + if ((AxisToRoadBits(DiagDirToAxis(GetTunnelBridgeDirection(tile))) & pieces) == ROAD_NONE) return_cmd_error((rtt == RTT_TRAM) ? STR_ERROR_THERE_IS_NO_TRAMWAY : STR_ERROR_THERE_IS_NO_ROAD); TileIndex other_end = GetOtherTunnelBridgeEnd(tile); /* Pay for *every* tile of the bridge or tunnel */ uint len = GetTunnelBridgeLength(other_end, tile) + 2; - cost.AddCost(len * 2 * _price[PR_CLEAR_ROAD]); + cost.AddCost(len * 2 * RoadClearCost(existing_rt)); if (flags & DC_EXEC) { - Company *c = Company::GetIfValid(GetRoadOwner(tile, rt)); - if (c != NULL) { - /* A full diagonal road tile has two road bits. */ - c->infrastructure.road[rt] -= len * 2 * TUNNELBRIDGE_TRACKBIT_FACTOR; - DirtyCompanyInfrastructureWindows(c->index); - } + /* A full diagonal road tile has two road bits. */ + UpdateCompanyRoadInfrastructure(existing_rt, GetRoadOwner(tile, rtt), -(int)(len * 2 * TUNNELBRIDGE_TRACKBIT_FACTOR)); - SetRoadTypes(other_end, GetRoadTypes(other_end) & ~RoadTypeToRoadTypes(rt)); - SetRoadTypes(tile, GetRoadTypes(tile) & ~RoadTypeToRoadTypes(rt)); + SetRoadType(other_end, rtt, INVALID_ROADTYPE); + SetRoadType(tile, rtt, INVALID_ROADTYPE); /* If the owner of the bridge sells all its road, also move the ownership * to the owner of the other roadtype, unless the bridge owner is a town. */ - RoadType other_rt = (rt == ROADTYPE_ROAD) ? ROADTYPE_TRAM : ROADTYPE_ROAD; - Owner other_owner = GetRoadOwner(tile, other_rt); + Owner other_owner = GetRoadOwner(tile, OtherRoadTramType(rtt)); if (!IsTileOwner(tile, other_owner) && !IsTileOwner(tile, OWNER_TOWN)) { SetTileOwner(tile, other_owner); SetTileOwner(other_end, other_owner); @@ -255,15 +402,11 @@ static CommandCost RemoveRoad(TileIndex tile, DoCommandFlag flags, RoadBits piec } } else { assert(IsDriveThroughStopTile(tile)); - cost.AddCost(_price[PR_CLEAR_ROAD] * 2); + cost.AddCost(RoadClearCost(existing_rt) * 2); if (flags & DC_EXEC) { - Company *c = Company::GetIfValid(GetRoadOwner(tile, rt)); - if (c != NULL) { - /* A full diagonal road tile has two road bits. */ - c->infrastructure.road[rt] -= 2; - DirtyCompanyInfrastructureWindows(c->index); - } - SetRoadTypes(tile, GetRoadTypes(tile) & ~RoadTypeToRoadTypes(rt)); + /* A full diagonal road tile has two road bits. */ + UpdateCompanyRoadInfrastructure(existing_rt, GetRoadOwner(tile, rtt), -2); + SetRoadType(tile, rtt, INVALID_ROADTYPE); MarkTileDirtyByTile(tile); } } @@ -279,8 +422,8 @@ static CommandCost RemoveRoad(TileIndex tile, DoCommandFlag flags, RoadBits piec tileh = SlopeWithOneCornerRaised(GetHighestSlopeCorner(tileh)); } - RoadBits present = GetRoadBits(tile, rt); - const RoadBits other = GetOtherRoadBits(tile, rt); + RoadBits present = GetRoadBits(tile, rtt); + const RoadBits other = GetRoadBits(tile, OtherRoadTramType(rtt)); const Foundation f = GetRoadFoundation(tileh, present); if (HasRoadWorks(tile) && _current_company != OWNER_WATER) return_cmd_error(STR_ERROR_ROAD_WORKS_IN_PROGRESS); @@ -295,7 +438,7 @@ static CommandCost RemoveRoad(TileIndex tile, DoCommandFlag flags, RoadBits piec /* limit the bits to delete to the existing bits. */ pieces &= present; - if (pieces == ROAD_NONE) return_cmd_error(rt == ROADTYPE_TRAM ? STR_ERROR_THERE_IS_NO_TRAMWAY : STR_ERROR_THERE_IS_NO_ROAD); + if (pieces == ROAD_NONE) return_cmd_error((rtt == RTT_TRAM) ? STR_ERROR_THERE_IS_NO_TRAMWAY : STR_ERROR_THERE_IS_NO_ROAD); /* Now set present what it will be after the remove */ present ^= pieces; @@ -310,46 +453,41 @@ static CommandCost RemoveRoad(TileIndex tile, DoCommandFlag flags, RoadBits piec if (HasRoadWorks(tile)) { /* flooding tile with road works, don't forget to remove the effect vehicle too */ assert(_current_company == OWNER_WATER); - EffectVehicle *v; - FOR_ALL_EFFECTVEHICLES(v) { + for (EffectVehicle *v : EffectVehicle::Iterate()) { if (TileVirtXY(v->x_pos, v->y_pos) == tile) { delete v; } } } - Company *c = Company::GetIfValid(GetRoadOwner(tile, rt)); - if (c != NULL) { - c->infrastructure.road[rt] -= CountBits(pieces); - DirtyCompanyInfrastructureWindows(c->index); - } + UpdateCompanyRoadInfrastructure(existing_rt, GetRoadOwner(tile, rtt), -(int)CountBits(pieces)); if (present == ROAD_NONE) { - RoadTypes rts = GetRoadTypes(tile) & ComplementRoadTypes(RoadTypeToRoadTypes(rt)); - if (rts == ROADTYPES_NONE) { + /* No other road type, just clear tile. */ + if (GetRoadType(tile, OtherRoadTramType(rtt)) == INVALID_ROADTYPE) { /* Includes MarkTileDirtyByTile() */ DoClearSquare(tile); } else { - if (rt == ROADTYPE_ROAD && IsRoadOwner(tile, ROADTYPE_ROAD, OWNER_TOWN)) { + if (rtt == RTT_ROAD && IsRoadOwner(tile, rtt, OWNER_TOWN)) { /* Update nearest-town index */ const Town *town = CalcClosestTownFromTile(tile); - SetTownIndex(tile, town == NULL ? INVALID_TOWN : town->index); + SetTownIndex(tile, town == nullptr ? INVALID_TOWN : town->index); } - SetRoadBits(tile, ROAD_NONE, rt); - SetRoadTypes(tile, rts); + SetRoadBits(tile, ROAD_NONE, rtt); + SetRoadType(tile, rtt, INVALID_ROADTYPE); MarkTileDirtyByTile(tile); } } else { /* When bits are removed, you *always* end up with something that * is not a complete straight road tile. However, trams do not have * onewayness, so they cannot remove it either. */ - if (rt != ROADTYPE_TRAM) SetDisallowedRoadDirections(tile, DRD_NONE); - SetRoadBits(tile, present, rt); + if (rtt == RTT_ROAD) SetDisallowedRoadDirections(tile, DRD_NONE); + SetRoadBits(tile, present, rtt); MarkTileDirtyByTile(tile); } } - CommandCost cost(EXPENSES_CONSTRUCTION, CountBits(pieces) * _price[PR_CLEAR_ROAD]); + CommandCost cost(EXPENSES_CONSTRUCTION, CountBits(pieces) * RoadClearCost(existing_rt)); /* If we build a foundation we have to pay for it. */ if (f == FOUNDATION_NONE && GetRoadFoundation(tileh, present) != FOUNDATION_NONE) cost.AddCost(_price[PR_BUILD_FOUNDATION]); @@ -361,21 +499,12 @@ static CommandCost RemoveRoad(TileIndex tile, DoCommandFlag flags, RoadBits piec return CMD_ERROR; } - /* Don't allow road to be removed from the crossing when there is tram; - * we can't draw the crossing without roadbits ;) */ - if (rt == ROADTYPE_ROAD && HasTileRoadType(tile, ROADTYPE_TRAM) && (flags & DC_EXEC || crossing_check)) return CMD_ERROR; - if (flags & DC_EXEC) { - Company *c = Company::GetIfValid(GetRoadOwner(tile, rt)); - if (c != NULL) { - /* A full diagonal road tile has two road bits. */ - c->infrastructure.road[rt] -= 2; - DirtyCompanyInfrastructureWindows(c->index); - } + /* A full diagonal road tile has two road bits. */ + UpdateCompanyRoadInfrastructure(existing_rt, GetRoadOwner(tile, rtt), -2); Track railtrack = GetCrossingRailTrack(tile); - RoadTypes rts = GetRoadTypes(tile) & ComplementRoadTypes(RoadTypeToRoadTypes(rt)); - if (rts == ROADTYPES_NONE) { + if (GetRoadType(tile, OtherRoadTramType(rtt)) == INVALID_ROADTYPE) { TrackBits tracks = GetCrossingRailBits(tile); bool reserved = HasCrossingReservation(tile); MakeRailNormal(tile, GetTileOwner(tile), tracks, GetRailType(tile)); @@ -383,18 +512,18 @@ static CommandCost RemoveRoad(TileIndex tile, DoCommandFlag flags, RoadBits piec /* Update rail count for level crossings. The plain track should still be accounted * for, so only subtract the difference to the level crossing cost. */ - c = Company::GetIfValid(GetTileOwner(tile)); - if (c != NULL) { + Company *c = Company::GetIfValid(GetTileOwner(tile)); + if (c != nullptr) { c->infrastructure.rail[GetRailType(tile)] -= LEVELCROSSING_TRACKBIT_FACTOR - 1; DirtyCompanyInfrastructureWindows(c->index); } } else { - SetRoadTypes(tile, rts); + SetRoadType(tile, rtt, INVALID_ROADTYPE); } MarkTileDirtyByTile(tile); YapfNotifyTrackLayoutChange(tile, railtrack); } - return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_CLEAR_ROAD] * 2); + return CommandCost(EXPENSES_CONSTRUCTION, RoadClearCost(existing_rt) * 2); } default: @@ -475,8 +604,8 @@ static CommandCost CheckRoadSlope(Slope tileh, RoadBits *pieces, RoadBits existi * @param tile tile where to build road * @param flags operation to perform * @param p1 bit 0..3 road pieces to build (RoadBits) - * bit 4..5 road type - * bit 6..7 disallowed directions to toggle + * bit 4..9 road type + * bit 11..12 disallowed directions to toggle * @param p2 the town that is building the road (0 if not applicable) * @param text unused * @return the cost of this operation or an error @@ -494,13 +623,13 @@ CommandCost CmdBuildRoad(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 if ((Company::IsValidID(company) && p2 != 0) || (company == OWNER_TOWN && !Town::IsValidID(p2)) || (company == OWNER_DEITY && p2 != 0)) return CMD_ERROR; if (company != OWNER_TOWN) { const Town *town = CalcClosestTownFromTile(tile); - p2 = (town != NULL) ? town->index : INVALID_TOWN; + p2 = (town != nullptr) ? town->index : INVALID_TOWN; if (company == OWNER_DEITY) { company = OWNER_TOWN; /* If we are not within a town, we are not owned by the town */ - if (town == NULL || DistanceSquare(tile, town->xy) > town->cache.squared_town_zone_radius[HZB_TOWN_EDGE]) { + if (town == nullptr || DistanceSquare(tile, town->xy) > town->cache.squared_town_zone_radius[HZB_TOWN_EDGE]) { company = OWNER_NONE; } } @@ -511,12 +640,13 @@ CommandCost CmdBuildRoad(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 /* do not allow building 'zero' road bits, code wouldn't handle it */ if (pieces == ROAD_NONE) return CMD_ERROR; - RoadType rt = Extract(p1); - if (!IsValidRoadType(rt) || !ValParamRoadType(rt)) return CMD_ERROR; + RoadType rt = Extract(p1); + if (!ValParamRoadType(rt)) return CMD_ERROR; - DisallowedRoadDirections toggle_drd = Extract(p1); + DisallowedRoadDirections toggle_drd = Extract(p1); Slope tileh = GetTileSlope(tile); + RoadTramType rtt = GetRoadTramType(rt); bool need_to_clear = false; switch (GetTileType(tile)) { @@ -525,21 +655,21 @@ CommandCost CmdBuildRoad(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 case ROAD_TILE_NORMAL: { if (HasRoadWorks(tile)) return_cmd_error(STR_ERROR_ROAD_WORKS_IN_PROGRESS); - other_bits = GetOtherRoadBits(tile, rt); - if (!HasTileRoadType(tile, rt)) break; + other_bits = GetRoadBits(tile, OtherRoadTramType(rtt)); + if (!HasTileRoadType(tile, rtt)) break; - existing = GetRoadBits(tile, rt); + existing = GetRoadBits(tile, rtt); bool crossing = !IsStraightRoad(existing | pieces); - if (rt != ROADTYPE_TRAM && (GetDisallowedRoadDirections(tile) != DRD_NONE || toggle_drd != DRD_NONE) && crossing) { + if (rtt == RTT_ROAD && (GetDisallowedRoadDirections(tile) != DRD_NONE || toggle_drd != DRD_NONE) && crossing) { /* Junctions cannot be one-way */ return_cmd_error(STR_ERROR_ONEWAY_ROADS_CAN_T_HAVE_JUNCTION); } if ((existing & pieces) == pieces) { /* We only want to set the (dis)allowed road directions */ - if (toggle_drd != DRD_NONE && rt != ROADTYPE_TRAM) { + if (toggle_drd != DRD_NONE && rtt == RTT_ROAD) { if (crossing) return_cmd_error(STR_ERROR_ONEWAY_ROADS_CAN_T_HAVE_JUNCTION); - Owner owner = GetRoadOwner(tile, ROADTYPE_ROAD); + Owner owner = GetRoadOwner(tile, rtt); if (owner != OWNER_NONE) { CommandCost ret = CheckOwnership(owner, tile); if (ret.Failed()) return ret; @@ -558,7 +688,7 @@ CommandCost CmdBuildRoad(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 } /* Ignore half built tiles */ - if ((flags & DC_EXEC) && rt != ROADTYPE_TRAM && IsStraightRoad(existing)) { + if ((flags & DC_EXEC) && IsStraightRoad(existing)) { SetDisallowedRoadDirections(tile, dis_new); MarkTileDirtyByTile(tile); } @@ -568,8 +698,8 @@ CommandCost CmdBuildRoad(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 } /* Disallow breaking end-of-line of someone else * so trams can still reverse on this tile. */ - if (rt == ROADTYPE_TRAM && HasExactlyOneBit(existing)) { - Owner owner = GetRoadOwner(tile, rt); + if (rtt == RTT_TRAM && HasExactlyOneBit(existing)) { + Owner owner = GetRoadOwner(tile, rtt); if (Company::IsValidID(owner)) { CommandCost ret = CheckOwnership(owner); if (ret.Failed()) return ret; @@ -579,15 +709,19 @@ CommandCost CmdBuildRoad(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 } case ROAD_TILE_CROSSING: + if (RoadNoLevelCrossing(rt)) { + return_cmd_error(STR_ERROR_CROSSING_DISALLOWED_ROAD); + } + other_bits = GetCrossingRoadBits(tile); if (pieces & ComplementRoadBits(other_bits)) goto do_clear; pieces = other_bits; // we need to pay for both roadbits - if (HasTileRoadType(tile, rt)) return_cmd_error(STR_ERROR_ALREADY_BUILT); + if (HasTileRoadType(tile, rtt)) return_cmd_error(STR_ERROR_ALREADY_BUILT); break; case ROAD_TILE_DEPOT: - if ((GetAnyRoadBits(tile, rt) & pieces) == pieces) return_cmd_error(STR_ERROR_ALREADY_BUILT); + if ((GetAnyRoadBits(tile, rtt) & pieces) == pieces) return_cmd_error(STR_ERROR_ALREADY_BUILT); goto do_clear; default: NOT_REACHED(); @@ -606,8 +740,12 @@ CommandCost CmdBuildRoad(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 if (GetRailTileType(tile) != RAIL_TILE_NORMAL) goto do_clear; + if (RoadNoLevelCrossing(rt)) { + return_cmd_error(STR_ERROR_CROSSING_DISALLOWED_ROAD); + } + if (RailNoLevelCrossings(GetRailType(tile))) { - return_cmd_error(STR_ERROR_CROSSING_DISALLOWED); + return_cmd_error(STR_ERROR_CROSSING_DISALLOWED_RAIL); } Axis roaddir; @@ -632,39 +770,35 @@ CommandCost CmdBuildRoad(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 Track railtrack = AxisToTrack(OtherAxis(roaddir)); YapfNotifyTrackLayoutChange(tile, railtrack); /* Update company infrastructure counts. A level crossing has two road bits. */ - Company *c = Company::GetIfValid(company); - if (c != NULL) { - c->infrastructure.road[rt] += 2; - if (rt != ROADTYPE_ROAD) c->infrastructure.road[ROADTYPE_ROAD] += 2; - DirtyCompanyInfrastructureWindows(company); - } + UpdateCompanyRoadInfrastructure(rt, company, 2); + /* Update rail count for level crossings. The plain track is already * counted, so only add the difference to the level crossing cost. */ - c = Company::GetIfValid(GetTileOwner(tile)); - if (c != NULL) { + Company *c = Company::GetIfValid(GetTileOwner(tile)); + if (c != nullptr) { c->infrastructure.rail[GetRailType(tile)] += LEVELCROSSING_TRACKBIT_FACTOR - 1; DirtyCompanyInfrastructureWindows(c->index); } /* Always add road to the roadtypes (can't draw without it) */ bool reserved = HasBit(GetRailReservationTrackBits(tile), railtrack); - MakeRoadCrossing(tile, company, company, GetTileOwner(tile), roaddir, GetRailType(tile), RoadTypeToRoadTypes(rt) | ROADTYPES_ROAD, p2); + MakeRoadCrossing(tile, company, company, GetTileOwner(tile), roaddir, GetRailType(tile), rtt == RTT_ROAD ? rt : INVALID_ROADTYPE, (rtt == RTT_TRAM) ? rt : INVALID_ROADTYPE, p2); SetCrossingReservation(tile, reserved); UpdateLevelCrossing(tile, false); MarkTileDirtyByTile(tile); } - return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_ROAD] * (rt == ROADTYPE_ROAD ? 2 : 4)); + return CommandCost(EXPENSES_CONSTRUCTION, 2 * RoadBuildCost(rt)); } case MP_STATION: { - if ((GetAnyRoadBits(tile, rt) & pieces) == pieces) return_cmd_error(STR_ERROR_ALREADY_BUILT); + if ((GetAnyRoadBits(tile, rtt) & pieces) == pieces) return_cmd_error(STR_ERROR_ALREADY_BUILT); if (!IsDriveThroughStopTile(tile)) goto do_clear; RoadBits curbits = AxisToRoadBits(DiagDirToAxis(GetRoadStopDir(tile))); if (pieces & ~curbits) goto do_clear; pieces = curbits; // we need to pay for both roadbits - if (HasTileRoadType(tile, rt)) return_cmd_error(STR_ERROR_ALREADY_BUILT); + if (HasTileRoadType(tile, rtt)) return_cmd_error(STR_ERROR_ALREADY_BUILT); break; } @@ -672,7 +806,7 @@ CommandCost CmdBuildRoad(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 if (GetTunnelBridgeTransportType(tile) != TRANSPORT_ROAD) goto do_clear; /* Only allow building the outern roadbit, so building long roads stops at existing bridges */ if (MirrorRoadBits(DiagDirToRoadBits(GetTunnelBridgeDirection(tile))) != pieces) goto do_clear; - if (HasTileRoadType(tile, rt)) return_cmd_error(STR_ERROR_ALREADY_BUILT); + if (HasTileRoadType(tile, rtt)) return_cmd_error(STR_ERROR_ALREADY_BUILT); /* Don't allow adding roadtype to the bridge/tunnel when vehicles are already driving on it */ CommandCost ret = TunnelBridgeIsFree(tile, GetOtherTunnelBridgeEnd(tile)); if (ret.Failed()) return ret; @@ -713,15 +847,10 @@ do_clear:; Slope slope = GetTileSlope(tile); Foundation found_new = GetRoadFoundation(slope, pieces | existing); - /* Test if all other roadtypes can be built at that foundation */ - for (RoadType rtest = ROADTYPE_ROAD; rtest < ROADTYPE_END; rtest++) { - if (rtest != rt) { // check only other road types - RoadBits bits = GetRoadBits(tile, rtest); - /* do not check if there are not road bits of given type */ - if (bits != ROAD_NONE && GetRoadFoundation(slope, bits) != found_new) { - return_cmd_error(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION); - } - } + RoadBits bits = GetRoadBits(tile, OtherRoadTramType(rtt)); + /* do not check if there are not road bits of given type */ + if (bits != ROAD_NONE && GetRoadFoundation(slope, bits) != found_new) { + return_cmd_error(STR_ERROR_LAND_SLOPED_IN_WRONG_DIRECTION); } } } @@ -729,6 +858,23 @@ do_clear:; CommandCost ret = EnsureNoVehicleOnGround(tile); if (ret.Failed()) return ret; + if (IsNormalRoadTile(tile)) { + /* If the road types don't match, try to convert only if vehicles of + * the new road type are not powered on the present road type and vehicles of + * the present road type are powered on the new road type. */ + RoadType existing_rt = GetRoadType(tile, rtt); + if (existing_rt != INVALID_ROADTYPE && existing_rt != rt) { + if (HasPowerOnRoad(rt, existing_rt)) { + rt = existing_rt; + } else if (HasPowerOnRoad(existing_rt, rt)) { + CommandCost ret = DoCommand(tile, tile, rt, flags, CMD_CONVERT_ROAD); + if (ret.Failed()) return ret; + cost.AddCost(ret); + } else { + return CMD_ERROR; + } + } + } } uint num_pieces = (!need_to_clear && IsTileType(tile, MP_TUNNELBRIDGE)) ? @@ -737,28 +883,28 @@ do_clear:; /* Count pieces */ CountBits(pieces); - cost.AddCost(num_pieces * _price[PR_BUILD_ROAD]); + cost.AddCost(num_pieces * RoadBuildCost(rt)); if (flags & DC_EXEC) { switch (GetTileType(tile)) { case MP_ROAD: { - RoadTileType rtt = GetRoadTileType(tile); - if (existing == ROAD_NONE || rtt == ROAD_TILE_CROSSING) { - SetRoadTypes(tile, GetRoadTypes(tile) | RoadTypeToRoadTypes(rt)); - SetRoadOwner(tile, rt, company); - if (rt == ROADTYPE_ROAD) SetTownIndex(tile, p2); + RoadTileType rttype = GetRoadTileType(tile); + if (existing == ROAD_NONE || rttype == ROAD_TILE_CROSSING) { + SetRoadType(tile, rtt, rt); + SetRoadOwner(tile, rtt, company); + if (rtt == RTT_ROAD) SetTownIndex(tile, p2); } - if (rtt != ROAD_TILE_CROSSING) SetRoadBits(tile, existing | pieces, rt); + if (rttype != ROAD_TILE_CROSSING) SetRoadBits(tile, existing | pieces, rtt); break; } case MP_TUNNELBRIDGE: { TileIndex other_end = GetOtherTunnelBridgeEnd(tile); - SetRoadTypes(other_end, GetRoadTypes(other_end) | RoadTypeToRoadTypes(rt)); - SetRoadTypes(tile, GetRoadTypes(tile) | RoadTypeToRoadTypes(rt)); - SetRoadOwner(other_end, rt, company); - SetRoadOwner(tile, rt, company); + SetRoadType(other_end, rtt, rt); + SetRoadType(tile, rtt, rt); + SetRoadOwner(other_end, rtt, company); + SetRoadOwner(tile, rtt, company); /* Mark tiles dirty that have been repaved */ if (IsBridge(tile)) { @@ -770,26 +916,23 @@ do_clear:; break; } - case MP_STATION: + case MP_STATION: { assert(IsDriveThroughStopTile(tile)); - SetRoadTypes(tile, GetRoadTypes(tile) | RoadTypeToRoadTypes(rt)); - SetRoadOwner(tile, rt, company); + SetRoadType(tile, rtt, rt); + SetRoadOwner(tile, rtt, company); break; + } default: - MakeRoadNormal(tile, pieces, RoadTypeToRoadTypes(rt), p2, company, company); + MakeRoadNormal(tile, pieces, (rtt == RTT_ROAD) ? rt : INVALID_ROADTYPE, (rtt == RTT_TRAM) ? rt : INVALID_ROADTYPE, p2, company, company); break; } /* Update company infrastructure count. */ - Company *c = Company::GetIfValid(GetRoadOwner(tile, rt)); - if (c != NULL) { - if (IsTileType(tile, MP_TUNNELBRIDGE)) num_pieces *= TUNNELBRIDGE_TRACKBIT_FACTOR; - c->infrastructure.road[rt] += num_pieces; - DirtyCompanyInfrastructureWindows(c->index); - } + if (IsTileType(tile, MP_TUNNELBRIDGE)) num_pieces *= TUNNELBRIDGE_TRACKBIT_FACTOR; + UpdateCompanyRoadInfrastructure(rt, GetRoadOwner(tile, rtt), num_pieces); - if (rt != ROADTYPE_TRAM && IsNormalRoadTile(tile)) { + if (rtt == RTT_ROAD && IsNormalRoadTile(tile)) { existing |= pieces; SetDisallowedRoadDirections(tile, IsStraightRoad(existing) ? GetDisallowedRoadDirections(tile) ^ toggle_drd : DRD_NONE); @@ -810,8 +953,14 @@ do_clear:; static bool CanConnectToRoad(TileIndex tile, RoadType rt, DiagDirection dir) { tile += TileOffsByDiagDir(dir); - if (!IsValidTile(tile)) return false; - RoadBits bits = GetAnyRoadBits(tile, rt, false); + if (!IsValidTile(tile) || !MayHaveRoad(tile)) return false; + + RoadTramType rtt = GetRoadTramType(rt); + RoadType existing = GetRoadType(tile, rtt); + if (existing == INVALID_ROADTYPE) return false; + if (!HasPowerOnRoad(existing, rt) && !HasPowerOnRoad(rt, existing)) return false; + + RoadBits bits = GetAnyRoadBits(tile, rtt, false); return (bits & DiagDirToRoadBits(ReverseDiagDir(dir))) != 0; } @@ -824,9 +973,9 @@ static bool CanConnectToRoad(TileIndex tile, RoadType rt, DiagDirection dir) * - p2 = (bit 0) - start tile starts in the 2nd half of tile (p2 & 1). Only used if bit 6 is set or if we are building a single tile * - p2 = (bit 1) - end tile starts in the 2nd half of tile (p2 & 2). Only used if bit 6 is set or if we are building a single tile * - p2 = (bit 2) - direction: 0 = along x-axis, 1 = along y-axis (p2 & 4) - * - p2 = (bit 3 + 4) - road type - * - p2 = (bit 5) - set road direction - * - p2 = (bit 6) - defines two different behaviors for this command: + * - p2 = (bit 3..8) - road type + * - p2 = (bit 10) - set road direction + * - p2 = (bit 11) - defines two different behaviors for this command: * - 0 = Build up to an obstacle. Do not build the first and last roadbits unless they can be connected to something, or if we are building a single tile * - 1 = Fail if an obstacle is found. Always take into account bit 0 and 1. This behavior is used for scripts * @param text unused @@ -837,10 +986,10 @@ CommandCost CmdBuildLongRoad(TileIndex start_tile, DoCommandFlag flags, uint32 p DisallowedRoadDirections drd = DRD_NORTHBOUND; if (p1 >= MapSize()) return CMD_ERROR; - TileIndex end_tile = p1; - RoadType rt = Extract(p2); - if (!IsValidRoadType(rt) || !ValParamRoadType(rt)) return CMD_ERROR; + + RoadType rt = Extract(p2); + if (!ValParamRoadType(rt)) return CMD_ERROR; Axis axis = Extract(p2); /* Only drag in X or Y direction dictated by the direction variable */ @@ -861,7 +1010,7 @@ CommandCost CmdBuildLongRoad(TileIndex start_tile, DoCommandFlag flags, uint32 p * when you just 'click' on one tile to build them. */ if ((axis == AXIS_Y) == (start_tile == end_tile && HasBit(p2, 0) == HasBit(p2, 1))) drd ^= DRD_BOTH; /* No disallowed direction bits have to be toggled */ - if (!HasBit(p2, 5)) drd = DRD_NONE; + if (!HasBit(p2, 10)) drd = DRD_NONE; CommandCost cost(EXPENSES_CONSTRUCTION); CommandCost last_error = CMD_ERROR; @@ -869,7 +1018,7 @@ CommandCost CmdBuildLongRoad(TileIndex start_tile, DoCommandFlag flags, uint32 p bool had_bridge = false; bool had_tunnel = false; bool had_success = false; - bool is_ai = HasBit(p2, 6); + bool is_ai = HasBit(p2, 11); /* Start tile is the first tile clicked by the user. */ for (;;) { @@ -889,7 +1038,7 @@ CommandCost CmdBuildLongRoad(TileIndex start_tile, DoCommandFlag flags, uint32 p if (tile == start_tile && HasBit(p2, 0)) bits &= DiagDirToRoadBits(dir); } - CommandCost ret = DoCommand(tile, drd << 6 | rt << 4 | bits, 0, flags, CMD_BUILD_ROAD); + CommandCost ret = DoCommand(tile, drd << 11 | rt << 4 | bits, 0, flags, CMD_BUILD_ROAD); if (ret.Failed()) { last_error = ret; if (last_error.GetErrorMessage() != STR_ERROR_ALREADY_BUILT) { @@ -933,7 +1082,7 @@ CommandCost CmdBuildLongRoad(TileIndex start_tile, DoCommandFlag flags, uint32 p * - p2 = (bit 0) - start tile starts in the 2nd half of tile (p2 & 1) * - p2 = (bit 1) - end tile starts in the 2nd half of tile (p2 & 2) * - p2 = (bit 2) - direction: 0 = along x-axis, 1 = along y-axis (p2 & 4) - * - p2 = (bit 3 + 4) - road type + * - p2 = (bit 3 - 8) - road type * @param text unused * @return the cost of this operation or an error */ @@ -944,8 +1093,8 @@ CommandCost CmdRemoveLongRoad(TileIndex start_tile, DoCommandFlag flags, uint32 if (p1 >= MapSize()) return CMD_ERROR; TileIndex end_tile = p1; - RoadType rt = Extract(p2); - if (!IsValidRoadType(rt)) return CMD_ERROR; + RoadType rt = Extract(p2); + if (!ValParamRoadType(rt)) return CMD_ERROR; Axis axis = Extract(p2); /* Only drag in X or Y direction dictated by the direction variable */ @@ -973,7 +1122,8 @@ CommandCost CmdRemoveLongRoad(TileIndex start_tile, DoCommandFlag flags, uint32 /* try to remove the halves. */ if (bits != 0) { - CommandCost ret = RemoveRoad(tile, flags & ~DC_EXEC, bits, rt, true); + RoadTramType rtt = GetRoadTramType(rt); + CommandCost ret = RemoveRoad(tile, flags & ~DC_EXEC, bits, rtt, true); if (ret.Succeeded()) { if (flags & DC_EXEC) { money -= ret.GetCost(); @@ -981,7 +1131,7 @@ CommandCost CmdRemoveLongRoad(TileIndex start_tile, DoCommandFlag flags, uint32 _additional_cash_required = DoCommand(start_tile, end_tile, p2, flags & ~DC_EXEC, CMD_REMOVE_LONG_ROAD).GetCost(); return cost; } - RemoveRoad(tile, flags, bits, rt, true, false); + RemoveRoad(tile, flags, bits, rtt, true, false); } cost.AddCost(ret); had_success = true; @@ -1004,7 +1154,7 @@ CommandCost CmdRemoveLongRoad(TileIndex start_tile, DoCommandFlag flags, uint32 * @param tile tile where to build the depot * @param flags operation to perform * @param p1 bit 0..1 entrance direction (DiagDirection) - * bit 2..3 road type + * bit 2..7 road type * @param p2 unused * @param text unused * @return the cost of this operation or an error @@ -1015,9 +1165,9 @@ CommandCost CmdRemoveLongRoad(TileIndex start_tile, DoCommandFlag flags, uint32 CommandCost CmdBuildRoadDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { DiagDirection dir = Extract(p1); - RoadType rt = Extract(p1); - if (!IsValidRoadType(rt) || !ValParamRoadType(rt)) return CMD_ERROR; + RoadType rt = Extract(p1); + if (!ValParamRoadType(rt)) return CMD_ERROR; CommandCost cost(EXPENSES_CONSTRUCTION); @@ -1041,8 +1191,7 @@ CommandCost CmdBuildRoadDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, ui dep->build_date = _date; /* A road depot has two road bits. */ - Company::Get(_current_company)->infrastructure.road[rt] += 2; - DirtyCompanyInfrastructureWindows(_current_company); + UpdateCompanyRoadInfrastructure(rt, _current_company, 2); MakeRoadDepot(tile, _current_company, dep->index, dir, rt); MarkTileDirtyByTile(tile); @@ -1064,9 +1213,11 @@ static CommandCost RemoveRoadDepot(TileIndex tile, DoCommandFlag flags) if (flags & DC_EXEC) { Company *c = Company::GetIfValid(GetTileOwner(tile)); - if (c != NULL) { + if (c != nullptr) { /* A road depot has two road bits. */ - c->infrastructure.road[FIND_FIRST_BIT(GetRoadTypes(tile))] -= 2; + RoadType rt = GetRoadTypeRoad(tile); + if (rt == INVALID_ROADTYPE) rt = GetRoadTypeTram(tile); + c->infrastructure.road[rt] -= 2; DirtyCompanyInfrastructureWindows(c->index); } @@ -1084,11 +1235,12 @@ static CommandCost ClearTile_Road(TileIndex tile, DoCommandFlag flags) RoadBits b = GetAllRoadBits(tile); /* Clear the road if only one piece is on the tile OR we are not using the DC_AUTO flag */ - if ((HasExactlyOneBit(b) && GetRoadBits(tile, ROADTYPE_TRAM) == ROAD_NONE) || !(flags & DC_AUTO)) { + if ((HasExactlyOneBit(b) && GetRoadBits(tile, RTT_TRAM) == ROAD_NONE) || !(flags & DC_AUTO)) { CommandCost ret(EXPENSES_CONSTRUCTION); - RoadType rt; - FOR_EACH_SET_ROADTYPE(rt, GetRoadTypes(tile)) { - CommandCost tmp_ret = RemoveRoad(tile, flags, GetRoadBits(tile, rt), rt, true); + FOR_ALL_ROADTRAMTYPES(rtt) { + if (!MayHaveRoad(tile) || GetRoadType(tile, rtt) == INVALID_ROADTYPE) continue; + + CommandCost tmp_ret = RemoveRoad(tile, flags, GetRoadBits(tile, rtt), rtt, true); if (tmp_ret.Failed()) return tmp_ret; ret.AddCost(tmp_ret); } @@ -1098,21 +1250,19 @@ static CommandCost ClearTile_Road(TileIndex tile, DoCommandFlag flags) } case ROAD_TILE_CROSSING: { - RoadTypes rts = GetRoadTypes(tile); CommandCost ret(EXPENSES_CONSTRUCTION); if (flags & DC_AUTO) return_cmd_error(STR_ERROR_MUST_REMOVE_ROAD_FIRST); /* Must iterate over the roadtypes in a reverse manner because * tram tracks must be removed before the road bits. */ - RoadType rt = ROADTYPE_TRAM; - do { - if (HasBit(rts, rt)) { - CommandCost tmp_ret = RemoveRoad(tile, flags, GetCrossingRoadBits(tile), rt, false); - if (tmp_ret.Failed()) return tmp_ret; - ret.AddCost(tmp_ret); - } - } while (rt-- != ROADTYPE_ROAD); + for (RoadTramType rtt : { RTT_TRAM, RTT_ROAD }) { + if (!MayHaveRoad(tile) || GetRoadType(tile, rtt) == INVALID_ROADTYPE) continue; + + CommandCost tmp_ret = RemoveRoad(tile, flags, GetCrossingRoadBits(tile), rtt, false); + if (tmp_ret.Failed()) return tmp_ret; + ret.AddCost(tmp_ret); + } if (flags & DC_EXEC) { DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); @@ -1174,6 +1324,33 @@ const byte _road_sloped_sprites[14] = { 0, 0 }; +/** + * Get the sprite offset within a spritegroup. + * @param slope Slope + * @param bits Roadbits + * @return Offset for the sprite within the spritegroup. + */ +static uint GetRoadSpriteOffset(Slope slope, RoadBits bits) +{ + if (slope != SLOPE_FLAT) { + switch (slope) { + case SLOPE_NE: return 11; + case SLOPE_SE: return 12; + case SLOPE_SW: return 13; + case SLOPE_NW: return 14; + default: NOT_REACHED(); + } + } else { + static const uint offsets[] = { + 0, 18, 17, 7, + 16, 0, 10, 5, + 15, 8, 1, 4, + 9, 3, 6, 2 + }; + return offsets[bits]; + } +} + /** * Should the road be drawn as a unpaved snow/desert road? * By default, roads are always drawn as unpaved if they are on desert or @@ -1191,15 +1368,13 @@ static bool DrawRoadAsSnowDesert(TileIndex tile, Roadside roadside) } /** - * Draws the catenary for the given tile - * @param ti information about the tile (slopes, height etc) - * @param tram the roadbits for the tram + * Draws the catenary for the RoadType of the given tile + * @param ti information about the tile (slopes, height etc) + * @param rt road type to draw catenary for + * @param rb the roadbits for the tram */ -void DrawRoadCatenary(const TileInfo *ti, RoadBits tram) +void DrawRoadTypeCatenary(const TileInfo *ti, RoadType rt, RoadBits rb) { - /* Do not draw catenary if it is invisible */ - if (IsInvisibilitySet(TO_CATENARY)) return; - /* Don't draw the catenary under a low bridge */ if (IsBridgeAbove(ti->tile) && !IsTransparencySet(TO_CATENARY)) { int height = GetBridgeHeight(GetNorthernBridgeEnd(ti->tile)); @@ -1207,19 +1382,89 @@ void DrawRoadCatenary(const TileInfo *ti, RoadBits tram) if (height <= GetTileMaxZ(ti->tile) + 1) return; } - SpriteID front; - SpriteID back; + if (CountBits(rb) > 2) { + /* On junctions we check whether neighbouring tiles also have catenary, and possibly + * do not draw catenary towards those neighbours, which do not have catenary. */ + RoadBits rb_new = ROAD_NONE; + for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) { + if (rb & DiagDirToRoadBits(dir)) { + TileIndex neighbour = TileAddByDiagDir(ti->tile, dir); + if (MayHaveRoad(neighbour)) { + RoadType rt_road = GetRoadTypeRoad(neighbour); + RoadType rt_tram = GetRoadTypeTram(neighbour); - if (ti->tileh != SLOPE_FLAT) { + if ((rt_road != INVALID_ROADTYPE && HasRoadCatenary(rt_road)) || + (rt_tram != INVALID_ROADTYPE && HasRoadCatenary(rt_tram))) { + rb_new |= DiagDirToRoadBits(dir); + } + } + } + } + if (CountBits(rb_new) >= 2) rb = rb_new; + } + + const RoadTypeInfo* rti = GetRoadTypeInfo(rt); + SpriteID front = GetCustomRoadSprite(rti, ti->tile, ROTSG_CATENARY_FRONT); + SpriteID back = GetCustomRoadSprite(rti, ti->tile, ROTSG_CATENARY_BACK); + + if (front != 0 || back != 0) { + if (front != 0) front += GetRoadSpriteOffset(ti->tileh, rb); + if (back != 0) back += GetRoadSpriteOffset(ti->tileh, rb); + } else if (ti->tileh != SLOPE_FLAT) { back = SPR_TRAMWAY_BACK_WIRES_SLOPED + _road_sloped_sprites[ti->tileh - 1]; front = SPR_TRAMWAY_FRONT_WIRES_SLOPED + _road_sloped_sprites[ti->tileh - 1]; } else { - back = SPR_TRAMWAY_BASE + _road_backpole_sprites_1[tram]; - front = SPR_TRAMWAY_BASE + _road_frontwire_sprites_1[tram]; + back = SPR_TRAMWAY_BASE + _road_backpole_sprites_1[rb]; + front = SPR_TRAMWAY_BASE + _road_frontwire_sprites_1[rb]; } - AddSortableSpriteToDraw(back, PAL_NONE, ti->x, ti->y, 16, 16, TILE_HEIGHT + BB_HEIGHT_UNDER_BRIDGE, ti->z, IsTransparencySet(TO_CATENARY)); - AddSortableSpriteToDraw(front, PAL_NONE, ti->x, ti->y, 16, 16, TILE_HEIGHT + BB_HEIGHT_UNDER_BRIDGE, ti->z, IsTransparencySet(TO_CATENARY)); + /* Catenary uses 1st company colour to help identify owner. + * For tiles with OWNER_TOWN or OWNER_NONE, recolour CC to grey as a neutral colour. */ + Owner owner = GetRoadOwner(ti->tile, GetRoadTramType(rt)); + PaletteID pal = (owner == OWNER_NONE || owner == OWNER_TOWN ? GENERAL_SPRITE_COLOUR(COLOUR_GREY) : COMPANY_SPRITE_COLOUR(owner)); + if (back != 0) AddSortableSpriteToDraw(back, pal, ti->x, ti->y, 16, 16, TILE_HEIGHT + BB_HEIGHT_UNDER_BRIDGE, ti->z, IsTransparencySet(TO_CATENARY)); + if (front != 0) AddSortableSpriteToDraw(front, pal, ti->x, ti->y, 16, 16, TILE_HEIGHT + BB_HEIGHT_UNDER_BRIDGE, ti->z, IsTransparencySet(TO_CATENARY)); +} + +/** + * Draws the catenary for the given tile + * @param ti information about the tile (slopes, height etc) + */ +void DrawRoadCatenary(const TileInfo *ti) +{ + RoadBits road = ROAD_NONE; + RoadBits tram = ROAD_NONE; + + if (IsTileType(ti->tile, MP_ROAD)) { + if (IsNormalRoad(ti->tile)) { + road = GetRoadBits(ti->tile, RTT_ROAD); + tram = GetRoadBits(ti->tile, RTT_TRAM); + } else if (IsLevelCrossing(ti->tile)) { + tram = road = (GetCrossingRailAxis(ti->tile) == AXIS_Y ? ROAD_X : ROAD_Y); + } + } else if (IsTileType(ti->tile, MP_STATION)) { + if (IsRoadStop(ti->tile)) { + if (IsDriveThroughStopTile(ti->tile)) { + Axis axis = GetRoadStopDir(ti->tile) == DIAGDIR_NE ? AXIS_X : AXIS_Y; + tram = road = (axis == AXIS_X ? ROAD_X : ROAD_Y); + } else { + tram = road = DiagDirToRoadBits(GetRoadStopDir(ti->tile)); + } + } + } else { + // No road here, no catenary to draw + return; + } + + RoadType rt = GetRoadTypeRoad(ti->tile); + if (rt != INVALID_ROADTYPE && HasRoadCatenaryDrawn(rt)) { + DrawRoadTypeCatenary(ti, rt, road); + } + + rt = GetRoadTypeTram(ti->tile); + if (rt != INVALID_ROADTYPE && HasRoadCatenaryDrawn(rt)) { + DrawRoadTypeCatenary(ti, rt, tram); + } } /** @@ -1240,56 +1485,124 @@ static void DrawRoadDetail(SpriteID img, const TileInfo *ti, int dx, int dy, int } /** - * Draw ground sprite and road pieces + * Draw road underlay and overlay sprites. * @param ti TileInfo + * @param road_rti Road road type information + * @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) */ -static void DrawRoadBits(TileInfo *ti) +void DrawRoadOverlays(const TileInfo *ti, PaletteID pal, const RoadTypeInfo *road_rti, const RoadTypeInfo *tram_rti, uint road_offset, uint tram_offset) { - RoadBits road = GetRoadBits(ti->tile, ROADTYPE_ROAD); - RoadBits tram = GetRoadBits(ti->tile, ROADTYPE_TRAM); - - SpriteID image = 0; - PaletteID pal = PAL_NONE; - - if (ti->tileh != SLOPE_FLAT) { - DrawFoundation(ti, GetRoadFoundation(ti->tileh, road | tram)); - - /* DrawFoundation() modifies ti. - * Default sloped sprites.. */ - if (ti->tileh != SLOPE_FLAT) image = _road_sloped_sprites[ti->tileh - 1] + SPR_ROAD_SLOPE_START; + /* 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); + } else { + DrawGroundSprite(SPR_TRAMWAY_TRAM + tram_offset, pal); + } } - if (image == 0) image = _road_tile_sprites_1[road != ROAD_NONE ? road : tram]; + /* Draw road overlay */ + if (road_rti != nullptr) { + if (road_rti->UsesOverlay()) { + SpriteID ground = GetCustomRoadSprite(road_rti, ti->tile, ROTSG_OVERLAY); + if (ground != 0) DrawGroundSprite(ground + road_offset, pal); + } + } - Roadside roadside = GetRoadside(ti->tile); + /* Draw tram overlay */ + if (tram_rti != nullptr) { + if (tram_rti->UsesOverlay()) { + SpriteID ground = GetCustomRoadSprite(tram_rti, ti->tile, ROTSG_OVERLAY); + if (ground != 0) DrawGroundSprite(ground + tram_offset, pal); + } else if (road_rti != nullptr) { + DrawGroundSprite(SPR_TRAMWAY_OVERLAY + tram_offset, pal); + } + } +} +/** + * Get ground sprite to draw for a road tile. + * @param ti TileInof + * @param roadside Road side type + * @param rti Road type info + * @param offset Road sprite offset + * @param[out] pal Palette to draw. + */ +static SpriteID GetRoadGroundSprite(const TileInfo *ti, Roadside roadside, const RoadTypeInfo *rti, uint offset, PaletteID *pal) +{ + /* Draw bare ground sprite if no road or road uses overlay system. */ + if (rti == nullptr || rti->UsesOverlay()) { + if (DrawRoadAsSnowDesert(ti->tile, roadside)) { + return SPR_FLAT_SNOW_DESERT_TILE + SlopeToSpriteOffset(ti->tileh); + } + + switch (roadside) { + case ROADSIDE_BARREN: *pal = PALETTE_TO_BARE_LAND; + return SPR_FLAT_GRASS_TILE + SlopeToSpriteOffset(ti->tileh); + case ROADSIDE_GRASS: + case ROADSIDE_GRASS_ROAD_WORKS: return SPR_FLAT_GRASS_TILE + SlopeToSpriteOffset(ti->tileh); + default: break; // Paved + } + } + + /* Draw original road base sprite */ + SpriteID image = SPR_ROAD_Y + offset; if (DrawRoadAsSnowDesert(ti->tile, roadside)) { image += 19; } else { switch (roadside) { - case ROADSIDE_BARREN: pal = PALETTE_TO_BARE_LAND; break; + case ROADSIDE_BARREN: *pal = PALETTE_TO_BARE_LAND; break; case ROADSIDE_GRASS: break; case ROADSIDE_GRASS_ROAD_WORKS: break; default: image -= 19; break; // Paved } } - DrawGroundSprite(image, pal); + return image; +} - /* For tram we overlay the road graphics with either tram tracks only - * (when there is actual road beneath the trams) or with tram tracks - * and some dirts which hides the road graphics */ - if (tram != ROAD_NONE) { - if (ti->tileh != SLOPE_FLAT) { - image = _road_sloped_sprites[ti->tileh - 1] + SPR_TRAMWAY_SLOPED_OFFSET; - } else { - image = _road_tile_sprites_1[tram] - SPR_ROAD_Y; - } - image += (road == ROAD_NONE) ? SPR_TRAMWAY_TRAM : SPR_TRAMWAY_OVERLAY; - DrawGroundSprite(image, pal); +/** + * Draw ground sprite and road pieces + * @param ti TileInfo + */ +static void DrawRoadBits(TileInfo *ti) +{ + RoadBits road = GetRoadBits(ti->tile, RTT_ROAD); + RoadBits tram = GetRoadBits(ti->tile, RTT_TRAM); + + RoadType road_rt = GetRoadTypeRoad(ti->tile); + RoadType tram_rt = GetRoadTypeTram(ti->tile); + const RoadTypeInfo *road_rti = road_rt == INVALID_ROADTYPE ? nullptr : GetRoadTypeInfo(road_rt); + const RoadTypeInfo *tram_rti = tram_rt == INVALID_ROADTYPE ? nullptr : GetRoadTypeInfo(tram_rt); + + if (ti->tileh != SLOPE_FLAT) { + DrawFoundation(ti, GetRoadFoundation(ti->tileh, road | tram)); + /* DrawFoundation() modifies ti. */ } - if (road != ROAD_NONE) { + /* Determine sprite offsets */ + uint road_offset = GetRoadSpriteOffset(ti->tileh, road); + uint tram_offset = GetRoadSpriteOffset(ti->tileh, tram); + + /* Draw baseset underlay */ + Roadside roadside = GetRoadside(ti->tile); + + PaletteID pal = PAL_NONE; + SpriteID image = GetRoadGroundSprite(ti, roadside, road_rti, road == ROAD_NONE ? tram_offset : road_offset, &pal); + DrawGroundSprite(image, pal); + + DrawRoadOverlays(ti, pal, road_rti, tram_rti, road_offset, tram_offset); + + /* Draw one way */ + 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)); @@ -1302,7 +1615,8 @@ static void DrawRoadBits(TileInfo *ti) return; } - if (tram != ROAD_NONE) DrawRoadCatenary(ti, tram); + /* Draw road, tram catenary */ + DrawRoadCatenary(ti); /* Return if full detail is disabled, or we are zoomed fully out. */ if (!HasBit(_display_opt, DO_FULL_DETAIL) || _cur_dpi->zoom > ZOOM_LVL_DETAIL) return; @@ -1337,41 +1651,38 @@ static void DrawTile_Road(TileInfo *ti) case ROAD_TILE_CROSSING: { if (ti->tileh != SLOPE_FLAT) DrawFoundation(ti, FOUNDATION_LEVELED); - PaletteID pal = PAL_NONE; + Axis axis = GetCrossingRailAxis(ti->tile); + const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile)); + RoadType road_rt = GetRoadTypeRoad(ti->tile); + RoadType tram_rt = GetRoadTypeTram(ti->tile); + const RoadTypeInfo *road_rti = road_rt == INVALID_ROADTYPE ? nullptr : GetRoadTypeInfo(road_rt); + const RoadTypeInfo *tram_rti = tram_rt == INVALID_ROADTYPE ? nullptr : GetRoadTypeInfo(tram_rt); + + PaletteID pal = PAL_NONE; + + /* Draw base ground */ if (rti->UsesOverlay()) { - Axis axis = GetCrossingRailAxis(ti->tile); - SpriteID road = SPR_ROAD_Y + axis; + SpriteID image = SPR_ROAD_Y + axis; Roadside roadside = GetRoadside(ti->tile); - if (DrawRoadAsSnowDesert(ti->tile, roadside)) { - road += 19; + image += 19; } else { switch (roadside) { case ROADSIDE_BARREN: pal = PALETTE_TO_BARE_LAND; break; case ROADSIDE_GRASS: break; - default: road -= 19; break; // Paved + default: image -= 19; break; // Paved } } - DrawGroundSprite(road, pal); - - SpriteID rail = GetCustomRailSprite(rti, ti->tile, RTSG_CROSSING) + axis; - /* Draw tracks, but draw PBS reserved tracks darker. */ - pal = (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation && HasCrossingReservation(ti->tile)) ? PALETTE_CRASH : PAL_NONE; - DrawGroundSprite(rail, pal); - - DrawRailTileSeq(ti, &_crossing_layout, TO_CATENARY, rail, 0, PAL_NONE); + DrawGroundSprite(image, pal); } else { - SpriteID image = rti->base_sprites.crossing; - - if (GetCrossingRoadAxis(ti->tile) == AXIS_X) image++; + SpriteID image = rti->base_sprites.crossing + axis; if (IsCrossingBarred(ti->tile)) image += 2; Roadside roadside = GetRoadside(ti->tile); - if (DrawRoadAsSnowDesert(ti->tile, roadside)) { image += 8; } else { @@ -1383,18 +1694,31 @@ static void DrawTile_Road(TileInfo *ti) } DrawGroundSprite(image, pal); - - /* PBS debugging, draw reserved tracks darker */ - if (_game_mode != GM_MENU && _settings_client.gui.show_track_reservation && HasCrossingReservation(ti->tile)) { - DrawGroundSprite(GetCrossingRoadAxis(ti->tile) == AXIS_Y ? GetRailTypeInfo(GetRailType(ti->tile))->base_sprites.single_x : GetRailTypeInfo(GetRailType(ti->tile))->base_sprites.single_y, PALETTE_CRASH); - } } - if (HasTileRoadType(ti->tile, ROADTYPE_TRAM)) { - DrawGroundSprite(SPR_TRAMWAY_OVERLAY + (GetCrossingRoadAxis(ti->tile) ^ 1), pal); - DrawRoadCatenary(ti, GetCrossingRoadBits(ti->tile)); + DrawRoadOverlays(ti, pal, road_rti, tram_rti, axis, axis); + + /* 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; + SpriteID rail = GetCustomRailSprite(rti, ti->tile, RTSG_CROSSING) + axis; + DrawGroundSprite(rail, pal); + + DrawRailTileSeq(ti, &_crossing_layout, TO_CATENARY, rail, 0, PAL_NONE); + } 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; + 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); } + + /* Draw road, tram catenary */ + DrawRoadCatenary(ti); + + /* Draw rail catenary */ if (HasRailCatenaryDrawn(GetRailType(ti->tile))) DrawRailCatenary(ti); + break; } @@ -1404,15 +1728,42 @@ static void DrawTile_Road(TileInfo *ti) PaletteID palette = COMPANY_SPRITE_COLOUR(GetTileOwner(ti->tile)); - const DrawTileSprites *dts; - if (HasTileRoadType(ti->tile, ROADTYPE_TRAM)) { - dts = &_tram_depot[GetRoadDepotDirection(ti->tile)]; + RoadType road_rt = GetRoadTypeRoad(ti->tile); + RoadType tram_rt = GetRoadTypeTram(ti->tile); + const RoadTypeInfo *rti = GetRoadTypeInfo(road_rt == INVALID_ROADTYPE ? tram_rt : road_rt); + + int relocation = GetCustomRoadSprite(rti, ti->tile, ROTSG_DEPOT); + bool default_gfx = relocation == 0; + if (default_gfx) { + if (HasBit(rti->flags, ROTF_CATENARY)) { + if (_loaded_newgrf_features.tram == TRAMWAY_REPLACE_DEPOT_WITH_TRACK && road_rt == INVALID_ROADTYPE && !rti->UsesOverlay()) { + /* Sprites with track only work for default tram */ + relocation = SPR_TRAMWAY_DEPOT_WITH_TRACK - SPR_ROAD_DEPOT; + default_gfx = false; + } else { + /* Sprites without track are always better, if provided */ + relocation = SPR_TRAMWAY_DEPOT_NO_TRACK - SPR_ROAD_DEPOT; + } + } } else { - dts = &_road_depot[GetRoadDepotDirection(ti->tile)]; + relocation -= SPR_ROAD_DEPOT; } + DiagDirection dir = GetRoadDepotDirection(ti->tile); + const DrawTileSprites *dts = &_road_depot[dir]; DrawGroundSprite(dts->ground.sprite, PAL_NONE); - DrawOrigTileSeq(ti, dts, TO_BUILDINGS, palette); + + if (default_gfx) { + uint offset = GetRoadSpriteOffset(SLOPE_FLAT, DiagDirToRoadBits(dir)); + if (rti->UsesOverlay()) { + SpriteID ground = GetCustomRoadSprite(rti, ti->tile, ROTSG_OVERLAY); + if (ground != 0) DrawGroundSprite(ground + offset, PAL_NONE); + } else if (road_rt == INVALID_ROADTYPE) { + DrawGroundSprite(SPR_TRAMWAY_OVERLAY + offset, PAL_NONE); + } + } + + DrawRailTileSeq(ti, dts, TO_BUILDINGS, relocation, 0, palette); break; } } @@ -1429,10 +1780,39 @@ static void DrawTile_Road(TileInfo *ti) void DrawRoadDepotSprite(int x, int y, DiagDirection dir, RoadType rt) { PaletteID palette = COMPANY_SPRITE_COLOUR(_local_company); - const DrawTileSprites *dts = (rt == ROADTYPE_TRAM) ? &_tram_depot[dir] : &_road_depot[dir]; + const RoadTypeInfo* rti = GetRoadTypeInfo(rt); + int relocation = GetCustomRoadSprite(rti, INVALID_TILE, ROTSG_DEPOT); + bool default_gfx = relocation == 0; + if (default_gfx) { + if (HasBit(rti->flags, ROTF_CATENARY)) { + if (_loaded_newgrf_features.tram == TRAMWAY_REPLACE_DEPOT_WITH_TRACK && RoadTypeIsTram(rt) && !rti->UsesOverlay()) { + /* Sprites with track only work for default tram */ + relocation = SPR_TRAMWAY_DEPOT_WITH_TRACK - SPR_ROAD_DEPOT; + default_gfx = false; + } else { + /* Sprites without track are always better, if provided */ + relocation = SPR_TRAMWAY_DEPOT_NO_TRACK - SPR_ROAD_DEPOT; + } + } + } else { + relocation -= SPR_ROAD_DEPOT; + } + + const DrawTileSprites *dts = &_road_depot[dir]; DrawSprite(dts->ground.sprite, PAL_NONE, x, y); - DrawOrigTileSeqInGUI(x, y, dts, palette); + + if (default_gfx) { + uint offset = GetRoadSpriteOffset(SLOPE_FLAT, DiagDirToRoadBits(dir)); + if (rti->UsesOverlay()) { + SpriteID ground = GetCustomRoadSprite(rti, INVALID_TILE, ROTSG_OVERLAY); + if (ground != 0) DrawSprite(ground + offset, PAL_NONE, x, y); + } else if (RoadTypeIsTram(rt)) { + DrawSprite(SPR_TRAMWAY_OVERLAY + offset, PAL_NONE, x, y); + } + } + + DrawRailTileSeqInGUI(x, y, dts, relocation, 0, palette); } /** @@ -1449,7 +1829,7 @@ void UpdateNearestTownForRoadTiles(bool invalidate) TownID tid = INVALID_TOWN; if (!invalidate) { const Town *town = CalcClosestTownFromTile(t); - if (town != NULL) tid = town->index; + if (town != nullptr) tid = town->index; } SetTownIndex(t, tid); } @@ -1522,7 +1902,7 @@ static void TileLoop_Road(TileIndex tile) if (!HasRoadWorks(tile)) { HouseZonesBits grp = HZB_TOWN_EDGE; - if (t != NULL) { + if (t != nullptr) { grp = GetTownRadiusGroup(t, tile); /* Show an animation to indicate road work */ @@ -1570,11 +1950,25 @@ static void TileLoop_Road(TileIndex tile) if (_settings_game.economy.mod_road_rebuild) { /* Generate a nicer town surface */ - const RoadBits old_rb = GetAnyRoadBits(tile, ROADTYPE_ROAD); + const RoadBits old_rb = GetAnyRoadBits(tile, RTT_ROAD); const RoadBits new_rb = CleanUpRoadBits(tile, old_rb); if (old_rb != new_rb) { - RemoveRoad(tile, DC_EXEC | DC_AUTO | DC_NO_WATER, (old_rb ^ new_rb), ROADTYPE_ROAD, true); + RemoveRoad(tile, DC_EXEC | DC_AUTO | DC_NO_WATER, (old_rb ^ new_rb), RTT_ROAD, true); + + /* If new_rb is 0, there are now no road pieces left and the tile is no longer a road tile */ + if (new_rb == 0) { + MarkTileDirtyByTile(tile); + return; + } + } + } + + /* Possibly change road type */ + if (GetRoadOwner(tile, RTT_ROAD) == OWNER_TOWN) { + RoadType rt = GetTownRoadType(t); + if (rt != GetRoadTypeRoad(tile)) { + SetRoadType(tile, RTT_ROAD, rt); } } @@ -1619,18 +2013,18 @@ static TrackStatus GetTileTrackStatus_Road(TileIndex tile, TransportType mode, u if (IsLevelCrossing(tile)) trackdirbits = TrackBitsToTrackdirBits(GetCrossingRailBits(tile)); break; - case TRANSPORT_ROAD: - if ((GetRoadTypes(tile) & sub_mode) == 0) break; + case TRANSPORT_ROAD: { + RoadTramType rtt = (RoadTramType)sub_mode; + if (!HasTileRoadType(tile, rtt)) break; switch (GetRoadTileType(tile)) { case ROAD_TILE_NORMAL: { const uint drd_to_multiplier[DRD_END] = { 0x101, 0x100, 0x1, 0x0 }; - RoadType rt = (RoadType)FindFirstBit(sub_mode); - RoadBits bits = GetRoadBits(tile, rt); + RoadBits bits = GetRoadBits(tile, rtt); /* no roadbit at this side of tile, return 0 */ if (side != INVALID_DIAGDIR && (DiagDirToRoadBits(side) & bits) == 0) break; - uint multiplier = drd_to_multiplier[rt == ROADTYPE_TRAM ? DRD_NONE : GetDisallowedRoadDirections(tile)]; + uint multiplier = drd_to_multiplier[(rtt == RTT_TRAM) ? DRD_NONE : GetDisallowedRoadDirections(tile)]; if (!HasRoadWorks(tile)) trackdirbits = (TrackdirBits)(_road_trackbits[bits] * multiplier); break; } @@ -1656,6 +2050,7 @@ static TrackStatus GetTileTrackStatus_Road(TileIndex tile, TransportType mode, u } } break; + } default: break; } @@ -1679,13 +2074,25 @@ static void GetTileDesc_Road(TileIndex tile, TileDesc *td) Owner road_owner = INVALID_OWNER; Owner tram_owner = INVALID_OWNER; + RoadType road_rt = GetRoadTypeRoad(tile); + RoadType tram_rt = GetRoadTypeTram(tile); + 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); + } + switch (GetRoadTileType(tile)) { case ROAD_TILE_CROSSING: { td->str = STR_LAI_ROAD_DESCRIPTION_ROAD_RAIL_LEVEL_CROSSING; - RoadTypes rts = GetRoadTypes(tile); rail_owner = GetTileOwner(tile); - if (HasBit(rts, ROADTYPE_ROAD)) road_owner = GetRoadOwner(tile, ROADTYPE_ROAD); - if (HasBit(rts, ROADTYPE_TRAM)) tram_owner = GetRoadOwner(tile, ROADTYPE_TRAM); const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(tile)); td->railtype = rti->strings.name; @@ -1696,15 +2103,11 @@ static void GetTileDesc_Road(TileIndex tile, TileDesc *td) case ROAD_TILE_DEPOT: td->str = STR_LAI_ROAD_DESCRIPTION_ROAD_VEHICLE_DEPOT; - road_owner = GetTileOwner(tile); // Tile has only one owner, roadtype does not matter td->build_date = Depot::GetByTile(tile)->build_date; break; default: { - RoadTypes rts = GetRoadTypes(tile); - td->str = (HasBit(rts, ROADTYPE_ROAD) ? _road_tile_strings[GetRoadside(tile)] : STR_LAI_ROAD_DESCRIPTION_TRAMWAY); - if (HasBit(rts, ROADTYPE_ROAD)) road_owner = GetRoadOwner(tile, ROADTYPE_ROAD); - if (HasBit(rts, ROADTYPE_TRAM)) tram_owner = GetRoadOwner(tile, ROADTYPE_TRAM); + td->str = (road_rt != INVALID_ROADTYPE ? _road_tile_strings[GetRoadside(tile)] : STR_LAI_ROAD_DESCRIPTION_TRAMWAY); break; } } @@ -1751,7 +2154,7 @@ static VehicleEnterTileStatus VehicleEnter_Road(Vehicle *v, TileIndex tile, int rv->state = RVSB_IN_DEPOT; rv->vehstatus |= VS_HIDDEN; rv->direction = ReverseDir(rv->direction); - if (rv->Next() == NULL) VehicleEnterDepot(rv->First()); + if (rv->Next() == nullptr) VehicleEnterDepot(rv->First()); rv->tile = tile; InvalidateWindowData(WC_VEHICLE_DEPOT, rv->tile); @@ -1774,14 +2177,15 @@ static void ChangeTileOwner_Road(TileIndex tile, Owner old_owner, Owner new_owne DoCommand(tile, 0, 0, DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR); } else { /* A road depot has two road bits. No need to dirty windows here, we'll redraw the whole screen anyway. */ - RoadType rt = (RoadType)FIND_FIRST_BIT(GetRoadTypes(tile)); + RoadType rt = GetRoadTypeRoad(tile); + if (rt == INVALID_ROADTYPE) rt = GetRoadTypeTram(tile); Company::Get(old_owner)->infrastructure.road[rt] -= 2; Company::Get(new_owner)->infrastructure.road[rt] += 2; SetTileOwner(tile, new_owner); - for (RoadType rt = ROADTYPE_ROAD; rt < ROADTYPE_END; rt++) { - if (GetRoadOwner(tile, rt) == old_owner) { - SetRoadOwner(tile, rt, new_owner); + FOR_ALL_ROADTRAMTYPES(rtt) { + if (GetRoadOwner(tile, rtt) == old_owner) { + SetRoadOwner(tile, rtt, new_owner); } } } @@ -1789,17 +2193,18 @@ static void ChangeTileOwner_Road(TileIndex tile, Owner old_owner, Owner new_owne return; } - for (RoadType rt = ROADTYPE_ROAD; rt < ROADTYPE_END; rt++) { + FOR_ALL_ROADTRAMTYPES(rtt) { /* Update all roadtypes, no matter if they are present */ - if (GetRoadOwner(tile, rt) == old_owner) { - if (HasTileRoadType(tile, rt)) { + if (GetRoadOwner(tile, rtt) == old_owner) { + RoadType rt = GetRoadType(tile, rtt); + if (rt != INVALID_ROADTYPE) { /* A level crossing has two road bits. No need to dirty windows here, we'll redraw the whole screen anyway. */ - uint num_bits = IsLevelCrossing(tile) ? 2 : CountBits(GetRoadBits(tile, rt)); + uint num_bits = IsLevelCrossing(tile) ? 2 : CountBits(GetRoadBits(tile, rtt)); Company::Get(old_owner)->infrastructure.road[rt] -= num_bits; if (new_owner != INVALID_OWNER) Company::Get(new_owner)->infrastructure.road[rt] += num_bits; } - SetRoadOwner(tile, rt, new_owner == INVALID_OWNER ? OWNER_NONE : new_owner); + SetRoadOwner(tile, rtt, new_owner == INVALID_OWNER ? OWNER_NONE : new_owner); } } @@ -1858,19 +2263,244 @@ static CommandCost TerraformTile_Road(TileIndex tile, DoCommandFlag flags, int z return DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); } +/** Update power of road vehicle under which is the roadtype being converted */ +static Vehicle *UpdateRoadVehPowerProc(Vehicle *v, void *data) +{ + if (v->type != VEH_ROAD) return nullptr; + + RoadVehicleList *affected_rvs = static_cast(data); + include(*affected_rvs, RoadVehicle::From(v)->First()); + + return nullptr; +} + +/** + * Checks the tile and returns whether the current player is allowed to convert the roadtype to another roadtype without taking ownership + * @param owner the tile owner. + * @param rtt Road/tram type. + * @return whether the road is convertible + */ +static bool CanConvertUnownedRoadType(Owner owner, RoadTramType rtt) +{ + return (owner == OWNER_NONE || (owner == OWNER_TOWN && rtt == RTT_ROAD)); +} + +/** + * Convert the ownership of the RoadType of the tile if applyable + * @param tile the tile of which convert ownership + * @param num_pieces the count of the roadbits to assign to the new owner + * @param owner the current owner of the RoadType + * @param from_type the old road type + * @param to_type the new road type + */ +static void ConvertRoadTypeOwner(TileIndex tile, uint num_pieces, Owner owner, RoadType from_type, RoadType to_type) +{ + // Scenario editor, maybe? Don't touch the owners when converting roadtypes... + if (_current_company >= MAX_COMPANIES) return; + + // We can't get a company from invalid owners but we can get ownership of roads without an owner + if (owner >= MAX_COMPANIES && owner != OWNER_NONE) return; + + Company *c; + + switch (owner) { + case OWNER_NONE: + SetRoadOwner(tile, GetRoadTramType(to_type), (Owner)_current_company); + UpdateCompanyRoadInfrastructure(to_type, _current_company, num_pieces); + break; + + default: + c = Company::Get(owner); + c->infrastructure.road[from_type] -= num_pieces; + c->infrastructure.road[to_type] += num_pieces; + DirtyCompanyInfrastructureWindows(c->index); + break; + } +} + +/** + * Convert one road subtype to another. + * Not meant to convert from road to tram. + * + * @param tile end tile of road conversion drag + * @param flags operation to perform + * @param p1 start tile of drag + * @param p2 various bitstuffed elements: + * - p2 = (bit 0..5) new roadtype to convert to. + * @param text unused + * @return the cost of this operation or an error + */ +CommandCost CmdConvertRoad(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) +{ + RoadType to_type = Extract(p2); + + TileIndex area_start = p1; + TileIndex area_end = tile; + + if (!ValParamRoadType(to_type)) return CMD_ERROR; + if (area_start >= MapSize()) return CMD_ERROR; + + RoadVehicleList affected_rvs; + RoadTramType rtt = GetRoadTramType(to_type); + + CommandCost cost(EXPENSES_CONSTRUCTION); + 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); + for (; (tile = *iter) != INVALID_TILE; ++(*iter)) { + /* Is road present on tile? */ + if (!MayHaveRoad(tile)) continue; + + /* Converting to the same subtype? */ + RoadType from_type = GetRoadType(tile, rtt); + if (from_type == INVALID_ROADTYPE || from_type == to_type) continue; + + /* Check if there is any infrastructure on tile */ + TileType tt = GetTileType(tile); + switch (tt) { + case MP_STATION: + if (!IsRoadStop(tile)) continue; + break; + case MP_ROAD: + if (IsLevelCrossing(tile) && RoadNoLevelCrossing(to_type)) { + error.MakeError(STR_ERROR_CROSSING_DISALLOWED_ROAD); + continue; + } + break; + case MP_TUNNELBRIDGE: + if (GetTunnelBridgeTransportType(tile) != TRANSPORT_ROAD) continue; + break; + default: continue; + } + + /* Trying to convert other's road */ + Owner owner = GetRoadOwner(tile, rtt); + if (!CanConvertUnownedRoadType(owner, rtt)) { + CommandCost ret = CheckOwnership(owner, tile); + if (ret.Failed()) { + error = ret; + continue; + } + } + + /* Vehicle on the tile when not converting normal <-> powered + * Tunnels and bridges have special check later */ + if (tt != MP_TUNNELBRIDGE) { + if (!HasPowerOnRoad(from_type, to_type)) { + CommandCost ret = EnsureNoVehicleOnGround(tile); + if (ret.Failed()) { + error = ret; + continue; + } + + if (rtt == RTT_ROAD && owner == OWNER_TOWN) { + error.MakeError(STR_ERROR_INCOMPATIBLE_ROAD); + continue; + } + } + + uint num_pieces = CountBits(GetAnyRoadBits(tile, rtt));; + found_convertible_road = true; + cost.AddCost(num_pieces * RoadConvertCost(from_type, to_type)); + + if (flags & DC_EXEC) { // we can safely convert, too + /* Update the company infrastructure counters. */ + if (!IsRoadStopTile(tile) && owner == _current_company) { + ConvertRoadTypeOwner(tile, num_pieces, owner, from_type, to_type); + } + + /* Perform the conversion */ + SetRoadType(tile, rtt, to_type); + MarkTileDirtyByTile(tile); + + /* update power of train on this tile */ + FindVehicleOnPos(tile, &affected_rvs, &UpdateRoadVehPowerProc); + + if (IsRoadDepotTile(tile)) { + /* Update build vehicle window related to this depot */ + InvalidateWindowData(WC_VEHICLE_DEPOT, tile); + InvalidateWindowData(WC_BUILD_VEHICLE, tile); + } + } + } else { + TileIndex endtile = GetOtherTunnelBridgeEnd(tile); + + /* If both ends of tunnel/bridge are in the range, do not try to convert twice - + * it would cause assert because of different test and exec runs */ + if (endtile < tile) { + if (OrthogonalTileArea(area_start, area_end).Contains(endtile)) continue; + } + + /* When not converting rail <-> el. rail, any vehicle cannot be in tunnel/bridge */ + if (!HasPowerOnRoad(from_type, to_type)) { + CommandCost ret = TunnelBridgeIsFree(tile, endtile); + if (ret.Failed()) { + error = ret; + continue; + } + + if (rtt == RTT_ROAD && owner == OWNER_TOWN) { + error.MakeError(STR_ERROR_INCOMPATIBLE_ROAD); + continue; + } + } + + /* There are 2 pieces on *every* tile of the bridge or tunnel */ + uint num_pieces = (GetTunnelBridgeLength(tile, endtile) + 2) * 2; + found_convertible_road = true; + cost.AddCost(num_pieces * RoadConvertCost(from_type, to_type)); + + if (flags & DC_EXEC) { + /* Update the company infrastructure counters. */ + if (owner == _current_company) { + ConvertRoadTypeOwner(tile, num_pieces, owner, from_type, to_type); + ConvertRoadTypeOwner(endtile, num_pieces, owner, from_type, to_type); + SetTunnelBridgeOwner(tile, endtile, _current_company); + } + + /* Perform the conversion */ + SetRoadType(tile, rtt, to_type); + SetRoadType(endtile, rtt, to_type); + + FindVehicleOnPos(tile, &affected_rvs, &UpdateRoadVehPowerProc); + FindVehicleOnPos(endtile, &affected_rvs, &UpdateRoadVehPowerProc); + + if (IsBridge(tile)) { + MarkBridgeDirty(tile); + } else { + MarkTileDirtyByTile(tile); + MarkTileDirtyByTile(endtile); + } + } + } + } + + if (flags & DC_EXEC) { + /* Roadtype changed, update roadvehicles as when entering different track */ + for (RoadVehicle *v : affected_rvs) { + v->CargoChanged(); + } + } + + delete iter; + return found_convertible_road ? cost : error; +} + + /** Tile callback functions for road tiles */ extern const TileTypeProcs _tile_type_road_procs = { DrawTile_Road, // draw_tile_proc GetSlopePixelZ_Road, // get_slope_z_proc ClearTile_Road, // clear_tile_proc - NULL, // add_accepted_cargo_proc + nullptr, // add_accepted_cargo_proc GetTileDesc_Road, // get_tile_desc_proc GetTileTrackStatus_Road, // get_tile_track_status_proc ClickTile_Road, // click_tile_proc - NULL, // animate_tile_proc + nullptr, // animate_tile_proc TileLoop_Road, // tile_loop_proc ChangeTileOwner_Road, // change_tile_owner_proc - NULL, // add_produced_cargo_proc + nullptr, // add_produced_cargo_proc VehicleEnter_Road, // vehicle_enter_tile_proc GetFoundation_Road, // get_foundation_proc TerraformTile_Road, // terraform_tile_proc diff --git a/src/road_cmd.h b/src/road_cmd.h index 3cf588dcd6..753ebd21d4 100644 --- a/src/road_cmd.h +++ b/src/road_cmd.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/road_func.h b/src/road_func.h index 06be7c4aa0..9376460575 100644 --- a/src/road_func.h +++ b/src/road_func.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. @@ -13,29 +11,9 @@ #define ROAD_FUNC_H #include "core/bitmath_func.hpp" -#include "road_type.h" +#include "road.h" #include "economy_func.h" - -/** - * Iterate through each set RoadType in a RoadTypes value. - * For more informations see FOR_EACH_SET_BIT_EX. - * - * @param var Loop index variable that stores fallowing set road type. Must be of type RoadType. - * @param road_types The value to iterate through (any expression). - * - * @see FOR_EACH_SET_BIT_EX - */ -#define FOR_EACH_SET_ROADTYPE(var, road_types) FOR_EACH_SET_BIT_EX(RoadType, var, RoadTypes, road_types) - -/** - * Whether the given roadtype is valid. - * @param rt the roadtype to check for validness - * @return true if and only if valid - */ -static inline bool IsValidRoadType(RoadType rt) -{ - return rt == ROADTYPE_ROAD || rt == ROADTYPE_TRAM; -} +#include "transparency.h" /** * Whether the given roadtype is valid. @@ -47,32 +25,6 @@ static inline bool IsValidRoadBits(RoadBits r) return r < ROAD_END; } -/** - * Maps a RoadType to the corresponding RoadTypes value - * - * @param rt the roadtype to get the roadtypes from - * @return the roadtypes with the given roadtype - */ -static inline RoadTypes RoadTypeToRoadTypes(RoadType rt) -{ - assert(IsValidRoadType(rt)); - return (RoadTypes)(1 << rt); -} - -/** - * Returns the RoadTypes which are not present in the given RoadTypes - * - * This function returns the complement of a given RoadTypes. - * - * @param r The given RoadTypes - * @return The complement of the given RoadTypes - */ -static inline RoadTypes ComplementRoadTypes(RoadTypes r) -{ - return (RoadTypes)(ROADTYPES_ALL ^ r); -} - - /** * Calculate the complement of a RoadBits value * @@ -167,18 +119,44 @@ static inline RoadBits AxisToRoadBits(Axis a) * Calculates the maintenance cost of a number of road bits. * @param roadtype Road type to get the cost for. * @param num Number of road bits. + * @param total_num Total number of road bits of all road/tram-types. * @return Total cost. */ -static inline Money RoadMaintenanceCost(RoadType roadtype, uint32 num) +static inline Money RoadMaintenanceCost(RoadType roadtype, uint32 num, uint32 total_num) { - assert(IsValidRoadType(roadtype)); - return (_price[PR_INFRASTRUCTURE_ROAD] * (roadtype == ROADTYPE_TRAM ? 3 : 2) * num * (1 + IntSqrt(num))) >> 9; // 2 bits fraction for the multiplier and 7 bits scaling. + assert(roadtype < ROADTYPE_END); + return (_price[PR_INFRASTRUCTURE_ROAD] * GetRoadTypeInfo(roadtype)->maintenance_multiplier * num * (1 + IntSqrt(total_num))) >> 12; } -bool HasRoadTypesAvail(const CompanyID company, const RoadTypes rts); -bool ValParamRoadType(const RoadType rt); -RoadTypes GetCompanyRoadtypes(const CompanyID company); +/** + * Test if a road type has catenary + * @param roadtype Road type to test + */ +static inline bool HasRoadCatenary(RoadType roadtype) +{ + assert(roadtype < ROADTYPE_END); + return HasBit(GetRoadTypeInfo(roadtype)->flags, ROTF_CATENARY); +} + +/** + * Test if we should draw road catenary + * @param roadtype Road type to test + */ +static inline bool HasRoadCatenaryDrawn(RoadType roadtype) +{ + return HasRoadCatenary(roadtype) && !IsInvisibilitySet(TO_CATENARY); +} + +bool HasRoadTypeAvail(CompanyID company, RoadType roadtype); +bool ValParamRoadType(RoadType roadtype); +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 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); #endif /* ROAD_FUNC_H */ diff --git a/src/road_gui.cpp b/src/road_gui.cpp index b11bb8e871..6803f16287 100644 --- a/src/road_gui.cpp +++ b/src/road_gui.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. @@ -30,6 +28,10 @@ #include "road_gui.h" #include "zoom_func.h" #include "build_confirmation_func.h" +#include "engine_base.h" +#include "strings_func.h" +#include "core/geometry_func.hpp" +#include "date_func.h" #include "widgets/road_widget.h" @@ -65,7 +67,7 @@ static RoadType _cur_roadtype; static DiagDirection _road_depot_orientation; static DiagDirection _road_station_picker_orientation; -void CcPlaySound_SPLAT_OTHER(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) +void CcPlaySound_SPLAT_OTHER(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) { if (result.Succeeded() && _settings_client.sound.confirm) SndPlayTileFx(SND_1F_SPLAT_OTHER, tile); } @@ -78,8 +80,9 @@ void CcPlaySound_SPLAT_OTHER(const CommandCost &result, TileIndex tile, uint32 p * @param p1 bit 0-3 railtype or roadtypes * bit 8-9 transport type * @param p2 unused + * @param cmd unused */ -void CcBuildRoadTunnel(const CommandCost &result, TileIndex start_tile, uint32 p1, uint32 p2) +void CcBuildRoadTunnel(const CommandCost &result, TileIndex start_tile, uint32 p1, uint32 p2, uint32 cmd) { if (result.Succeeded()) { if (_settings_client.sound.confirm) SndPlayTileFx(SND_1F_SPLAT_OTHER, start_tile); @@ -96,52 +99,6 @@ void CcBuildRoadTunnel(const CommandCost &result, TileIndex start_tile, uint32 p } } -/** Structure holding information per roadtype for several functions */ -struct RoadTypeInfo { - StringID err_build_road; ///< Building a normal piece of road - StringID err_remove_road; ///< Removing a normal piece of road - StringID err_depot; ///< Building a depot - StringID err_build_station[2]; ///< Building a bus or truck station - StringID err_remove_station[2]; ///< Removing of a bus or truck station - - StringID picker_title[2]; ///< Title for the station picker for bus or truck stations - StringID picker_tooltip[2]; ///< Tooltip for the station picker for bus or truck stations - - SpriteID cursor_nesw; ///< Cursor for building NE and SW bits - SpriteID cursor_nwse; ///< Cursor for building NW and SE bits - SpriteID cursor_autoroad; ///< Cursor for building autoroad -}; - -/** What errors/cursors must be shown for several types of roads */ -static const RoadTypeInfo _road_type_infos[] = { - { - STR_ERROR_CAN_T_BUILD_ROAD_HERE, - STR_ERROR_CAN_T_REMOVE_ROAD_FROM, - STR_ERROR_CAN_T_BUILD_ROAD_DEPOT, - { STR_ERROR_CAN_T_BUILD_BUS_STATION, STR_ERROR_CAN_T_BUILD_TRUCK_STATION }, - { STR_ERROR_CAN_T_REMOVE_BUS_STATION, STR_ERROR_CAN_T_REMOVE_TRUCK_STATION }, - { STR_STATION_BUILD_BUS_ORIENTATION, STR_STATION_BUILD_TRUCK_ORIENTATION }, - { STR_STATION_BUILD_BUS_ORIENTATION_TOOLTIP, STR_STATION_BUILD_TRUCK_ORIENTATION_TOOLTIP }, - - SPR_CURSOR_ROAD_NESW, - SPR_CURSOR_ROAD_NWSE, - SPR_CURSOR_AUTOROAD, - }, - { - STR_ERROR_CAN_T_BUILD_TRAMWAY_HERE, - STR_ERROR_CAN_T_REMOVE_TRAMWAY_FROM, - STR_ERROR_CAN_T_BUILD_TRAM_DEPOT, - { STR_ERROR_CAN_T_BUILD_PASSENGER_TRAM_STATION, STR_ERROR_CAN_T_BUILD_CARGO_TRAM_STATION }, - { STR_ERROR_CAN_T_REMOVE_PASSENGER_TRAM_STATION, STR_ERROR_CAN_T_REMOVE_CARGO_TRAM_STATION }, - { STR_STATION_BUILD_PASSENGER_TRAM_ORIENTATION, STR_STATION_BUILD_CARGO_TRAM_ORIENTATION }, - { STR_STATION_BUILD_PASSENGER_TRAM_ORIENTATION_TOOLTIP, STR_STATION_BUILD_CARGO_TRAM_ORIENTATION_TOOLTIP }, - - SPR_CURSOR_TRAMWAY_NESW, - SPR_CURSOR_TRAMWAY_NWSE, - SPR_CURSOR_AUTOTRAM, - }, -}; - /** * If required, connects a new structure to an existing road or tram by building the missing roadbit. * @param tile Tile containing the structure to connect. @@ -152,13 +109,13 @@ void ConnectRoadToStructure(TileIndex tile, DiagDirection direction) tile += TileOffsByDiagDir(direction); /* if there is a roadpiece just outside of the station entrance, build a connecting route */ if (IsNormalRoadTile(tile)) { - if (GetRoadBits(tile, _cur_roadtype) != ROAD_NONE) { + if (GetRoadBits(tile, GetRoadTramType(_cur_roadtype)) != ROAD_NONE) { DoCommandP(tile, _cur_roadtype << 4 | DiagDirToRoadBits(ReverseDiagDir(direction)), 0, CMD_BUILD_ROAD); } } } -void CcRoadDepot(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) +void CcRoadDepot(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) { if (result.Failed()) return; @@ -176,17 +133,19 @@ void CcRoadDepot(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2 * bit 8..15: Length of the road stop. * @param p2 bit 0: 0 For bus stops, 1 for truck stops. * bit 1: 0 For normal stops, 1 for drive-through. - * bit 2..3: The roadtypes. - * bit 5: Allow stations directly adjacent to other stations. - * bit 6..7: Entrance direction (#DiagDirection). + * bit 2: Allow stations directly adjacent to other stations. + * bit 3..4: Entrance direction (#DiagDirection) for normal stops. + * bit 3: #Axis of the road for drive-through stops. + * bit 5..9: The roadtype. * bit 16..31: Station ID to join (NEW_STATION if build new one). + * @param cmd Unused. * @see CmdBuildRoadStop */ -void CcRoadStop(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) +void CcRoadStop(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) { if (result.Failed()) return; - DiagDirection dir = (DiagDirection)GB(p2, 6, 2); + DiagDirection dir = (DiagDirection)GB(p2, 3, 2); if (_settings_client.sound.confirm) SndPlayTileFx(SND_1F_SPLAT_OTHER, tile); if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); TileArea roadstop_area(tile, GB(p1, 0, 8), GB(p1, 8, 8)); @@ -202,8 +161,8 @@ void CcRoadStop(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) * @param start_tile First tile of the area. * @param end_tile Last tile of the area. * @param p2 bit 0: 0 For bus stops, 1 for truck stops. - * bit 2..3: The roadtypes. - * bit 5: Allow stations directly adjacent to other stations. + * bit 2: Allow stations directly adjacent to other stations. + * bit 5..10: The roadtypes. * @param cmd Command to use. * @see CcRoadStop() */ @@ -216,7 +175,7 @@ static void PlaceRoadStop(TileIndex start_tile, TileIndex end_tile, uint32 p2, u SetBit(p2, 1); // It's a drive-through stop. ddir -= DIAGDIR_END; // Adjust picker result to actual direction. } - p2 |= ddir << 6; // Set the DiagDirecion into p2 bits 6 and 7. + p2 |= ddir << 3; // Set the DiagDirecion into p2 bits 3 and 4. TileArea ta(start_tile, end_tile); CommandContainer cmdcont = { ta.tile, (uint32)(ta.w | ta.h << 8), p2, cmd, CcRoadStop, "" }; @@ -298,17 +257,22 @@ static bool RoadToolbar_CtrlChanged(Window *w) /** Road toolbar window handler. */ struct BuildRoadToolbarWindow : Window { - int last_started_action; ///< Last started user action. + RoadType roadtype; ///< Road type to build. + const RoadTypeInfo *rti; ///< Information about current road type + int last_started_action; ///< Last started user action. bool last_started_action_remove; ///< Use bulldozer button with last action bool last_started_action_oneway; ///< Use 'one way road' button with last action BuildRoadToolbarWindow(WindowDesc *desc, WindowNumber window_number) : Window(desc) { + this->Initialize(_cur_roadtype); this->InitNested(window_number); - this->SetWidgetsDisabledState(true, - WID_ROT_REMOVE, - WID_ROT_ONE_WAY, - WIDGET_LIST_END); + this->SetupRoadToolbar(); + this->SetWidgetDisabledState(WID_ROT_REMOVE, true); + + if (RoadTypeIsRoad(this->roadtype)) { + this->SetWidgetDisabledState(WID_ROT_ONE_WAY, true); + } this->OnInvalidateData(); this->last_started_action = WIDGET_LIST_END; @@ -321,6 +285,7 @@ struct BuildRoadToolbarWindow : Window { ~BuildRoadToolbarWindow() { if (_thd.GetCallbackWnd() == this) this->OnPlaceObjectAbort(); + if (_game_mode == GM_NORMAL && (this->IsWidgetLowered(WID_ROT_BUS_STATION) || this->IsWidgetLowered(WID_ROT_TRUCK_STATION))) SetViewportCatchmentStation(nullptr, true); if (_settings_client.gui.link_terraform_toolbar) DeleteWindowById(WC_SCEN_LAND_GEN, 0, false); } @@ -329,11 +294,12 @@ struct BuildRoadToolbarWindow : Window { * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; - bool can_build = CanBuildVehicleInfrastructure(VEH_ROAD); + if (_game_mode != GM_EDITOR && !CanBuildVehicleInfrastructure(VEH_ROAD, GetRoadTramType(this->roadtype))) delete this; + bool can_build = _game_mode != GM_EDITOR; this->SetWidgetsDisabledState(!can_build, WID_ROT_DEPOT, WID_ROT_BUS_STATION, @@ -346,6 +312,53 @@ struct BuildRoadToolbarWindow : Window { } } + void Initialize(RoadType roadtype) + { + assert(roadtype < ROADTYPE_END); + this->roadtype = roadtype; + this->rti = GetRoadTypeInfo(this->roadtype); + } + + /** + * Configures the road toolbar for roadtype given + * @param roadtype the roadtype to display + */ + void SetupRoadToolbar() + { + this->GetWidget(WID_ROT_ROAD_X)->widget_data = rti->gui_sprites.build_x_road; + this->GetWidget(WID_ROT_ROAD_Y)->widget_data = rti->gui_sprites.build_y_road; + this->GetWidget(WID_ROT_AUTOROAD)->widget_data = rti->gui_sprites.auto_road; + if (_game_mode != GM_EDITOR) { + this->GetWidget(WID_ROT_DEPOT)->widget_data = rti->gui_sprites.build_depot; + } + this->GetWidget(WID_ROT_CONVERT_ROAD)->widget_data = rti->gui_sprites.convert_road; + this->GetWidget(WID_ROT_BUILD_TUNNEL)->widget_data = rti->gui_sprites.build_tunnel; + } + + /** + * Switch to another road type. + * @param roadtype New road type. + */ + void ModifyRoadType(RoadType roadtype) + { + this->Initialize(roadtype); + this->SetupRoadToolbar(); + this->ReInit(); + } + + void SetStringParameters(int widget) const override + { + if (widget == WID_ROT_CAPTION) { + if (this->rti->max_speed > 0) { + SetDParam(0, STR_TOOLBAR_RAILTYPE_VELOCITY); + SetDParam(1, this->rti->strings.toolbar_caption); + SetDParam(2, this->rti->max_speed / 2); + } else { + SetDParam(0, this->rti->strings.toolbar_caption); + } + } + } + /** * Update the remove button lowered state of the road toolbar * @@ -358,8 +371,11 @@ struct BuildRoadToolbarWindow : Window { * Both are only valid if they are able to apply as options. */ switch (clicked_widget) { case WID_ROT_REMOVE: - this->RaiseWidget(WID_ROT_ONE_WAY); - this->SetWidgetDirty(WID_ROT_ONE_WAY); + if (RoadTypeIsRoad(this->roadtype)) { + this->RaiseWidget(WID_ROT_ONE_WAY); + this->SetWidgetDirty(WID_ROT_ONE_WAY); + } + break; case WID_ROT_ONE_WAY: @@ -369,51 +385,51 @@ struct BuildRoadToolbarWindow : Window { case WID_ROT_BUS_STATION: case WID_ROT_TRUCK_STATION: - this->DisableWidget(WID_ROT_ONE_WAY); + if (RoadTypeIsRoad(this->roadtype)) this->DisableWidget(WID_ROT_ONE_WAY); this->SetWidgetDisabledState(WID_ROT_REMOVE, !this->IsWidgetLowered(clicked_widget)); break; case WID_ROT_ROAD_X: case WID_ROT_ROAD_Y: case WID_ROT_AUTOROAD: - this->SetWidgetsDisabledState(!this->IsWidgetLowered(clicked_widget), - WID_ROT_REMOVE, - WID_ROT_ONE_WAY, - WIDGET_LIST_END); + this->SetWidgetDisabledState(WID_ROT_REMOVE, !this->IsWidgetLowered(clicked_widget)); + if (RoadTypeIsRoad(this->roadtype)) { + this->SetWidgetDisabledState(WID_ROT_ONE_WAY, !this->IsWidgetLowered(clicked_widget)); + } break; default: /* When any other buttons than road/station, raise and * disable the removal button */ - this->SetWidgetsDisabledState(true, - WID_ROT_REMOVE, - WID_ROT_ONE_WAY, - WIDGET_LIST_END); - this->SetWidgetsLoweredState(false, - WID_ROT_REMOVE, - WID_ROT_ONE_WAY, - WIDGET_LIST_END); + this->SetWidgetDisabledState(WID_ROT_REMOVE, true); + this->SetWidgetLoweredState(WID_ROT_REMOVE, false); + + if (RoadTypeIsRoad(this->roadtype)) { + this->SetWidgetDisabledState(WID_ROT_ONE_WAY, true); + this->SetWidgetLoweredState(WID_ROT_ONE_WAY, false); + } + break; } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { _remove_button_clicked = false; _one_way_button_clicked = false; switch (widget) { case WID_ROT_ROAD_X: - HandlePlacePushButton(this, WID_ROT_ROAD_X, _road_type_infos[_cur_roadtype].cursor_nwse, HT_RECT); + HandlePlacePushButton(this, WID_ROT_ROAD_X, this->rti->cursor.road_nwse, HT_RECT); this->last_started_action = widget; break; case WID_ROT_ROAD_Y: - HandlePlacePushButton(this, WID_ROT_ROAD_Y, _road_type_infos[_cur_roadtype].cursor_nesw, HT_RECT); + HandlePlacePushButton(this, WID_ROT_ROAD_Y, this->rti->cursor.road_swne, HT_RECT); this->last_started_action = widget; break; case WID_ROT_AUTOROAD: - HandlePlacePushButton(this, WID_ROT_AUTOROAD, _road_type_infos[_cur_roadtype].cursor_autoroad, HT_RECT); + HandlePlacePushButton(this, WID_ROT_AUTOROAD, this->rti->cursor.autoroad, HT_RECT); this->last_started_action = widget; break; @@ -423,15 +439,15 @@ struct BuildRoadToolbarWindow : Window { break; case WID_ROT_DEPOT: - if (_game_mode == GM_EDITOR || !CanBuildVehicleInfrastructure(VEH_ROAD)) return; - if (HandlePlacePushButton(this, WID_ROT_DEPOT, SPR_CURSOR_ROAD_DEPOT, HT_RECT | HT_SCROLL_VIEWPORT)) { + if (_game_mode == GM_EDITOR || !CanBuildVehicleInfrastructure(VEH_ROAD, GetRoadTramType(this->roadtype))) return; + if (HandlePlacePushButton(this, WID_ROT_DEPOT, this->rti->cursor.depot, HT_RECT | HT_SCROLL_VIEWPORT)) { ShowRoadDepotPicker(this); this->last_started_action = widget; } break; case WID_ROT_BUS_STATION: - if (_game_mode == GM_EDITOR || !CanBuildVehicleInfrastructure(VEH_ROAD)) return; + if (_game_mode == GM_EDITOR || !CanBuildVehicleInfrastructure(VEH_ROAD, GetRoadTramType(this->roadtype))) return; if (HandlePlacePushButton(this, WID_ROT_BUS_STATION, SPR_CURSOR_BUS_STATION, HT_RECT)) { ShowRVStationPicker(this, ROADSTOP_BUS); this->last_started_action = widget; @@ -439,7 +455,7 @@ struct BuildRoadToolbarWindow : Window { break; case WID_ROT_TRUCK_STATION: - if (_game_mode == GM_EDITOR || !CanBuildVehicleInfrastructure(VEH_ROAD)) return; + if (_game_mode == GM_EDITOR || !CanBuildVehicleInfrastructure(VEH_ROAD, GetRoadTramType(this->roadtype))) return; if (HandlePlacePushButton(this, WID_ROT_TRUCK_STATION, SPR_CURSOR_TRUCK_STATION, HT_RECT)) { ShowRVStationPicker(this, ROADSTOP_TRUCK); this->last_started_action = widget; @@ -459,7 +475,7 @@ struct BuildRoadToolbarWindow : Window { break; case WID_ROT_BUILD_TUNNEL: - HandlePlacePushButton(this, WID_ROT_BUILD_TUNNEL, SPR_CURSOR_ROAD_TUNNEL, HT_SPECIAL); + HandlePlacePushButton(this, WID_ROT_BUILD_TUNNEL, this->rti->cursor.tunnel, HT_SPECIAL); this->last_started_action = widget; break; @@ -471,22 +487,27 @@ struct BuildRoadToolbarWindow : Window { if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); break; + case WID_ROT_CONVERT_ROAD: + HandlePlacePushButton(this, WID_ROT_CONVERT_ROAD, this->rti->cursor.convert_road, HT_RECT); + this->last_started_action = widget; + break; + default: NOT_REACHED(); } this->UpdateOptionWidgetStatus((RoadToolbarWidgets)widget); if (_ctrl_pressed) RoadToolbar_CtrlChanged(this); } - virtual EventState OnHotkey(int hotkey) + EventState OnHotkey(int hotkey) override { MarkTileDirtyByTile(TileVirtXY(_thd.pos.x, _thd.pos.y)); // redraw tile selection return Window::OnHotkey(hotkey); } - virtual void OnPlaceObject(Point pt, TileIndex tile) + void OnPlaceObject(Point pt, TileIndex tile) override { _remove_button_clicked = this->IsWidgetLowered(WID_ROT_REMOVE); - _one_way_button_clicked = this->IsWidgetLowered(WID_ROT_ONE_WAY); + _one_way_button_clicked = RoadTypeIsRoad(this->roadtype) ? this->IsWidgetLowered(WID_ROT_ONE_WAY) : false; switch (this->last_started_action) { case WID_ROT_ROAD_X: _place_road_flag = RF_DIR_X; @@ -531,21 +552,28 @@ struct BuildRoadToolbarWindow : Window { VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_BUILD_BRIDGE); break; + case WID_ROT_CONVERT_ROAD: + VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_CONVERT_ROAD); + break; + default: NOT_REACHED(); } MoveAllWindowsOffScreen(); } - virtual void OnPlaceObjectAbort() + void OnPlaceObjectAbort() override { + if (_game_mode != GM_EDITOR && (this->IsWidgetLowered(WID_ROT_BUS_STATION) || this->IsWidgetLowered(WID_ROT_TRUCK_STATION))) SetViewportCatchmentStation(nullptr, true); + MoveAllHiddenWindowsBackToScreen(); this->RaiseButtons(); - this->SetWidgetsDisabledState(true, - WID_ROT_REMOVE, - WID_ROT_ONE_WAY, - WIDGET_LIST_END); + this->SetWidgetDisabledState(WID_ROT_REMOVE, true); this->SetWidgetDirty(WID_ROT_REMOVE); - this->SetWidgetDirty(WID_ROT_ONE_WAY); + + if (RoadTypeIsRoad(this->roadtype)) { + this->SetWidgetDisabledState(WID_ROT_ONE_WAY, true); + this->SetWidgetDirty(WID_ROT_ONE_WAY); + } if (ConfirmationWindowShown() && (this->last_started_action == WID_ROT_BUILD_BRIDGE || _ctrl_pressed)) return; DeleteWindowById(WC_BUS_STATION, TRANSPORT_ROAD); @@ -555,7 +583,7 @@ struct BuildRoadToolbarWindow : Window { DeleteWindowByClass(WC_BUILD_BRIDGE); } - virtual void SelectLastTool() + void SelectLastTool() override { // User misplaced something - activate last selected tool again if (this->last_started_action == WIDGET_LIST_END) @@ -568,7 +596,7 @@ struct BuildRoadToolbarWindow : Window { _one_way_button_clicked = this->last_started_action_oneway; } - virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) + void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) override { if (this->last_started_action == WID_ROT_BUILD_TUNNEL) { this->OnPlacePresize(pt, TileVirtXY(pt.x, pt.y)); @@ -615,7 +643,7 @@ struct BuildRoadToolbarWindow : Window { VpSelectTilesWithMethod(pt.x, pt.y, select_method); } - virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) + void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) override { if (pt.x != -1) { this->last_started_action_remove = _remove_button_clicked; @@ -627,12 +655,13 @@ struct BuildRoadToolbarWindow : Window { case WID_ROT_BUILD_TUNNEL: if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); else VpStartPreSizing(); - DoCommandP(end_tile, RoadTypeToRoadTypes(_cur_roadtype) | (TRANSPORT_ROAD << 8), 0, + DoCommandP(end_tile, _cur_roadtype | (TRANSPORT_ROAD << 8), 0, CMD_BUILD_TUNNEL | CMD_MSG(STR_ERROR_CAN_T_BUILD_TUNNEL_HERE), CcBuildRoadTunnel); + break; case WID_ROT_BUILD_BRIDGE: if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); - ShowBuildBridgeWindow(start_tile, end_tile, TRANSPORT_ROAD, RoadTypeToRoadTypes(_cur_roadtype)); + ShowBuildBridgeWindow(start_tile, end_tile, TRANSPORT_ROAD, _cur_roadtype); break; default: NOT_REACHED(); } @@ -649,12 +678,16 @@ struct BuildRoadToolbarWindow : Window { * Use the first three bits (0x07) if dir == Y * else use the last 2 bits (X dir has * not the 3rd bit set) */ + + /* Even if _cur_roadtype_id is a uint8 we only use 5 bits so + * we could ignore the last 3 bits and reuse them for other + * flags */ _place_road_flag = (RoadFlags)((_place_road_flag & RF_DIR_Y) ? (_place_road_flag & 0x07) : (_place_road_flag >> 3)); - DoCommandP(start_tile, end_tile, _place_road_flag | (_cur_roadtype << 3) | (_one_way_button_clicked << 5), + DoCommandP(start_tile, end_tile, _place_road_flag | (_cur_roadtype << 3) | (_one_way_button_clicked << 10), _remove_button_clicked ? - CMD_REMOVE_LONG_ROAD | CMD_MSG(_road_type_infos[_cur_roadtype].err_remove_road) : - CMD_BUILD_LONG_ROAD | CMD_MSG(_road_type_infos[_cur_roadtype].err_build_road), CcPlaySound_SPLAT_OTHER); + CMD_REMOVE_LONG_ROAD | CMD_MSG(this->rti->strings.err_remove_road) : + CMD_BUILD_LONG_ROAD | CMD_MSG(this->rti->strings.err_build_road), CcPlaySound_SPLAT_OTHER); break; case DDSP_BUILD_BUSSTOP: @@ -662,9 +695,9 @@ struct BuildRoadToolbarWindow : Window { if (this->IsWidgetLowered(WID_ROT_BUS_STATION)) { if (_remove_button_clicked) { TileArea ta(start_tile, end_tile); - DoCommandP(ta.tile, ta.w | ta.h << 8, (_ctrl_pressed << 1) | ROADSTOP_BUS, CMD_REMOVE_ROAD_STOP | CMD_MSG(_road_type_infos[_cur_roadtype].err_remove_station[ROADSTOP_BUS]), CcPlaySound_SPLAT_OTHER); + DoCommandP(ta.tile, ta.w | ta.h << 8, (_ctrl_pressed << 1) | ROADSTOP_BUS, CMD_REMOVE_ROAD_STOP | CMD_MSG(this->rti->strings.err_remove_station[ROADSTOP_BUS]), CcPlaySound_SPLAT_OTHER); } else { - PlaceRoadStop(start_tile, end_tile, (_ctrl_pressed << 5) | RoadTypeToRoadTypes(_cur_roadtype) << 2 | ROADSTOP_BUS, CMD_BUILD_ROAD_STOP | CMD_MSG(_road_type_infos[_cur_roadtype].err_build_station[ROADSTOP_BUS])); + PlaceRoadStop(start_tile, end_tile, _cur_roadtype << 5 | (_ctrl_pressed << 2) | ROADSTOP_BUS, CMD_BUILD_ROAD_STOP | CMD_MSG(this->rti->strings.err_build_station[ROADSTOP_BUS])); } } break; @@ -674,9 +707,9 @@ struct BuildRoadToolbarWindow : Window { if (this->IsWidgetLowered(WID_ROT_TRUCK_STATION)) { if (_remove_button_clicked) { TileArea ta(start_tile, end_tile); - DoCommandP(ta.tile, ta.w | ta.h << 8, (_ctrl_pressed << 1) | ROADSTOP_TRUCK, CMD_REMOVE_ROAD_STOP | CMD_MSG(_road_type_infos[_cur_roadtype].err_remove_station[ROADSTOP_TRUCK]), CcPlaySound_SPLAT_OTHER); + DoCommandP(ta.tile, ta.w | ta.h << 8, (_ctrl_pressed << 1) | ROADSTOP_TRUCK, CMD_REMOVE_ROAD_STOP | CMD_MSG(this->rti->strings.err_remove_station[ROADSTOP_TRUCK]), CcPlaySound_SPLAT_OTHER); } else { - PlaceRoadStop(start_tile, end_tile, (_ctrl_pressed << 5) | RoadTypeToRoadTypes(_cur_roadtype) << 2 | ROADSTOP_TRUCK, CMD_BUILD_ROAD_STOP | CMD_MSG(_road_type_infos[_cur_roadtype].err_build_station[ROADSTOP_TRUCK])); + PlaceRoadStop(start_tile, end_tile, _cur_roadtype << 5 | (_ctrl_pressed << 2) | ROADSTOP_TRUCK, CMD_BUILD_ROAD_STOP | CMD_MSG(this->rti->strings.err_build_station[ROADSTOP_TRUCK])); } } break; @@ -686,53 +719,60 @@ struct BuildRoadToolbarWindow : Window { assert(start_tile == end_tile); assert(last_started_action == WID_ROT_DEPOT); DoCommandP(start_tile, _cur_roadtype << 2 | _road_depot_orientation, 0, - CMD_BUILD_ROAD_DEPOT | CMD_MSG(_road_type_infos[_cur_roadtype].err_depot), CcRoadDepot); - break; + CMD_BUILD_ROAD_DEPOT | CMD_MSG(this->rti->strings.err_depot), CcRoadDepot); + + break; + + case DDSP_CONVERT_ROAD: + DoCommandP(end_tile, start_tile, _cur_roadtype, CMD_CONVERT_ROAD | CMD_MSG(rti->strings.err_convert_road), CcPlaySound_SPLAT_OTHER); + break; } MoveAllHiddenWindowsBackToScreen(); } } - virtual void OnPlacePresize(Point pt, TileIndex tile) + void OnPlacePresize(Point pt, TileIndex tile) override { - DoCommand(tile, RoadTypeToRoadTypes(_cur_roadtype) | (TRANSPORT_ROAD << 8), 0, DC_AUTO, CMD_BUILD_TUNNEL); + DoCommand(tile, _cur_roadtype | (TRANSPORT_ROAD << 8), 0, DC_AUTO, CMD_BUILD_TUNNEL); VpSetPresizeRange(tile, _build_tunnel_endtile == 0 ? tile : _build_tunnel_endtile); } - virtual EventState OnCTRLStateChange() + EventState OnCTRLStateChange() override { if (RoadToolbar_CtrlChanged(this)) return ES_HANDLED; return ES_NOT_HANDLED; } - static HotkeyList hotkeys; + static HotkeyList road_hotkeys; + static HotkeyList tram_hotkeys; }; /** * Handler for global hotkeys of the BuildRoadToolbarWindow. * @param hotkey Hotkey + * @param last_build Last build road type * @return ES_HANDLED if hotkey was accepted. */ +static EventState RoadTramToolbarGlobalHotkeys(int hotkey, RoadType last_build) +{ + Window *w = (_game_mode == GM_NORMAL) ? ShowBuildRoadToolbar(last_build) : ShowBuildRoadScenToolbar(last_build); + if (w == nullptr) return ES_NOT_HANDLED; + return w->OnHotkey(hotkey); +} + static EventState RoadToolbarGlobalHotkeys(int hotkey) { - Window *w = NULL; - switch (_game_mode) { - case GM_NORMAL: { - extern RoadType _last_built_roadtype; - w = ShowBuildRoadToolbar(_last_built_roadtype); - break; - } + if (_game_mode == GM_NORMAL && !CanBuildVehicleInfrastructure(VEH_ROAD, RTT_ROAD)) return ES_NOT_HANDLED; - case GM_EDITOR: - w = ShowBuildRoadScenToolbar(); - break; + extern RoadType _last_built_roadtype; + return RoadTramToolbarGlobalHotkeys(hotkey, _last_built_roadtype); +} - default: - break; - } - - if (w == NULL) return ES_NOT_HANDLED; - return w->OnHotkey(hotkey); +static EventState TramToolbarGlobalHotkeys(int hotkey) +{ + if (_game_mode != GM_NORMAL || !CanBuildVehicleInfrastructure(VEH_ROAD, RTT_TRAM)) return ES_NOT_HANDLED; + extern RoadType _last_built_tramtype; + return RoadTramToolbarGlobalHotkeys(hotkey, _last_built_tramtype); } static Hotkey roadtoolbar_hotkeys[] = { @@ -747,15 +787,32 @@ static Hotkey roadtoolbar_hotkeys[] = { Hotkey('B', "bridge", WID_ROT_BUILD_BRIDGE), Hotkey('T', "tunnel", WID_ROT_BUILD_TUNNEL), Hotkey('R', "remove", WID_ROT_REMOVE), + Hotkey('C', "convert", WID_ROT_CONVERT_ROAD), HOTKEY_LIST_END }; -HotkeyList BuildRoadToolbarWindow::hotkeys("roadtoolbar", roadtoolbar_hotkeys, RoadToolbarGlobalHotkeys); +HotkeyList BuildRoadToolbarWindow::road_hotkeys("roadtoolbar", roadtoolbar_hotkeys, RoadToolbarGlobalHotkeys); + +static Hotkey tramtoolbar_hotkeys[] = { + Hotkey('1', "build_x", WID_ROT_ROAD_X), + Hotkey('2', "build_y", WID_ROT_ROAD_Y), + Hotkey('3', "autoroad", WID_ROT_AUTOROAD), + Hotkey('4', "demolish", WID_ROT_DEMOLISH), + Hotkey('5', "depot", WID_ROT_DEPOT), + Hotkey('6', "bus_station", WID_ROT_BUS_STATION), + Hotkey('7', "truck_station", WID_ROT_TRUCK_STATION), + Hotkey('B', "bridge", WID_ROT_BUILD_BRIDGE), + Hotkey('T', "tunnel", WID_ROT_BUILD_TUNNEL), + Hotkey('R', "remove", WID_ROT_REMOVE), + Hotkey('C', "convert", WID_ROT_CONVERT_ROAD), + HOTKEY_LIST_END +}; +HotkeyList BuildRoadToolbarWindow::tram_hotkeys("tramtoolbar", tramtoolbar_hotkeys, TramToolbarGlobalHotkeys); static const NWidgetPart _nested_build_road_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), - NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_ROAD_TOOLBAR_ROAD_CONSTRUCTION_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), + NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_ROT_CAPTION), SetDataTip(STR_WHITE_STRING, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN), EndContainer(), NWidget(NWID_HORIZONTAL), @@ -782,6 +839,8 @@ static const NWidgetPart _nested_build_road_widgets[] = { SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_TUNNEL, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL), NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_REMOVE), SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_REMOVE, STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD), + NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_CONVERT_ROAD), + SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_CONVERT_ROAD, STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_ROAD), EndContainer(), }; @@ -790,13 +849,13 @@ static WindowDesc _build_road_desc( WC_BUILD_TOOLBAR, WC_NONE, WDF_CONSTRUCTION, _nested_build_road_widgets, lengthof(_nested_build_road_widgets), - &BuildRoadToolbarWindow::hotkeys + &BuildRoadToolbarWindow::road_hotkeys ); static const NWidgetPart _nested_build_tramway_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), - NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_ROAD_TOOLBAR_TRAM_CONSTRUCTION_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), + NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_ROT_CAPTION), SetDataTip(STR_WHITE_STRING, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN), EndContainer(), NWidget(NWID_HORIZONTAL), @@ -815,13 +874,14 @@ static const NWidgetPart _nested_build_tramway_widgets[] = { NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_TRUCK_STATION), SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_TRUCK_BAY, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_CARGO_TRAM_STATION), NWidget(WWT_PANEL, COLOUR_DARK_GREEN, -1), SetMinimalSize(0, 22), SetFill(1, 1), EndContainer(), - NWidget(WWT_EMPTY, COLOUR_DARK_GREEN, WID_ROT_ONE_WAY), SetMinimalSize(0, 0), NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUILD_BRIDGE), SetFill(0, 1), SetMinimalSize(43, 22), SetDataTip(SPR_IMG_BRIDGE, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_BRIDGE), NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUILD_TUNNEL), SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_TUNNEL, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL), NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_REMOVE), SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_REMOVE, STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS), + NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_CONVERT_ROAD), + SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_CONVERT_ROAD, STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_TRAM), EndContainer(), }; @@ -830,7 +890,7 @@ static WindowDesc _build_tramway_desc( WC_BUILD_TOOLBAR, WC_NONE, WDF_CONSTRUCTION, _nested_build_tramway_widgets, lengthof(_nested_build_tramway_widgets), - &BuildRoadToolbarWindow::hotkeys + &BuildRoadToolbarWindow::tram_hotkeys ); /** @@ -838,21 +898,22 @@ static WindowDesc _build_tramway_desc( * * If the terraform toolbar is linked to the toolbar, that window is also opened. * - * @return newly opened road toolbar, or NULL if the toolbar could not be opened. + * @return newly opened road toolbar, or nullptr if the toolbar could not be opened. */ Window *ShowBuildRoadToolbar(RoadType roadtype) { - if (!Company::IsValidID(_local_company)) return NULL; - _cur_roadtype = roadtype; + if (!Company::IsValidID(_local_company)) return nullptr; + if (!ValParamRoadType(roadtype)) return nullptr; + _cur_roadtype = roadtype; DeleteToolbarLinkedWindows(); - return AllocateWindowDescFront(roadtype == ROADTYPE_ROAD ? &_build_road_desc : &_build_tramway_desc, TRANSPORT_ROAD); + return AllocateWindowDescFront(RoadTypeIsRoad(_cur_roadtype) ? &_build_road_desc : &_build_tramway_desc, TRANSPORT_ROAD); } static const NWidgetPart _nested_build_road_scen_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), - NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_ROAD_TOOLBAR_ROAD_CONSTRUCTION_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), + NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_ROT_CAPTION), SetDataTip(STR_WHITE_STRING, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN), EndContainer(), NWidget(NWID_HORIZONTAL), @@ -873,6 +934,8 @@ static const NWidgetPart _nested_build_road_scen_widgets[] = { SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_TUNNEL, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_ROAD_TUNNEL), NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_REMOVE), SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_REMOVE, STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_ROAD), + NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_CONVERT_ROAD), + SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_CONVERT_ROAD, STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_ROAD), EndContainer(), }; @@ -881,18 +944,55 @@ static WindowDesc _build_road_scen_desc( WC_SCEN_BUILD_TOOLBAR, WC_NONE, WDF_CONSTRUCTION, _nested_build_road_scen_widgets, lengthof(_nested_build_road_scen_widgets), - &BuildRoadToolbarWindow::hotkeys + &BuildRoadToolbarWindow::road_hotkeys +); + +static const NWidgetPart _nested_build_tramway_scen_widgets[] = { + NWidget(NWID_HORIZONTAL), + NWidget(WWT_CLOSEBOX, COLOUR_DARK_GREEN), + NWidget(WWT_CAPTION, COLOUR_DARK_GREEN, WID_ROT_CAPTION), SetDataTip(STR_WHITE_STRING, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS), + NWidget(WWT_STICKYBOX, COLOUR_DARK_GREEN), + EndContainer(), + NWidget(NWID_HORIZONTAL), + NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_ROAD_X), + SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_TRAMWAY_X_DIR, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION), + NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_ROAD_Y), + SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_TRAMWAY_Y_DIR, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_SECTION), + NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_AUTOROAD), + SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_AUTOTRAM, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_AUTOTRAM), + NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_DEMOLISH), + SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_DYNAMITE, STR_TOOLTIP_DEMOLISH_BUILDINGS_ETC), + NWidget(WWT_PANEL, COLOUR_DARK_GREEN, -1), SetMinimalSize(0, 22), SetFill(1, 1), EndContainer(), + NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUILD_BRIDGE), + SetFill(0, 1), SetMinimalSize(43, 22), SetDataTip(SPR_IMG_BRIDGE, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_BRIDGE), + NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_BUILD_TUNNEL), + SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_ROAD_TUNNEL, STR_ROAD_TOOLBAR_TOOLTIP_BUILD_TRAMWAY_TUNNEL), + NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_REMOVE), + SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_REMOVE, STR_ROAD_TOOLBAR_TOOLTIP_TOGGLE_BUILD_REMOVE_FOR_TRAMWAYS), + NWidget(WWT_IMGBTN, COLOUR_DARK_GREEN, WID_ROT_CONVERT_ROAD), + SetFill(0, 1), SetMinimalSize(22, 22), SetDataTip(SPR_IMG_CONVERT_ROAD, STR_ROAD_TOOLBAR_TOOLTIP_CONVERT_TRAM), + EndContainer(), +}; + +static WindowDesc _build_tramway_scen_desc( + WDP_AUTO, "toolbar_tram_scen", 0, 0, + WC_SCEN_BUILD_TOOLBAR, WC_NONE, + WDF_CONSTRUCTION, + _nested_build_tramway_scen_widgets, lengthof(_nested_build_tramway_scen_widgets), + &BuildRoadToolbarWindow::tram_hotkeys ); /** * Show the road building toolbar in the scenario editor. - * @return The just opened toolbar, or \c NULL if the toolbar was already open. + * @return The just opened toolbar, or \c nullptr if the toolbar was already open. */ -Window *ShowBuildRoadScenToolbar() +Window *ShowBuildRoadScenToolbar(RoadType roadtype) { DeleteToolbarLinkedWindows(); - _cur_roadtype = ROADTYPE_ROAD; - return AllocateWindowDescFront(&_build_road_scen_desc, TRANSPORT_ROAD); + DeleteWindowById(WC_SCEN_BUILD_TOOLBAR, TRANSPORT_ROAD); + _cur_roadtype = roadtype; + + return AllocateWindowDescFront(RoadTypeIsRoad(_cur_roadtype) ? &_build_road_scen_desc : &_build_tramway_scen_desc, TRANSPORT_ROAD); } struct BuildRoadDepotWindow : public PickerWindowBase { @@ -901,7 +1001,7 @@ struct BuildRoadDepotWindow : public PickerWindowBase { this->CreateNestedTree(); this->LowerWidget(_road_depot_orientation + WID_BROD_DEPOT_NE); - if ( _cur_roadtype == ROADTYPE_TRAM) { + if (RoadTypeIsTram(_cur_roadtype)) { this->GetWidget(WID_BROD_CAPTION)->widget_data = STR_BUILD_DEPOT_TRAM_ORIENTATION_CAPTION; for (int i = WID_BROD_DEPOT_NE; i <= WID_BROD_DEPOT_NW; i++) this->GetWidget(i)->tool_tip = STR_BUILD_DEPOT_TRAM_ORIENTATION_SELECT_TOOLTIP; } @@ -909,7 +1009,7 @@ struct BuildRoadDepotWindow : public PickerWindowBase { this->FinishInitNested(TRANSPORT_ROAD); } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { if (!IsInsideMM(widget, WID_BROD_DEPOT_NE, WID_BROD_DEPOT_NW + 1)) return; @@ -917,14 +1017,14 @@ struct BuildRoadDepotWindow : public PickerWindowBase { size->height = ScaleGUITrad(48) + 2; } - virtual void DrawWidget(const Rect &r, int widget) const + 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); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_BROD_DEPOT_NW: @@ -975,7 +1075,7 @@ static const NWidgetPart _nested_build_road_depot_widgets[] = { }; static WindowDesc _build_road_depot_desc( - WDP_AUTO, NULL, 0, 0, + WDP_AUTO, nullptr, 0, 0, WC_BUILD_DEPOT, WC_BUILD_TOOLBAR, WDF_CONSTRUCTION, _nested_build_road_depot_widgets, lengthof(_nested_build_road_depot_widgets) @@ -992,13 +1092,14 @@ struct BuildRoadStationWindow : public PickerWindowBase { this->CreateNestedTree(); /* Trams don't have non-drivethrough stations */ - if (_cur_roadtype == ROADTYPE_TRAM && _road_station_picker_orientation < DIAGDIR_END) { + if (RoadTypeIsTram(_cur_roadtype) && _road_station_picker_orientation < DIAGDIR_END) { _road_station_picker_orientation = DIAGDIR_END; } + const RoadTypeInfo *rti = GetRoadTypeInfo(_cur_roadtype); + this->GetWidget(WID_BROS_CAPTION)->widget_data = rti->strings.picker_title[rs]; - this->GetWidget(WID_BROS_CAPTION)->widget_data = _road_type_infos[_cur_roadtype].picker_title[rs]; - for (uint i = (_cur_roadtype == ROADTYPE_TRAM ? WID_BROS_STATION_X : WID_BROS_STATION_NE); i < WID_BROS_LT_OFF; i++) { - this->GetWidget(i)->tool_tip = _road_type_infos[_cur_roadtype].picker_tooltip[rs]; + for (uint i = RoadTypeIsTram(_cur_roadtype) ? WID_BROS_STATION_X : WID_BROS_STATION_NE; i < WID_BROS_LT_OFF; i++) { + this->GetWidget(i)->tool_tip = rti->strings.picker_tooltip[rs]; } this->LowerWidget(_road_station_picker_orientation + WID_BROS_STATION_NE); @@ -1014,7 +1115,7 @@ struct BuildRoadStationWindow : public PickerWindowBase { DeleteWindowById(WC_SELECT_STATION, 0); } - virtual void OnPaint() + void OnPaint() override { this->DrawWidgets(); @@ -1041,7 +1142,7 @@ struct BuildRoadStationWindow : public PickerWindowBase { } } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + 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; @@ -1049,15 +1150,15 @@ struct BuildRoadStationWindow : public PickerWindowBase { size->height = ScaleGUITrad(48) + 2; } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { if (!IsInsideMM(widget, WID_BROS_STATION_NE, WID_BROS_STATION_Y + 1)) return; 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, widget < WID_BROS_STATION_X ? ROADTYPE_ROAD : _cur_roadtype, widget - WID_BROS_STATION_NE); + StationPickerDrawSprite(r.left + 1 + ScaleGUITrad(31), r.bottom - ScaleGUITrad(31), st, INVALID_RAILTYPE, _cur_roadtype, widget - WID_BROS_STATION_NE); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_BROS_STATION_NE: @@ -1088,7 +1189,7 @@ struct BuildRoadStationWindow : public PickerWindowBase { } } - virtual void OnRealtimeTick(uint delta_ms) + void OnRealtimeTick(uint delta_ms) override { CheckRedrawStationCoverage(this); } @@ -1135,7 +1236,7 @@ static const NWidgetPart _nested_road_station_picker_widgets[] = { }; static WindowDesc _road_station_picker_desc( - WDP_AUTO, NULL, 0, 0, + WDP_AUTO, nullptr, 0, 0, WC_BUS_STATION, WC_BUILD_TOOLBAR, WDF_CONSTRUCTION, _nested_road_station_picker_widgets, lengthof(_nested_road_station_picker_widgets) @@ -1173,7 +1274,7 @@ static const NWidgetPart _nested_tram_station_picker_widgets[] = { }; static WindowDesc _tram_station_picker_desc( - WDP_AUTO, NULL, 0, 0, + WDP_AUTO, nullptr, 0, 0, WC_BUS_STATION, WC_BUILD_TOOLBAR, WDF_CONSTRUCTION, _nested_tram_station_picker_widgets, lengthof(_nested_tram_station_picker_widgets) @@ -1181,7 +1282,7 @@ static WindowDesc _tram_station_picker_desc( static void ShowRVStationPicker(Window *parent, RoadStopType rs) { - new BuildRoadStationWindow(_cur_roadtype == ROADTYPE_ROAD ? &_road_station_picker_desc : &_tram_station_picker_desc, parent, rs); + new BuildRoadStationWindow(RoadTypeIsRoad(_cur_roadtype) ? &_road_station_picker_desc : &_tram_station_picker_desc, parent, rs); } void InitializeRoadGui() @@ -1189,3 +1290,118 @@ void InitializeRoadGui() _road_depot_orientation = DIAGDIR_NW; _road_station_picker_orientation = DIAGDIR_NW; } + +/** + * I really don't know why rail_gui.cpp has this too, shouldn't be included in the other one? + */ +void InitializeRoadGUI() +{ + BuildRoadToolbarWindow *w = dynamic_cast(FindWindowById(WC_BUILD_TOOLBAR, TRANSPORT_ROAD)); + if (w != nullptr) w->ModifyRoadType(_cur_roadtype); +} + +DropDownList GetRoadTypeDropDownList(RoadTramTypes rtts, bool for_replacement, bool all_option) +{ + RoadTypes used_roadtypes; + RoadTypes avail_roadtypes; + + const Company *c = Company::Get(_local_company); + + /* Find the used roadtypes. */ + if (for_replacement) { + avail_roadtypes = GetCompanyRoadTypes(c->index, false); + used_roadtypes = GetRoadTypes(false); + } else { + avail_roadtypes = c->avail_roadtypes; + used_roadtypes = GetRoadTypes(true); + } + + /* Filter listed road types */ + if (!HasBit(rtts, RTT_ROAD)) used_roadtypes &= _roadtypes_type; + if (!HasBit(rtts, RTT_TRAM)) used_roadtypes &= ~_roadtypes_type; + + DropDownList list; + + if (all_option) { + list.emplace_back(new DropDownListStringItem(STR_REPLACE_ALL_ROADTYPE, INVALID_ROADTYPE, false)); + } + + Dimension d = { 0, 0 }; + RoadType rt; + /* Get largest icon size, to ensure text is aligned on each menu item. */ + if (!for_replacement) { + FOR_ALL_SORTED_ROADTYPES(rt) { + if (!HasBit(used_roadtypes, rt)) continue; + const RoadTypeInfo *rti = GetRoadTypeInfo(rt); + d = maxdim(d, GetSpriteSize(rti->gui_sprites.build_x_road)); + } + } + + FOR_ALL_SORTED_ROADTYPES(rt) { + /* If it's not used ever, don't show it to the user. */ + if (!HasBit(used_roadtypes, rt)) continue; + + const RoadTypeInfo *rti = GetRoadTypeInfo(rt); + + DropDownListParamStringItem *item; + if (for_replacement) { + item = new DropDownListParamStringItem(rti->strings.replace_text, rt, !HasBit(avail_roadtypes, rt)); + } else { + StringID str = rti->max_speed > 0 ? STR_TOOLBAR_RAILTYPE_VELOCITY : STR_JUST_STRING; + DropDownListIconItem *iconitem = new DropDownListIconItem(rti->gui_sprites.build_x_road, PAL_NONE, str, rt, !HasBit(avail_roadtypes, rt)); + iconitem->SetDimension(d); + item = iconitem; + } + item->SetParam(0, rti->strings.menu_text); + item->SetParam(1, rti->max_speed / 2); + list.emplace_back(item); + } + + if (list.size() == 0) { + /* Empty dropdowns are not allowed */ + list.emplace_back(new DropDownListStringItem(STR_NONE, INVALID_ROADTYPE, true)); + } + + return list; +} + +DropDownList GetScenRoadTypeDropDownList(RoadTramTypes rtts) +{ + RoadTypes avail_roadtypes = GetRoadTypes(false); + avail_roadtypes = AddDateIntroducedRoadTypes(avail_roadtypes, _date); + RoadTypes used_roadtypes = GetRoadTypes(true); + + /* Filter listed road types */ + if (!HasBit(rtts, RTT_ROAD)) used_roadtypes &= _roadtypes_type; + if (!HasBit(rtts, RTT_TRAM)) used_roadtypes &= ~_roadtypes_type; + + DropDownList list; + + /* If it's not used ever, don't show it to the user. */ + Dimension d = { 0, 0 }; + RoadType rt; + FOR_ALL_SORTED_ROADTYPES(rt) { + if (!HasBit(used_roadtypes, rt)) continue; + const RoadTypeInfo *rti = GetRoadTypeInfo(rt); + d = maxdim(d, GetSpriteSize(rti->gui_sprites.build_x_road)); + } + FOR_ALL_SORTED_ROADTYPES(rt) { + if (!HasBit(used_roadtypes, rt)) continue; + + const RoadTypeInfo *rti = GetRoadTypeInfo(rt); + + StringID str = rti->max_speed > 0 ? STR_TOOLBAR_RAILTYPE_VELOCITY : STR_JUST_STRING; + DropDownListIconItem *item = new DropDownListIconItem(rti->gui_sprites.build_x_road, PAL_NONE, str, rt, !HasBit(avail_roadtypes, rt)); + item->SetDimension(d); + item->SetParam(0, rti->strings.menu_text); + item->SetParam(1, rti->max_speed); + list.emplace_back(item); + } + + if (list.size() == 0) { + /* Empty dropdowns are not allowed */ + list.emplace_back(new DropDownListStringItem(STR_NONE, -1, true)); + } + + return list; +} diff --git a/src/road_gui.h b/src/road_gui.h index c56443c375..580c11e32e 100644 --- a/src/road_gui.h +++ b/src/road_gui.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. @@ -15,9 +13,13 @@ #include "road_type.h" #include "tile_type.h" #include "direction_type.h" +#include "widgets/dropdown_type.h" struct Window *ShowBuildRoadToolbar(RoadType roadtype); -struct Window *ShowBuildRoadScenToolbar(); +struct Window *ShowBuildRoadScenToolbar(RoadType roadtype); void ConnectRoadToStructure(TileIndex tile, DiagDirection direction); +DropDownList GetRoadTypeDropDownList(RoadTramTypes rtts, bool for_replacement = false, bool all_option = false); +DropDownList GetScenRoadTypeDropDownList(RoadTramTypes rtts); +void InitializeRoadGUI(); #endif /* ROAD_GUI_H */ diff --git a/src/road_internal.h b/src/road_internal.h index 8da909e94a..f0062100a5 100644 --- a/src/road_internal.h +++ b/src/road_internal.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. @@ -17,8 +15,8 @@ RoadBits CleanUpRoadBits(const TileIndex tile, RoadBits org_rb); -CommandCost CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, Owner owner, RoadType rt, DoCommandFlag flags, bool town_check = true); +CommandCost CheckAllowRemoveRoad(TileIndex tile, RoadBits remove, Owner owner, RoadTramType rtt, DoCommandFlag flags, bool town_check = true); -void DrawRoadCatenary(const TileInfo *ti, RoadBits tram); +void DrawRoadCatenary(const TileInfo *ti); #endif /* ROAD_INTERNAL_H */ diff --git a/src/road_map.cpp b/src/road_map.cpp index 4984117bab..9954e42993 100644 --- a/src/road_map.cpp +++ b/src/road_map.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. @@ -32,15 +30,15 @@ * @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, RoadType rt, bool straight_tunnel_bridge_entrance) +RoadBits GetAnyRoadBits(TileIndex tile, RoadTramType rtt, bool straight_tunnel_bridge_entrance) { - if (!HasTileRoadType(tile, rt)) return ROAD_NONE; + if (!MayHaveRoad(tile) || !HasTileRoadType(tile, rtt)) return ROAD_NONE; switch (GetTileType(tile)) { case MP_ROAD: switch (GetRoadTileType(tile)) { default: - case ROAD_TILE_NORMAL: return GetRoadBits(tile, rt); + case ROAD_TILE_NORMAL: return GetRoadBits(tile, rtt); case ROAD_TILE_CROSSING: return GetCrossingRoadBits(tile); case ROAD_TILE_DEPOT: return DiagDirToRoadBits(GetRoadDepotDirection(tile)); } diff --git a/src/road_map.h b/src/road_map.h index 49526d37f2..22d0fa54d3 100644 --- a/src/road_map.h +++ b/src/road_map.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. @@ -26,6 +24,24 @@ enum RoadTileType { ROAD_TILE_DEPOT, ///< Depot (one entrance) }; +/** + * Test whether a tile can have road/tram types. + * @param t Tile to query. + * @return true if tile can be queried about road/tram types. + */ +static inline bool MayHaveRoad(TileIndex t) +{ + switch (GetTileType(t)) { + case MP_ROAD: + case MP_STATION: + case MP_TUNNELBRIDGE: + return true; + + default: + return false; + } +} + /** * Get the type of the road tile. * @param t Tile to query. @@ -108,26 +124,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, RoadType rt) +static inline RoadBits GetRoadBits(TileIndex t, RoadTramType rtt) { assert(IsNormalRoad(t)); - switch (rt) { - default: NOT_REACHED(); - case ROADTYPE_ROAD: return (RoadBits)GB(_m[t].m5, 0, 4); - case ROADTYPE_TRAM: return (RoadBits)GB(_m[t].m3, 0, 4); - } -} - -/** - * Get all RoadBits set on a tile except from the given RoadType - * - * @param t The tile from which we want to get the RoadBits - * @param rt The RoadType which we exclude from the querry - * @return all set RoadBits of the tile which are not from the given RoadType - */ -static inline RoadBits GetOtherRoadBits(TileIndex t, RoadType rt) -{ - return GetRoadBits(t, rt == ROADTYPE_ROAD ? ROADTYPE_TRAM : ROADTYPE_ROAD); + if (rtt == RTT_TRAM) return (RoadBits)GB(_m[t].m3, 0, 4); + return (RoadBits)GB(_m[t].m5, 0, 4); } /** @@ -138,7 +139,7 @@ static inline RoadBits GetOtherRoadBits(TileIndex t, RoadType rt) */ static inline RoadBits GetAllRoadBits(TileIndex tile) { - return GetRoadBits(tile, ROADTYPE_ROAD) | GetRoadBits(tile, ROADTYPE_TRAM); + return GetRoadBits(tile, RTT_ROAD) | GetRoadBits(tile, RTT_TRAM); } /** @@ -148,96 +149,125 @@ static inline RoadBits GetAllRoadBits(TileIndex tile) * @param rt Road type. * @pre IsNormalRoad(t) */ -static inline void SetRoadBits(TileIndex t, RoadBits r, RoadType rt) +static inline void SetRoadBits(TileIndex t, RoadBits r, RoadTramType rtt) { assert(IsNormalRoad(t)); // XXX incomplete - switch (rt) { - default: NOT_REACHED(); - case ROADTYPE_ROAD: SB(_m[t].m5, 0, 4, r); break; - case ROADTYPE_TRAM: SB(_m[t].m3, 0, 4, r); break; + if (rtt == RTT_TRAM) { + SB(_m[t].m3, 0, 4, r); + } else { + SB(_m[t].m5, 0, 4, r); } } +static inline RoadType GetRoadTypeRoad(TileIndex t) +{ + assert(MayHaveRoad(t)); + return (RoadType)GB(_m[t].m4, 0, 6); +} + +static inline RoadType GetRoadTypeTram(TileIndex t) +{ + assert(MayHaveRoad(t)); + return (RoadType)GB(_me[t].m8, 6, 6); +} + +static inline RoadType GetRoadType(TileIndex t, RoadTramType rtt) +{ + return (rtt == RTT_TRAM) ? GetRoadTypeTram(t) : GetRoadTypeRoad(t); +} + /** * Get the present road types of a tile. * @param t The tile to query. * @return Present road types. */ -static inline RoadTypes GetRoadTypes(TileIndex t) +static inline RoadTypes GetPresentRoadTypes(TileIndex t) { - return (RoadTypes)GB(_me[t].m7, 6, 2); + RoadTypes result = ROADTYPES_NONE; + if (MayHaveRoad(t)) { + if (GetRoadTypeRoad(t) != INVALID_ROADTYPE) SetBit(result, GetRoadTypeRoad(t)); + if (GetRoadTypeTram(t) != INVALID_ROADTYPE) SetBit(result, GetRoadTypeTram(t)); + } + return result; +} + +static inline bool HasRoadTypeRoad(TileIndex t) +{ + return GetRoadTypeRoad(t) != INVALID_ROADTYPE; +} + +static inline bool HasRoadTypeTram(TileIndex t) +{ + return GetRoadTypeTram(t) != INVALID_ROADTYPE; } /** - * Set the present road types of a tile. - * @param t The tile to change. - * @param rt The new road types. - */ -static inline void SetRoadTypes(TileIndex t, RoadTypes rt) -{ - assert(IsTileType(t, MP_ROAD) || IsTileType(t, MP_STATION) || IsTileType(t, MP_TUNNELBRIDGE)); - SB(_me[t].m7, 6, 2, rt); -} - -/** - * Check if a tile has a specific road type. + * Check if a tile has a road or a tram road type. * @param t The tile to check. - * @param rt Road type to check. + * @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, RoadType rt) +static inline bool HasTileRoadType(TileIndex t, RoadTramType rtt) { - return HasBit(GetRoadTypes(t), rt); + return GetRoadType(t, rtt) != INVALID_ROADTYPE; +} + +/** + * Check if a tile has one of the specified road types. + * @param t The tile to check. + * @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) +{ + if (!MayHaveRoad(t)) return false; + return (GetPresentRoadTypes(t) & rts); } /** * Get the owner of a specific road type. * @param t The tile to query. - * @param rt The road type to get the owner of. + * @param rtt RoadTramType. * @return Owner of the given road type. */ -static inline Owner GetRoadOwner(TileIndex t, RoadType rt) +static inline Owner GetRoadOwner(TileIndex t, RoadTramType rtt) { - assert(IsTileType(t, MP_ROAD) || IsTileType(t, MP_STATION) || IsTileType(t, MP_TUNNELBRIDGE)); - switch (rt) { - default: NOT_REACHED(); - case ROADTYPE_ROAD: return (Owner)GB(IsNormalRoadTile(t) ? _m[t].m1 : _me[t].m7, 0, 5); - case ROADTYPE_TRAM: { - /* 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); - return o == OWNER_TOWN ? OWNER_NONE : o; - } - } + assert(MayHaveRoad(t)); + if (rtt == RTT_ROAD) return (Owner)GB(IsNormalRoadTile(t) ? _m[t].m1 : _me[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); + return o == OWNER_TOWN ? OWNER_NONE : o; } /** * Set the owner of a specific road type. * @param t The tile to change. - * @param rt The road type to change the owner of. + * @param rtt RoadTramType. * @param o New owner of the given road type. */ -static inline void SetRoadOwner(TileIndex t, RoadType rt, Owner o) +static inline void SetRoadOwner(TileIndex t, RoadTramType rtt, Owner o) { - switch (rt) { - default: NOT_REACHED(); - case ROADTYPE_ROAD: SB(IsNormalRoadTile(t) ? _m[t].m1 : _me[t].m7, 0, 5, o); break; - case ROADTYPE_TRAM: SB(_m[t].m3, 4, 4, o == OWNER_NONE ? OWNER_TOWN : o); break; + if (rtt == RTT_ROAD) { + SB(IsNormalRoadTile(t) ? _m[t].m1 : _me[t].m7, 0, 5, o); + } else { + SB(_m[t].m3, 4, 4, o == OWNER_NONE ? OWNER_TOWN : o); } } /** * Check if a specific road type is owned by an owner. * @param t The tile to query. - * @param rt The road type to compare the owner of. + * @param tram True to check tram, false to check road. * @param o Owner to compare with. * @pre HasTileRoadType(t, rt) * @return True if the road type is owned by the given owner. */ -static inline bool IsRoadOwner(TileIndex t, RoadType rt, Owner o) +static inline bool IsRoadOwner(TileIndex t, RoadTramType rtt, Owner o) { - assert(HasTileRoadType(t, rt)); - return (GetRoadOwner(t, rt) == o); + assert(HasTileRoadType(t, rtt)); + return (GetRoadOwner(t, rtt) == o); } /** @@ -248,7 +278,7 @@ static inline bool IsRoadOwner(TileIndex t, RoadType rt, Owner o) */ static inline bool HasTownOwnedRoad(TileIndex t) { - return HasTileRoadType(t, ROADTYPE_ROAD) && IsRoadOwner(t, ROADTYPE_ROAD, OWNER_TOWN); + return HasTileRoadType(t, RTT_ROAD) && IsRoadOwner(t, RTT_ROAD, OWNER_TOWN); } /** Which directions are disallowed ? */ @@ -539,29 +569,80 @@ static inline DiagDirection GetRoadDepotDirection(TileIndex t) } -RoadBits GetAnyRoadBits(TileIndex tile, RoadType rt, bool straight_tunnel_bridge_entrance = false); +RoadBits GetAnyRoadBits(TileIndex 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) +{ + assert(MayHaveRoad(t)); + assert(rt == INVALID_ROADTYPE || RoadTypeIsRoad(rt)); + SB(_m[t].m4, 0, 6, rt); +} + +/** + * Set the tram road type of a tile. + * @param t The tile to change. + * @param rt The road type to set. + */ +static inline void SetRoadTypeTram(TileIndex t, RoadType rt) +{ + assert(MayHaveRoad(t)); + assert(rt == INVALID_ROADTYPE || RoadTypeIsTram(rt)); + SB(_me[t].m8, 6, 6, rt); +} + +/** + * Set the road type of a tile. + * @param t The tile to change. + * @param rtt Set road or tram type. + * @param rt The road type to set. + */ +static inline void SetRoadType(TileIndex t, RoadTramType rtt, RoadType rt) +{ + if (rtt == RTT_TRAM) { + SetRoadTypeTram(t, rt); + } else { + SetRoadTypeRoad(t, rt); + } +} + +/** + * Set the present road types of a tile. + * @param t The tile to change. + * @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) +{ + SetRoadTypeRoad(t, road_rt); + SetRoadTypeTram(t, tram_rt); +} /** * Make a normal road tile. - * @param t Tile to make a normal road. - * @param bits Road bits to set for all present road types. - * @param rot New present road types. - * @param town Town ID if the road is a town-owned road. - * @param road New owner of road. - * @param tram New owner of tram tracks. + * @param t Tile to make a normal road. + * @param bits Road bits to set for all present road types. + * @param road_rt The road roadtype to set for the tile. + * @param tram_rt The tram roadtype to set for the tile. + * @param town Town ID if the road is a town-owned road. + * @param road New owner of road. + * @param tram New owner of tram tracks. */ -static inline void MakeRoadNormal(TileIndex t, RoadBits bits, RoadTypes rot, TownID town, Owner road, Owner tram) +static inline void MakeRoadNormal(TileIndex 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 = (HasBit(rot, ROADTYPE_TRAM) ? bits : 0); - _m[t].m4 = 0; - _m[t].m5 = (HasBit(rot, ROADTYPE_ROAD) ? bits : 0) | ROAD_TILE_NORMAL << 6; + _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 = rot << 6; - SetRoadOwner(t, ROADTYPE_TRAM, tram); + _me[t].m7 = 0; + SetRoadTypes(t, road_rt, tram_rt); + SetRoadOwner(t, RTT_TRAM, tram); } /** @@ -572,21 +653,23 @@ static inline void MakeRoadNormal(TileIndex t, RoadBits bits, RoadTypes rot, Tow * @param rail New owner of the rail track. * @param roaddir Axis of the road. * @param rat New rail type. - * @param rot New present road types. + * @param road_rt The road roadtype to set for the tile. + * @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, RoadTypes rot, uint town) +static inline void MakeRoadCrossing(TileIndex 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 = 0; + _m[t].m4 = INVALID_ROADTYPE; _m[t].m5 = ROAD_TILE_CROSSING << 6 | roaddir; SB(_me[t].m6, 2, 4, 0); - _me[t].m7 = rot << 6 | road; - _me[t].m8 = rat; - SetRoadOwner(t, ROADTYPE_TRAM, tram); + _me[t].m7 = road; + _me[t].m8 = INVALID_ROADTYPE << 6 | rat; + SetRoadTypes(t, road_rt, tram_rt); + SetRoadOwner(t, RTT_TRAM, tram); } /** @@ -594,7 +677,7 @@ static inline void MakeRoadCrossing(TileIndex t, Owner road, Owner tram, Owner r * @param t Tile to make a level crossing. * @param owner New owner of the depot. * @param did New depot ID. - * @param dir Direction of the depot exit. + * @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) @@ -603,11 +686,13 @@ static inline void MakeRoadDepot(TileIndex t, Owner owner, DepotID did, DiagDire SetTileOwner(t, owner); _m[t].m2 = did; _m[t].m3 = 0; - _m[t].m4 = 0; + _m[t].m4 = INVALID_ROADTYPE; _m[t].m5 = ROAD_TILE_DEPOT << 6 | dir; SB(_me[t].m6, 2, 4, 0); - _me[t].m7 = RoadTypeToRoadTypes(rt) << 6 | owner; - SetRoadOwner(t, ROADTYPE_TRAM, owner); + _me[t].m7 = owner; + _me[t].m8 = INVALID_ROADTYPE << 6; + SetRoadType(t, GetRoadTramType(rt), rt); + SetRoadOwner(t, RTT_TRAM, owner); } #endif /* ROAD_MAP_H */ diff --git a/src/road_type.h b/src/road_type.h index 5251a53923..969b141ba2 100644 --- a/src/road_type.h +++ b/src/road_type.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. @@ -14,37 +12,34 @@ #include "core/enum_type.hpp" +typedef uint32 RoadTypeLabel; + /** * The different roadtypes we support * * @note currently only ROADTYPE_ROAD and ROADTYPE_TRAM are supported. */ enum RoadType { - ROADTYPE_BEGIN = 0, ///< Used for iterations - ROADTYPE_ROAD = 0, ///< Basic road type - ROADTYPE_TRAM = 1, ///< Trams - ROADTYPE_END, ///< Used for iterations - INVALID_ROADTYPE = 0xFF, ///< flag for invalid roadtype + ROADTYPE_BEGIN = 0, ///< Used for iterations + ROADTYPE_ROAD = 0, ///< Basic road type + ROADTYPE_TRAM = 1, ///< Trams + ROADTYPE_END = 63, ///< Used for iterations + INVALID_ROADTYPE = 63, ///< flag for invalid roadtype }; DECLARE_POSTFIX_INCREMENT(RoadType) -template <> struct EnumPropsT : MakeEnumPropsT {}; +template <> struct EnumPropsT : MakeEnumPropsT {}; /** - * The different roadtypes we support, but then a bitmask of them - * @note currently only roadtypes with ROADTYPE_ROAD and ROADTYPE_TRAM are supported. + * The different roadtypes we support, but then a bitmask of them. + * @note Must be treated as a uint64 type, narrowing it causes bit membership tests to give wrong results. */ -enum RoadTypes { +enum RoadTypes : uint64 { ROADTYPES_NONE = 0, ///< No roadtypes ROADTYPES_ROAD = 1 << ROADTYPE_ROAD, ///< Road ROADTYPES_TRAM = 1 << ROADTYPE_TRAM, ///< Trams - ROADTYPES_ALL = ROADTYPES_ROAD | ROADTYPES_TRAM, ///< Road + trams - ROADTYPES_END, ///< Used for iterations? - INVALID_ROADTYPES = 0xFF, ///< Invalid roadtypes + INVALID_ROADTYPES = UINT64_MAX, ///< Invalid roadtypes }; DECLARE_ENUM_AS_BIT_SET(RoadTypes) -template <> struct EnumPropsT : MakeEnumPropsT {}; -typedef SimpleTinyEnumT RoadTypesByte; - /** * Enumeration for the road parts on a tile. diff --git a/src/roadstop.cpp b/src/roadstop.cpp index ca049979ca..a7f25fe0c3 100644 --- a/src/roadstop.cpp +++ b/src/roadstop.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. @@ -43,9 +41,9 @@ RoadStop::~RoadStop() */ RoadStop *RoadStop::GetNextRoadStop(const RoadVehicle *v) const { - for (RoadStop *rs = this->next; rs != NULL; rs = rs->next) { + for (RoadStop *rs = this->next; rs != nullptr; rs = rs->next) { /* The vehicle cannot go to this roadstop (different roadtype) */ - if ((GetRoadTypes(rs->xy) & v->compatible_roadtypes) == ROADTYPES_NONE) continue; + if (!HasTileAnyRoadType(rs->xy, v->compatible_roadtypes)) continue; /* The vehicle is articulated and can therefore not go to a standard road stop. */ if (IsStandardRoadStopTile(rs->xy) && v->HasArticulatedPart()) continue; @@ -53,7 +51,7 @@ RoadStop *RoadStop::GetNextRoadStop(const RoadVehicle *v) const return rs; } - return NULL; + return nullptr; } /** @@ -63,7 +61,7 @@ RoadStop *RoadStop::GetNextRoadStop(const RoadVehicle *v) const */ void RoadStop::MakeDriveThrough() { - assert(this->east == NULL && this->west == NULL); + assert(this->east == nullptr && this->west == nullptr); RoadStopType rst = GetRoadStopType(this->xy); DiagDirection dir = GetRoadStopDir(this->xy); @@ -73,21 +71,21 @@ void RoadStop::MakeDriveThrough() /* Information about the tile north of us */ TileIndex north_tile = this->xy - offset; bool north = IsDriveThroughRoadStopContinuation(this->xy, north_tile); - RoadStop *rs_north = north ? RoadStop::GetByTile(north_tile, rst) : NULL; + RoadStop *rs_north = north ? RoadStop::GetByTile(north_tile, rst) : nullptr; /* Information about the tile south of us */ TileIndex south_tile = this->xy + offset; bool south = IsDriveThroughRoadStopContinuation(this->xy, south_tile); - RoadStop *rs_south = south ? RoadStop::GetByTile(south_tile, rst) : NULL; + RoadStop *rs_south = south ? RoadStop::GetByTile(south_tile, rst) : nullptr; /* Amount of road stops that will be added to the 'northern' head */ int added = 1; - if (north && rs_north->east != NULL) { // (east != NULL) == (west != NULL) + if (north && rs_north->east != nullptr) { // (east != nullptr) == (west != nullptr) /* There is a more northern one, so this can join them */ this->east = rs_north->east; this->west = rs_north->west; - if (south && rs_south->east != NULL) { // (east != NULL) == (west != NULL) + if (south && rs_south->east != nullptr) { // (east != nullptr) == (west != nullptr) /* There more southern tiles too, they must 'join' us too */ ClrBit(rs_south->status, RSSFB_BASE_ENTRY); this->east->occupied += rs_south->east->occupied; @@ -100,13 +98,13 @@ void RoadStop::MakeDriveThrough() /* Make all 'children' of the southern tile take the new master */ for (; IsDriveThroughRoadStopContinuation(this->xy, south_tile); south_tile += offset) { rs_south = RoadStop::GetByTile(south_tile, rst); - if (rs_south->east == NULL) break; + if (rs_south->east == nullptr) break; rs_south->east = rs_north->east; rs_south->west = rs_north->west; added++; } } - } else if (south && rs_south->east != NULL) { // (east != NULL) == (west != NULL) + } else if (south && rs_south->east != nullptr) { // (east != nullptr) == (west != nullptr) /* There is one to the south, but not to the north... so we become 'parent' */ this->east = rs_south->east; this->west = rs_south->west; @@ -131,7 +129,7 @@ void RoadStop::MakeDriveThrough() */ void RoadStop::ClearDriveThrough() { - assert(this->east != NULL && this->west != NULL); + assert(this->east != nullptr && this->west != nullptr); RoadStopType rst = GetRoadStopType(this->xy); DiagDirection dir = GetRoadStopDir(this->xy); @@ -141,12 +139,12 @@ void RoadStop::ClearDriveThrough() /* Information about the tile north of us */ TileIndex north_tile = this->xy - offset; bool north = IsDriveThroughRoadStopContinuation(this->xy, north_tile); - RoadStop *rs_north = north ? RoadStop::GetByTile(north_tile, rst) : NULL; + RoadStop *rs_north = north ? RoadStop::GetByTile(north_tile, rst) : nullptr; /* Information about the tile south of us */ TileIndex south_tile = this->xy + offset; bool south = IsDriveThroughRoadStopContinuation(this->xy, south_tile); - RoadStop *rs_south = south ? RoadStop::GetByTile(south_tile, rst) : NULL; + RoadStop *rs_south = south ? RoadStop::GetByTile(south_tile, rst) : nullptr; /* Must only be cleared after we determined which neighbours are * part of our little entry 'queue' */ @@ -207,8 +205,8 @@ void RoadStop::ClearDriveThrough() /* Make sure we don't get used for something 'incorrect' */ ClrBit(this->status, RSSFB_BASE_ENTRY); - this->east = NULL; - this->west = NULL; + this->east = nullptr; + this->west = nullptr; } /** @@ -271,7 +269,7 @@ bool RoadStop::Enter(RoadVehicle *rv) for (RoadStop *rs = st->GetPrimaryRoadStop(type);; rs = rs->next) { if (rs->xy == tile) return rs; - assert(rs->next != NULL); + assert(rs->next != nullptr); } } @@ -325,25 +323,25 @@ struct RoadStopEntryRebuilderHelper { * Add road vehicles to the station's list if needed. * @param v the found vehicle * @param data the extra data used to make our decision - * @return always NULL + * @return always nullptr */ Vehicle *FindVehiclesInRoadStop(Vehicle *v, void *data) { RoadStopEntryRebuilderHelper *rserh = (RoadStopEntryRebuilderHelper*)data; /* Not a RV or not in the right direction or crashed :( */ - if (v->type != VEH_ROAD || DirToDiagDir(v->direction) != rserh->dir || !v->IsPrimaryVehicle() || (v->vehstatus & VS_CRASHED) != 0) return NULL; + if (v->type != VEH_ROAD || DirToDiagDir(v->direction) != rserh->dir || !v->IsPrimaryVehicle() || (v->vehstatus & VS_CRASHED) != 0) return nullptr; RoadVehicle *rv = RoadVehicle::From(v); /* Don't add ones not in a road stop */ - if (rv->state < RVSB_IN_ROAD_STOP) return NULL; + if (rv->state < RVSB_IN_ROAD_STOP) return nullptr; /* Do not add duplicates! */ for (RVList::iterator it = rserh->vehicles.begin(); it != rserh->vehicles.end(); it++) { - if (rv == *it) return NULL; + if (rv == *it) return nullptr; } rserh->vehicles.push_back(rv); - return NULL; + return nullptr; } /** diff --git a/src/roadstop_base.h b/src/roadstop_base.h index ee470db8d1..768b54282d 100644 --- a/src/roadstop_base.h +++ b/src/roadstop_base.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. @@ -190,7 +188,4 @@ private: } }; -#define FOR_ALL_ROADSTOPS_FROM(var, start) FOR_ALL_ITEMS_FROM(RoadStop, roadstop_index, var, start) -#define FOR_ALL_ROADSTOPS(var) FOR_ALL_ROADSTOPS_FROM(var, 0) - #endif /* ROADSTOP_BASE_H */ diff --git a/src/roadveh.h b/src/roadveh.h index ca069b7acf..028af9decb 100644 --- a/src/roadveh.h +++ b/src/roadveh.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. @@ -16,8 +14,10 @@ #include "engine_base.h" #include "cargotype.h" #include "track_func.h" -#include "road_type.h" +#include "road.h" +#include "road_map.h" #include "newgrf_engine.h" +#include struct RoadVehicle; @@ -82,10 +82,30 @@ static const byte RV_OVERTAKE_TIMEOUT = 35; void RoadVehUpdateCache(RoadVehicle *v, bool same_length = false); void GetRoadVehSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, int &yoffs, EngineImageType image_type); +struct RoadVehPathCache { + std::deque td; + std::deque tile; + + inline bool empty() const { return this->td.empty(); } + + inline size_t size() const + { + assert(this->td.size() == this->tile.size()); + return this->td.size(); + } + + inline void clear() + { + this->td.clear(); + this->tile.clear(); + } +}; + /** * Buses, trucks and trams belong to this class. */ struct RoadVehicle FINAL : public GroundVehicle { + RoadVehPathCache path; ///< Cached path. byte state; ///< @see RoadVehicleStates byte frame; uint16 blocked_ctr; @@ -94,8 +114,8 @@ struct RoadVehicle FINAL : public GroundVehicle { uint16 crashed_ctr; ///< Animation counter when the vehicle has crashed. @see RoadVehIsCrashed byte reverse_ctr; - RoadType roadtype; - RoadTypes compatible_roadtypes; + RoadType roadtype; //!< Roadtype of this vehicle. + RoadTypes compatible_roadtypes; //!< Roadtypes this consist is powered on. /** We don't want GCC to zero our struct! It already is zeroed and has an index! */ RoadVehicle() : GroundVehicleBase() {} @@ -112,7 +132,7 @@ struct RoadVehicle FINAL : public GroundVehicle { int GetDisplaySpeed() const { return this->gcache.last_speed / 2; } int GetDisplayMaxSpeed() const { return this->vcache.cached_max_speed / 2; } Money GetRunningCost() const; - int GetDisplayImageWidth(Point *offset = NULL) const; + int GetDisplayImageWidth(Point *offset = nullptr) const; bool IsInDepot() const { return this->state == RVSB_IN_DEPOT; } bool Tick(); void OnNewDay(); @@ -125,6 +145,7 @@ struct RoadVehicle FINAL : public GroundVehicle { int GetCurrentMaxSpeed() const; int UpdateSpeed(); + void SetDestTile(TileIndex tile); protected: // These functions should not be called outside acceleration code. @@ -222,7 +243,7 @@ protected: // These functions should not be called outside acceleration code. { /* Trams have a slightly greater friction coefficient than trains. * The rest of road vehicles have bigger values. */ - uint32 coeff = (this->roadtype == ROADTYPE_TRAM) ? 40 : 75; + uint32 coeff = RoadTypeIsTram(this->roadtype) ? 40 : 75; /* The friction coefficient increases with speed in a way that * it doubles at 128 km/h, triples at 256 km/h and so on. */ return coeff * (128 + this->GetCurrentSpeed()) / 128; @@ -252,7 +273,7 @@ protected: // These functions should not be called outside acceleration code. */ inline uint16 GetMaxTrackSpeed() const { - return 0; + return GetRoadTypeInfo(GetRoadType(this->tile, GetRoadTramType(this->roadtype)))->max_speed; } /** @@ -261,7 +282,7 @@ protected: // These functions should not be called outside acceleration code. */ inline bool TileMayHaveSlopedTrack() const { - TrackStatus ts = GetTileTrackStatus(this->tile, TRANSPORT_ROAD, this->compatible_roadtypes); + TrackStatus ts = GetTileTrackStatus(this->tile, TRANSPORT_ROAD, GetRoadTramType(this->roadtype)); TrackBits trackbits = TrackStatusToTrackBits(ts); return trackbits == TRACK_BIT_X || trackbits == TRACK_BIT_Y; @@ -298,6 +319,4 @@ protected: // These functions should not be called outside acceleration code. } }; -#define FOR_ALL_ROADVEHICLES(var) FOR_ALL_VEHICLES_OF_TYPE(RoadVehicle, var) - #endif /* ROADVEH_H */ diff --git a/src/roadveh_cmd.cpp b/src/roadveh_cmd.cpp index 9704770016..261af7042b 100644 --- a/src/roadveh_cmd.cpp +++ b/src/roadveh_cmd.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. @@ -86,14 +84,14 @@ bool RoadVehicle::IsBus() const /** * Get the width of a road vehicle image in the GUI. - * @param offset Additional offset for positioning the sprite; set to NULL if not needed + * @param offset Additional offset for positioning the sprite; set to nullptr if not needed * @return Width in pixels */ int RoadVehicle::GetDisplayImageWidth(Point *offset) const { int reference_width = ROADVEHINFO_DEFAULT_VEHICLE_WIDTH; - if (offset != NULL) { + if (offset != nullptr) { offset->x = ScaleGUITrad(reference_width) / 2; offset->y = 0; } @@ -192,7 +190,7 @@ static uint GetRoadVehLength(const RoadVehicle *v) uint length = VEHICLE_LENGTH; uint16 veh_len = CALLBACK_FAILED; - if (e->GetGRF() != NULL && e->GetGRF()->grf_version >= 8) { + if (e->GetGRF() != nullptr && e->GetGRF()->grf_version >= 8) { /* Use callback 36 */ veh_len = GetVehicleProperty(v, PROP_ROADVEH_SHORTEN_FACTOR, CALLBACK_FAILED); if (veh_len != CALLBACK_FAILED && veh_len >= VEHICLE_LENGTH) ErrorUnknownCallbackResult(e->GetGRFID(), CBID_VEHICLE_LENGTH, veh_len); @@ -223,7 +221,7 @@ void RoadVehUpdateCache(RoadVehicle *v, bool same_length) v->gcache.cached_total_length = 0; - for (RoadVehicle *u = v; u != NULL; u = u->Next()) { + for (RoadVehicle *u = v; u != nullptr; u = u->Next()) { /* Check the v->first cache. */ assert(u->First() == v); @@ -260,7 +258,10 @@ void RoadVehUpdateCache(RoadVehicle *v, bool same_length) */ CommandCost CmdBuildRoadVehicle(TileIndex tile, DoCommandFlag flags, const Engine *e, uint16 data, Vehicle **ret) { - if (HasTileRoadType(tile, ROADTYPE_TRAM) != HasBit(e->info.misc_flags, EF_ROAD_TRAM)) return_cmd_error(STR_ERROR_DEPOT_WRONG_DEPOT_TYPE); + /* Check that the vehicle can drive on the road in question */ + RoadType rt = e->u.road.roadtype; + const RoadTypeInfo *rti = GetRoadTypeInfo(rt); + if (!HasTileAnyRoadType(tile, rti->powered_roadtypes)) return_cmd_error(STR_ERROR_DEPOT_WRONG_DEPOT_TYPE); if (flags & DC_EXEC) { const RoadVehicleInfo *rvi = &e->u.road; @@ -304,8 +305,8 @@ CommandCost CmdBuildRoadVehicle(TileIndex tile, DoCommandFlag flags, const Engin v->random_bits = VehicleRandomBits(); v->SetFrontEngine(); - v->roadtype = HasBit(e->info.misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD; - v->compatible_roadtypes = RoadTypeToRoadTypes(v->roadtype); + v->roadtype = rt; + v->compatible_roadtypes = rti->powered_roadtypes; v->gcache.cached_veh_length = VEHICLE_LENGTH; if (e->flags & ENGINE_EXCLUSIVE_PREVIEW) SetBit(v->vehicle_flags, VF_BUILT_AS_PROTOTYPE); @@ -315,7 +316,7 @@ CommandCost CmdBuildRoadVehicle(TileIndex tile, DoCommandFlag flags, const Engin v->InvalidateNewGRFCacheOfChain(); /* Call various callbacks after the whole consist has been constructed */ - for (RoadVehicle *u = v; u != NULL; u = u->Next()) { + for (RoadVehicle *u = v; u != nullptr; u = u->Next()) { u->cargo_cap = u->GetEngine()->DetermineCapacity(u); u->refit_cap = 0; v->InvalidateNewGRFCache(); @@ -350,8 +351,8 @@ bool RoadVehicle::FindClosestDepot(TileIndex *location, DestinationID *destinati FindDepotData rfdd = FindClosestRoadDepot(this, 0); if (rfdd.best_length == UINT_MAX) return false; - if (location != NULL) *location = rfdd.tile; - if (destination != NULL) *destination = GetDepotIndex(rfdd.tile); + if (location != nullptr) *location = rfdd.tile; + if (destination != nullptr) *destination = GetDepotIndex(rfdd.tile); return true; } @@ -368,7 +369,7 @@ bool RoadVehicle::FindClosestDepot(TileIndex *location, DestinationID *destinati CommandCost CmdTurnRoadVeh(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { RoadVehicle *v = RoadVehicle::GetIfValid(p1); - if (v == NULL) return CMD_ERROR; + if (v == nullptr) return CMD_ERROR; if (!v->IsPrimaryVehicle()) return CMD_ERROR; @@ -397,7 +398,7 @@ CommandCost CmdTurnRoadVeh(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 void RoadVehicle::MarkDirty() { - for (RoadVehicle *v = this; v != NULL; v = v->Next()) { + for (RoadVehicle *v = this; v != nullptr; v = v->Next()) { v->colourmap = PAL_NONE; v->UpdateViewport(true, false); } @@ -437,16 +438,16 @@ void RoadVehicle::UpdateDeltaXY() */ inline int RoadVehicle::GetCurrentMaxSpeed() const { - int max_speed = this->vcache.cached_max_speed; + int max_speed = this->gcache.cached_max_track_speed; /* Limit speed to 50% while reversing, 75% in curves. */ - for (const RoadVehicle *u = this; u != NULL; u = u->Next()) { + for (const RoadVehicle *u = this; u != nullptr; u = u->Next()) { if (_settings_game.vehicle.roadveh_acceleration_model == AM_REALISTIC) { if (this->state <= RVSB_TRACKDIR_MASK && IsReversingRoadTrackdir((Trackdir)this->state)) { - max_speed = this->vcache.cached_max_speed / 2; + max_speed = this->gcache.cached_max_track_speed / 2; break; } else if ((u->direction & 1) == 0) { - max_speed = this->vcache.cached_max_speed * 3 / 4; + max_speed = this->gcache.cached_max_track_speed * 3 / 4; } } @@ -467,8 +468,8 @@ static void DeleteLastRoadVeh(RoadVehicle *v) { RoadVehicle *first = v->First(); Vehicle *u = v; - for (; v->Next() != NULL; v = v->Next()) u = v; - u->SetNext(NULL); + for (; v->Next() != nullptr; v = v->Next()) u = v; + u->SetNext(nullptr); v->last_station_visited = first->last_station_visited; // for PreDestructor /* Only leave the road stop when we're really gone. */ @@ -488,7 +489,7 @@ static void RoadVehSetRandomDirection(RoadVehicle *v) v->direction = ChangeDir(v->direction, delta[r & 3]); v->UpdateViewport(true, true); - } while ((v = v->Next()) != NULL); + } while ((v = v->Next()) != nullptr); } /** @@ -504,7 +505,7 @@ static bool RoadVehIsCrashed(RoadVehicle *v) } else if (v->crashed_ctr <= 45) { if ((v->tick_counter & 7) == 0) RoadVehSetRandomDirection(v); } else if (v->crashed_ctr >= 2220 && !(v->tick_counter & 0x1F)) { - bool ret = v->Next() != NULL; + bool ret = v->Next() != nullptr; DeleteLastRoadVeh(v); return ret; } @@ -516,7 +517,7 @@ static bool RoadVehIsCrashed(RoadVehicle *v) * Check routine whether a road and a train vehicle have collided. * @param v %Train vehicle to test. * @param data Road vehicle to test. - * @return %Train vehicle if the vehicles collided, else \c NULL. + * @return %Train vehicle if the vehicles collided, else \c nullptr. */ static Vehicle *EnumCheckRoadVehCrashTrain(Vehicle *v, void *data) { @@ -525,7 +526,7 @@ static Vehicle *EnumCheckRoadVehCrashTrain(Vehicle *v, void *data) return (v->type == VEH_TRAIN && abs(v->z_pos - u->z_pos) <= 6 && abs(v->x_pos - u->x_pos) <= 4 && - abs(v->y_pos - u->y_pos) <= 4) ? v : NULL; + abs(v->y_pos - u->y_pos) <= 4) ? v : nullptr; } uint RoadVehicle::Crash(bool flooded) @@ -564,7 +565,7 @@ static void RoadVehCrash(RoadVehicle *v) static bool RoadVehCheckTrainCrash(RoadVehicle *v) { - for (RoadVehicle *u = v; u != NULL; u = u->Next()) { + for (RoadVehicle *u = v; u != nullptr; u = u->Next()) { if (u->state == RVSB_WORMHOLE) continue; TileIndex tile = u->tile; @@ -641,7 +642,7 @@ static Vehicle *EnumCheckRoadVehClose(Vehicle *v, void *data) } } - return NULL; + return nullptr; } static RoadVehicle *RoadVehFindCloseTo(RoadVehicle *v, int x, int y, Direction dir, bool update_blocked_ctr = true) @@ -649,7 +650,7 @@ static RoadVehicle *RoadVehFindCloseTo(RoadVehicle *v, int x, int y, Direction d RoadVehFindData rvf; RoadVehicle *front = v->First(); - if (front->reverse_ctr != 0) return NULL; + if (front->reverse_ctr != 0) return nullptr; rvf.x = x; rvf.y = y; @@ -670,10 +671,10 @@ static RoadVehicle *RoadVehFindCloseTo(RoadVehicle *v, int x, int y, Direction d * It can be disabled. */ if (rvf.best_diff == UINT_MAX) { front->blocked_ctr = 0; - return NULL; + return nullptr; } - if (update_blocked_ctr && ++front->blocked_ctr > 1480) return NULL; + if (update_blocked_ctr && ++front->blocked_ctr > 1480) return nullptr; return RoadVehicle::From(rvf.best); } @@ -691,7 +692,7 @@ static void RoadVehArrivesAt(const RoadVehicle *v, Station *st) st->had_vehicle_of_type |= HVOT_BUS; SetDParam(0, st->index); AddVehicleNewsItem( - v->roadtype == ROADTYPE_ROAD ? STR_NEWS_FIRST_BUS_ARRIVAL : STR_NEWS_FIRST_PASSENGER_TRAM_ARRIVAL, + RoadTypeIsRoad(v->roadtype) ? STR_NEWS_FIRST_BUS_ARRIVAL : STR_NEWS_FIRST_PASSENGER_TRAM_ARRIVAL, (v->owner == _local_company) ? NT_ARRIVAL_COMPANY : NT_ARRIVAL_OTHER, v->index, st->index @@ -705,7 +706,7 @@ static void RoadVehArrivesAt(const RoadVehicle *v, Station *st) st->had_vehicle_of_type |= HVOT_TRUCK; SetDParam(0, st->index); AddVehicleNewsItem( - v->roadtype == ROADTYPE_ROAD ? STR_NEWS_FIRST_TRUCK_ARRIVAL : STR_NEWS_FIRST_CARGO_TRAM_ARRIVAL, + RoadTypeIsRoad(v->roadtype) ? STR_NEWS_FIRST_TRUCK_ARRIVAL : STR_NEWS_FIRST_CARGO_TRAM_ARRIVAL, (v->owner == _local_company) ? NT_ARRIVAL_COMPANY : NT_ARRIVAL_OTHER, v->index, st->index @@ -772,7 +773,7 @@ static Vehicle *EnumFindVehBlockingOvertake(Vehicle *v, void *data) { const OvertakeData *od = (OvertakeData*)data; - return (v->type == VEH_ROAD && v->First() == v && v != od->u && v != od->v) ? v : NULL; + return (v->type == VEH_ROAD && v->First() == v && v != od->u && v != od->v) ? v : nullptr; } /** @@ -783,7 +784,8 @@ static Vehicle *EnumFindVehBlockingOvertake(Vehicle *v, void *data) */ static bool CheckRoadBlockedForOvertaking(OvertakeData *od) { - TrackStatus ts = GetTileTrackStatus(od->tile, TRANSPORT_ROAD, od->v->compatible_roadtypes); + if (!HasTileAnyRoadType(od->tile, od->v->compatible_roadtypes)) return true; + TrackStatus ts = GetTileTrackStatus(od->tile, TRANSPORT_ROAD, GetRoadTramType(od->v->roadtype)); TrackdirBits trackdirbits = TrackStatusToTrackdirBits(ts); TrackdirBits red_signals = TrackStatusToRedSignals(ts); // barred level crossing TrackBits trackbits = TrackdirBitsToTrackBits(trackdirbits); @@ -803,7 +805,7 @@ static void RoadVehCheckOvertake(RoadVehicle *v, RoadVehicle *u) od.u = u; /* Trams can't overtake other trams */ - if (v->roadtype == ROADTYPE_TRAM) return; + if (RoadTypeIsTram(v->roadtype)) return; /* Don't overtake in stations */ if (IsTileType(v->tile, MP_STATION) || IsTileType(u->tile, MP_STATION)) return; @@ -855,7 +857,7 @@ static void RoadZPosAffectSpeed(RoadVehicle *v, int old_z) v->cur_speed = v->cur_speed * 232 / 256; // slow down by ~10% } else { uint16 spd = v->cur_speed + 2; - if (spd <= v->vcache.cached_max_speed) v->cur_speed = spd; + if (spd <= v->gcache.cached_max_track_speed) v->cur_speed = spd; } } @@ -884,12 +886,12 @@ static Trackdir RoadFindPathToDest(RoadVehicle *v, TileIndex tile, DiagDirection Trackdir best_track; bool path_found = true; - TrackStatus ts = GetTileTrackStatus(tile, TRANSPORT_ROAD, v->compatible_roadtypes); + TrackStatus ts = GetTileTrackStatus(tile, TRANSPORT_ROAD, GetRoadTramType(v->roadtype)); TrackdirBits red_signals = TrackStatusToRedSignals(ts); // crossing TrackdirBits trackdirs = TrackStatusToTrackdirBits(ts); if (IsTileType(tile, MP_ROAD)) { - if (IsRoadDepot(tile) && (!IsTileOwner(tile, v->owner) || GetRoadDepotDirection(tile) == enterdir || (GetRoadTypes(tile) & v->compatible_roadtypes) == 0)) { + if (IsRoadDepot(tile) && (!IsTileOwner(tile, v->owner) || GetRoadDepotDirection(tile) == enterdir)) { /* Road depot owned by another company or with the wrong orientation */ trackdirs = TRACKDIR_BIT_NONE; } @@ -924,16 +926,18 @@ static Trackdir RoadFindPathToDest(RoadVehicle *v, TileIndex tile, DiagDirection /* Remove tracks unreachable from the enter dir */ trackdirs &= DiagdirReachesTrackdirs(enterdir); if (trackdirs == TRACKDIR_BIT_NONE) { + /* If vehicle expected a path, it no longer exists, so invalidate it. */ + if (!v->path.empty()) v->path.clear(); /* No reachable tracks, so we'll reverse */ return_track(_road_reverse_table[enterdir]); } if (v->reverse_ctr != 0) { bool reverse = true; - if (v->roadtype == ROADTYPE_TRAM) { + if (RoadTypeIsTram(v->roadtype)) { /* Trams may only reverse on a tile if it contains at least the straight * trackbits or when it is a valid turning tile (i.e. one roadbit) */ - RoadBits rb = GetAnyRoadBits(tile, ROADTYPE_TRAM); + RoadBits rb = GetAnyRoadBits(tile, RTT_TRAM); RoadBits straight = AxisToRoadBits(DiagDirToAxis(enterdir)); reverse = ((rb & straight) == straight) || (rb == DiagDirToRoadBits(enterdir)); @@ -954,12 +958,35 @@ static Trackdir RoadFindPathToDest(RoadVehicle *v, TileIndex tile, DiagDirection /* Only one track to choose between? */ if (KillFirstBit(trackdirs) == TRACKDIR_BIT_NONE) { + if (!v->path.empty() && v->path.tile.front() == tile) { + /* Vehicle expected a choice here, invalidate its path. */ + v->path.clear(); + } return_track(FindFirstBit2x64(trackdirs)); } + /* Attempt to follow cached path. */ + if (!v->path.empty()) { + if (v->path.tile.front() != tile) { + /* Vehicle didn't expect a choice here, invalidate its path. */ + v->path.clear(); + } else { + Trackdir trackdir = v->path.td.front(); + + if (HasBit(trackdirs, trackdir)) { + v->path.td.pop_front(); + v->path.tile.pop_front(); + return_track(trackdir); + } + + /* Vehicle expected a choice which is no longer available. */ + v->path.clear(); + } + } + switch (_settings_game.pf.pathfinder_for_roadvehs) { case VPF_NPF: best_track = NPFRoadVehicleChooseTrack(v, tile, enterdir, path_found); break; - case VPF_YAPF: best_track = YapfRoadVehicleChooseTrack(v, tile, enterdir, trackdirs, path_found); break; + case VPF_YAPF: best_track = YapfRoadVehicleChooseTrack(v, tile, enterdir, trackdirs, path_found, v->path); break; default: NOT_REACHED(); } @@ -981,7 +1008,7 @@ struct RoadDriveEntry { static bool RoadVehLeaveDepot(RoadVehicle *v, bool first) { /* Don't leave unless v and following wagons are in the depot. */ - for (const RoadVehicle *u = v; u != NULL; u = u->Next()) { + for (const RoadVehicle *u = v; u != nullptr; u = u->Next()) { if (u->state != RVSB_IN_DEPOT || u->tile != v->tile) return false; } @@ -989,7 +1016,7 @@ static bool RoadVehLeaveDepot(RoadVehicle *v, bool first) v->direction = DiagDirToDir(dir); Trackdir tdir = DiagDirToDiagTrackdir(dir); - const RoadDriveEntry *rdp = _road_drive_data[v->roadtype][(_settings_game.vehicle.road_side << RVS_DRIVE_SIDE) + tdir]; + const RoadDriveEntry *rdp = _road_drive_data[GetRoadTramType(v->roadtype)][(_settings_game.vehicle.road_side << RVS_DRIVE_SIDE) + tdir]; int x = TileX(v->tile) * TILE_SIZE + (rdp[RVC_DEPOT_START_FRAME].x & 0xF); int y = TileY(v->tile) * TILE_SIZE + (rdp[RVC_DEPOT_START_FRAME].y & 0xF); @@ -1001,7 +1028,7 @@ static bool RoadVehLeaveDepot(RoadVehicle *v, bool first) return true; } - if (RoadVehFindCloseTo(v, x, y, v->direction, false) != NULL) return true; + if (RoadVehFindCloseTo(v, x, y, v->direction, false) != nullptr) return true; VehicleServiceInDepot(v); @@ -1084,7 +1111,7 @@ static Trackdir FollowPreviousRoadVehicle(const RoadVehicle *v, const RoadVehicl }; RoadBits required = required_roadbits[dir & 0x07]; - if ((required & GetAnyRoadBits(tile, v->roadtype, true)) == ROAD_NONE) { + if ((required & GetAnyRoadBits(tile, GetRoadTramType(v->roadtype), true)) == ROAD_NONE) { dir = INVALID_TRACKDIR; } @@ -1095,15 +1122,16 @@ static Trackdir FollowPreviousRoadVehicle(const RoadVehicle *v, const RoadVehicl * Can a tram track build without destruction on the given tile? * @param c the company that would be building the tram tracks * @param t the tile to build on. + * @param rt the tram type to build. * @param r the road bits needed. * @return true when a track track can be build on 't' */ -static bool CanBuildTramTrackOnTile(CompanyID c, TileIndex t, RoadBits r) +static bool CanBuildTramTrackOnTile(CompanyID c, TileIndex t, RoadType rt, RoadBits r) { /* The 'current' company is not necessarily the owner of the vehicle. */ - Backup cur_company(_current_company, c, FILE_LINE); + Backup cur_company(_current_company, c, FILE_LINE); - CommandCost ret = DoCommand(t, ROADTYPE_TRAM << 4 | r, 0, DC_NO_WATER, CMD_BUILD_ROAD); + CommandCost ret = DoCommand(t, rt << 4 | r, 0, DC_NO_WATER, CMD_BUILD_ROAD); cur_company.Restore(); return ret.Succeeded(); @@ -1136,7 +1164,7 @@ bool IndividualRoadVehicleController(RoadVehicle *v, const RoadVehicle *prev) if (v->IsFrontEngine()) { const Vehicle *u = RoadVehFindCloseTo(v, gp.x, gp.y, v->direction); - if (u != NULL) { + if (u != nullptr) { v->cur_speed = u->First()->cur_speed; return false; } @@ -1161,7 +1189,7 @@ bool IndividualRoadVehicleController(RoadVehicle *v, const RoadVehicle *prev) /* Get move position data for next frame. * For a drive-through road stop use 'straight road' move data. * In this case v->state is masked to give the road stop entry direction. */ - RoadDriveEntry rd = _road_drive_data[v->roadtype][( + RoadDriveEntry rd = _road_drive_data[GetRoadTramType(v->roadtype)][( (HasBit(v->state, RVS_IN_DT_ROAD_STOP) ? v->state & RVSB_ROAD_STOP_TRACKDIR_MASK : v->state) + (_settings_game.vehicle.road_side << RVS_DRIVE_SIDE)) ^ v->overtaking][v->frame + 1]; @@ -1171,7 +1199,11 @@ bool IndividualRoadVehicleController(RoadVehicle *v, const RoadVehicle *prev) if (v->IsFrontEngine()) { /* If this is the front engine, look for the right path. */ - dir = RoadFindPathToDest(v, tile, (DiagDirection)(rd.x & 3)); + if (HasTileAnyRoadType(tile, v->compatible_roadtypes)) { + dir = RoadFindPathToDest(v, tile, (DiagDirection)(rd.x & 3)); + } else { + dir = _road_reverse_table[(DiagDirection)(rd.x & 3)]; + } } else { dir = FollowPreviousRoadVehicle(v, prev, tile, (DiagDirection)(rd.x & 3), false); } @@ -1189,7 +1221,7 @@ again: v->overtaking = 0; /* Turning around */ - if (v->roadtype == ROADTYPE_TRAM) { + if (RoadTypeIsTram(v->roadtype)) { /* Determine the road bits the tram needs to be able to turn around * using the 'big' corner loop. */ RoadBits needed; @@ -1200,9 +1232,10 @@ again: case TRACKDIR_RVREV_SW: needed = ROAD_NE; break; case TRACKDIR_RVREV_NW: needed = ROAD_SE; break; } - if ((v->Previous() != NULL && v->Previous()->tile == tile) || + if ((v->Previous() != nullptr && v->Previous()->tile == tile) || (v->IsFrontEngine() && IsNormalRoadTile(tile) && !HasRoadWorks(tile) && - (needed & GetRoadBits(tile, ROADTYPE_TRAM)) != ROAD_NONE)) { + HasTileAnyRoadType(tile, v->compatible_roadtypes) && + (needed & GetRoadBits(tile, RTT_TRAM)) != ROAD_NONE)) { /* * Taking the 'big' corner for trams only happens when: * - The previous vehicle in this (articulated) tram chain is @@ -1213,7 +1246,7 @@ again: * going to cause the tram to split up. * - Or the front of the tram can drive over the next tile. */ - } else if (!v->IsFrontEngine() || !CanBuildTramTrackOnTile(v->owner, tile, needed) || ((~needed & GetAnyRoadBits(v->tile, ROADTYPE_TRAM, false)) == ROAD_NONE)) { + } else if (!v->IsFrontEngine() || !CanBuildTramTrackOnTile(v->owner, tile, v->roadtype, needed) || ((~needed & GetAnyRoadBits(v->tile, RTT_TRAM, false)) == ROAD_NONE)) { /* * Taking the 'small' corner for trams only happens when: * - We are not the from vehicle of an articulated tram. @@ -1241,7 +1274,7 @@ again: } /* Get position data for first frame on the new tile */ - const RoadDriveEntry *rdp = _road_drive_data[v->roadtype][(dir + (_settings_game.vehicle.road_side << RVS_DRIVE_SIDE)) ^ v->overtaking]; + const RoadDriveEntry *rdp = _road_drive_data[GetRoadTramType(v->roadtype)][(dir + (_settings_game.vehicle.road_side << RVS_DRIVE_SIDE)) ^ v->overtaking]; int x = TileX(tile) * TILE_SIZE + rdp[start_frame].x; int y = TileY(tile) * TILE_SIZE + rdp[start_frame].y; @@ -1249,7 +1282,7 @@ again: Direction new_dir = RoadVehGetSlidingDirection(v, x, y); if (v->IsFrontEngine()) { Vehicle *u = RoadVehFindCloseTo(v, x, y, new_dir); - if (u != NULL) { + if (u != nullptr) { v->cur_speed = u->First()->cur_speed; return false; } @@ -1293,9 +1326,18 @@ again: } if (!HasBit(r, VETS_ENTERED_WORMHOLE)) { + TileIndex old_tile = v->tile; + v->tile = tile; v->state = (byte)dir; v->frame = start_frame; + RoadTramType rtt = GetRoadTramType(v->roadtype); + if (GetRoadType(old_tile, rtt) != GetRoadType(tile, rtt)) { + if (v->IsFrontEngine()) { + RoadVehUpdateCache(v); + } + v->First()->CargoChanged(); + } } if (new_dir != v->direction) { v->direction = new_dir; @@ -1313,7 +1355,7 @@ again: Trackdir dir; uint turn_around_start_frame = RVC_TURN_AROUND_START_FRAME; - if (v->roadtype == ROADTYPE_TRAM && !IsRoadDepotTile(v->tile) && HasExactlyOneBit(GetAnyRoadBits(v->tile, ROADTYPE_TRAM, true))) { + if (RoadTypeIsTram(v->roadtype) && !IsRoadDepotTile(v->tile) && HasExactlyOneBit(GetAnyRoadBits(v->tile, RTT_TRAM, true))) { /* * The tram is turning around with one tram 'roadbit'. This means that * it is using the 'big' corner 'drive data'. However, to support the @@ -1345,13 +1387,13 @@ again: return false; } - const RoadDriveEntry *rdp = _road_drive_data[v->roadtype][(_settings_game.vehicle.road_side << RVS_DRIVE_SIDE) + dir]; + const RoadDriveEntry *rdp = _road_drive_data[GetRoadTramType(v->roadtype)][(_settings_game.vehicle.road_side << RVS_DRIVE_SIDE) + dir]; int x = TileX(v->tile) * TILE_SIZE + rdp[turn_around_start_frame].x; 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) != NULL) return false; + if (v->IsFrontEngine() && RoadVehFindCloseTo(v, x, y, new_dir) != nullptr) return false; uint32 r = VehicleEnterTile(v, v->tile, x, y); if (HasBit(r, VETS_CANNOT_ENTER)) { @@ -1377,7 +1419,7 @@ again: /* This vehicle is not in a wormhole and it hasn't entered a new tile. If * it's on a depot tile, check if it's time to activate the next vehicle in * the chain yet. */ - if (v->Next() != NULL && IsRoadDepotTile(v->tile)) { + if (v->Next() != nullptr && IsRoadDepotTile(v->tile)) { if (v->frame == v->gcache.cached_veh_length + RVC_DEPOT_START_FRAME) { RoadVehLeaveDepot(v->Next(), false); } @@ -1394,7 +1436,7 @@ again: * Check for another vehicle to overtake */ RoadVehicle *u = RoadVehFindCloseTo(v, x, y, new_dir); - if (u != NULL) { + if (u != nullptr) { u = u->First(); /* There is a vehicle in front overtake it if possible */ if (v->overtaking == 0) RoadVehCheckOvertake(v, u); @@ -1453,7 +1495,7 @@ again: TileIndex next_tile = TileAddByDir(v->tile, v->direction); /* Check if next inline bay is free and has compatible road. */ - if (RoadStop::IsDriveThroughRoadStopContinuation(v->tile, next_tile) && (GetRoadTypes(next_tile) & v->compatible_roadtypes) != 0) { + if (RoadStop::IsDriveThroughRoadStopContinuation(v->tile, next_tile) && HasTileAnyRoadType(next_tile, v->compatible_roadtypes)) { v->frame++; v->x_pos = x; v->y_pos = y; @@ -1544,7 +1586,7 @@ static bool RoadVehController(RoadVehicle *v) j -= adv_spd; RoadVehicle *u = v; - for (RoadVehicle *prev = NULL; u != NULL; prev = u, u = u->Next()) { + for (RoadVehicle *prev = nullptr; u != nullptr; prev = u, u = u->Next()) { if (!IndividualRoadVehicleController(u, prev)) { blocked = true; break; @@ -1561,7 +1603,7 @@ static bool RoadVehController(RoadVehicle *v) v->SetLastSpeed(); - for (RoadVehicle *u = v; u != NULL; u = u->Next()) { + for (RoadVehicle *u = v; u != nullptr; u = u->Next()) { if ((u->vehstatus & VS_HIDDEN) != 0) continue; u->UpdateViewport(false, false); @@ -1600,6 +1642,13 @@ bool RoadVehicle::Tick() return true; } +void RoadVehicle::SetDestTile(TileIndex tile) +{ + if (tile == this->dest_tile) return; + this->path.clear(); + this->dest_tile = tile; +} + static void CheckIfRoadVehNeedsService(RoadVehicle *v) { /* If we already got a slot at a stop, use that FIRST, and go to a depot later */ diff --git a/src/roadveh_gui.cpp b/src/roadveh_gui.cpp index 63e0549582..f25bd734f9 100644 --- a/src/roadveh_gui.cpp +++ b/src/roadveh_gui.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. @@ -47,7 +45,7 @@ void DrawRoadVehDetails(const Vehicle *v, int left, int right, int y) memset(subtype_text, 0, sizeof(subtype_text)); - for (const Vehicle *u = v; u != NULL; u = u->Next()) { + for (const Vehicle *u = v; u != nullptr; u = u->Next()) { max_cargo[u->cargo_type] += u->cargo_cap; if (u->cargo_cap > 0) { StringID text = GetCargoSubtypeText(u); @@ -80,7 +78,7 @@ void DrawRoadVehDetails(const Vehicle *v, int left, int right, int y) DrawString(left, right, y + FONT_HEIGHT_NORMAL + y_offset, capacity, TC_BLUE); - for (const Vehicle *u = v; u != NULL; u = u->Next()) { + for (const Vehicle *u = v; u != nullptr; u = u->Next()) { if (u->cargo_cap == 0) continue; str = STR_VEHICLE_DETAILS_CARGO_EMPTY; @@ -143,7 +141,7 @@ void DrawRoadVehImage(const Vehicle *v, int left, int right, int y, VehicleID se _cur_dpi = &tmp_dpi; int px = rtl ? max_width + skip : -skip; - for (; u != NULL && (rtl ? px > 0 : px < max_width); u = u->Next()) { + for (; u != nullptr && (rtl ? px > 0 : px < max_width); u = u->Next()) { Point offset; int width = u->GetDisplayImageWidth(&offset); diff --git a/src/safeguards.h b/src/safeguards.h index f447627e68..5351116ecb 100644 --- a/src/safeguards.h +++ b/src/safeguards.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. @@ -12,7 +10,7 @@ * * Unsafe methods are, for example, strndup and strncpy because they may leave the * string without a null termination, but also strdup and strndup because they can - * return NULL and then all strdups would need to be guarded against that instead + * return nullptr and then all strdups would need to be guarded against that instead * of using the current MallocT/ReallocT/CallocT technique of just giving the user * an error that too much memory was used instead of spreading that code though * the whole code base. diff --git a/src/saveload/afterload.cpp b/src/saveload/afterload.cpp index 96def205c5..022fd28e93 100644 --- a/src/saveload/afterload.cpp +++ b/src/saveload/afterload.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. @@ -19,6 +17,7 @@ #include "../network/network_func.h" #include "../gfxinit.h" #include "../viewport_func.h" +#include "../viewport_kdtree.h" #include "../industry.h" #include "../clear_map.h" #include "../vehicle_func.h" @@ -56,6 +55,7 @@ #include "../error.h" #include "../disaster_vehicle.h" #include "../ship.h" +#include "../water.h" #include "saveload_internal.h" @@ -169,9 +169,7 @@ static void ConvertTownOwner() /* since savegame version 4.1, exclusive transport rights are stored at towns */ static void UpdateExclusiveRights() { - Town *t; - - FOR_ALL_TOWNS(t) { + for (Town *t : Town::Iterate()) { t->exclusivity = INVALID_COMPANY; } @@ -221,6 +219,14 @@ void UpdateAllVirtCoords() UpdateAllStationVirtCoords(); UpdateAllSignVirtCoords(); UpdateAllTownVirtCoords(); + RebuildViewportKdtree(); +} + +void ClearAllCachedNames() +{ + ClearAllStationCachedNames(); + ClearAllTownCachedNames(); + ClearAllIndustryCachedNames(); } /** @@ -228,7 +234,7 @@ void UpdateAllVirtCoords() * This is not done directly in AfterLoadGame because these * functions require that all saveload conversions have been * done. As people tend to add savegame conversion stuff after - * the intialization of the windows and caches quite some bugs + * the initialization of the windows and caches quite some bugs * had been made. * Moving this out of there is both cleaner and less bug-prone. */ @@ -239,11 +245,11 @@ static void InitializeWindowsAndCaches() SetupColoursAndInitialWindow(); /* Update coordinates of the signs. */ + ClearAllCachedNames(); UpdateAllVirtCoords(); ResetViewportAfterLoadGame(); - Company *c; - FOR_ALL_COMPANIES(c) { + 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, * thus the MIN_YEAR (which is really nothing more than Zero, initialized value) test */ @@ -253,39 +259,39 @@ static void InitializeWindowsAndCaches() } /* Count number of objects per type */ - Object *o; - FOR_ALL_OBJECTS(o) { + for (Object *o : Object::Iterate()) { Object::IncTypeCount(o->type); } /* Identify owners of persistent storage arrays */ - Industry *i; - FOR_ALL_INDUSTRIES(i) { - if (i->psa != NULL) { + for (Industry *i : Industry::Iterate()) { + if (i->psa != nullptr) { i->psa->feature = GSF_INDUSTRIES; i->psa->tile = i->location.tile; } } - Station *s; - FOR_ALL_STATIONS(s) { - if (s->airport.psa != NULL) { + for (Station *s : Station::Iterate()) { + if (s->airport.psa != nullptr) { s->airport.psa->feature = GSF_AIRPORTS; s->airport.psa->tile = s->airport.tile; } } - Town *t; - FOR_ALL_TOWNS(t) { + for (Town *t : Town::Iterate()) { for (std::list::iterator it = t->psa_list.begin(); it != t->psa_list.end(); ++it) { (*it)->feature = GSF_FAKE_TOWNS; (*it)->tile = t->xy; } } + for (RoadVehicle *rv : RoadVehicle::Iterate()) { + if (rv->IsFrontEngine()) { + rv->CargoChanged(); + } + } RecomputePrices(); GroupStatistics::UpdateAfterLoad(); - Station::RecomputeIndustriesNearForAll(); RebuildSubsidisedSourceAndDestinationCache(); /* Towns have a noise controlled number of airports system @@ -302,9 +308,9 @@ static void InitializeWindowsAndCaches() } typedef void (CDECL *SignalHandlerPointer)(int); -static SignalHandlerPointer _prev_segfault = NULL; -static SignalHandlerPointer _prev_abort = NULL; -static SignalHandlerPointer _prev_fpe = NULL; +static SignalHandlerPointer _prev_segfault = nullptr; +static SignalHandlerPointer _prev_abort = nullptr; +static SignalHandlerPointer _prev_fpe = nullptr; static void CDECL HandleSavegameLoadCrash(int signum); @@ -374,7 +380,7 @@ static void CDECL HandleSavegameLoadCrash(int signum) char *p = buffer; p += seprintf(p, lastof(buffer), "Loading your savegame caused OpenTTD to crash.\n"); - for (const GRFConfig *c = _grfconfig; !_saveload_crash_with_missing_newgrfs && c != NULL; c = c->next) { + for (const GRFConfig *c = _grfconfig; !_saveload_crash_with_missing_newgrfs && c != nullptr; c = c->next) { _saveload_crash_with_missing_newgrfs = HasBit(c->flags, GCF_COMPATIBLE) || c->status == GCS_NOT_FOUND; } @@ -392,7 +398,7 @@ static void CDECL HandleSavegameLoadCrash(int signum) "Please load the savegame with the appropriate NewGRFs installed.\n" "The missing/compatible NewGRFs are:\n"); - for (const GRFConfig *c = _grfconfig; c != NULL; c = c->next) { + for (const GRFConfig *c = _grfconfig; c != nullptr; c = c->next) { if (HasBit(c->flags, GCF_COMPATIBLE)) { const GRFIdentifier *replaced = GetOverriddenIdentifier(c); char buf[40]; @@ -413,14 +419,14 @@ static void CDECL HandleSavegameLoadCrash(int signum) ShowInfo(buffer); - SignalHandlerPointer call = NULL; + SignalHandlerPointer call = nullptr; switch (signum) { case SIGSEGV: call = _prev_segfault; break; case SIGABRT: call = _prev_abort; break; case SIGFPE: call = _prev_fpe; break; default: NOT_REACHED(); } - if (call != NULL) call(signum); + if (call != nullptr) call(signum); } /** @@ -433,15 +439,15 @@ static void FixOwnerOfRailTrack(TileIndex t) assert(!Company::IsValidID(GetTileOwner(t)) && (IsLevelCrossingTile(t) || IsPlainRailTile(t))); /* remove leftover rail piece from crossing (from very old savegames) */ - Train *v = NULL, *w; - FOR_ALL_TRAINS(w) { + Train *v = nullptr; + for (Train *w : Train::Iterate()) { if (w->tile == t) { v = w; break; } } - if (v != NULL) { + if (v != nullptr) { /* when there is a train on crossing (it could happen in TTD), set owner of crossing to train owner */ SetTileOwner(t, v->owner); return; @@ -460,8 +466,19 @@ static void FixOwnerOfRailTrack(TileIndex t) if (IsLevelCrossingTile(t)) { /* else change the crossing to normal road (road vehicles won't care) */ - MakeRoadNormal(t, GetCrossingRoadBits(t), GetRoadTypes(t), GetTownIndex(t), - GetRoadOwner(t, ROADTYPE_ROAD), GetRoadOwner(t, ROADTYPE_TRAM)); + 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); + + /* 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); + SetRoadOwner(t, RTT_TRAM, tram); return; } @@ -537,6 +554,12 @@ bool AfterLoadGame() GamelogTestRevision(); GamelogTestMode(); + RebuildTownKdtree(); + RebuildStationKdtree(); + /* This needs to be done even before conversion, because some conversions will destroy objects + * that otherwise won't exist in the tree. */ + RebuildViewportKdtree(); + if (IsSavegameVersionBefore(SLV_98)) GamelogGRFAddList(_grfconfig); if (IsSavegameVersionBefore(SLV_119)) { @@ -565,14 +588,13 @@ bool AfterLoadGame() * recompute the width and height. Doing this unconditionally for all old * savegames simplifies the code. */ if (IsSavegameVersionBefore(SLV_2)) { - Station *st; - FOR_ALL_STATIONS(st) { + for (Station *st : Station::Iterate()) { st->train_station.w = st->train_station.h = 0; } for (TileIndex t = 0; t < map_size; t++) { if (!IsTileType(t, MP_STATION)) continue; if (_m[t].m5 > 7) continue; // is it a rail station tile? - st = Station::Get(_m[t].m2); + Station *st = Station::Get(_m[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); @@ -621,25 +643,22 @@ bool AfterLoadGame() } if (IsSavegameVersionBefore(SLV_84)) { - Company *c; - FOR_ALL_COMPANIES(c) { + for (Company *c : Company::Iterate()) { c->name = CopyFromOldName(c->name_1); - if (c->name != NULL) c->name_1 = STR_SV_UNNAMED; + if (c->name != nullptr) c->name_1 = STR_SV_UNNAMED; c->president_name = CopyFromOldName(c->president_name_1); - if (c->president_name != NULL) c->president_name_1 = SPECSTR_PRESIDENT_NAME; + if (c->president_name != nullptr) c->president_name_1 = SPECSTR_PRESIDENT_NAME; } - Station *st; - FOR_ALL_STATIONS(st) { + for (Station *st : Station::Iterate()) { st->name = CopyFromOldName(st->string_id); /* generating new name would be too much work for little effect, use the station name fallback */ - if (st->name != NULL) st->string_id = STR_SV_STNAME_FALLBACK; + if (st->name != nullptr) st->string_id = STR_SV_STNAME_FALLBACK; } - Town *t; - FOR_ALL_TOWNS(t) { + for (Town *t : Town::Iterate()) { t->name = CopyFromOldName(t->townnametype); - if (t->name != NULL) t->townnametype = SPECSTR_TOWNNAME_START + _settings_game.game_creation.town_name; + if (t->name != nullptr) t->townnametype = SPECSTR_TOWNNAME_START + _settings_game.game_creation.town_name; } } @@ -648,16 +667,13 @@ bool AfterLoadGame() if (IsSavegameVersionBefore(SLV_106)) { /* no station is determined by 'tile == INVALID_TILE' now (instead of '0') */ - Station *st; - FOR_ALL_STATIONS(st) { + for (Station *st : Station::Iterate()) { if (st->airport.tile == 0) st->airport.tile = INVALID_TILE; - if (st->dock_tile == 0) st->dock_tile = INVALID_TILE; if (st->train_station.tile == 0) st->train_station.tile = INVALID_TILE; } /* the same applies to Company::location_of_HQ */ - Company *c; - FOR_ALL_COMPANIES(c) { + for (Company *c : Company::Iterate()) { if (c->location_of_HQ == 0 || (IsSavegameVersionBefore(SLV_4) && c->location_of_HQ == 0xFFFF)) { c->location_of_HQ = INVALID_TILE; } @@ -669,7 +685,7 @@ bool AfterLoadGame() /* Check if all NewGRFs are present, we are very strict in MP mode */ GRFListCompatibility gcf_res = IsGoodGRFConfigList(_grfconfig); - for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) { + for (GRFConfig *c = _grfconfig; c != nullptr; c = c->next) { if (c->status == GCS_NOT_FOUND) { GamelogGRFRemove(c->ident.grfid); } else if (HasBit(c->flags, GCF_COMPATIBLE)) { @@ -739,6 +755,15 @@ bool AfterLoadGame() _settings_game.linkgraph.distribution_default = DT_MANUAL; } + if (IsSavegameVersionBefore(SLV_105)) { + extern int32 _old_ending_year_slv_105; // in date.cpp + _settings_game.game_creation.ending_year = _old_ending_year_slv_105 - 1; + } else if (IsSavegameVersionBefore(SLV_ENDING_YEAR)) { + /* Ending year was a GUI setting before SLV_105, was removed in revision 683b65ee1 (svn r14755). */ + /* This also converts scenarios, both when loading them into the editor, and when starting a new game. */ + _settings_game.game_creation.ending_year = DEF_END_YEAR; + } + /* Load the sprites */ GfxLoadSprites(); LoadStringWidthTable(); @@ -765,8 +790,7 @@ bool AfterLoadGame() * here as AfterLoadVehicles can check it indirectly via the newgrf * code. */ if (IsSavegameVersionBefore(SLV_139)) { - Station *st; - FOR_ALL_STATIONS(st) { + for (Station *st : Station::Iterate()) { if (st->airport.tile != INVALID_TILE && st->airport.type == 15) { st->airport.type = AT_OILRIG; } @@ -778,9 +802,8 @@ bool AfterLoadGame() /* Make sure there is an AI attached to an AI company */ { - Company *c; - FOR_ALL_COMPANIES(c) { - if (c->is_ai && c->ai_instance == NULL) AI::StartNew(c->index); + for (const Company *c : Company::Iterate()) { + if (c->is_ai && c->ai_instance == nullptr) AI::StartNew(c->index); } } @@ -809,8 +832,7 @@ bool AfterLoadGame() } /* Fix the cache for cargo payments. */ - CargoPayment *cp; - FOR_ALL_CARGO_PAYMENTS(cp) { + for (CargoPayment *cp : CargoPayment::Iterate()) { cp->front->cargo_payment = cp; cp->current_station = cp->front->last_station_visited; } @@ -971,16 +993,14 @@ bool AfterLoadGame() /* From version 9.0, we update the max passengers of a town (was sometimes negative * before that. */ if (IsSavegameVersionBefore(SLV_9)) { - Town *t; - FOR_ALL_TOWNS(t) UpdateTownMaxPass(t); + for (Town *t : Town::Iterate()) UpdateTownMaxPass(t); } /* From version 16.0, we included autorenew on engines, which are now saved, but * of course, we do need to initialize them for older savegames. */ if (IsSavegameVersionBefore(SLV_16)) { - Company *c; - FOR_ALL_COMPANIES(c) { - c->engine_renew_list = NULL; + for (Company *c : Company::Iterate()) { + c->engine_renew_list = nullptr; c->settings.engine_renew = false; c->settings.engine_renew_months = 6; c->settings.engine_renew_money = 100000; @@ -992,8 +1012,8 @@ bool AfterLoadGame() * becomes company 0, unless we are in the scenario editor where all the * companies are 'invalid'. */ - c = Company::GetIfValid(COMPANY_FIRST); - if (!_network_dedicated && c != NULL) { + Company *c = Company::GetIfValid(COMPANY_FIRST); + if (!_network_dedicated && c != nullptr) { c->settings = _settings_client.company; } } @@ -1045,18 +1065,18 @@ bool AfterLoadGame() break; case ROAD_TILE_DEPOT: break; } - SetRoadTypes(t, ROADTYPES_ROAD); + SB(_me[t].m7, 6, 2, 1); // Set pre-NRT road type bits for conversion later. break; case MP_STATION: - if (IsRoadStop(t)) SetRoadTypes(t, ROADTYPES_ROAD); + if (IsRoadStop(t)) SB(_me[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) { - SetRoadTypes(t, ROADTYPES_ROAD); + SB(_me[t].m7, 6, 2, 1); // Set pre-NRT road type bits for conversion later. } break; @@ -1072,7 +1092,7 @@ bool AfterLoadGame() for (TileIndex t = 0; t < map_size; t++) { switch (GetTileType(t)) { case MP_ROAD: - if (fix_roadtypes) SetRoadTypes(t, (RoadTypes)GB(_me[t].m7, 5, 3)); + 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 switch (GetRoadTileType(t)) { default: SlErrorCorrupt("Invalid road tile type"); @@ -1097,7 +1117,7 @@ bool AfterLoadGame() } if (!IsRoadDepot(t) && !HasTownOwnedRoad(t)) { const Town *town = CalcClosestTownFromTile(t); - if (town != NULL) SetTownIndex(t, town->index); + if (town != nullptr) SetTownIndex(t, town->index); } _m[t].m4 = 0; break; @@ -1105,7 +1125,7 @@ bool AfterLoadGame() case MP_STATION: if (!IsRoadStop(t)) break; - if (fix_roadtypes) SetRoadTypes(t, (RoadTypes)GB(_m[t].m3, 0, 3)); + 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; @@ -1114,7 +1134,7 @@ bool AfterLoadGame() 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) SetRoadTypes(t, (RoadTypes)GB(_m[t].m3, 0, 3)); + if (fix_roadtypes) SB(_me[t].m7, 6, 2, (RoadTypes)GB(_m[t].m3, 0, 3)); Owner o = GetTileOwner(t); SB(_me[t].m7, 0, 5, o); // road owner @@ -1132,87 +1152,6 @@ bool AfterLoadGame() } } - if (IsSavegameVersionBefore(SLV_42)) { - Vehicle *v; - - for (TileIndex t = 0; t < map_size; t++) { - 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(_m[t].m5, 5)) { // transport route under bridge? - if (GB(_m[t].m5, 3, 2) == TRANSPORT_RAIL) { - MakeRailNormal( - t, - GetTileOwner(t), - axis == AXIS_X ? TRACK_BIT_Y : TRACK_BIT_X, - GetRailType(t) - ); - } else { - TownID town = IsTileOwner(t, OWNER_TOWN) ? ClosestTownFromTile(t, UINT_MAX)->index : 0; - - MakeRoadNormal( - t, - axis == AXIS_X ? ROAD_Y : ROAD_X, - ROADTYPES_ROAD, - town, - GetTileOwner(t), OWNER_NONE - ); - } - } else { - if (GB(_m[t].m5, 3, 2) == 0) { - MakeClear(t, CLEAR_GRASS, 3); - } else { - if (!IsTileFlat(t)) { - MakeShore(t); - } else { - if (GetTileOwner(t) == OWNER_WATER) { - MakeSea(t); - } else { - MakeCanal(t, GetTileOwner(t), Random()); - } - } - } - } - SetBridgeMiddle(t, axis); - } else { // ramp - Axis axis = (Axis)GB(_m[t].m5, 0, 1); - uint north_south = GB(_m[t].m5, 5, 1); - DiagDirection dir = ReverseDiagDir(XYNSToDiagDir(axis, north_south)); - TransportType type = (TransportType)GB(_m[t].m5, 1, 2); - - _m[t].m5 = 1 << 7 | type << 2 | dir; - } - } - } - - FOR_ALL_VEHICLES(v) { - if (!v->IsGroundVehicle()) continue; - if (IsBridgeTile(v->tile)) { - DiagDirection dir = GetTunnelBridgeDirection(v->tile); - - if (dir != DirToDiagDir(v->direction)) continue; - switch (dir) { - default: SlErrorCorrupt("Invalid vehicle direction"); - case DIAGDIR_NE: if ((v->x_pos & 0xF) != 0) continue; break; - case DIAGDIR_SE: if ((v->y_pos & 0xF) != TILE_SIZE - 1) continue; break; - case DIAGDIR_SW: if ((v->x_pos & 0xF) != TILE_SIZE - 1) continue; break; - case DIAGDIR_NW: if ((v->y_pos & 0xF) != 0) continue; break; - } - } else if (v->z_pos > GetSlopePixelZ(v->x_pos, v->y_pos)) { - v->tile = GetNorthernBridgeEnd(v->tile); - } else { - continue; - } - if (v->type == VEH_TRAIN) { - Train::From(v)->track = TRACK_BIT_WORMHOLE; - } else { - RoadVehicle::From(v)->state = RVSB_WORMHOLE; - } - } - } - /* Railtype moved from m3 to m8 in version SLV_EXTEND_RAILTYPES. */ if (IsSavegameVersionBefore(SLV_EXTEND_RAILTYPES)) { for (TileIndex t = 0; t < map_size; t++) { @@ -1245,12 +1184,120 @@ bool AfterLoadGame() } } + if (IsSavegameVersionBefore(SLV_42)) { + for (TileIndex t = 0; t < map_size; t++) { + 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(_m[t].m5, 5)) { // transport route under bridge? + if (GB(_m[t].m5, 3, 2) == TRANSPORT_RAIL) { + MakeRailNormal( + t, + GetTileOwner(t), + axis == AXIS_X ? TRACK_BIT_Y : TRACK_BIT_X, + GetRailType(t) + ); + } else { + TownID town = IsTileOwner(t, OWNER_TOWN) ? ClosestTownFromTile(t, UINT_MAX)->index : 0; + + /* 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; + SetRoadOwner(t, RTT_TRAM, OWNER_NONE); + } + } else { + if (GB(_m[t].m5, 3, 2) == 0) { + MakeClear(t, CLEAR_GRASS, 3); + } else { + if (!IsTileFlat(t)) { + MakeShore(t); + } else { + if (GetTileOwner(t) == OWNER_WATER) { + MakeSea(t); + } else { + MakeCanal(t, GetTileOwner(t), Random()); + } + } + } + } + SetBridgeMiddle(t, axis); + } else { // ramp + Axis axis = (Axis)GB(_m[t].m5, 0, 1); + uint north_south = GB(_m[t].m5, 5, 1); + DiagDirection dir = ReverseDiagDir(XYNSToDiagDir(axis, north_south)); + TransportType type = (TransportType)GB(_m[t].m5, 1, 2); + + _m[t].m5 = 1 << 7 | type << 2 | dir; + } + } + } + + for (Vehicle* v : Vehicle::Iterate()) { + if (!v->IsGroundVehicle()) continue; + if (IsBridgeTile(v->tile)) { + DiagDirection dir = GetTunnelBridgeDirection(v->tile); + + if (dir != DirToDiagDir(v->direction)) continue; + switch (dir) { + default: SlErrorCorrupt("Invalid vehicle direction"); + case DIAGDIR_NE: if ((v->x_pos & 0xF) != 0) continue; break; + case DIAGDIR_SE: if ((v->y_pos & 0xF) != TILE_SIZE - 1) continue; break; + case DIAGDIR_SW: if ((v->x_pos & 0xF) != TILE_SIZE - 1) continue; break; + case DIAGDIR_NW: if ((v->y_pos & 0xF) != 0) continue; break; + } + } else if (v->z_pos > GetSlopePixelZ(v->x_pos, v->y_pos)) { + v->tile = GetNorthernBridgeEnd(v->tile); + } else { + continue; + } + if (v->type == VEH_TRAIN) { + Train::From(v)->track = TRACK_BIT_WORMHOLE; + } else { + RoadVehicle::From(v)->state = RVSB_WORMHOLE; + } + } + } + + if (IsSavegameVersionBefore(SLV_ROAD_TYPES)) { + /* Add road subtypes */ + for (TileIndex t = 0; t < map_size; t++) { + bool has_road = false; + switch (GetTileType(t)) { + case MP_ROAD: + has_road = true; + break; + case MP_STATION: + has_road = IsRoadStop(t); + break; + case MP_TUNNELBRIDGE: + has_road = GetTunnelBridgeTransportType(t) == TRANSPORT_ROAD; + break; + default: + break; + } + + 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; + + 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. + } + } + } + /* Elrails got added in rev 24 */ if (IsSavegameVersionBefore(SLV_24)) { RailType min_rail = RAILTYPE_ELECTRIC; - Train *v; - FOR_ALL_TRAINS(v) { + for (Train *v : Train::Iterate()) { RailType rt = RailVehInfo(v->engine_type)->railtype; v->railtype = rt; @@ -1287,7 +1334,7 @@ bool AfterLoadGame() } } - FOR_ALL_TRAINS(v) { + for (Train *v : Train::Iterate()) { if (v->IsFrontEngine() || v->IsFreeWagon()) v->ConsistChanged(CCF_TRACK); } @@ -1297,8 +1344,7 @@ bool AfterLoadGame() * replaced, shall keep their old length. In all prior versions, just default * to false */ if (IsSavegameVersionBefore(SLV_16, 1)) { - Company *c; - FOR_ALL_COMPANIES(c) c->settings.renew_keep_length = false; + for (Company *c : Company::Iterate()) c->settings.renew_keep_length = false; } if (IsSavegameVersionBefore(SLV_123)) { @@ -1345,15 +1391,13 @@ bool AfterLoadGame() } if (IsSavegameVersionBefore(SLV_25)) { - RoadVehicle *rv; - FOR_ALL_ROADVEHICLES(rv) { + for (RoadVehicle *rv : RoadVehicle::Iterate()) { rv->vehstatus &= ~0x40; } } if (IsSavegameVersionBefore(SLV_26)) { - Station *st; - FOR_ALL_STATIONS(st) { + for (Station *st : Station::Iterate()) { st->last_vehicle_type = VEH_INVALID; } } @@ -1361,14 +1405,12 @@ bool AfterLoadGame() YapfNotifyTrackLayoutChange(INVALID_TILE, INVALID_TRACK); if (IsSavegameVersionBefore(SLV_34)) { - Company *c; - FOR_ALL_COMPANIES(c) ResetCompanyLivery(c); + for (Company *c : Company::Iterate()) ResetCompanyLivery(c); } - Company *c; - FOR_ALL_COMPANIES(c) { + for (Company *c : Company::Iterate()) { c->avail_railtypes = GetCompanyRailtypes(c->index); - c->avail_roadtypes = GetCompanyRoadtypes(c->index); + c->avail_roadtypes = GetCompanyRoadTypes(c->index); } if (!IsSavegameVersionBefore(SLV_27)) AfterLoadStations(); @@ -1376,22 +1418,16 @@ bool AfterLoadGame() /* Time starts at 0 instead of 1920. * Account for this in older games by adding an offset */ if (IsSavegameVersionBefore(SLV_31)) { - Station *st; - Waypoint *wp; - Engine *e; - Industry *i; - Vehicle *v; - _date += DAYS_TILL_ORIGINAL_BASE_YEAR; _cur_year += ORIGINAL_BASE_YEAR; - FOR_ALL_STATIONS(st) st->build_date += DAYS_TILL_ORIGINAL_BASE_YEAR; - FOR_ALL_WAYPOINTS(wp) wp->build_date += DAYS_TILL_ORIGINAL_BASE_YEAR; - FOR_ALL_ENGINES(e) e->intro_date += DAYS_TILL_ORIGINAL_BASE_YEAR; - FOR_ALL_COMPANIES(c) c->inaugurated_year += ORIGINAL_BASE_YEAR; - FOR_ALL_INDUSTRIES(i) i->last_prod_year += ORIGINAL_BASE_YEAR; + for (Station *st : Station::Iterate()) st->build_date += DAYS_TILL_ORIGINAL_BASE_YEAR; + for (Waypoint *wp : Waypoint::Iterate()) wp->build_date += DAYS_TILL_ORIGINAL_BASE_YEAR; + for (Engine *e : Engine::Iterate()) e->intro_date += DAYS_TILL_ORIGINAL_BASE_YEAR; + for (Company *c : Company::Iterate()) c->inaugurated_year += ORIGINAL_BASE_YEAR; + for (Industry *i : Industry::Iterate()) i->last_prod_year += ORIGINAL_BASE_YEAR; - FOR_ALL_VEHICLES(v) { + for (Vehicle *v : Vehicle::Iterate()) { v->date_of_last_service += DAYS_TILL_ORIGINAL_BASE_YEAR; v->build_year += ORIGINAL_BASE_YEAR; } @@ -1401,8 +1437,6 @@ bool AfterLoadGame() * To give this prettiness to old savegames, we remove all farmfields and * plant new ones. */ if (IsSavegameVersionBefore(SLV_32)) { - Industry *i; - for (TileIndex t = 0; t < map_size; t++) { if (IsTileType(t, MP_CLEAR) && IsClearGround(t, CLEAR_FIELDS)) { /* remove fields */ @@ -1410,7 +1444,7 @@ bool AfterLoadGame() } } - FOR_ALL_INDUSTRIES(i) { + for (Industry *i : Industry::Iterate()) { uint j; if (GetIndustrySpec(i->type)->behaviour & INDUSTRYBEH_PLANT_ON_BUILT) { @@ -1421,14 +1455,11 @@ bool AfterLoadGame() /* Setting no refit flags to all orders in savegames from before refit in orders were added */ if (IsSavegameVersionBefore(SLV_36)) { - Order *order; - Vehicle *v; - - FOR_ALL_ORDERS(order) { + for (Order *order : Order::Iterate()) { order->SetRefit(CT_NO_REFIT); } - FOR_ALL_VEHICLES(v) { + for (Vehicle *v : Vehicle::Iterate()) { v->current_order.SetRefit(CT_NO_REFIT); } } @@ -1507,13 +1538,12 @@ bool AfterLoadGame() } if (IsSavegameVersionBefore(SLV_45)) { - Vehicle *v; /* Originally just the fact that some cargo had been paid for was * stored to stop people cheating and cashing in several times. This * wasn't enough though as it was cleared when the vehicle started * loading again, even if it didn't actually load anything, so now the * amount that has been paid is stored. */ - FOR_ALL_VEHICLES(v) { + for (Vehicle *v : Vehicle::Iterate()) { ClrBit(v->vehicle_flags, 2); } } @@ -1521,16 +1551,14 @@ bool AfterLoadGame() /* Buoys do now store the owner of the previous water tile, which can never * be OWNER_NONE. So replace OWNER_NONE with OWNER_WATER. */ if (IsSavegameVersionBefore(SLV_46)) { - Waypoint *wp; - FOR_ALL_WAYPOINTS(wp) { + for (Waypoint *wp : Waypoint::Iterate()) { if ((wp->facilities & FACIL_DOCK) != 0 && IsTileOwner(wp->xy, OWNER_NONE) && TileHeight(wp->xy) == 0) SetTileOwner(wp->xy, OWNER_WATER); } } if (IsSavegameVersionBefore(SLV_50)) { - Aircraft *v; /* Aircraft units changed from 8 mph to 1 km-ish/h */ - FOR_ALL_AIRCRAFT(v) { + for (Aircraft *v : Aircraft::Iterate()) { if (v->subtype <= AIR_AIRCRAFT) { const AircraftVehicleInfo *avi = AircraftVehInfo(v->engine_type); v->cur_speed *= 128; @@ -1540,7 +1568,7 @@ bool AfterLoadGame() } } - if (IsSavegameVersionBefore(SLV_49)) FOR_ALL_COMPANIES(c) c->face = ConvertFromOldCompanyManagerFace(c->face); + 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++) { @@ -1554,9 +1582,7 @@ bool AfterLoadGame() * fast was added in version 54. From version 56 this is now saved in the * town as cities can be built specifically in the scenario editor. */ if (IsSavegameVersionBefore(SLV_56)) { - Town *t; - - FOR_ALL_TOWNS(t) { + for (Town *t : Town::Iterate()) { if (_settings_game.economy.larger_towns != 0 && (t->index % _settings_game.economy.larger_towns) == 0) { t->larger_town = true; } @@ -1564,9 +1590,8 @@ bool AfterLoadGame() } if (IsSavegameVersionBefore(SLV_57)) { - Vehicle *v; /* Added a FIFO queue of vehicles loading at stations */ - FOR_ALL_VEHICLES(v) { + for (Vehicle *v : Vehicle::Iterate()) { if ((v->type != VEH_TRAIN || Train::From(v)->IsFrontEngine()) && // for all locs !(v->vehstatus & (VS_STOPPED | VS_CRASHED)) && // not stopped or crashed v->current_order.IsType(OT_LOADING)) { // loading @@ -1580,8 +1605,7 @@ bool AfterLoadGame() } else if (IsSavegameVersionBefore(SLV_59)) { /* For some reason non-loading vehicles could be in the station's loading vehicle list */ - Station *st; - FOR_ALL_STATIONS(st) { + for (Station *st : Station::Iterate()) { std::list::iterator iter; for (iter = st->loading_vehicles.begin(); iter != st->loading_vehicles.end();) { Vehicle *v = *iter; @@ -1618,8 +1642,7 @@ bool AfterLoadGame() if (IsSavegameVersionBefore(SLV_69)) { /* In some old savegames a bit was cleared when it should not be cleared */ - RoadVehicle *rv; - FOR_ALL_ROADVEHICLES(rv) { + for (RoadVehicle *rv : RoadVehicle::Iterate()) { if (rv->state == 250 || rv->state == 251) { SetBit(rv->state, 2); } @@ -1628,8 +1651,7 @@ bool AfterLoadGame() if (IsSavegameVersionBefore(SLV_70)) { /* Added variables to support newindustries */ - Industry *i; - FOR_ALL_INDUSTRIES(i) i->founder = OWNER_NONE; + for (Industry *i : Industry::Iterate()) i->founder = OWNER_NONE; } /* From version 82, old style canals (above sealevel (0), WATER owner) are no longer supported. @@ -1660,8 +1682,7 @@ bool AfterLoadGame() } if (IsSavegameVersionBefore(SLV_74)) { - Station *st; - FOR_ALL_STATIONS(st) { + for (Station *st : Station::Iterate()) { for (CargoID c = 0; c < NUM_CARGO; c++) { st->goods[c].last_speed = 0; if (st->goods[c].cargo.AvailableCount() != 0) SetBit(st->goods[c].status, GoodsEntry::GES_RATING); @@ -1670,9 +1691,8 @@ bool AfterLoadGame() } if (IsSavegameVersionBefore(SLV_78)) { - Industry *i; uint j; - FOR_ALL_INDUSTRIES(i) { + for (Industry * i : Industry::Iterate()) { const IndustrySpec *indsp = GetIndustrySpec(i->type); for (j = 0; j < lengthof(i->produced_cargo); j++) { i->produced_cargo[j] = indsp->produced_cargo[j]; @@ -1699,33 +1719,30 @@ bool AfterLoadGame() if (IsSavegameVersionBefore(SLV_93)) { /* Rework of orders. */ - Order *order; - FOR_ALL_ORDERS(order) order->ConvertFromOldSavegame(); + for (Order *order : Order::Iterate()) order->ConvertFromOldSavegame(); - Vehicle *v; - FOR_ALL_VEHICLES(v) { - if (v->orders.list != NULL && v->orders.list->GetFirstOrder() != NULL && v->orders.list->GetFirstOrder()->IsType(OT_NOTHING)) { + for (Vehicle *v : Vehicle::Iterate()) { + if (v->orders.list != nullptr && v->orders.list->GetFirstOrder() != nullptr && v->orders.list->GetFirstOrder()->IsType(OT_NOTHING)) { v->orders.list->FreeChain(); - v->orders.list = NULL; + v->orders.list = nullptr; } v->current_order.ConvertFromOldSavegame(); if (v->type == VEH_ROAD && v->IsPrimaryVehicle() && v->FirstShared() == v) { + Order* order; FOR_VEHICLE_ORDERS(v, order) order->SetNonStopType(ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS); } } } else if (IsSavegameVersionBefore(SLV_94)) { /* Unload and transfer are now mutual exclusive. */ - Order *order; - FOR_ALL_ORDERS(order) { + for (Order *order : Order::Iterate()) { if ((order->GetUnloadType() & (OUFB_UNLOAD | OUFB_TRANSFER)) == (OUFB_UNLOAD | OUFB_TRANSFER)) { order->SetUnloadType(OUFB_TRANSFER); order->SetLoadType(OLFB_NO_LOAD); } } - Vehicle *v; - FOR_ALL_VEHICLES(v) { + for (Vehicle *v : Vehicle::Iterate()) { if ((v->current_order.GetUnloadType() & (OUFB_UNLOAD | OUFB_TRANSFER)) == (OUFB_UNLOAD | OUFB_TRANSFER)) { v->current_order.SetUnloadType(OUFB_TRANSFER); v->current_order.SetLoadType(OLFB_NO_LOAD); @@ -1740,7 +1757,7 @@ bool AfterLoadGame() * *really* old revisions of OTTD; else it is already set in InitializeCompanies()) * 2) shares that are owned by inactive companies or self * (caused by cheating clients in earlier revisions) */ - FOR_ALL_COMPANIES(c) { + for (Company *c : Company::Iterate()) { for (uint i = 0; i < 4; i++) { CompanyID company = c->share_owners[i]; if (company == INVALID_COMPANY) continue; @@ -1828,7 +1845,7 @@ bool AfterLoadGame() if (IsBuoyTile(t) || IsDriveThroughStopTile(t) || IsTileType(t, MP_WATER)) { Owner o = GetTileOwner(t); if (o < MAX_COMPANIES && !Company::IsValidID(o)) { - Backup cur_company(_current_company, o, FILE_LINE); + Backup cur_company(_current_company, o, FILE_LINE); ChangeTileOwner(t, o, INVALID_OWNER); cur_company.Restore(); } @@ -1839,10 +1856,10 @@ bool AfterLoadGame() } } else if (IsTileType(t, MP_ROAD)) { /* works for all RoadTileType */ - for (RoadType rt = ROADTYPE_ROAD; rt < ROADTYPE_END; rt++) { + FOR_ALL_ROADTRAMTYPES(rtt) { /* update even non-existing road types to update tile owner too */ - Owner o = GetRoadOwner(t, rt); - if (o < MAX_COMPANIES && !Company::IsValidID(o)) SetRoadOwner(t, rt, OWNER_NONE); + Owner o = GetRoadOwner(t, rtt); + if (o < MAX_COMPANIES && !Company::IsValidID(o)) SetRoadOwner(t, rtt, OWNER_NONE); } if (IsLevelCrossing(t)) { if (!Company::IsValidID(GetTileOwner(t))) FixOwnerOfRailTrack(t); @@ -1868,14 +1885,13 @@ bool AfterLoadGame() if (_settings_game.pf.yapf.ship_use_yapf) { _settings_game.pf.pathfinder_for_ships = VPF_YAPF; } else { - _settings_game.pf.pathfinder_for_ships = (_settings_game.pf.new_pathfinding_all ? VPF_NPF : VPF_OPF); + _settings_game.pf.pathfinder_for_ships = VPF_NPF; } } if (IsSavegameVersionBefore(SLV_88)) { /* Profits are now with 8 bit fract */ - Vehicle *v; - FOR_ALL_VEHICLES(v) { + for (Vehicle *v : Vehicle::Iterate()) { v->profit_this_year <<= 8; v->profit_last_year <<= 8; v->running_ticks = 0; @@ -1893,10 +1909,10 @@ bool AfterLoadGame() } if (IsSavegameVersionBefore(SLV_62)) { + GroupStatistics::UpdateAfterLoad(); // Ensure statistics pool is initialised before trying to delete vehicles /* Remove all trams from savegames without tram support. * There would be trams without tram track under causing crashes sooner or later. */ - RoadVehicle *v; - FOR_ALL_ROADVEHICLES(v) { + for (RoadVehicle *v : RoadVehicle::Iterate()) { if (v->First() == v && HasBit(EngInfo(v->engine_type)->misc_flags, EF_ROAD_TRAM)) { ShowErrorMessage(STR_WARNING_LOADGAME_REMOVED_TRAMS, INVALID_STRING_ID, WL_CRITICAL); delete v; @@ -1967,8 +1983,7 @@ bool AfterLoadGame() /* Reserve all tracks trains are currently on. */ if (IsSavegameVersionBefore(SLV_101)) { - const Train *t; - FOR_ALL_TRAINS(t) { + for (const Train *t : Train::Iterate()) { if (t->First() == t) t->ReserveTrackUnderConsist(); } } @@ -1985,22 +2000,19 @@ bool AfterLoadGame() UpdateNearestTownForRoadTiles(false); /* signs with invalid owner left from older savegames */ - Sign *si; - FOR_ALL_SIGNS(si) { + for (Sign *si : Sign::Iterate()) { if (si->owner != OWNER_NONE && !Company::IsValidID(si->owner)) si->owner = OWNER_NONE; } /* Station can get named based on an industry type, but the current ones * are not, so mark them as if they are not named by an industry. */ - Station *st; - FOR_ALL_STATIONS(st) { + for (Station *st : Station::Iterate()) { st->indtype = IT_INVALID; } } if (IsSavegameVersionBefore(SLV_104)) { - Aircraft *a; - FOR_ALL_AIRCRAFT(a) { + for (Aircraft *a : Aircraft::Iterate()) { /* Set engine_type of shadow and rotor */ if (!a->IsNormalAircraft()) { a->engine_type = a->First()->engine_type; @@ -2008,18 +2020,15 @@ bool AfterLoadGame() } /* More companies ... */ - Company *c; - FOR_ALL_COMPANIES(c) { + for (Company *c : Company::Iterate()) { if (c->bankrupt_asked == 0xFF) c->bankrupt_asked = 0xFFFF; } - Engine *e; - FOR_ALL_ENGINES(e) { + for (Engine *e : Engine::Iterate()) { if (e->company_avail == 0xFF) e->company_avail = 0xFFFF; } - Town *t; - FOR_ALL_TOWNS(t) { + for (Town *t : Town::Iterate()) { if (t->have_ratings == 0xFF) t->have_ratings = 0xFFFF; for (uint i = 8; i != MAX_COMPANIES; i++) t->ratings[i] = RATING_INITIAL; } @@ -2103,13 +2112,12 @@ bool AfterLoadGame() _settings_game.economy.town_layout = TL_BETTER_ROADS; } else { _settings_game.economy.allow_town_roads = true; - _settings_game.economy.town_layout = _settings_game.economy.town_layout - 1; + _settings_game.economy.town_layout = static_cast(_settings_game.economy.town_layout - 1); } /* Initialize layout of all towns. Older versions were using different * generator for random town layout, use it if needed. */ - Town *t; - FOR_ALL_TOWNS(t) { + for (Town *t : Town::Iterate()) { if (_settings_game.economy.town_layout != TL_RANDOM) { t->layout = _settings_game.economy.town_layout; continue; @@ -2122,7 +2130,7 @@ bool AfterLoadGame() case 5: layout = 1; break; case 0: layout = 2; break; } - t->layout = layout - 1; + t->layout = static_cast(layout - 1); } } @@ -2130,35 +2138,31 @@ bool AfterLoadGame() /* There could be (deleted) stations with invalid owner, set owner to OWNER NONE. * The conversion affects oil rigs and buoys too, but it doesn't matter as * they have st->owner == OWNER_NONE already. */ - Station *st; - FOR_ALL_STATIONS(st) { + for (Station *st : Station::Iterate()) { if (!Company::IsValidID(st->owner)) st->owner = OWNER_NONE; } } /* Trains could now stop in a specific location. */ if (IsSavegameVersionBefore(SLV_117)) { - Order *o; - FOR_ALL_ORDERS(o) { + for (Order *o : Order::Iterate()) { if (o->IsType(OT_GOTO_STATION)) o->SetStopLocation(OSL_PLATFORM_FAR_END); } } if (IsSavegameVersionBefore(SLV_120)) { extern VehicleDefaultSettings _old_vds; - Company *c; - FOR_ALL_COMPANIES(c) { + for (Company *c : Company::Iterate()) { c->settings.vehicle = _old_vds; } } if (IsSavegameVersionBefore(SLV_121)) { /* Delete small ufos heading for non-existing vehicles */ - Vehicle *v; - FOR_ALL_DISASTERVEHICLES(v) { + for (Vehicle *v : DisasterVehicle::Iterate()) { if (v->subtype == 2 /* ST_SMALL_UFO */ && v->current_order.GetDestination() != 0) { const Vehicle *u = Vehicle::GetIfValid(v->dest_tile); - if (u == NULL || u->type != VEH_ROAD || !RoadVehicle::From(u)->IsFrontEngine()) { + if (u == nullptr || u->type != VEH_ROAD || !RoadVehicle::From(u)->IsFrontEngine()) { delete v; } } @@ -2170,8 +2174,7 @@ bool AfterLoadGame() * However, some 0.7 versions might have cargo payment. For those we just * add cargopayment for the vehicles that don't have it. */ - Station *st; - FOR_ALL_STATIONS(st) { + for (Station *st : Station::Iterate()) { std::list::iterator iter; for (iter = st->loading_vehicles.begin(); iter != st->loading_vehicles.end(); ++iter) { /* There are always as many CargoPayments as Vehicles. We need to make the @@ -2179,7 +2182,7 @@ bool AfterLoadGame() assert_compile(CargoPaymentPool::MAX_SIZE == VehiclePool::MAX_SIZE); assert(CargoPayment::CanAllocateItem()); Vehicle *v = *iter; - if (v->cargo_payment == NULL) v->cargo_payment = new CargoPayment(v); + if (v->cargo_payment == nullptr) v->cargo_payment = new CargoPayment(v); } } } @@ -2188,14 +2191,14 @@ bool AfterLoadGame() /* Animated tiles would sometimes not be actually animated or * in case of old savegames duplicate. */ - extern SmallVector _animated_tiles; + extern std::vector _animated_tiles; - for (TileIndex *tile = _animated_tiles.Begin(); tile < _animated_tiles.End(); /* Nothing */) { + for (auto tile = _animated_tiles.begin(); tile < _animated_tiles.end(); /* Nothing */) { /* Remove if tile is not animated */ - bool remove = _tile_type_procs[GetTileType(*tile)]->animate_tile_proc == NULL; + bool remove = _tile_type_procs[GetTileType(*tile)]->animate_tile_proc == nullptr; /* and remove if duplicate */ - for (TileIndex *j = _animated_tiles.Begin(); !remove && j < tile; j++) { + for (auto j = _animated_tiles.begin(); !remove && j < tile; j++) { remove = *tile == *j; } @@ -2209,8 +2212,7 @@ bool AfterLoadGame() if (IsSavegameVersionBefore(SLV_124) && !IsSavegameVersionBefore(SLV_1)) { /* The train station tile area was added, but for really old (TTDPatch) it's already valid. */ - Waypoint *wp; - FOR_ALL_WAYPOINTS(wp) { + for (Waypoint *wp : Waypoint::Iterate()) { if (wp->facilities & FACIL_TRAIN) { wp->train_station.tile = wp->xy; wp->train_station.w = 1; @@ -2225,8 +2227,7 @@ bool AfterLoadGame() if (IsSavegameVersionBefore(SLV_125)) { /* Convert old subsidies */ - Subsidy *s; - FOR_ALL_SUBSIDIES(s) { + for (Subsidy *s : Subsidy::Iterate()) { if (s->remaining < 12) { /* Converting nonawarded subsidy */ s->remaining = 12 - s->remaining; // convert "age" to "remaining" @@ -2264,7 +2265,7 @@ bool AfterLoadGame() /* Town -> Town */ const Station *ss = Station::GetIfValid(s->src); const Station *sd = Station::GetIfValid(s->dst); - if (ss != NULL && sd != NULL && ss->owner == sd->owner && + if (ss != nullptr && sd != nullptr && ss->owner == sd->owner && Company::IsValidID(ss->owner)) { s->src_type = s->dst_type = ST_TOWN; s->src = ss->town->index; @@ -2302,8 +2303,15 @@ bool AfterLoadGame() } if (IsSavegameVersionBefore(SLV_128)) { - const Depot *d; - FOR_ALL_DEPOTS(d) { + for (const Depot *d : Depot::Iterate()) { + /* 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)) { + DEBUG(sl, 0, "Removing invalid depot %d at %d, %d", 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; } @@ -2312,8 +2320,7 @@ bool AfterLoadGame() /* The behaviour of force_proceed has been changed. Now * it counts signals instead of some random time out. */ if (IsSavegameVersionBefore(SLV_131)) { - Train *t; - FOR_ALL_TRAINS(t) { + for (Train *t : Train::Iterate()) { if (t->force_proceed != TFP_NONE) { t->force_proceed = TFP_STUCK; } @@ -2343,13 +2350,11 @@ bool AfterLoadGame() /* Wait counter and load/unload ticks got split. */ if (IsSavegameVersionBefore(SLV_136)) { - Aircraft *a; - FOR_ALL_AIRCRAFT(a) { + for (Aircraft *a : Aircraft::Iterate()) { a->turn_counter = a->current_order.IsType(OT_LOADING) ? 0 : a->load_unload_ticks; } - Train *t; - FOR_ALL_TRAINS(t) { + for (Train *t : Train::Iterate()) { t->wait_counter = t->current_order.IsType(OT_LOADING) ? 0 : t->load_unload_ticks; } } @@ -2392,8 +2397,7 @@ bool AfterLoadGame() } if (IsSavegameVersionBefore(SLV_140)) { - Station *st; - FOR_ALL_STATIONS(st) { + for (Station *st : Station::Iterate()) { if (st->airport.tile != INVALID_TILE) { st->airport.w = st->airport.GetSpec()->size_x; st->airport.h = st->airport.GetSpec()->size_y; @@ -2410,15 +2414,13 @@ bool AfterLoadGame() /* We need to properly number/name the depots. * The first step is making sure none of the depots uses the * 'default' names, after that we can assign the names. */ - Depot *d; - FOR_ALL_DEPOTS(d) d->town_cn = UINT16_MAX; + for (Depot *d : Depot::Iterate()) d->town_cn = UINT16_MAX; - FOR_ALL_DEPOTS(d) MakeDefaultName(d); + for (Depot* d : Depot::Iterate()) MakeDefaultName(d); } if (IsSavegameVersionBefore(SLV_142)) { - Depot *d; - FOR_ALL_DEPOTS(d) d->build_date = _date; + for (Depot *d : Depot::Iterate()) d->build_date = _date; } /* In old versions it was possible to remove an airport while a plane was @@ -2427,17 +2429,16 @@ bool AfterLoadGame() * For old savegames with such aircraft we just throw them in the air and * treat the aircraft like they were flying already. */ if (IsSavegameVersionBefore(SLV_146)) { - Aircraft *v; - FOR_ALL_AIRCRAFT(v) { + for (Aircraft *v : Aircraft::Iterate()) { if (!v->IsNormalAircraft()) continue; Station *st = GetTargetAirportIfValid(v); - if (st == NULL && v->state != FLYING) { + if (st == nullptr && v->state != FLYING) { v->state = FLYING; UpdateAircraftCache(v); AircraftNextAirportPos_and_Order(v); /* get aircraft back on running altitude */ if ((v->vehstatus & VS_CRASHED) == 0) { - GetAircraftFlightLevelBounds(v, &v->z_pos, NULL); + GetAircraftFlightLevelBounds(v, &v->z_pos, nullptr); SetAircraftPosition(v, v->x_pos, v->y_pos, GetAircraftFlightLevel(v)); } } @@ -2478,8 +2479,7 @@ bool AfterLoadGame() /* Add (random) colour to all objects. */ if (IsSavegameVersionBefore(SLV_148)) { - Object *o; - FOR_ALL_OBJECTS(o) { + for (Object *o : Object::Iterate()) { Owner owner = GetTileOwner(o->location.tile); o->colour = (owner == OWNER_NONE) ? Random() & 0xF : Company::Get(owner)->livery->colour1; } @@ -2497,13 +2497,12 @@ bool AfterLoadGame() * renumber those. First set all affected waypoints to the * highest possible number to get them numbered in the * order they have in the pool. */ - Waypoint *wp; - FOR_ALL_WAYPOINTS(wp) { - if (wp->name != NULL) wp->town_cn = UINT16_MAX; + for (Waypoint *wp : Waypoint::Iterate()) { + if (wp->name != nullptr) wp->town_cn = UINT16_MAX; } - FOR_ALL_WAYPOINTS(wp) { - if (wp->name != NULL) MakeDefaultName(wp); + for (Waypoint* wp : Waypoint::Iterate()) { + if (wp->name != nullptr) MakeDefaultName(wp); } } @@ -2513,8 +2512,7 @@ bool AfterLoadGame() /* The moment vehicles go from hidden to visible changed. This means * that vehicles don't always get visible anymore causing things to * get messed up just after loading the savegame. This fixes that. */ - Vehicle *v; - FOR_ALL_VEHICLES(v) { + for (Vehicle *v : Vehicle::Iterate()) { /* Not all vehicle types can be inside a tunnel. Furthermore, * testing IsTunnelTile() for invalid tiles causes a crash. */ if (!v->IsGroundVehicle()) continue; @@ -2577,8 +2575,7 @@ bool AfterLoadGame() } if (IsSavegameVersionBefore(SLV_153)) { - RoadVehicle *rv; - FOR_ALL_ROADVEHICLES(rv) { + for (RoadVehicle *rv : RoadVehicle::Iterate()) { if (rv->state == RVSB_IN_DEPOT || rv->state == RVSB_WORMHOLE) continue; bool loading = rv->current_order.IsType(OT_LOADING) || rv->current_order.IsType(OT_LEAVESTATION); @@ -2593,8 +2590,7 @@ bool AfterLoadGame() if (IsSavegameVersionBefore(SLV_156)) { /* The train's pathfinder lost flag got moved. */ - Train *t; - FOR_ALL_TRAINS(t) { + for (Train *t : Train::Iterate()) { if (!HasBit(t->flags, 5)) continue; ClrBit(t->flags, 5); @@ -2602,16 +2598,14 @@ bool AfterLoadGame() } /* Introduced terraform/clear limits. */ - Company *c; - FOR_ALL_COMPANIES(c) { + for (Company *c : Company::Iterate()) { c->terraform_limit = _settings_game.construction.terraform_frame_burst << 16; c->clear_limit = _settings_game.construction.clear_frame_burst << 16; } } if (IsSavegameVersionBefore(SLV_158)) { - Vehicle *v; - FOR_ALL_VEHICLES(v) { + for (Vehicle *v : Vehicle::Iterate()) { switch (v->type) { case VEH_TRAIN: { Train *t = Train::From(v); @@ -2646,7 +2640,7 @@ bool AfterLoadGame() if (rv->state == RVSB_IN_DEPOT || rv->state == RVSB_WORMHOLE) break; - TrackStatus ts = GetTileTrackStatus(rv->tile, TRANSPORT_ROAD, rv->compatible_roadtypes); + TrackStatus ts = GetTileTrackStatus(rv->tile, TRANSPORT_ROAD, GetRoadTramType(rv->roadtype)); TrackBits trackbits = TrackStatusToTrackBits(ts); /* Only X/Y tracks can be sloped. */ @@ -2695,7 +2689,7 @@ bool AfterLoadGame() } /* Fill Vehicle::cur_real_order_index */ - FOR_ALL_VEHICLES(v) { + for (Vehicle *v : Vehicle::Iterate()) { if (!v->IsPrimaryVehicle()) continue; /* Older versions are less strict with indices being in range and fix them on the fly */ @@ -2715,8 +2709,7 @@ bool AfterLoadGame() * will keep reversing disabled, otherwise it'll be turned on. */ _settings_game.pf.reverse_at_signals = IsSavegameVersionBefore(SLV_100) || (_settings_game.pf.wait_oneway_signal != 255 && _settings_game.pf.wait_twoway_signal != 255 && _settings_game.pf.wait_for_pbs_path != 255); - Train *t; - FOR_ALL_TRAINS(t) { + for (Train *t : Train::Iterate()) { _settings_game.vehicle.max_train_length = max(_settings_game.vehicle.max_train_length, CeilDiv(t->gcache.cached_total_length, TILE_SIZE)); } } @@ -2733,9 +2726,8 @@ bool AfterLoadGame() /* Before savegame version 161, persistent storages were not stored in a pool. */ if (!IsSavegameVersionBefore(SLV_76)) { - Industry *ind; - FOR_ALL_INDUSTRIES(ind) { - assert(ind->psa != NULL); + for (Industry *ind : Industry::Iterate()) { + assert(ind->psa != nullptr); /* Check if the old storage was empty. */ bool is_empty = true; @@ -2750,16 +2742,15 @@ bool AfterLoadGame() ind->psa->grfid = _industry_mngr.GetGRFID(ind->type); } else { delete ind->psa; - ind->psa = NULL; + ind->psa = nullptr; } } } if (!IsSavegameVersionBefore(SLV_145)) { - Station *st; - FOR_ALL_STATIONS(st) { + for (Station *st : Station::Iterate()) { if (!(st->facilities & FACIL_AIRPORT)) continue; - assert(st->airport.psa != NULL); + assert(st->airport.psa != nullptr); /* Check if the old storage was empty. */ bool is_empty = true; @@ -2774,7 +2765,7 @@ bool AfterLoadGame() st->airport.psa->grfid = _airport_mngr.GetGRFID(st->airport.type); } else { delete st->airport.psa; - st->airport.psa = NULL; + st->airport.psa = nullptr; } } @@ -2808,18 +2799,16 @@ bool AfterLoadGame() if (IsSavegameVersionBefore(SLV_164)) FixupTrainLengths(); if (IsSavegameVersionBefore(SLV_165)) { - Town *t; - - FOR_ALL_TOWNS(t) { + for (Town *t : Town::Iterate()) { /* Set the default cargo requirement for town growth */ switch (_settings_game.game_creation.landscape) { case LT_ARCTIC: - if (FindFirstCargoWithTownEffect(TE_FOOD) != NULL) t->goal[TE_FOOD] = TOWN_GROWTH_WINTER; + if (FindFirstCargoWithTownEffect(TE_FOOD) != nullptr) t->goal[TE_FOOD] = TOWN_GROWTH_WINTER; break; case LT_TROPIC: - if (FindFirstCargoWithTownEffect(TE_FOOD) != NULL) t->goal[TE_FOOD] = TOWN_GROWTH_DESERT; - if (FindFirstCargoWithTownEffect(TE_WATER) != NULL) t->goal[TE_WATER] = TOWN_GROWTH_DESERT; + if (FindFirstCargoWithTownEffect(TE_FOOD) != nullptr) t->goal[TE_FOOD] = TOWN_GROWTH_DESERT; + if (FindFirstCargoWithTownEffect(TE_WATER) != nullptr) t->goal[TE_WATER] = TOWN_GROWTH_DESERT; break; } } @@ -2827,7 +2816,7 @@ bool AfterLoadGame() if (IsSavegameVersionBefore(SLV_165)) { /* Adjust zoom level to account for new levels */ - _saved_scrollpos_zoom = _saved_scrollpos_zoom + ZOOM_LVL_SHIFT; + _saved_scrollpos_zoom = static_cast(_saved_scrollpos_zoom + ZOOM_LVL_SHIFT); _saved_scrollpos_x *= ZOOM_LVL_BASE; _saved_scrollpos_y *= ZOOM_LVL_BASE; } @@ -2844,8 +2833,7 @@ bool AfterLoadGame() Town::Get(GetTownIndex(t))->cargo_accepted.Add(t); } - Town *town; - FOR_ALL_TOWNS(town) { + for (Town *town : Town::Iterate()) { UpdateTownCargoes(town); } } @@ -2855,15 +2843,14 @@ bool AfterLoadGame() for (TileIndex t = 0; t < map_size; t++) { if (!IsStandardRoadStopTile(t)) continue; Owner o = GetTileOwner(t); - SetRoadOwner(t, ROADTYPE_ROAD, o); - SetRoadOwner(t, ROADTYPE_TRAM, o); + SetRoadOwner(t, RTT_ROAD, o); + SetRoadOwner(t, RTT_TRAM, o); } } if (IsSavegameVersionBefore(SLV_175)) { /* Introduced tree planting limit. */ - Company *c; - FOR_ALL_COMPANIES(c) c->tree_limit = _settings_game.construction.tree_frame_burst << 16; + for (Company *c : Company::Iterate()) c->tree_limit = _settings_game.construction.tree_frame_burst << 16; } if (IsSavegameVersionBefore(SLV_177)) { @@ -2872,7 +2859,7 @@ bool AfterLoadGame() if (_economy.inflation_payment > MAX_INFLATION) _economy.inflation_payment = MAX_INFLATION; /* We have to convert the quarters of bankruptcy into months of bankruptcy */ - FOR_ALL_COMPANIES(c) { + for (Company *c : Company::Iterate()) { c->months_of_bankruptcy = 3 * c->months_of_bankruptcy; } } @@ -2884,9 +2871,8 @@ bool AfterLoadGame() } if (IsSavegameVersionBefore(SLV_182)) { - Aircraft *v; /* Aircraft acceleration variable was bonkers */ - FOR_ALL_AIRCRAFT(v) { + for (Aircraft *v : Aircraft::Iterate()) { if (v->subtype <= AIR_AIRCRAFT) { const AircraftVehicleInfo *avi = AircraftVehInfo(v->engine_type); v->acceleration = avi->acceleration; @@ -2930,16 +2916,15 @@ bool AfterLoadGame() * Now they have the same length, but that means that trailing articulated parts will * take longer to go through the curve than the parts in front which already left the courve. * So, make articulated parts catch up. */ - RoadVehicle *v; bool roadside = _settings_game.vehicle.road_side == 1; - SmallVector skip_frames; - FOR_ALL_ROADVEHICLES(v) { + std::vector skip_frames; + for (RoadVehicle *v : RoadVehicle::Iterate()) { if (!v->IsFrontEngine()) continue; - skip_frames.Clear(); + skip_frames.clear(); TileIndex prev_tile = v->tile; uint prev_tile_skip = 0; uint cur_skip = 0; - for (RoadVehicle *u = v; u != NULL; u = u->Next()) { + for (RoadVehicle *u = v; u != nullptr; u = u->Next()) { if (u->tile != prev_tile) { prev_tile_skip = cur_skip; prev_tile = u->tile; @@ -2947,24 +2932,24 @@ bool AfterLoadGame() cur_skip = prev_tile_skip; } - uint *this_skip = skip_frames.Append(); - *this_skip = prev_tile_skip; + /*C++17: uint &this_skip = */ skip_frames.push_back(prev_tile_skip); + uint &this_skip = skip_frames.back(); /* The following 3 curves now take longer than before */ switch (u->state) { case 2: cur_skip++; - if (u->frame <= (roadside ? 9 : 5)) *this_skip = cur_skip; + if (u->frame <= (roadside ? 9 : 5)) this_skip = cur_skip; break; case 4: cur_skip++; - if (u->frame <= (roadside ? 5 : 9)) *this_skip = cur_skip; + if (u->frame <= (roadside ? 5 : 9)) this_skip = cur_skip; break; case 5: cur_skip++; - if (u->frame <= (roadside ? 4 : 2)) *this_skip = cur_skip; + if (u->frame <= (roadside ? 4 : 2)) this_skip = cur_skip; break; default: @@ -2973,16 +2958,29 @@ bool AfterLoadGame() } while (cur_skip > skip_frames[0]) { RoadVehicle *u = v; - RoadVehicle *prev = NULL; - for (uint *it = skip_frames.Begin(); it != skip_frames.End(); ++it, prev = u, u = u->Next()) { + RoadVehicle *prev = nullptr; + for (uint sf : skip_frames) { extern bool IndividualRoadVehicleController(RoadVehicle *v, const RoadVehicle *prev); - if (*it >= cur_skip) IndividualRoadVehicleController(u, prev); + if (sf >= cur_skip) IndividualRoadVehicleController(u, prev); + + prev = u; + u = u->Next(); } cur_skip--; } } } + if (IsSavegameVersionBefore(SLV_190)) { + for (Order *order : Order::Iterate()) { + order->SetTravelTimetabled(order->GetTravelTime() > 0); + order->SetWaitTimetabled(order->GetWaitTime() > 0); + } + for (OrderList *orderlist : OrderList::Iterate()) { + orderlist->RecalculateTimetableDuration(); + } + } + /* * Only keep order-backups for network clients (and when replaying). * If we are a network server or not networking, then we just loaded a previously @@ -2993,8 +2991,7 @@ bool AfterLoadGame() #ifndef DEBUG_DUMP_COMMANDS /* Note: We cannot use CleanPool since that skips part of the destructor * and then leaks un-reachable Orders in the order pool. */ - OrderBackup *ob; - FOR_ALL_ORDER_BACKUPS(ob) { + for (OrderBackup *ob : OrderBackup::Iterate()) { delete ob; } #endif @@ -3002,8 +2999,7 @@ bool AfterLoadGame() if (IsSavegameVersionBefore(SLV_198)) { /* Convert towns growth_rate and grow_counter to ticks */ - Town *t; - FOR_ALL_TOWNS(t) { + for (Town *t : Town::Iterate()) { /* 0x8000 = TOWN_GROWTH_RATE_CUSTOM previously */ if (t->growth_rate & 0x8000) SetBit(t->flags, TOWN_CUSTOM_GROWTH); if (t->growth_rate != TOWN_GROWTH_RATE_NONE) { @@ -3016,8 +3012,7 @@ bool AfterLoadGame() if (IsSavegameVersionBefore(SLV_EXTEND_INDUSTRY_CARGO_SLOTS)) { /* Make sure added industry cargo slots are cleared */ - Industry *i; - FOR_ALL_INDUSTRIES(i) { + for (Industry *i : Industry::Iterate()) { for (size_t ci = 2; ci < lengthof(i->produced_cargo); ci++) { i->produced_cargo[ci] = CT_INVALID; i->produced_cargo_waiting[ci] = 0; @@ -3046,8 +3041,7 @@ bool AfterLoadGame() if (IsSavegameVersionBefore(SLV_SHIPS_STOP_IN_LOCKS)) { /* Move ships from lock slope to upper or lower position. */ - Ship *s; - FOR_ALL_SHIPS(s) { + for (Ship *s : Ship::Iterate()) { /* Suitable tile? */ if (!IsTileType(s->tile, MP_WATER) || !IsLock(s->tile) || GetLockPart(s->tile) != LOCK_PART_MIDDLE) continue; @@ -3080,17 +3074,61 @@ bool AfterLoadGame() } } - { - /* Update water class for trees for all current savegame versions. */ + if (IsSavegameVersionBefore(SLV_TOWN_CARGOGEN)) { + /* Ensure the original cargo generation mode is used */ + _settings_game.economy.town_cargogen_mode = TCGM_ORIGINAL; + } + + if (IsSavegameVersionBefore(SLV_SERVE_NEUTRAL_INDUSTRIES)) { + /* Ensure the original neutral industry/station behaviour is used */ + _settings_game.station.serve_neutral_industries = true; + + /* Link oil rigs to their industry and back. */ + for (Station *st : Station::Iterate()) { + if (IsTileType(st->xy, MP_STATION) && IsOilRig(st->xy)) { + /* Industry tile is always adjacent during construction by TileDiffXY(0, 1) */ + st->industry = Industry::GetByTile(st->xy + TileDiffXY(0, 1)); + st->industry->neutral_station = st; + } + } + } else { + /* Link neutral station back to industry, as this is not saved. */ + for (Industry *ind : Industry::Iterate()) if (ind->neutral_station != nullptr) ind->neutral_station->industry = ind; + } + + if (IsSavegameVersionBefore(SLV_TREES_WATER_CLASS)) { + /* Update water class for trees. */ for (TileIndex t = 0; t < map_size; t++) { 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++) { + /* 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)) { + SetDockingTile(t, false); + } + /* Add docks and oilrigs to Station::ship_station. */ + if (IsTileType(t, MP_STATION)) { + if (IsDock(t) || IsOilRig(t)) Station::GetByTile(t)->ship_station.Add(t); + } + } + + /* Scan for docking tiles */ + for (Station *st : Station::Iterate()) { + if (st->ship_station.tile != INVALID_TILE) UpdateStationDockingTiles(st); + } + } + + /* Compute station catchment areas. This is needed here in case UpdateStationAcceptance is called below. */ + Station::RecomputeCatchmentForAll(); + /* Station acceptance is some kind of cache */ if (IsSavegameVersionBefore(SLV_127)) { - Station *st; - FOR_ALL_STATIONS(st) UpdateStationAcceptance(st, false); + for (Station *st : Station::Iterate()) UpdateStationAcceptance(st, false); } /* Road stops is 'only' updating some caches */ diff --git a/src/saveload/ai_sl.cpp b/src/saveload/ai_sl.cpp index 2492bb666a..9b58aea11c 100644 --- a/src/saveload/ai_sl.cpp +++ b/src/saveload/ai_sl.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. @@ -53,7 +51,7 @@ static void SaveReal_AIPL(int *index_ptr) _ai_saveload_settings[0] = '\0'; config->SettingsToString(_ai_saveload_settings, lastof(_ai_saveload_settings)); - SlObject(NULL, _ai_company); + SlObject(nullptr, _ai_company); /* If the AI was active, store his data too */ if (Company::IsValidAiID(index)) AI::Save(index); } @@ -62,7 +60,7 @@ static void Load_AIPL() { /* Free all current data */ for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) { - AIConfig::GetConfig(c, AIConfig::SSS_FORCE_GAME)->Change(NULL); + AIConfig::GetConfig(c, AIConfig::SSS_FORCE_GAME)->Change(nullptr); } CompanyID index; @@ -71,7 +69,7 @@ static void Load_AIPL() _ai_saveload_is_random = 0; _ai_saveload_version = -1; - SlObject(NULL, _ai_company); + SlObject(nullptr, _ai_company); if (_networking && !_network_server) { if (Company::IsValidAiID(index)) AIInstance::LoadEmpty(); @@ -81,7 +79,7 @@ static void Load_AIPL() AIConfig *config = AIConfig::GetConfig(index, AIConfig::SSS_FORCE_GAME); if (StrEmpty(_ai_saveload_name)) { /* A random AI. */ - config->Change(NULL, -1, false, true); + config->Change(nullptr, -1, false, true); } else { config->Change(_ai_saveload_name, _ai_saveload_version, false, _ai_saveload_is_random); if (!config->HasScript()) { @@ -125,5 +123,5 @@ static void Save_AIPL() } extern const ChunkHandler _ai_chunk_handlers[] = { - { 'AIPL', Save_AIPL, Load_AIPL, NULL, NULL, CH_ARRAY | CH_LAST}, + { 'AIPL', Save_AIPL, Load_AIPL, nullptr, nullptr, CH_ARRAY | CH_LAST}, }; diff --git a/src/saveload/airport_sl.cpp b/src/saveload/airport_sl.cpp index 1172d2593e..a7470d268f 100644 --- a/src/saveload/airport_sl.cpp +++ b/src/saveload/airport_sl.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. @@ -37,6 +35,6 @@ static void Load_ATID() } extern const ChunkHandler _airport_chunk_handlers[] = { - { 'ATID', Save_ATID, Load_ATID, NULL, NULL, CH_ARRAY }, - { 'APID', Save_APID, Load_APID, NULL, NULL, CH_ARRAY | CH_LAST }, + { 'ATID', Save_ATID, Load_ATID, nullptr, nullptr, CH_ARRAY }, + { 'APID', Save_APID, Load_APID, nullptr, nullptr, CH_ARRAY | CH_LAST }, }; diff --git a/src/saveload/animated_tile_sl.cpp b/src/saveload/animated_tile_sl.cpp index c54c4724ab..9f03e598d7 100644 --- a/src/saveload/animated_tile_sl.cpp +++ b/src/saveload/animated_tile_sl.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. @@ -18,15 +16,15 @@ #include "../safeguards.h" -extern SmallVector _animated_tiles; +extern std::vector _animated_tiles; /** * Save the ANIT chunk. */ static void Save_ANIT() { - SlSetLength(_animated_tiles.Length() * sizeof(*_animated_tiles.Begin())); - SlArray(_animated_tiles.Begin(), _animated_tiles.Length(), SLE_UINT32); + SlSetLength(_animated_tiles.size() * sizeof(_animated_tiles.front())); + SlArray(_animated_tiles.data(), _animated_tiles.size(), SLE_UINT32); } /** @@ -42,15 +40,15 @@ static void Load_ANIT() for (int i = 0; i < 256; i++) { if (anim_list[i] == 0) break; - *_animated_tiles.Append() = anim_list[i]; + _animated_tiles.push_back(anim_list[i]); } return; } - uint count = (uint)SlGetFieldLength() / sizeof(*_animated_tiles.Begin()); - _animated_tiles.Clear(); - _animated_tiles.Append(count); - SlArray(_animated_tiles.Begin(), count, SLE_UINT32); + uint count = (uint)SlGetFieldLength() / sizeof(_animated_tiles.front()); + _animated_tiles.clear(); + _animated_tiles.resize(_animated_tiles.size() + count); + SlArray(_animated_tiles.data(), count, SLE_UINT32); } /** @@ -58,5 +56,5 @@ static void Load_ANIT() * the animated tile table. */ extern const ChunkHandler _animated_tile_chunk_handlers[] = { - { 'ANIT', Save_ANIT, Load_ANIT, NULL, NULL, CH_RIFF | CH_LAST}, + { 'ANIT', Save_ANIT, Load_ANIT, nullptr, nullptr, CH_RIFF | CH_LAST}, }; diff --git a/src/saveload/autoreplace_sl.cpp b/src/saveload/autoreplace_sl.cpp index 1798df1ada..88f925cc5d 100644 --- a/src/saveload/autoreplace_sl.cpp +++ b/src/saveload/autoreplace_sl.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. @@ -28,9 +26,7 @@ static const SaveLoad _engine_renew_desc[] = { static void Save_ERNW() { - EngineRenew *er; - - FOR_ALL_ENGINE_RENEWS(er) { + for (EngineRenew *er : EngineRenew::Iterate()) { SlSetArrayIndex(er->index); SlObject(er, _engine_renew_desc); } @@ -55,13 +51,11 @@ static void Load_ERNW() static void Ptrs_ERNW() { - EngineRenew *er; - - FOR_ALL_ENGINE_RENEWS(er) { + for (EngineRenew *er : EngineRenew::Iterate()) { SlObject(er, _engine_renew_desc); } } extern const ChunkHandler _autoreplace_chunk_handlers[] = { - { 'ERNW', Save_ERNW, Load_ERNW, Ptrs_ERNW, NULL, CH_ARRAY | CH_LAST}, + { 'ERNW', Save_ERNW, Load_ERNW, Ptrs_ERNW, nullptr, CH_ARRAY | CH_LAST}, }; diff --git a/src/saveload/cargomonitor_sl.cpp b/src/saveload/cargomonitor_sl.cpp index 9a313970ff..75f081eb25 100644 --- a/src/saveload/cargomonitor_sl.cpp +++ b/src/saveload/cargomonitor_sl.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. @@ -121,6 +119,6 @@ static void LoadPickup() /** Chunk definition of the cargomonitoring maps. */ extern const ChunkHandler _cargomonitor_chunk_handlers[] = { - { 'CMDL', SaveDelivery, LoadDelivery, NULL, NULL, CH_ARRAY}, - { 'CMPU', SavePickup, LoadPickup, NULL, NULL, CH_ARRAY | CH_LAST}, + { 'CMDL', SaveDelivery, LoadDelivery, nullptr, nullptr, CH_ARRAY}, + { 'CMPU', SavePickup, LoadPickup, nullptr, nullptr, CH_ARRAY | CH_LAST}, }; diff --git a/src/saveload/cargopacket_sl.cpp b/src/saveload/cargopacket_sl.cpp index e3f372e9a8..e9476fd4b1 100644 --- a/src/saveload/cargopacket_sl.cpp +++ b/src/saveload/cargopacket_sl.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. @@ -23,14 +21,13 @@ /* static */ void CargoPacket::AfterLoad() { if (IsSavegameVersionBefore(SLV_44)) { - Vehicle *v; /* If we remove a station while cargo from it is still en route, payment calculation will assume * 0, 0 to be the source of the cargo, resulting in very high payments usually. v->source_xy * stores the coordinates, preserving them even if the station is removed. However, if a game is loaded * where this situation exists, the cargo-source information is lost. in this case, we set the source * to the current tile of the vehicle to prevent excessive profits */ - FOR_ALL_VEHICLES(v) { + for (const Vehicle *v : Vehicle::Iterate()) { const CargoPacketList *packets = v->cargo.Packets(); for (VehicleCargoList::ConstIterator it(packets->begin()); it != packets->end(); it++) { CargoPacket *cp = *it; @@ -44,8 +41,7 @@ * station where the goods came from is already removed, the source * information is lost. In that case we set it to the position of this * station */ - Station *st; - FOR_ALL_STATIONS(st) { + for (Station *st : Station::Iterate()) { for (CargoID c = 0; c < NUM_CARGO; c++) { GoodsEntry *ge = &st->goods[c]; @@ -61,8 +57,7 @@ if (IsSavegameVersionBefore(SLV_120)) { /* CargoPacket's source should be either INVALID_STATION or a valid station */ - CargoPacket *cp; - FOR_ALL_CARGOPACKETS(cp) { + for (CargoPacket *cp : CargoPacket::Iterate()) { if (!Station::IsValidID(cp->source)) cp->source = INVALID_STATION; } } @@ -71,18 +66,15 @@ /* Only since version 68 we have cargo packets. Savegames from before used * 'new CargoPacket' + cargolist.Append so their caches are already * correct and do not need rebuilding. */ - Vehicle *v; - FOR_ALL_VEHICLES(v) v->cargo.InvalidateCache(); + for (Vehicle *v : Vehicle::Iterate()) v->cargo.InvalidateCache(); - Station *st; - FOR_ALL_STATIONS(st) { + for (Station *st : Station::Iterate()) { for (CargoID c = 0; c < NUM_CARGO; c++) st->goods[c].cargo.InvalidateCache(); } } if (IsSavegameVersionBefore(SLV_181)) { - Vehicle *v; - FOR_ALL_VEHICLES(v) v->cargo.KeepAll(); + for (Vehicle *v : Vehicle::Iterate()) v->cargo.KeepAll(); } } @@ -116,9 +108,7 @@ const SaveLoad *GetCargoPacketDesc() */ static void Save_CAPA() { - CargoPacket *cp; - - FOR_ALL_CARGOPACKETS(cp) { + for (CargoPacket *cp : CargoPacket::Iterate()) { SlSetArrayIndex(cp->index); SlObject(cp, GetCargoPacketDesc()); } @@ -139,5 +129,5 @@ static void Load_CAPA() /** Chunk handlers related to cargo packets. */ extern const ChunkHandler _cargopacket_chunk_handlers[] = { - { 'CAPA', Save_CAPA, Load_CAPA, NULL, NULL, CH_ARRAY | CH_LAST}, + { 'CAPA', Save_CAPA, Load_CAPA, nullptr, nullptr, CH_ARRAY | CH_LAST}, }; diff --git a/src/saveload/cheat_sl.cpp b/src/saveload/cheat_sl.cpp index 4616b7e852..9af1759221 100644 --- a/src/saveload/cheat_sl.cpp +++ b/src/saveload/cheat_sl.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. @@ -51,5 +49,5 @@ static void Load_CHTS() /** Chunk handlers related to cheats. */ extern const ChunkHandler _cheat_chunk_handlers[] = { - { 'CHTS', Save_CHTS, Load_CHTS, NULL, NULL, CH_RIFF | CH_LAST}, + { 'CHTS', Save_CHTS, Load_CHTS, nullptr, nullptr, CH_RIFF | CH_LAST}, }; diff --git a/src/saveload/company_sl.cpp b/src/saveload/company_sl.cpp index a51f8081b0..5b9266c7b4 100644 --- a/src/saveload/company_sl.cpp +++ b/src/saveload/company_sl.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. @@ -96,22 +94,21 @@ CompanyManagerFace ConvertFromOldCompanyManagerFace(uint32 face) void AfterLoadCompanyStats() { /* Reset infrastructure statistics to zero. */ - Company *c; - FOR_ALL_COMPANIES(c) MemSetT(&c->infrastructure, 0); + for (Company *c : Company::Iterate()) MemSetT(&c->infrastructure, 0); /* Collect airport count. */ - Station *st; - FOR_ALL_STATIONS(st) { + for (const Station *st : Station::Iterate()) { if ((st->facilities & FACIL_AIRPORT) && Company::IsValidID(st->owner)) { Company::Get(st->owner)->infrastructure.airport++; } } + Company *c; for (TileIndex tile = 0; tile < MapSize(); tile++) { switch (GetTileType(tile)) { case MP_RAILWAY: c = Company::GetIfValid(GetTileOwner(tile)); - if (c != NULL) { + if (c != nullptr) { uint pieces = 1; if (IsPlainRail(tile)) { TrackBits bits = GetTrackBits(tile); @@ -127,36 +124,38 @@ void AfterLoadCompanyStats() case MP_ROAD: { if (IsLevelCrossing(tile)) { c = Company::GetIfValid(GetTileOwner(tile)); - if (c != NULL) c->infrastructure.rail[GetRailType(tile)] += LEVELCROSSING_TRACKBIT_FACTOR; + if (c != nullptr) c->infrastructure.rail[GetRailType(tile)] += LEVELCROSSING_TRACKBIT_FACTOR; } /* Iterate all present road types as each can have a different owner. */ - RoadType rt; - FOR_EACH_SET_ROADTYPE(rt, GetRoadTypes(tile)) { - c = Company::GetIfValid(IsRoadDepot(tile) ? GetTileOwner(tile) : GetRoadOwner(tile, rt)); + FOR_ALL_ROADTRAMTYPES(rtt) { + RoadType rt = GetRoadType(tile, rtt); + if (rt == INVALID_ROADTYPE) continue; + c = Company::GetIfValid(IsRoadDepot(tile) ? GetTileOwner(tile) : GetRoadOwner(tile, rtt)); /* A level crossings and depots have two road bits. */ - if (c != NULL) c->infrastructure.road[rt] += IsNormalRoad(tile) ? CountBits(GetRoadBits(tile, rt)) : 2; + if (c != nullptr) c->infrastructure.road[rt] += IsNormalRoad(tile) ? CountBits(GetRoadBits(tile, rtt)) : 2; } break; } case MP_STATION: c = Company::GetIfValid(GetTileOwner(tile)); - if (c != NULL && GetStationType(tile) != STATION_AIRPORT && !IsBuoy(tile)) c->infrastructure.station++; + if (c != nullptr && GetStationType(tile) != STATION_AIRPORT && !IsBuoy(tile)) c->infrastructure.station++; switch (GetStationType(tile)) { case STATION_RAIL: case STATION_WAYPOINT: - if (c != NULL && !IsStationTileBlocked(tile)) c->infrastructure.rail[GetRailType(tile)]++; + if (c != nullptr && !IsStationTileBlocked(tile)) c->infrastructure.rail[GetRailType(tile)]++; break; case STATION_BUS: case STATION_TRUCK: { /* Iterate all present road types as each can have a different owner. */ - RoadType rt; - FOR_EACH_SET_ROADTYPE(rt, GetRoadTypes(tile)) { - c = Company::GetIfValid(GetRoadOwner(tile, rt)); - if (c != NULL) c->infrastructure.road[rt] += 2; // A road stop has two road bits. + FOR_ALL_ROADTRAMTYPES(rtt) { + RoadType rt = GetRoadType(tile, rtt); + if (rt == INVALID_ROADTYPE) continue; + c = Company::GetIfValid(GetRoadOwner(tile, rtt)); + if (c != nullptr) c->infrastructure.road[rt] += 2; // A road stop has two road bits. } break; } @@ -164,7 +163,7 @@ void AfterLoadCompanyStats() case STATION_DOCK: case STATION_BUOY: if (GetWaterClass(tile) == WATER_CLASS_CANAL) { - if (c != NULL) c->infrastructure.water++; + if (c != nullptr) c->infrastructure.water++; } break; @@ -176,7 +175,7 @@ void AfterLoadCompanyStats() case MP_WATER: if (IsShipDepot(tile) || IsLock(tile)) { c = Company::GetIfValid(GetTileOwner(tile)); - if (c != NULL) { + if (c != nullptr) { if (IsShipDepot(tile)) c->infrastructure.water += LOCK_DEPOT_TILE_FACTOR; if (IsLock(tile) && GetLockPart(tile) == LOCK_PART_MIDDLE) { /* The middle tile specifies the owner of the lock. */ @@ -190,7 +189,7 @@ void AfterLoadCompanyStats() case MP_OBJECT: if (GetWaterClass(tile) == WATER_CLASS_CANAL) { c = Company::GetIfValid(GetTileOwner(tile)); - if (c != NULL) c->infrastructure.water++; + if (c != nullptr) c->infrastructure.water++; } break; @@ -205,22 +204,23 @@ void AfterLoadCompanyStats() switch (GetTunnelBridgeTransportType(tile)) { case TRANSPORT_RAIL: c = Company::GetIfValid(GetTileOwner(tile)); - if (c != NULL) c->infrastructure.rail[GetRailType(tile)] += len; + if (c != nullptr) c->infrastructure.rail[GetRailType(tile)] += len; break; case TRANSPORT_ROAD: { /* Iterate all present road types as each can have a different owner. */ - RoadType rt; - FOR_EACH_SET_ROADTYPE(rt, GetRoadTypes(tile)) { - c = Company::GetIfValid(GetRoadOwner(tile, rt)); - if (c != NULL) c->infrastructure.road[rt] += len * 2; // A full diagonal road has two road bits. + FOR_ALL_ROADTRAMTYPES(rtt) { + RoadType rt = GetRoadType(tile, rtt); + if (rt == INVALID_ROADTYPE) continue; + c = Company::GetIfValid(GetRoadOwner(tile, rtt)); + if (c != nullptr) c->infrastructure.road[rt] += len * 2; // A full diagonal road has two road bits. } break; } case TRANSPORT_WATER: c = Company::GetIfValid(GetTileOwner(tile)); - if (c != NULL) c->infrastructure.water += len; + if (c != nullptr) c->infrastructure.water += len; break; default: @@ -414,7 +414,7 @@ static void SaveLoad_PLYR_common(Company *c, CompanyProperties *cprops) int i; SlObject(cprops, _company_desc); - if (c != NULL) { + if (c != nullptr) { SlObject(c, _company_settings_desc); } else { char nothing; @@ -444,7 +444,7 @@ static void SaveLoad_PLYR_common(Company *c, CompanyProperties *cprops) /* Write each livery entry. */ int num_liveries = IsSavegameVersionBefore(SLV_63) ? LS_END - 4 : (IsSavegameVersionBefore(SLV_85) ? LS_END - 2: LS_END); bool update_in_use = IsSavegameVersionBefore(SLV_GROUP_LIVERIES); - if (c != NULL) { + if (c != nullptr) { for (i = 0; i < num_liveries; i++) { SlObject(&c->livery[i], _company_livery_desc); if (update_in_use && i != LS_DEFAULT) { @@ -485,8 +485,7 @@ static void SaveLoad_PLYR(Company *c) static void Save_PLYR() { - Company *c; - FOR_ALL_COMPANIES(c) { + for (Company *c : Company::Iterate()) { SlSetArrayIndex(c->index); SlAutolength((AutolengthProc*)SaveLoad_PLYR, c); } @@ -507,7 +506,7 @@ static void Check_PLYR() int index; while ((index = SlIterateArray()) != -1) { CompanyProperties *cprops = new CompanyProperties(); - SaveLoad_PLYR_common(NULL, cprops); + SaveLoad_PLYR_common(nullptr, cprops); /* We do not load old custom names */ if (IsSavegameVersionBefore(SLV_84)) { @@ -520,7 +519,7 @@ static void Check_PLYR() } } - if (cprops->name == NULL && !IsInsideMM(cprops->name_1, SPECSTR_COMPANY_NAME_START, SPECSTR_COMPANY_NAME_LAST + 1) && + if (cprops->name == nullptr && !IsInsideMM(cprops->name_1, SPECSTR_COMPANY_NAME_START, SPECSTR_COMPANY_NAME_LAST + 1) && cprops->name_1 != STR_GAME_SAVELOAD_NOT_AVAILABLE && cprops->name_1 != STR_SV_UNNAMED && cprops->name_1 != SPECSTR_ANDCO_NAME && cprops->name_1 != SPECSTR_PRESIDENT_NAME && cprops->name_1 != SPECSTR_SILLY_NAME) { @@ -533,8 +532,7 @@ static void Check_PLYR() static void Ptrs_PLYR() { - Company *c; - FOR_ALL_COMPANIES(c) { + for (Company *c : Company::Iterate()) { SlObject(c, _company_settings_desc); } } diff --git a/src/saveload/depot_sl.cpp b/src/saveload/depot_sl.cpp index b92417693c..eb4b9384bc 100644 --- a/src/saveload/depot_sl.cpp +++ b/src/saveload/depot_sl.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. @@ -32,9 +30,7 @@ static const SaveLoad _depot_desc[] = { static void Save_DEPT() { - Depot *depot; - - FOR_ALL_DEPOTS(depot) { + for (Depot *depot : Depot::Iterate()) { SlSetArrayIndex(depot->index); SlObject(depot, _depot_desc); } @@ -55,14 +51,12 @@ static void Load_DEPT() static void Ptrs_DEPT() { - Depot *depot; - - FOR_ALL_DEPOTS(depot) { + for (Depot *depot : Depot::Iterate()) { SlObject(depot, _depot_desc); if (IsSavegameVersionBefore(SLV_141)) depot->town = Town::Get((size_t)depot->town); } } extern const ChunkHandler _depot_chunk_handlers[] = { - { 'DEPT', Save_DEPT, Load_DEPT, Ptrs_DEPT, NULL, CH_ARRAY | CH_LAST}, + { 'DEPT', Save_DEPT, Load_DEPT, Ptrs_DEPT, nullptr, CH_ARRAY | CH_LAST}, }; diff --git a/src/saveload/economy_sl.cpp b/src/saveload/economy_sl.cpp index 0ddab13514..637d2529c6 100644 --- a/src/saveload/economy_sl.cpp +++ b/src/saveload/economy_sl.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. @@ -22,8 +20,8 @@ static void Load_PRIC() { /* Old games store 49 base prices, very old games store them as int32 */ int vt = IsSavegameVersionBefore(SLV_65) ? SLE_FILE_I32 : SLE_FILE_I64; - SlArray(NULL, 49, vt | SLE_VAR_NULL); - SlArray(NULL, 49, SLE_FILE_U16 | SLE_VAR_NULL); + SlArray(nullptr, 49, vt | SLE_VAR_NULL); + SlArray(nullptr, 49, SLE_FILE_U16 | SLE_VAR_NULL); } /** Cargo payment rates in pre 126 savegames */ @@ -31,8 +29,8 @@ static void Load_CAPR() { uint num_cargo = IsSavegameVersionBefore(SLV_55) ? 12 : IsSavegameVersionBefore(SLV_EXTEND_CARGOTYPES) ? 32 : NUM_CARGO; int vt = IsSavegameVersionBefore(SLV_65) ? SLE_FILE_I32 : SLE_FILE_I64; - SlArray(NULL, num_cargo, vt | SLE_VAR_NULL); - SlArray(NULL, num_cargo, SLE_FILE_U16 | SLE_VAR_NULL); + SlArray(nullptr, num_cargo, vt | SLE_VAR_NULL); + SlArray(nullptr, num_cargo, SLE_FILE_U16 | SLE_VAR_NULL); } static const SaveLoad _economy_desc[] = { @@ -74,8 +72,7 @@ static const SaveLoad _cargopayment_desc[] = { static void Save_CAPY() { - CargoPayment *cp; - FOR_ALL_CARGO_PAYMENTS(cp) { + for (CargoPayment *cp : CargoPayment::Iterate()) { SlSetArrayIndex(cp->index); SlObject(cp, _cargopayment_desc); } @@ -93,16 +90,15 @@ static void Load_CAPY() static void Ptrs_CAPY() { - CargoPayment *cp; - FOR_ALL_CARGO_PAYMENTS(cp) { + for (CargoPayment *cp : CargoPayment::Iterate()) { SlObject(cp, _cargopayment_desc); } } extern const ChunkHandler _economy_chunk_handlers[] = { - { 'CAPY', Save_CAPY, Load_CAPY, Ptrs_CAPY, NULL, CH_ARRAY}, - { 'PRIC', NULL, Load_PRIC, NULL, NULL, CH_RIFF | CH_AUTO_LENGTH}, - { 'CAPR', NULL, Load_CAPR, NULL, NULL, CH_RIFF | CH_AUTO_LENGTH}, - { 'ECMY', Save_ECMY, Load_ECMY, NULL, NULL, CH_RIFF | CH_LAST}, + { 'CAPY', Save_CAPY, Load_CAPY, Ptrs_CAPY, nullptr, CH_ARRAY}, + { 'PRIC', nullptr, Load_PRIC, nullptr, nullptr, CH_RIFF | CH_AUTO_LENGTH}, + { 'CAPR', nullptr, Load_CAPR, nullptr, nullptr, CH_RIFF | CH_AUTO_LENGTH}, + { 'ECMY', Save_ECMY, Load_ECMY, nullptr, nullptr, CH_RIFF | CH_LAST}, }; diff --git a/src/saveload/engine_sl.cpp b/src/saveload/engine_sl.cpp index 5221d1bbdc..44ba6498ef 100644 --- a/src/saveload/engine_sl.cpp +++ b/src/saveload/engine_sl.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. @@ -68,7 +66,7 @@ static Engine* CallocEngine() */ static void FreeEngine(Engine *e) { - if (e != NULL) { + if (e != nullptr) { e->~Engine(); free(e); } @@ -88,8 +86,7 @@ Engine *GetTempDataEngine(EngineID index) static void Save_ENGN() { - Engine *e; - FOR_ALL_ENGINES(e) { + for (Engine *e : Engine::Iterate()) { SlSetArrayIndex(e->index); SlObject(e, _engine_desc); } @@ -120,8 +117,7 @@ static void Load_ENGN() */ void CopyTempEngineData() { - Engine *e; - FOR_ALL_ENGINES(e) { + for (Engine *e : Engine::Iterate()) { if (e->index >= _temp_engine.size()) break; const Engine *se = GetTempDataEngine(e->index); @@ -141,9 +137,14 @@ void CopyTempEngineData() e->preview_wait = se->preview_wait; e->company_avail = se->company_avail; e->company_hidden = se->company_hidden; - if (se->name != NULL) e->name = stredup(se->name); + if (se->name != nullptr) e->name = stredup(se->name); } + ResetTempEngineData(); +} + +void ResetTempEngineData() +{ /* Get rid of temporary data */ for (std::vector::iterator it = _temp_engine.begin(); it != _temp_engine.end(); ++it) { FreeEngine(*it); @@ -177,26 +178,27 @@ static const SaveLoad _engine_id_mapping_desc[] = { static void Save_EIDS() { - const EngineIDMapping *end = _engine_mngr.End(); uint index = 0; - for (EngineIDMapping *eid = _engine_mngr.Begin(); eid != end; eid++, index++) { + for (EngineIDMapping &eid : _engine_mngr) { SlSetArrayIndex(index); - SlObject(eid, _engine_id_mapping_desc); + SlObject(&eid, _engine_id_mapping_desc); + index++; } } static void Load_EIDS() { - _engine_mngr.Clear(); + _engine_mngr.clear(); while (SlIterateArray() != -1) { - EngineIDMapping *eid = _engine_mngr.Append(); + /*C++17: EngineIDMapping *eid = &*/ _engine_mngr.emplace_back(); + EngineIDMapping *eid = &_engine_mngr.back(); SlObject(eid, _engine_id_mapping_desc); } } extern const ChunkHandler _engine_chunk_handlers[] = { - { 'EIDS', Save_EIDS, Load_EIDS, NULL, NULL, CH_ARRAY }, - { 'ENGN', Save_ENGN, Load_ENGN, NULL, NULL, CH_ARRAY }, - { 'ENGS', NULL, Load_ENGS, NULL, NULL, CH_RIFF | CH_LAST }, + { 'EIDS', Save_EIDS, Load_EIDS, nullptr, nullptr, CH_ARRAY }, + { 'ENGN', Save_ENGN, Load_ENGN, nullptr, nullptr, CH_ARRAY }, + { 'ENGS', nullptr, Load_ENGS, nullptr, nullptr, CH_RIFF | CH_LAST }, }; diff --git a/src/saveload/game_sl.cpp b/src/saveload/game_sl.cpp index 325ae1c9d4..28a6c6c11a 100644 --- a/src/saveload/game_sl.cpp +++ b/src/saveload/game_sl.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. @@ -52,19 +50,19 @@ static void SaveReal_GSDT(int *index_ptr) _game_saveload_settings[0] = '\0'; config->SettingsToString(_game_saveload_settings, lastof(_game_saveload_settings)); - SlObject(NULL, _game_script); + SlObject(nullptr, _game_script); Game::Save(); } static void Load_GSDT() { /* Free all current data */ - GameConfig::GetConfig(GameConfig::SSS_FORCE_GAME)->Change(NULL); + GameConfig::GetConfig(GameConfig::SSS_FORCE_GAME)->Change(nullptr); if ((CompanyID)SlIterateArray() == (CompanyID)-1) return; _game_saveload_version = -1; - SlObject(NULL, _game_script); + SlObject(nullptr, _game_script); if (_networking && !_network_server) { GameInstance::LoadEmpty(); @@ -110,7 +108,7 @@ static void Load_GSDT() static void Save_GSDT() { SlSetArrayIndex(0); - SlAutolength((AutolengthProc *)SaveReal_GSDT, NULL); + SlAutolength((AutolengthProc *)SaveReal_GSDT, nullptr); } extern GameStrings *_current_data; @@ -129,15 +127,15 @@ static const SaveLoad _game_language_string[] = { SLE_END() }; -static void SaveReal_GSTR(LanguageStrings *ls) +static void SaveReal_GSTR(const LanguageStrings *ls) { _game_saveload_string = ls->language; - _game_saveload_strings = ls->lines.Length(); + _game_saveload_strings = (uint)ls->lines.size(); - SlObject(NULL, _game_language_header); - for (uint i = 0; i < _game_saveload_strings; i++) { - _game_saveload_string = ls->lines[i]; - SlObject(NULL, _game_language_string); + SlObject(nullptr, _game_language_header); + for (const auto &i : ls->lines) { + _game_saveload_string = i.c_str(); + SlObject(nullptr, _game_language_string); } } @@ -147,22 +145,22 @@ static void Load_GSTR() _current_data = new GameStrings(); while (SlIterateArray() != -1) { - _game_saveload_string = NULL; - SlObject(NULL, _game_language_header); + _game_saveload_string = nullptr; + SlObject(nullptr, _game_language_header); - LanguageStrings *ls = new LanguageStrings(_game_saveload_string != NULL ? _game_saveload_string : ""); + std::unique_ptr ls(new LanguageStrings(_game_saveload_string != nullptr ? _game_saveload_string : "")); for (uint i = 0; i < _game_saveload_strings; i++) { - SlObject(NULL, _game_language_string); - *ls->lines.Append() = stredup(_game_saveload_string != NULL ? _game_saveload_string : ""); + SlObject(nullptr, _game_language_string); + ls->lines.emplace_back(_game_saveload_string != nullptr ? _game_saveload_string : ""); } - *_current_data->raw_strings.Append() = ls; + _current_data->raw_strings.push_back(std::move(ls)); } - /* If there were no strings in the savegame, set GameStrings to NULL */ - if (_current_data->raw_strings.Length() == 0) { + /* If there were no strings in the savegame, set GameStrings to nullptr */ + if (_current_data->raw_strings.size() == 0) { delete _current_data; - _current_data = NULL; + _current_data = nullptr; return; } @@ -172,15 +170,15 @@ static void Load_GSTR() static void Save_GSTR() { - if (_current_data == NULL) return; + if (_current_data == nullptr) return; - for (uint i = 0; i < _current_data->raw_strings.Length(); i++) { + for (uint i = 0; i < _current_data->raw_strings.size(); i++) { SlSetArrayIndex(i); - SlAutolength((AutolengthProc *)SaveReal_GSTR, _current_data->raw_strings[i]); + SlAutolength((AutolengthProc *)SaveReal_GSTR, _current_data->raw_strings[i].get()); } } extern const ChunkHandler _game_chunk_handlers[] = { - { 'GSTR', Save_GSTR, Load_GSTR, NULL, NULL, CH_ARRAY }, - { 'GSDT', Save_GSDT, Load_GSDT, NULL, NULL, CH_ARRAY | CH_LAST}, + { 'GSTR', Save_GSTR, Load_GSTR, nullptr, nullptr, CH_ARRAY }, + { 'GSDT', Save_GSDT, Load_GSDT, nullptr, nullptr, CH_ARRAY | CH_LAST}, }; diff --git a/src/saveload/gamelog_sl.cpp b/src/saveload/gamelog_sl.cpp index d1c502d3be..576bfa5bc7 100644 --- a/src/saveload/gamelog_sl.cpp +++ b/src/saveload/gamelog_sl.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. @@ -106,7 +104,7 @@ assert_compile(lengthof(_glog_desc) == GLCT_END); static void Load_GLOG_common(LoggedAction *&gamelog_action, uint &gamelog_actions) { - assert(gamelog_action == NULL); + assert(gamelog_action == nullptr); assert(gamelog_actions == 0); GamelogActionType at; @@ -117,7 +115,7 @@ static void Load_GLOG_common(LoggedAction *&gamelog_action, uint &gamelog_action la->at = at; SlObject(la, _glog_action_desc); // has to be saved after 'DATE'! - la->change = NULL; + la->change = nullptr; la->changes = 0; GamelogChangeType ct; @@ -125,7 +123,7 @@ static void Load_GLOG_common(LoggedAction *&gamelog_action, uint &gamelog_action la->change = ReallocT(la->change, la->changes + 1); LoggedChange *lc = &la->change[la->changes++]; - /* for SLE_STR, pointer has to be valid! so make it NULL */ + /* for SLE_STR, pointer has to be valid! so make it nullptr */ memset(lc, 0, sizeof(*lc)); lc->ct = ct; @@ -179,5 +177,5 @@ static void Check_GLOG() } extern const ChunkHandler _gamelog_chunk_handlers[] = { - { 'GLOG', Save_GLOG, Load_GLOG, NULL, Check_GLOG, CH_RIFF | CH_LAST } + { 'GLOG', Save_GLOG, Load_GLOG, nullptr, Check_GLOG, CH_RIFF | CH_LAST } }; diff --git a/src/saveload/goal_sl.cpp b/src/saveload/goal_sl.cpp index a8cdc2305d..4ee9f39ebe 100644 --- a/src/saveload/goal_sl.cpp +++ b/src/saveload/goal_sl.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. @@ -28,8 +26,7 @@ static const SaveLoad _goals_desc[] = { static void Save_GOAL() { - Goal *s; - FOR_ALL_GOALS(s) { + for (Goal *s : Goal::Iterate()) { SlSetArrayIndex(s->index); SlObject(s, _goals_desc); } @@ -45,5 +42,5 @@ static void Load_GOAL() } extern const ChunkHandler _goal_chunk_handlers[] = { - { 'GOAL', Save_GOAL, Load_GOAL, NULL, NULL, CH_ARRAY | CH_LAST}, + { 'GOAL', Save_GOAL, Load_GOAL, nullptr, nullptr, CH_ARRAY | CH_LAST}, }; diff --git a/src/saveload/group_sl.cpp b/src/saveload/group_sl.cpp index 025c8ee3a7..33c63ee44f 100644 --- a/src/saveload/group_sl.cpp +++ b/src/saveload/group_sl.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,7 @@ static const SaveLoad _group_desc[] = { static void Save_GRPS() { - Group *g; - - FOR_ALL_GROUPS(g) { + for (Group *g : Group::Iterate()) { SlSetArrayIndex(g->index); SlObject(g, _group_desc); } @@ -61,5 +57,5 @@ static void Load_GRPS() } extern const ChunkHandler _group_chunk_handlers[] = { - { 'GRPS', Save_GRPS, Load_GRPS, NULL, NULL, CH_ARRAY | CH_LAST}, + { 'GRPS', Save_GRPS, Load_GRPS, nullptr, nullptr, CH_ARRAY | CH_LAST}, }; diff --git a/src/saveload/industry_sl.cpp b/src/saveload/industry_sl.cpp index 9e81861c4e..f5b1464c1e 100644 --- a/src/saveload/industry_sl.cpp +++ b/src/saveload/industry_sl.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. @@ -25,6 +23,7 @@ static const SaveLoad _industry_desc[] = { SLE_VAR(Industry, location.w, SLE_FILE_U8 | SLE_VAR_U16), SLE_VAR(Industry, location.h, SLE_FILE_U8 | SLE_VAR_U16), SLE_REF(Industry, town, REF_TOWN), + SLE_CONDREF(Industry, neutral_station, REF_STATION, SLV_SERVE_NEUTRAL_INDUSTRIES, SL_MAX_VERSION), SLE_CONDNULL( 2, SL_MIN_VERSION, SLV_61), ///< used to be industry's produced_cargo SLE_CONDARR(Industry, produced_cargo, SLE_UINT8, 2, SLV_78, SLV_EXTEND_INDUSTRY_CARGO_SLOTS), SLE_CONDARR(Industry, produced_cargo, SLE_UINT8, 16, SLV_EXTEND_INDUSTRY_CARGO_SLOTS, SL_MAX_VERSION), @@ -78,10 +77,8 @@ static const SaveLoad _industry_desc[] = { static void Save_INDY() { - Industry *ind; - /* Write the industries */ - FOR_ALL_INDUSTRIES(ind) { + for (Industry *ind : Industry::Iterate()) { SlSetArrayIndex(ind->index); SlObject(ind, _industry_desc); } @@ -130,9 +127,7 @@ static void Load_TIDS() static void Ptrs_INDY() { - Industry *i; - - FOR_ALL_INDUSTRIES(i) { + for (Industry *i : Industry::Iterate()) { SlObject(i, _industry_desc); } } @@ -182,9 +177,9 @@ static void Load_ITBL() } extern const ChunkHandler _industry_chunk_handlers[] = { - { 'INDY', Save_INDY, Load_INDY, Ptrs_INDY, NULL, CH_ARRAY}, - { 'IIDS', Save_IIDS, Load_IIDS, NULL, NULL, CH_ARRAY}, - { 'TIDS', Save_TIDS, Load_TIDS, NULL, NULL, CH_ARRAY}, - { 'IBLD', LoadSave_IBLD, LoadSave_IBLD, NULL, NULL, CH_RIFF}, - { 'ITBL', Save_ITBL, Load_ITBL, NULL, NULL, CH_ARRAY | CH_LAST}, + { 'INDY', Save_INDY, Load_INDY, Ptrs_INDY, nullptr, CH_ARRAY}, + { 'IIDS', Save_IIDS, Load_IIDS, nullptr, nullptr, CH_ARRAY}, + { 'TIDS', Save_TIDS, Load_TIDS, nullptr, nullptr, CH_ARRAY}, + { 'IBLD', LoadSave_IBLD, LoadSave_IBLD, nullptr, nullptr, CH_RIFF}, + { 'ITBL', Save_ITBL, Load_ITBL, nullptr, nullptr, CH_ARRAY | CH_LAST}, }; diff --git a/src/saveload/labelmaps_sl.cpp b/src/saveload/labelmaps_sl.cpp index 3b898a3b87..542b85b9f1 100644 --- a/src/saveload/labelmaps_sl.cpp +++ b/src/saveload/labelmaps_sl.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. @@ -14,10 +12,11 @@ #include "../tunnelbridge_map.h" #include "saveload.h" +#include "saveload_internal.h" #include "../safeguards.h" -static SmallVector _railtype_list; +static std::vector _railtype_list; /** * Test if any saved rail type labels are different to the currently loaded @@ -26,7 +25,7 @@ static SmallVector _railtype_list; */ static bool NeedRailTypeConversion() { - for (uint i = 0; i < _railtype_list.Length(); i++) { + for (uint i = 0; i < _railtype_list.size(); i++) { if ((RailType)i < RAILTYPE_END) { const RailtypeInfo *rti = GetRailTypeInfo((RailType)i); if (rti->label != _railtype_list[i]) return true; @@ -42,13 +41,13 @@ static bool NeedRailTypeConversion() void AfterLoadLabelMaps() { if (NeedRailTypeConversion()) { - SmallVector railtype_conversion_map; + std::vector railtype_conversion_map; - for (uint i = 0; i < _railtype_list.Length(); i++) { + for (uint i = 0; i < _railtype_list.size(); i++) { RailType r = GetRailTypeByLabel(_railtype_list[i]); if (r == INVALID_RAILTYPE) r = RAILTYPE_BEGIN; - *railtype_conversion_map.Append() = r; + railtype_conversion_map.push_back(r); } for (TileIndex t = 0; t < MapSize(); t++) { @@ -81,7 +80,12 @@ void AfterLoadLabelMaps() } } - _railtype_list.Clear(); + ResetLabelMaps(); +} + +void ResetLabelMaps() +{ + _railtype_list.clear(); } /** Container for a label for SaveLoad system */ @@ -108,17 +112,17 @@ static void Save_RAIL() static void Load_RAIL() { - _railtype_list.Clear(); + ResetLabelMaps(); LabelObject lo; while (SlIterateArray() != -1) { SlObject(&lo, _label_object_desc); - *_railtype_list.Append() = (RailTypeLabel)lo.label; + _railtype_list.push_back((RailTypeLabel)lo.label); } } extern const ChunkHandler _labelmaps_chunk_handlers[] = { - { 'RAIL', Save_RAIL, Load_RAIL, NULL, NULL, CH_ARRAY | CH_LAST}, + { 'RAIL', Save_RAIL, Load_RAIL, nullptr, nullptr, CH_ARRAY | CH_LAST}, }; diff --git a/src/saveload/linkgraph_sl.cpp b/src/saveload/linkgraph_sl.cpp index 76390a0101..29b685cf7d 100644 --- a/src/saveload/linkgraph_sl.cpp +++ b/src/saveload/linkgraph_sl.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. @@ -51,11 +49,11 @@ const SaveLoad *GetLinkGraphDesc() */ const SaveLoad *GetLinkGraphJobDesc() { - static SmallVector saveloads; + static std::vector saveloads; static const char *prefix = "linkgraph."; /* Build the SaveLoad array on first call and don't touch it later on */ - if (saveloads.Length() == 0) { + if (saveloads.size() == 0) { size_t offset_gamesettings = cpp_offsetof(GameSettings, linkgraph); size_t offset_component = cpp_offsetof(LinkGraphJob, settings); @@ -64,12 +62,12 @@ const SaveLoad *GetLinkGraphJobDesc() int setting = 0; const SettingDesc *desc = GetSettingDescription(setting); while (desc->save.cmd != SL_END) { - if (desc->desc.name != NULL && strncmp(desc->desc.name, prefix, prefixlen) == 0) { + if (desc->desc.name != nullptr && strncmp(desc->desc.name, prefix, prefixlen) == 0) { SaveLoad sl = desc->save; char *&address = reinterpret_cast(sl.address); address -= offset_gamesettings; address += offset_component; - *(saveloads.Append()) = sl; + saveloads.push_back(sl); } desc = GetSettingDescription(++setting); } @@ -82,8 +80,8 @@ const SaveLoad *GetLinkGraphJobDesc() int i = 0; do { - *(saveloads.Append()) = job_desc[i++]; - } while (saveloads[saveloads.Length() - 1].cmd != SL_END); + saveloads.push_back(job_desc[i++]); + } while (saveloads[saveloads.size() - 1].cmd != SL_END); } return &saveloads[0]; @@ -230,18 +228,18 @@ static void Load_LGRS() void AfterLoadLinkGraphs() { if (IsSavegameVersionBefore(SLV_191)) { - LinkGraph *lg; - FOR_ALL_LINK_GRAPHS(lg) { + for (LinkGraph *lg : LinkGraph::Iterate()) { for (NodeID node_id = 0; node_id < lg->Size(); ++node_id) { - (*lg)[node_id].UpdateLocation(Station::Get((*lg)[node_id].Station())->xy); + const Station *st = Station::GetIfValid((*lg)[node_id].Station()); + if (st != nullptr) (*lg)[node_id].UpdateLocation(st->xy); } } - LinkGraphJob *lgj; - FOR_ALL_LINK_GRAPH_JOBS(lgj) { - lg = &(const_cast(lgj->Graph())); + for (LinkGraphJob *lgj : LinkGraphJob::Iterate()) { + LinkGraph *lg = &(const_cast(lgj->Graph())); for (NodeID node_id = 0; node_id < lg->Size(); ++node_id) { - (*lg)[node_id].UpdateLocation(Station::Get((*lg)[node_id].Station())->xy); + const Station *st = Station::GetIfValid((*lg)[node_id].Station()); + if (st != nullptr) (*lg)[node_id].UpdateLocation(st->xy); } } } @@ -254,8 +252,7 @@ void AfterLoadLinkGraphs() */ static void Save_LGRP() { - LinkGraph *lg; - FOR_ALL_LINK_GRAPHS(lg) { + for (LinkGraph *lg : LinkGraph::Iterate()) { SlSetArrayIndex(lg->index); SlAutolength((AutolengthProc*)DoSave_LGRP, lg); } @@ -266,8 +263,7 @@ static void Save_LGRP() */ static void Save_LGRJ() { - LinkGraphJob *lgj; - FOR_ALL_LINK_GRAPH_JOBS(lgj) { + for (LinkGraphJob *lgj : LinkGraphJob::Iterate()) { SlSetArrayIndex(lgj->index); SlAutolength((AutolengthProc*)DoSave_LGRJ, lgj); } @@ -290,7 +286,7 @@ static void Ptrs_LGRS() } extern const ChunkHandler _linkgraph_chunk_handlers[] = { - { 'LGRP', Save_LGRP, Load_LGRP, NULL, NULL, CH_ARRAY }, - { 'LGRJ', Save_LGRJ, Load_LGRJ, NULL, NULL, CH_ARRAY }, - { 'LGRS', Save_LGRS, Load_LGRS, Ptrs_LGRS, NULL, CH_LAST } + { 'LGRP', Save_LGRP, Load_LGRP, nullptr, nullptr, CH_ARRAY }, + { 'LGRJ', Save_LGRJ, Load_LGRJ, nullptr, nullptr, CH_ARRAY }, + { 'LGRS', Save_LGRS, Load_LGRS, Ptrs_LGRS, nullptr, CH_LAST } }; diff --git a/src/saveload/map_sl.cpp b/src/saveload/map_sl.cpp index 5402ecc0d2..51c56684a9 100644 --- a/src/saveload/map_sl.cpp +++ b/src/saveload/map_sl.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. @@ -13,6 +11,7 @@ #include "../map_func.h" #include "../core/bitmath_func.hpp" #include "../fios.h" +#include #include "saveload.h" @@ -51,80 +50,80 @@ static const uint MAP_SL_BUF_SIZE = 4096; static void Load_MAPT() { - SmallStackSafeStackAlloc buf; + std::array buf; TileIndex size = MapSize(); for (TileIndex i = 0; i != size;) { - SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8); + SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].type = buf[j]; } } static void Save_MAPT() { - SmallStackSafeStackAlloc buf; + std::array buf; TileIndex size = MapSize(); SlSetLength(size); for (TileIndex i = 0; i != size;) { for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].type; - SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8); + SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); } } static void Load_MAPH() { - SmallStackSafeStackAlloc buf; + std::array buf; TileIndex size = MapSize(); for (TileIndex i = 0; i != size;) { - SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8); + SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].height = buf[j]; } } static void Save_MAPH() { - SmallStackSafeStackAlloc buf; + std::array buf; TileIndex size = MapSize(); SlSetLength(size); for (TileIndex i = 0; i != size;) { for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].height; - SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8); + SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); } } static void Load_MAP1() { - SmallStackSafeStackAlloc buf; + std::array buf; TileIndex size = MapSize(); for (TileIndex i = 0; i != size;) { - SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8); + SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m1 = buf[j]; } } static void Save_MAP1() { - SmallStackSafeStackAlloc buf; + std::array buf; TileIndex size = MapSize(); SlSetLength(size); for (TileIndex i = 0; i != size;) { for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m1; - SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8); + SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); } } static void Load_MAP2() { - SmallStackSafeStackAlloc buf; + std::array buf; TileIndex size = MapSize(); for (TileIndex i = 0; i != size;) { - SlArray(buf, MAP_SL_BUF_SIZE, + SlArray(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 ); @@ -134,94 +133,94 @@ static void Load_MAP2() static void Save_MAP2() { - SmallStackSafeStackAlloc buf; + std::array buf; TileIndex size = MapSize(); 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; - SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT16); + SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT16); } } static void Load_MAP3() { - SmallStackSafeStackAlloc buf; + std::array buf; TileIndex size = MapSize(); for (TileIndex i = 0; i != size;) { - SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8); + SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m3 = buf[j]; } } static void Save_MAP3() { - SmallStackSafeStackAlloc buf; + std::array buf; TileIndex size = MapSize(); SlSetLength(size); for (TileIndex i = 0; i != size;) { for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m3; - SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8); + SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); } } static void Load_MAP4() { - SmallStackSafeStackAlloc buf; + std::array buf; TileIndex size = MapSize(); for (TileIndex i = 0; i != size;) { - SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8); + SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m4 = buf[j]; } } static void Save_MAP4() { - SmallStackSafeStackAlloc buf; + std::array buf; TileIndex size = MapSize(); SlSetLength(size); for (TileIndex i = 0; i != size;) { for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m4; - SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8); + SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); } } static void Load_MAP5() { - SmallStackSafeStackAlloc buf; + std::array buf; TileIndex size = MapSize(); for (TileIndex i = 0; i != size;) { - SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8); + SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m5 = buf[j]; } } static void Save_MAP5() { - SmallStackSafeStackAlloc buf; + std::array buf; TileIndex size = MapSize(); SlSetLength(size); for (TileIndex i = 0; i != size;) { for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m5; - SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8); + SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); } } static void Load_MAP6() { - SmallStackSafeStackAlloc buf; + std::array buf; TileIndex size = MapSize(); if (IsSavegameVersionBefore(SLV_42)) { for (TileIndex i = 0; i != size;) { /* 1024, otherwise we overflow on 64x64 maps! */ - SlArray(buf, 1024, SLE_UINT8); + SlArray(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); @@ -231,7 +230,7 @@ static void Load_MAP6() } } else { for (TileIndex i = 0; i != size;) { - SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8); + SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _me[i++].m6 = buf[j]; } } @@ -239,73 +238,73 @@ static void Load_MAP6() static void Save_MAP6() { - SmallStackSafeStackAlloc buf; + std::array buf; TileIndex size = MapSize(); SlSetLength(size); for (TileIndex i = 0; i != size;) { for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _me[i++].m6; - SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8); + SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); } } static void Load_MAP7() { - SmallStackSafeStackAlloc buf; + std::array buf; TileIndex size = MapSize(); for (TileIndex i = 0; i != size;) { - SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8); + SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _me[i++].m7 = buf[j]; } } static void Save_MAP7() { - SmallStackSafeStackAlloc buf; + std::array buf; TileIndex size = MapSize(); SlSetLength(size); for (TileIndex i = 0; i != size;) { for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _me[i++].m7; - SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8); + SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT8); } } static void Load_MAP8() { - SmallStackSafeStackAlloc buf; + std::array buf; TileIndex size = MapSize(); for (TileIndex i = 0; i != size;) { - SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT16); + SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT16); for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _me[i++].m8 = buf[j]; } } static void Save_MAP8() { - SmallStackSafeStackAlloc buf; + std::array buf; TileIndex size = MapSize(); 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; - SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT16); + SlArray(buf.data(), MAP_SL_BUF_SIZE, SLE_UINT16); } } extern const ChunkHandler _map_chunk_handlers[] = { - { 'MAPS', Save_MAPS, Load_MAPS, NULL, Check_MAPS, CH_RIFF }, - { 'MAPT', Save_MAPT, Load_MAPT, NULL, NULL, CH_RIFF }, - { 'MAPH', Save_MAPH, Load_MAPH, NULL, NULL, CH_RIFF }, - { 'MAPO', Save_MAP1, Load_MAP1, NULL, NULL, CH_RIFF }, - { 'MAP2', Save_MAP2, Load_MAP2, NULL, NULL, CH_RIFF }, - { 'M3LO', Save_MAP3, Load_MAP3, NULL, NULL, CH_RIFF }, - { 'M3HI', Save_MAP4, Load_MAP4, NULL, NULL, CH_RIFF }, - { 'MAP5', Save_MAP5, Load_MAP5, NULL, NULL, CH_RIFF }, - { 'MAPE', Save_MAP6, Load_MAP6, NULL, NULL, CH_RIFF }, - { 'MAP7', Save_MAP7, Load_MAP7, NULL, NULL, CH_RIFF }, - { 'MAP8', Save_MAP8, Load_MAP8, NULL, NULL, CH_RIFF | CH_LAST }, + { 'MAPS', Save_MAPS, Load_MAPS, nullptr, Check_MAPS, CH_RIFF }, + { 'MAPT', Save_MAPT, Load_MAPT, nullptr, nullptr, CH_RIFF }, + { 'MAPH', Save_MAPH, Load_MAPH, nullptr, nullptr, CH_RIFF }, + { 'MAPO', Save_MAP1, Load_MAP1, nullptr, nullptr, CH_RIFF }, + { 'MAP2', Save_MAP2, Load_MAP2, nullptr, nullptr, CH_RIFF }, + { 'M3LO', Save_MAP3, Load_MAP3, nullptr, nullptr, CH_RIFF }, + { 'M3HI', Save_MAP4, Load_MAP4, nullptr, nullptr, CH_RIFF }, + { 'MAP5', Save_MAP5, Load_MAP5, nullptr, nullptr, CH_RIFF }, + { 'MAPE', Save_MAP6, Load_MAP6, nullptr, nullptr, CH_RIFF }, + { 'MAP7', Save_MAP7, Load_MAP7, nullptr, nullptr, CH_RIFF }, + { 'MAP8', Save_MAP8, Load_MAP8, nullptr, nullptr, CH_RIFF | CH_LAST }, }; diff --git a/src/saveload/misc_sl.cpp b/src/saveload/misc_sl.cpp index cca3365b57..7ef4e3018e 100644 --- a/src/saveload/misc_sl.cpp +++ b/src/saveload/misc_sl.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. @@ -30,13 +28,13 @@ extern byte _trees_tick_ctr; /* Keep track of current game position */ int _saved_scrollpos_x; int _saved_scrollpos_y; -ZoomLevelByte _saved_scrollpos_zoom; +ZoomLevel _saved_scrollpos_zoom; void SaveViewportBeforeSaveGame() { const Window *w = FindWindowById(WC_MAIN_WINDOW, 0); - if (w != NULL) { + if (w != nullptr) { _saved_scrollpos_x = w->viewport->scrollpos_x; _saved_scrollpos_y = w->viewport->scrollpos_y; _saved_scrollpos_zoom = w->viewport->zoom; @@ -151,6 +149,6 @@ static void SaveLoad_VIEW() } extern const ChunkHandler _misc_chunk_handlers[] = { - { 'DATE', SaveLoad_DATE, SaveLoad_DATE, NULL, Check_DATE, CH_RIFF}, - { 'VIEW', SaveLoad_VIEW, SaveLoad_VIEW, NULL, NULL, CH_RIFF | CH_LAST}, + { 'DATE', SaveLoad_DATE, SaveLoad_DATE, nullptr, Check_DATE, CH_RIFF}, + { 'VIEW', SaveLoad_VIEW, SaveLoad_VIEW, nullptr, nullptr, CH_RIFF | CH_LAST}, }; diff --git a/src/saveload/newgrf_sl.cpp b/src/saveload/newgrf_sl.cpp index e40b45926c..b2d2b0df99 100644 --- a/src/saveload/newgrf_sl.cpp +++ b/src/saveload/newgrf_sl.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. @@ -73,7 +71,7 @@ static void Save_NGRF() { int index = 0; - for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) { + for (GRFConfig *c = _grfconfig; c != nullptr; c = c->next) { if (HasBit(c->flags, GCF_STATIC)) continue; SlSetArrayIndex(index++); SlObject(c, _grfconfig_desc); @@ -98,7 +96,7 @@ static void Load_NGRF() if (_game_mode == GM_MENU) { /* Intro game must not have NewGRF. */ - if (_grfconfig != NULL) SlErrorCorrupt("The intro game must not use NewGRF"); + if (_grfconfig != nullptr) SlErrorCorrupt("The intro game must not use NewGRF"); /* Activate intro NewGRFs (townnames) */ ResetGRFConfig(false); @@ -114,5 +112,5 @@ static void Check_NGRF() } extern const ChunkHandler _newgrf_chunk_handlers[] = { - { 'NGRF', Save_NGRF, Load_NGRF, NULL, Check_NGRF, CH_ARRAY | CH_LAST } + { 'NGRF', Save_NGRF, Load_NGRF, nullptr, Check_NGRF, CH_ARRAY | CH_LAST } }; diff --git a/src/saveload/newgrf_sl.h b/src/saveload/newgrf_sl.h index c0714d65d6..191046de25 100644 --- a/src/saveload/newgrf_sl.h +++ b/src/saveload/newgrf_sl.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/saveload/object_sl.cpp b/src/saveload/object_sl.cpp index 6b0b99e479..2c385b6552 100644 --- a/src/saveload/object_sl.cpp +++ b/src/saveload/object_sl.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,10 +31,8 @@ static const SaveLoad _object_desc[] = { static void Save_OBJS() { - Object *o; - /* Write the objects */ - FOR_ALL_OBJECTS(o) { + for (Object *o : Object::Iterate()) { SlSetArrayIndex(o->index); SlObject(o, _object_desc); } @@ -53,8 +49,7 @@ static void Load_OBJS() static void Ptrs_OBJS() { - Object *o; - FOR_ALL_OBJECTS(o) { + for (Object *o : Object::Iterate()) { SlObject(o, _object_desc); if (IsSavegameVersionBefore(SLV_148) && !IsTileType(o->location.tile, MP_OBJECT)) { /* Due to a small bug stale objects could remain. */ @@ -74,6 +69,6 @@ static void Load_OBID() } extern const ChunkHandler _object_chunk_handlers[] = { - { 'OBID', Save_OBID, Load_OBID, NULL, NULL, CH_ARRAY }, - { 'OBJS', Save_OBJS, Load_OBJS, Ptrs_OBJS, NULL, CH_ARRAY | CH_LAST}, + { 'OBID', Save_OBID, Load_OBID, nullptr, nullptr, CH_ARRAY }, + { 'OBJS', Save_OBJS, Load_OBJS, Ptrs_OBJS, nullptr, CH_ARRAY | CH_LAST}, }; diff --git a/src/saveload/oldloader.cpp b/src/saveload/oldloader.cpp index e0ad0e732a..5dac33777d 100644 --- a/src/saveload/oldloader.cpp +++ b/src/saveload/oldloader.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. @@ -154,11 +152,11 @@ bool LoadChunk(LoadgameState *ls, void *base, const OldChunks *chunks) default: NOT_REACHED(); } - /* When both pointers are NULL, we are just skipping data */ - if (base_ptr == NULL && chunk->ptr == NULL) continue; + /* When both pointers are nullptr, we are just skipping data */ + if (base_ptr == nullptr && chunk->ptr == nullptr) continue; /* Writing to the var: bits 8 to 15 have the VAR type */ - if (chunk->ptr == NULL) ptr = base_ptr + chunk->offset; + if (chunk->ptr == nullptr) ptr = base_ptr + chunk->offset; /* Write the data */ switch (GetOldChunkVarType(chunk->type)) { @@ -174,7 +172,7 @@ bool LoadChunk(LoadgameState *ls, void *base, const OldChunks *chunks) } /* Increase pointer base for arrays when looping */ - if (chunk->amount > 1 && chunk->ptr != NULL) ptr += CalcOldVarLen(chunk->type); + if (chunk->amount > 1 && chunk->ptr != nullptr) ptr += CalcOldVarLen(chunk->type); } } } @@ -259,7 +257,7 @@ static SavegameType DetermineOldSavegameType(FILE *f, char *title, const char *l } } - if (title != NULL) { + if (title != nullptr) { switch (type) { case SGT_TTO: title = strecpy(title, "(TTO) ", last); break; case SGT_TTD: title = strecpy(title, "(TTD) ", last); break; @@ -284,14 +282,14 @@ bool LoadOldSaveGame(const char *file) /* Open file */ ls.file = FioFOpenFile(file, "rb", NO_DIRECTORY); - if (ls.file == NULL) { + if (ls.file == nullptr) { DEBUG(oldloader, 0, "Cannot open file '%s'", file); return false; } - SavegameType type = DetermineOldSavegameType(ls.file, NULL, NULL); + SavegameType type = DetermineOldSavegameType(ls.file, nullptr, nullptr); - LoadOldMainProc *proc = NULL; + LoadOldMainProc *proc = nullptr; switch (type) { case SGT_TTO: proc = &LoadTTOMain; break; @@ -303,7 +301,7 @@ bool LoadOldSaveGame(const char *file) bool game_loaded; try { - game_loaded = proc != NULL && proc(&ls); + game_loaded = proc != nullptr && proc(&ls); } catch (...) { game_loaded = false; } @@ -314,7 +312,7 @@ bool LoadOldSaveGame(const char *file) return false; } - _pause_mode = 2; + _pause_mode = PM_PAUSED_SAVELOAD; return true; } @@ -323,7 +321,7 @@ void GetOldSaveGameName(const char *file, char *title, const char *last) { FILE *f = FioFOpenFile(file, "rb", NO_DIRECTORY); - if (f == NULL) { + if (f == nullptr) { *title = '\0'; return; } diff --git a/src/saveload/oldloader.h b/src/saveload/oldloader.h index 5483440ea6..fcc7be4be0 100644 --- a/src/saveload/oldloader.h +++ b/src/saveload/oldloader.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. @@ -90,7 +88,7 @@ struct OldChunks { uint32 amount; ///< Amount of fields void *ptr; ///< Pointer where to save the data (may only be set if offset is 0) - uint offset; ///< Offset from basepointer (may only be set if ptr is NULL) + uint offset; ///< Offset from basepointer (may only be set if ptr is nullptr) OldChunkProc *proc; ///< Pointer to function that is called with OC_CHUNK }; @@ -125,12 +123,12 @@ static inline uint32 ReadUint32(LoadgameState *ls) * - OCL_CHUNK: load another proc to load a part of the savegame, 'amount' times * - OCL_ASSERT: to check if we are really at the place we expect to be.. because old savegames are too binary to be sure ;) */ -#define OCL_SVAR(type, base, offset) { type, 1, NULL, (uint)cpp_offsetof(base, offset), NULL } -#define OCL_VAR(type, amount, pointer) { type, amount, pointer, 0, NULL } -#define OCL_END() { OC_END, 0, NULL, 0, NULL } -#define OCL_CNULL(type, amount) { OC_NULL | type, amount, NULL, 0, NULL } -#define OCL_CCHUNK(type, amount, proc) { OC_CHUNK | type, amount, NULL, 0, proc } -#define OCL_ASSERT(type, size) { OC_ASSERT | type, 1, NULL, size, NULL } +#define OCL_SVAR(type, base, offset) { type, 1, nullptr, (uint)cpp_offsetof(base, offset), nullptr } +#define OCL_VAR(type, amount, pointer) { type, amount, pointer, 0, nullptr } +#define OCL_END() { OC_END, 0, nullptr, 0, nullptr } +#define OCL_CNULL(type, amount) { OC_NULL | type, amount, nullptr, 0, nullptr } +#define OCL_CCHUNK(type, amount, proc) { OC_CHUNK | type, amount, nullptr, 0, proc } +#define OCL_ASSERT(type, size) { OC_ASSERT | type, 1, nullptr, size, nullptr } #define OCL_NULL(amount) OCL_CNULL((OldChunkType)0, amount) #define OCL_CHUNK(amount, proc) OCL_CCHUNK((OldChunkType)0, amount, proc) diff --git a/src/saveload/oldloader_sl.cpp b/src/saveload/oldloader_sl.cpp index 1974bb31fa..659216c0c8 100644 --- a/src/saveload/oldloader_sl.cpp +++ b/src/saveload/oldloader_sl.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. @@ -31,6 +29,7 @@ #include "../core/smallvec_type.hpp" #include "saveload_internal.h" #include "oldloader.h" +#include #include "table/strings.h" #include "../table/engines.h" @@ -110,8 +109,7 @@ static void FixTTDMapArray() static void FixTTDDepots() { - const Depot *d; - FOR_ALL_DEPOTS_FROM(d, 252) { + for (const Depot *d : Depot::Iterate(252)) { if (!IsDepotTile(d->xy) || GetDepotIndex(d->xy) != d->index) { /** Workaround for SVXConverter bug, depots 252-255 could be invalid */ delete d; @@ -154,10 +152,8 @@ static uint32 RemapOldTownName(uint32 townnameparts, byte old_town_name_type) static void FixOldTowns() { - Town *town; - /* Convert town-names if needed */ - FOR_ALL_TOWNS(town) { + for (Town *town : Town::Iterate()) { if (IsInsideMM(town->townnametype, 0x20C1, 0x20C3)) { town->townnametype = SPECSTR_TOWNNAME_ENGLISH + _settings_game.game_creation.town_name; town->townnameparts = RemapOldTownName(town->townnameparts, _settings_game.game_creation.town_name); @@ -174,11 +170,9 @@ static StringID *_old_vehicle_names; */ void FixOldVehicles() { - Vehicle *v; - - FOR_ALL_VEHICLES(v) { + for (Vehicle *v : Vehicle::Iterate()) { if ((size_t)v->next == 0xFFFF) { - v->next = NULL; + v->next = nullptr; } else { v->next = Vehicle::GetIfValid((size_t)v->next); } @@ -386,8 +380,7 @@ static bool FixTTOEngines() 233, 234, 235, 236, 237, 238, 253 }; - Vehicle *v; - FOR_ALL_VEHICLES(v) { + for (Vehicle *v : Vehicle::Iterate()) { if (v->engine_type >= lengthof(tto_to_ttd)) return false; v->engine_type = tto_to_ttd[v->engine_type]; } @@ -452,7 +445,7 @@ static bool FixTTOEngines() e->preview_company = INVALID_COMPANY; e->preview_asked = (CompanyMask)-1; e->preview_wait = 0; - e->name = NULL; + e->name = nullptr; } return true; @@ -460,8 +453,7 @@ static bool FixTTOEngines() static void FixTTOCompanies() { - Company *c; - FOR_ALL_COMPANIES(c) { + for (Company *c : Company::Iterate()) { c->cur_economy.company_value = CalculateCompanyValue(c); // company value history is zeroed } } @@ -491,7 +483,7 @@ static inline uint RemapOrderIndex(uint x) return _savegame_type == SGT_TTO ? (x - 0x1AC4) / 2 : (x - 0x1C18) / 2; } -extern SmallVector _animated_tiles; +extern std::vector _animated_tiles; extern char *_old_name_array; static uint32 _old_town_index; @@ -621,7 +613,7 @@ static const OldChunks order_chunk[] = { static bool LoadOldOrder(LoadgameState *ls, int num) { - if (!LoadChunk(ls, NULL, order_chunk)) return false; + if (!LoadChunk(ls, nullptr, order_chunk)) return false; Order *o = new (num) Order(); o->AssignOrder(UnpackOldOrder(_old_order)); @@ -632,7 +624,7 @@ static bool LoadOldOrder(LoadgameState *ls, int num) /* Relink the orders to each other (in the orders for one vehicle are behind each other, * with an invalid order (OT_NOTHING) as indication that it is the last order */ Order *prev = Order::GetIfValid(num - 1); - if (prev != NULL) prev->next = o; + if (prev != nullptr) prev->next = o; } return true; @@ -646,12 +638,12 @@ static bool LoadOldAnimTileList(LoadgameState *ls, int num) OCL_END () }; - if (!LoadChunk(ls, NULL, anim_chunk)) return false; + if (!LoadChunk(ls, nullptr, anim_chunk)) return false; /* The first zero in the loaded array indicates the end of the list. */ for (int i = 0; i < 256; i++) { if (anim_list[i] == 0) break; - *_animated_tiles.Append() = anim_list[i]; + _animated_tiles.push_back(anim_list[i]); } return true; @@ -671,7 +663,7 @@ static bool LoadOldDepot(LoadgameState *ls, int num) if (d->xy != 0) { /* In some cases, there could be depots referencing invalid town. */ Town *t = Town::GetIfValid(RemapTownIndex(_old_town_index)); - if (t == NULL) t = Town::GetRandom(); + if (t == nullptr) t = Town::GetRandom(); d->town = t; } else { delete d; @@ -724,7 +716,7 @@ static const OldChunks station_chunk[] = { OCL_NULL( 4 ), ///< bus/lorry tile OCL_SVAR( OC_TILE, Station, train_station.tile ), OCL_SVAR( OC_TILE, Station, airport.tile ), - OCL_SVAR( OC_TILE, Station, dock_tile ), + OCL_NULL( 4 ), ///< dock tile OCL_SVAR( OC_FILE_U8 | OC_VAR_U16, Station, train_station.w ), OCL_NULL( 1 ), ///< sort-index, no longer in use @@ -876,7 +868,7 @@ static bool LoadOldCompanyYearly(LoadgameState *ls, int num) if (_savegame_type == SGT_TTO && i == 6) { _old_yearly = 0; // property maintenance } else { - if (!LoadChunk(ls, NULL, _company_yearly_chunk)) return false; + if (!LoadChunk(ls, nullptr, _company_yearly_chunk)) return false; } c->yearly_expenses[num][i] = _old_yearly; @@ -1106,8 +1098,8 @@ static bool LoadOldVehicleUnion(LoadgameState *ls, int num) uint temp = ls->total_read; bool res; - if (v == NULL) { - res = LoadChunk(ls, NULL, vehicle_empty_chunk); + if (v == nullptr) { + res = LoadChunk(ls, nullptr, vehicle_empty_chunk); } else { switch (v->type) { default: SlErrorCorrupt("Invalid vehicle type"); @@ -1240,7 +1232,7 @@ bool LoadOldVehicle(LoadgameState *ls, int num) uint type = ReadByte(ls); switch (type) { default: return false; - case 0x00 /* VEH_INVALID */: v = NULL; break; + case 0x00 /* VEH_INVALID */: v = nullptr; break; case 0x25 /* MONORAIL */: case 0x20 /* VEH_TRAIN */: v = new (_current_vehicle_id) Train(); break; case 0x21 /* VEH_ROAD */: v = new (_current_vehicle_id) RoadVehicle(); break; @@ -1251,7 +1243,7 @@ bool LoadOldVehicle(LoadgameState *ls, int num) } if (!LoadChunk(ls, v, vehicle_chunk)) return false; - if (v == NULL) continue; + if (v == nullptr) continue; v->refit_cap = v->cargo_cap; SpriteID sprite = v->sprite_seq.seq[0].sprite; @@ -1276,7 +1268,8 @@ bool LoadOldVehicle(LoadgameState *ls, int num) }; if (v->spritenum / 2 >= lengthof(spriteset_rail)) return false; v->spritenum = spriteset_rail[v->spritenum / 2]; // adjust railway sprite set offset - Train::From(v)->railtype = type == 0x25 ? 1 : 0; // monorail / rail + /* Should be the original values for monorail / rail, can't use RailType constants */ + Train::From(v)->railtype = static_cast(type == 0x25 ? 1 : 0); break; } @@ -1318,7 +1311,7 @@ bool LoadOldVehicle(LoadgameState *ls, int num) /* Read the vehicle type and allocate the right vehicle */ switch (ReadByte(ls)) { default: SlErrorCorrupt("Invalid vehicle type"); - case 0x00 /* VEH_INVALID */: v = NULL; break; + case 0x00 /* VEH_INVALID */: v = nullptr; break; case 0x10 /* VEH_TRAIN */: v = new (_current_vehicle_id) Train(); break; case 0x11 /* VEH_ROAD */: v = new (_current_vehicle_id) RoadVehicle(); break; case 0x12 /* VEH_SHIP */: v = new (_current_vehicle_id) Ship(); break; @@ -1328,7 +1321,7 @@ bool LoadOldVehicle(LoadgameState *ls, int num) } if (!LoadChunk(ls, v, vehicle_chunk)) return false; - if (v == NULL) continue; + if (v == nullptr) continue; _old_vehicle_names[_current_vehicle_id] = RemapOldStringID(_old_string_id); @@ -1754,11 +1747,11 @@ bool LoadTTDMain(LoadgameState *ls) _read_ttdpatch_flags = false; /* Load the biggest chunk */ - SmallStackSafeStackAlloc map3; - _old_map3 = map3.data; - _old_vehicle_names = NULL; + std::array map3; + _old_map3 = map3.data(); + _old_vehicle_names = nullptr; try { - if (!LoadChunk(ls, NULL, main_chunk)) { + if (!LoadChunk(ls, nullptr, main_chunk)) { DEBUG(oldloader, 0, "Loading failed"); free(_old_vehicle_names); return false; @@ -1797,13 +1790,13 @@ bool LoadTTOMain(LoadgameState *ls) _read_ttdpatch_flags = false; - SmallStackSafeStackAlloc engines; // we don't want to call Engine constructor here - _old_engines = (Engine *)engines.data; - SmallStackSafeStackAlloc vehnames; - _old_vehicle_names = vehnames.data; + std::array engines; // we don't want to call Engine constructor here + _old_engines = (Engine *)engines.data(); + std::array vehnames; + _old_vehicle_names = vehnames.data(); /* Load the biggest chunk */ - if (!LoadChunk(ls, NULL, main_chunk)) { + if (!LoadChunk(ls, nullptr, main_chunk)) { DEBUG(oldloader, 0, "Loading failed"); return false; } diff --git a/src/saveload/order_sl.cpp b/src/saveload/order_sl.cpp index b89514d479..c8747d36bb 100644 --- a/src/saveload/order_sl.cpp +++ b/src/saveload/order_sl.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. @@ -125,9 +123,7 @@ const SaveLoad *GetOrderDescription() static void Save_ORDR() { - Order *order; - - FOR_ALL_ORDERS(order) { + for (Order *order : Order::Iterate()) { SlSetArrayIndex(order->index); SlObject(order, GetOrderDescription()); } @@ -168,8 +164,8 @@ static void Load_ORDR() } /* Update all the next pointer */ - Order *o; - FOR_ALL_ORDERS(o) { + for (Order *o : Order::Iterate()) { + size_t order_index = o->index; /* Delete invalid orders */ if (o->IsType(OT_NOTHING)) { delete o; @@ -178,7 +174,7 @@ static void Load_ORDR() /* The orders were built like this: * While the order is valid, set the previous will get its next pointer set */ Order *prev = Order::GetIfValid(order_index - 1); - if (prev != NULL) prev->next = o; + if (prev != nullptr) prev->next = o; } } else { int index; @@ -186,10 +182,6 @@ static void Load_ORDR() while ((index = SlIterateArray()) != -1) { Order *order = new (index) Order(); SlObject(order, GetOrderDescription()); - if (IsSavegameVersionBefore(SLV_190)) { - order->SetTravelTimetabled(order->GetTravelTime() > 0); - order->SetWaitTimetabled(order->GetWaitTime() > 0); - } } } } @@ -199,9 +191,7 @@ static void Ptrs_ORDR() /* Orders from old savegames have pointers corrected in Load_ORDR */ if (IsSavegameVersionBefore(SLV_5, 2)) return; - Order *o; - - FOR_ALL_ORDERS(o) { + for (Order *o : Order::Iterate()) { SlObject(o, GetOrderDescription()); } } @@ -218,9 +208,7 @@ const SaveLoad *GetOrderListDescription() static void Save_ORDL() { - OrderList *list; - - FOR_ALL_ORDER_LISTS(list) { + for (OrderList *list : OrderList::Iterate()) { SlSetArrayIndex(list->index); SlObject(list, GetOrderListDescription()); } @@ -240,9 +228,7 @@ static void Load_ORDL() static void Ptrs_ORDL() { - OrderList *list; - - FOR_ALL_ORDER_LISTS(list) { + for (OrderList *list : OrderList::Iterate()) { SlObject(list, GetOrderListDescription()); } } @@ -279,8 +265,7 @@ static void Save_BKOR() * normal games this information isn't needed. */ if (!_networking || !_network_server) return; - OrderBackup *ob; - FOR_ALL_ORDER_BACKUPS(ob) { + for (OrderBackup *ob : OrderBackup::Iterate()) { SlSetArrayIndex(ob->index); SlObject(ob, GetOrderBackupDescription()); } @@ -299,14 +284,13 @@ void Load_BKOR() static void Ptrs_BKOR() { - OrderBackup *ob; - FOR_ALL_ORDER_BACKUPS(ob) { + for (OrderBackup *ob : OrderBackup::Iterate()) { SlObject(ob, GetOrderBackupDescription()); } } extern const ChunkHandler _order_chunk_handlers[] = { - { 'BKOR', Save_BKOR, Load_BKOR, Ptrs_BKOR, NULL, CH_ARRAY}, - { 'ORDR', Save_ORDR, Load_ORDR, Ptrs_ORDR, NULL, CH_ARRAY}, - { 'ORDL', Save_ORDL, Load_ORDL, Ptrs_ORDL, NULL, CH_ARRAY | CH_LAST}, + { 'BKOR', Save_BKOR, Load_BKOR, Ptrs_BKOR, nullptr, CH_ARRAY}, + { 'ORDR', Save_ORDR, Load_ORDR, Ptrs_ORDR, nullptr, CH_ARRAY}, + { 'ORDL', Save_ORDL, Load_ORDL, Ptrs_ORDL, nullptr, CH_ARRAY | CH_LAST}, }; diff --git a/src/saveload/saveload.cpp b/src/saveload/saveload.cpp index bff85dfc61..aeaa7a5edd 100644 --- a/src/saveload/saveload.cpp +++ b/src/saveload/saveload.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. @@ -26,7 +24,7 @@ #include "../stdafx.h" #include "../debug.h" #include "../station_base.h" -#include "../thread/thread.h" +#include "../thread.h" #include "../town.h" #include "../network/network.h" #include "../window_func.h" @@ -45,6 +43,7 @@ #include "../string_func.h" #include "../fios.h" #include "../error.h" +#include #include "table/strings.h" @@ -94,7 +93,7 @@ struct ReadBuffer { * Initialise our variables. * @param reader The filter to actually read data. */ - ReadBuffer(LoadFilter *reader) : bufp(NULL), bufe(NULL), reader(reader), read(0) + ReadBuffer(LoadFilter *reader) : bufp(nullptr), bufe(nullptr), reader(reader), read(0) { } @@ -125,15 +124,22 @@ struct ReadBuffer { /** Container for dumping the savegame (quickly) to memory. */ struct MemoryDumper { - AutoFreeSmallVector blocks; ///< Buffer with blocks of allocated memory. - byte *buf; ///< Buffer we're going to write to. - byte *bufe; ///< End of the buffer we write to. + std::vector blocks; ///< Buffer with blocks of allocated memory. + byte *buf; ///< Buffer we're going to write to. + byte *bufe; ///< End of the buffer we write to. /** Initialise our variables. */ - MemoryDumper() : buf(NULL), bufe(NULL) + MemoryDumper() : buf(nullptr), bufe(nullptr) { } + ~MemoryDumper() + { + for (auto p : this->blocks) { + free(p); + } + } + /** * Write a single byte into the dumper. * @param b The byte to write. @@ -143,7 +149,7 @@ struct MemoryDumper { /* Are we at the end of this chunk? */ if (this->buf == this->bufe) { this->buf = CallocT(MEMORY_CHUNK_SIZE); - *this->blocks.Append() = this->buf; + this->blocks.push_back(this->buf); this->bufe = this->buf + MEMORY_CHUNK_SIZE; } @@ -175,7 +181,7 @@ struct MemoryDumper { */ size_t GetSize() const { - return this->blocks.Length() * MEMORY_CHUNK_SIZE - (this->bufe - this->buf); + return this->blocks.size() * MEMORY_CHUNK_SIZE - (this->bufe - this->buf); } }; @@ -239,7 +245,7 @@ extern const ChunkHandler _airport_chunk_handlers[]; extern const ChunkHandler _object_chunk_handlers[]; extern const ChunkHandler _persistent_storage_chunk_handlers[]; -/** Array of all chunks in a savegame, \c NULL terminated. */ +/** Array of all chunks in a savegame, \c nullptr terminated. */ static const ChunkHandler * const _chunk_handlers[] = { _gamelog_chunk_handlers, _map_chunk_handlers, @@ -274,7 +280,7 @@ static const ChunkHandler * const _chunk_handlers[] = { _airport_chunk_handlers, _object_chunk_handlers, _persistent_storage_chunk_handlers, - NULL, + nullptr, }; /** @@ -282,10 +288,10 @@ static const ChunkHandler * const _chunk_handlers[] = { * @param ch the chunk handler iterator */ #define FOR_ALL_CHUNK_HANDLERS(ch) \ - for (const ChunkHandler * const *chsc = _chunk_handlers; *chsc != NULL; chsc++) \ - for (const ChunkHandler *ch = *chsc; ch != NULL; ch = (ch->flags & CH_LAST) ? NULL : ch + 1) + for (const ChunkHandler * const *chsc = _chunk_handlers; *chsc != nullptr; chsc++) \ + for (const ChunkHandler *ch = *chsc; ch != nullptr; ch = (ch->flags & CH_LAST) ? nullptr : ch + 1) -/** Null all pointers (convert index -> NULL) */ +/** Null all pointers (convert index -> nullptr) */ static void SlNullPointers() { _sl.action = SLA_NULL; @@ -298,7 +304,7 @@ static void SlNullPointers() DEBUG(sl, 1, "Nulling pointers"); FOR_ALL_CHUNK_HANDLERS(ch) { - if (ch->ptrs_proc != NULL) { + if (ch->ptrs_proc != nullptr) { DEBUG(sl, 2, "Nulling pointers for %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id); ch->ptrs_proc(); } @@ -323,14 +329,14 @@ void NORETURN SlError(StringID string, const char *extra_msg) if (_sl.action == SLA_LOAD_CHECK) { _load_check_data.error = string; free(_load_check_data.error_data); - _load_check_data.error_data = (extra_msg == NULL) ? NULL : stredup(extra_msg); + _load_check_data.error_data = (extra_msg == nullptr) ? nullptr : stredup(extra_msg); } else { _sl.error_str = string; free(_sl.extra_msg); - _sl.extra_msg = (extra_msg == NULL) ? NULL : stredup(extra_msg); + _sl.extra_msg = (extra_msg == nullptr) ? nullptr : stredup(extra_msg); } - /* We have to NULL all pointers here; we might be in a state where + /* We have to nullptr all pointers here; we might be in a state where * the pointers are actually filled with indices, which means that * when we access them during cleaning the pool dereferences of * those indices will be made with segmentation faults as result. */ @@ -370,9 +376,9 @@ void NORETURN SlErrorCorruptFmt(const char *format, ...) } -typedef void (*AsyncSaveFinishProc)(); ///< Callback for when the savegame loading is finished. -static AsyncSaveFinishProc _async_save_finish = NULL; ///< Callback to call when the savegame loading is finished. -static ThreadObject *_save_thread; ///< The thread we're using to compress and write a savegame +typedef void (*AsyncSaveFinishProc)(); ///< Callback for when the savegame loading is finished. +static std::atomic _async_save_finish; ///< Callback to call when the savegame loading is finished. +static std::thread _save_thread; ///< The thread we're using to compress and write a savegame /** * Called by save thread to tell we finished saving. @@ -381,9 +387,9 @@ static ThreadObject *_save_thread; ///< The thread we're usin static void SetAsyncSaveFinish(AsyncSaveFinishProc proc) { if (_exit_game) return; - while (_async_save_finish != NULL) CSleep(10); + while (_async_save_finish.load(std::memory_order_acquire) != nullptr) CSleep(10); - _async_save_finish = proc; + _async_save_finish.store(proc, std::memory_order_release); } /** @@ -391,16 +397,13 @@ static void SetAsyncSaveFinish(AsyncSaveFinishProc proc) */ void ProcessAsyncSaveFinish() { - if (_async_save_finish == NULL) return; + AsyncSaveFinishProc proc = _async_save_finish.exchange(nullptr, std::memory_order_acq_rel); + if (proc == nullptr) return; - _async_save_finish(); + proc(); - _async_save_finish = NULL; - - if (_save_thread != NULL) { - _save_thread->Join(); - delete _save_thread; - _save_thread = NULL; + if (_save_thread.joinable()) { + _save_thread.join(); } } @@ -858,7 +861,7 @@ static void SlSaveLoadConv(void *ptr, VarType conv) */ static inline size_t SlCalcNetStringLen(const char *ptr, size_t length) { - if (ptr == NULL) return 0; + if (ptr == nullptr) return 0; return min(strlen(ptr), length - 1); } @@ -943,7 +946,7 @@ static void SlString(void *ptr, size_t length, VarType conv) case SLE_VAR_STRQ: // Malloc'd string, free previous incarnation, and allocate free(*(char **)ptr); if (len == 0) { - *(char **)ptr = NULL; + *(char **)ptr = nullptr; return; } else { *(char **)ptr = MallocT(len + 1); // terminating '\0' @@ -1038,7 +1041,7 @@ void SlArray(void *array, size_t length, VarType conv) * Pointers cannot be saved to a savegame, so this functions gets * the index of the item, and if not available, it hussles with * pointers (looks really bad :() - * Remember that a NULL item has value 0, and all + * Remember that a nullptr item has value 0, and all * indices have +1, so vehicle 0 is saved as index 1. * @param obj The object that we want to get the index of * @param rt SLRefType type of the object the index is being sought of @@ -1048,7 +1051,7 @@ static size_t ReferenceToInt(const void *obj, SLRefType rt) { assert(_sl.action == SLA_SAVE); - if (obj == NULL) return 0; + if (obj == nullptr) return 0; switch (rt) { case REF_VEHICLE_OLD: // Old vehicles we save as new ones @@ -1071,7 +1074,7 @@ static size_t ReferenceToInt(const void *obj, SLRefType rt) * Pointers cannot be loaded from a savegame, so this function * gets the index from the savegame and returns the appropriate * pointer from the already loaded base. - * Remember that an index of 0 is a NULL pointer so all indices + * Remember that an index of 0 is a nullptr pointer so all indices * are +1 so vehicle 0 is saved as 1. * @param index The index that is being converted to a pointer * @param rt SLRefType type of the object the pointer is sought of @@ -1089,8 +1092,8 @@ static void *IntToReference(size_t index, SLRefType rt) rt = REF_VEHICLE; } - /* No need to look up NULL pointers, just return immediately */ - if (index == (rt == REF_VEHICLE_OLD ? 0xFFFF : 0)) return NULL; + /* No need to look up nullptr pointers, just return immediately */ + if (index == (rt == REF_VEHICLE_OLD ? 0xFFFF : 0)) return nullptr; /* Correct index. Old vehicles were saved differently: * invalid vehicle was 0xFFFF, now we use 0x0000 for everything invalid. */ @@ -1104,7 +1107,7 @@ static void *IntToReference(size_t index, SLRefType rt) case REF_ORDER: if (Order::IsValidID(index)) return Order::Get(index); /* in old versions, invalid order was used to mark end of order list */ - if (IsSavegameVersionBefore(SLV_5, 2)) return NULL; + if (IsSavegameVersionBefore(SLV_5, 2)) return nullptr; SlErrorCorrupt("Referencing invalid Order"); case REF_VEHICLE_OLD: @@ -1494,7 +1497,7 @@ bool SlObjectMember(void *ptr, const SaveLoad *sld) *(void **)ptr = IntToReference(*(size_t *)ptr, (SLRefType)conv); break; case SLA_NULL: - *(void **)ptr = NULL; + *(void **)ptr = nullptr; break; default: NOT_REACHED(); } @@ -1508,7 +1511,7 @@ bool SlObjectMember(void *ptr, const SaveLoad *sld) break; /* SL_WRITEBYTE writes a value to the savegame to identify the type of an object. - * When loading, the value is read explictly with SlReadByte() to determine which + * When loading, the value is read explicitly with SlReadByte() to determine which * object description to use. */ case SL_WRITEBYTE: switch (_sl.action) { @@ -1560,7 +1563,7 @@ void SlObject(void *object, const SaveLoad *sld) */ void SlGlobList(const SaveLoadGlobVarList *sldg) { - SlObject(NULL, (const SaveLoad*)sldg); + SlObject(nullptr, (const SaveLoad*)sldg); } /** @@ -1632,7 +1635,7 @@ static void SlLoadChunk(const ChunkHandler *ch) /** * Load a chunk of data for checking savegames. - * If the chunkhandler is NULL, the chunk is skipped. + * If the chunkhandler is nullptr, the chunk is skipped. * @param ch The chunkhandler that will be used for the operation */ static void SlLoadCheckChunk(const ChunkHandler *ch) @@ -1703,7 +1706,7 @@ static inline void SlStubSaveProc2(void *arg) */ static void SlStubSaveProc() { - SlAutolength(SlStubSaveProc2, NULL); + SlAutolength(SlStubSaveProc2, nullptr); } /** @@ -1716,7 +1719,7 @@ static void SlSaveChunk(const ChunkHandler *ch) ChunkSaveLoadProc *proc = ch->save_proc; /* Don't save any chunk information if there is no save handler. */ - if (proc == NULL) return; + if (proc == nullptr) return; SlWriteUint32(ch->id); DEBUG(sl, 2, "Saving chunk %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id); @@ -1768,7 +1771,7 @@ static void SlSaveChunks() static const ChunkHandler *SlFindChunkHandler(uint32 id) { FOR_ALL_CHUNK_HANDLERS(ch) if (ch->id == id) return ch; - return NULL; + return nullptr; } /** Load all chunks */ @@ -1781,7 +1784,7 @@ static void SlLoadChunks() DEBUG(sl, 2, "Loading chunk %c%c%c%c", id >> 24, id >> 16, id >> 8, id); ch = SlFindChunkHandler(id); - if (ch == NULL) SlErrorCorrupt("Unknown chunk type"); + if (ch == nullptr) SlErrorCorrupt("Unknown chunk type"); SlLoadChunk(ch); } } @@ -1796,7 +1799,7 @@ static void SlLoadCheckChunks() DEBUG(sl, 2, "Loading chunk %c%c%c%c", id >> 24, id >> 16, id >> 8, id); ch = SlFindChunkHandler(id); - if (ch == NULL) SlErrorCorrupt("Unknown chunk type"); + if (ch == nullptr) SlErrorCorrupt("Unknown chunk type"); SlLoadCheckChunk(ch); } } @@ -1809,7 +1812,7 @@ static void SlFixPointers() DEBUG(sl, 1, "Fixing pointers"); FOR_ALL_CHUNK_HANDLERS(ch) { - if (ch->ptrs_proc != NULL) { + if (ch->ptrs_proc != nullptr) { DEBUG(sl, 2, "Fixing pointers for %c%c%c%c", ch->id >> 24, ch->id >> 16, ch->id >> 8, ch->id); ch->ptrs_proc(); } @@ -1830,29 +1833,29 @@ struct FileReader : LoadFilter { * Create the file reader, so it reads from a specific file. * @param file The file to read from. */ - FileReader(FILE *file) : LoadFilter(NULL), file(file), begin(ftell(file)) + FileReader(FILE *file) : LoadFilter(nullptr), file(file), begin(ftell(file)) { } /** Make sure everything is cleaned up. */ ~FileReader() { - if (this->file != NULL) fclose(this->file); - this->file = NULL; + if (this->file != nullptr) fclose(this->file); + this->file = nullptr; /* Make sure we don't double free. */ - _sl.sf = NULL; + _sl.sf = nullptr; } - /* virtual */ size_t Read(byte *buf, size_t size) + size_t Read(byte *buf, size_t size) override { /* We're in the process of shutting down, i.e. in "failure" mode. */ - if (this->file == NULL) return 0; + if (this->file == nullptr) return 0; return fread(buf, 1, size, this->file); } - /* virtual */ void Reset() + void Reset() override { clearerr(this->file); if (fseek(this->file, this->begin, SEEK_SET)) { @@ -1869,7 +1872,7 @@ struct FileWriter : SaveFilter { * Create the file writer, so it writes to a specific file. * @param file The file to write to. */ - FileWriter(FILE *file) : SaveFilter(NULL), file(file) + FileWriter(FILE *file) : SaveFilter(nullptr), file(file) { } @@ -1879,21 +1882,21 @@ struct FileWriter : SaveFilter { this->Finish(); /* Make sure we don't double free. */ - _sl.sf = NULL; + _sl.sf = nullptr; } - /* virtual */ void Write(byte *buf, size_t size) + void Write(byte *buf, size_t size) override { /* We're in the process of shutting down, i.e. in "failure" mode. */ - if (this->file == NULL) return; + if (this->file == nullptr) return; if (fwrite(buf, 1, size, this->file) != size) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE); } - /* virtual */ void Finish() + void Finish() override { - if (this->file != NULL) fclose(this->file); - this->file = NULL; + if (this->file != nullptr) fclose(this->file); + this->file = nullptr; } }; @@ -1918,7 +1921,7 @@ struct LZOLoadFilter : LoadFilter { if (lzo_init() != LZO_E_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize decompressor"); } - /* virtual */ size_t Read(byte *buf, size_t ssize) + size_t Read(byte *buf, size_t ssize) override { assert(ssize >= LZO_BUFFER_SIZE); @@ -1948,7 +1951,7 @@ struct LZOLoadFilter : LoadFilter { if (tmp[0] != lzo_adler32(0, out, size + sizeof(uint32))) SlErrorCorrupt("Bad checksum"); /* Decompress */ - int ret = lzo1x_decompress_safe(out + sizeof(uint32) * 1, size, buf, &len, NULL); + int ret = lzo1x_decompress_safe(out + sizeof(uint32) * 1, size, buf, &len, nullptr); if (ret != LZO_E_OK) SlError(STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE); return len; } @@ -1966,7 +1969,7 @@ struct LZOSaveFilter : SaveFilter { if (lzo_init() != LZO_E_OK) SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, "cannot initialize compressor"); } - /* virtual */ void Write(byte *buf, size_t size) + void Write(byte *buf, size_t size) override { const lzo_bytep in = buf; /* Buffer size is from the LZO docs plus the chunk header size. */ @@ -2005,7 +2008,7 @@ struct NoCompLoadFilter : LoadFilter { { } - /* virtual */ size_t Read(byte *buf, size_t size) + size_t Read(byte *buf, size_t size) override { return this->chain->Read(buf, size); } @@ -2022,7 +2025,7 @@ struct NoCompSaveFilter : SaveFilter { { } - /* virtual */ void Write(byte *buf, size_t size) + void Write(byte *buf, size_t size) override { this->chain->Write(buf, size); } @@ -2056,7 +2059,7 @@ struct ZlibLoadFilter : LoadFilter { inflateEnd(&this->z); } - /* virtual */ size_t Read(byte *buf, size_t size) + size_t Read(byte *buf, size_t size) override { this->z.next_out = buf; this->z.avail_out = (uint)size; @@ -2135,14 +2138,14 @@ struct ZlibSaveFilter : SaveFilter { } while (this->z.avail_in || !this->z.avail_out); } - /* virtual */ void Write(byte *buf, size_t size) + void Write(byte *buf, size_t size) override { this->WriteLoop(buf, size, 0); } - /* virtual */ void Finish() + void Finish() override { - this->WriteLoop(NULL, 0, Z_FINISH); + this->WriteLoop(nullptr, 0, Z_FINISH); this->chain->Finish(); } }; @@ -2153,7 +2156,7 @@ struct ZlibSaveFilter : SaveFilter { ********** START OF LZMA CODE ************** ********************************************/ -#if defined(WITH_LZMA) +#if defined(WITH_LIBLZMA) #include /** @@ -2185,7 +2188,7 @@ struct LZMALoadFilter : LoadFilter { lzma_end(&this->lzma); } - /* virtual */ size_t Read(byte *buf, size_t size) + size_t Read(byte *buf, size_t size) override { this->lzma.next_out = buf; this->lzma.avail_out = size; @@ -2254,19 +2257,19 @@ struct LZMASaveFilter : SaveFilter { } while (this->lzma.avail_in || !this->lzma.avail_out); } - /* virtual */ void Write(byte *buf, size_t size) + void Write(byte *buf, size_t size) override { this->WriteLoop(buf, size, LZMA_RUN); } - /* virtual */ void Finish() + void Finish() override { - this->WriteLoop(NULL, 0, LZMA_FINISH); + this->WriteLoop(nullptr, 0, LZMA_FINISH); this->chain->Finish(); } }; -#endif /* WITH_LZMA */ +#endif /* WITH_LIBLZMA */ /******************************************* ************* END OF CODE ***************** @@ -2291,7 +2294,7 @@ static const SaveLoadFormat _saveload_formats[] = { /* Roughly 75% larger than zlib level 6 at only ~7% of the CPU usage. */ {"lzo", TO_BE32X('OTTD'), CreateLoadFilter, CreateSaveFilter, 0, 0, 0}, #else - {"lzo", TO_BE32X('OTTD'), NULL, NULL, 0, 0, 0}, + {"lzo", TO_BE32X('OTTD'), nullptr, nullptr, 0, 0, 0}, #endif /* Roughly 5 times larger at only 1% of the CPU usage over zlib level 6. */ {"none", TO_BE32X('OTTN'), CreateLoadFilter, CreateSaveFilter, 0, 0, 0}, @@ -2301,9 +2304,9 @@ static const SaveLoadFormat _saveload_formats[] = { * 1 is "only" 3 times as fast. Level 0 results in uncompressed savegames at about 8 times the cost of "none". */ {"zlib", TO_BE32X('OTTZ'), CreateLoadFilter, CreateSaveFilter, 0, 6, 9}, #else - {"zlib", TO_BE32X('OTTZ'), NULL, NULL, 0, 0, 0}, + {"zlib", TO_BE32X('OTTZ'), nullptr, nullptr, 0, 0, 0}, #endif -#if defined(WITH_LZMA) +#if defined(WITH_LIBLZMA) /* Level 2 compression is speed wise as fast as zlib level 6 compression (old default), but results in ~10% smaller saves. * Higher compression levels are possible, and might improve savegame size by up to 25%, but are also up to 10 times slower. * The next significant reduction in file size is at level 4, but that is already 4 times slower. Level 3 is primarily 50% @@ -2311,14 +2314,14 @@ static const SaveLoadFormat _saveload_formats[] = { * It's OTTX and not e.g. OTTL because liblzma is part of xz-utils and .tar.xz is preferred over .tar.lzma. */ {"lzma", TO_BE32X('OTTX'), CreateLoadFilter, CreateSaveFilter, 0, 2, 9}, #else - {"lzma", TO_BE32X('OTTX'), NULL, NULL, 0, 0, 0}, + {"lzma", TO_BE32X('OTTX'), nullptr, nullptr, 0, 0, 0}, #endif }; /** * Return the savegameformat of the game. Whether it was created with ZLIB compression * uncompressed, or another type - * @param s Name of the savegame format. If NULL it picks the first available one + * @param s Name of the savegame format. If nullptr it picks the first available one * @param compression_level Output for telling what compression level we want. * @return Pointer to SaveLoadFormat struct giving all characteristics of this type of savegame */ @@ -2332,12 +2335,12 @@ static const SaveLoadFormat *GetSavegameFormat(char *s, byte *compression_level) if (!StrEmpty(s)) { /* Get the ":..." of the compression level out of the way */ char *complevel = strrchr(s, ':'); - if (complevel != NULL) *complevel = '\0'; + if (complevel != nullptr) *complevel = '\0'; for (const SaveLoadFormat *slf = &_saveload_formats[0]; slf != endof(_saveload_formats); slf++) { - if (slf->init_write != NULL && strcmp(s, slf->name) == 0) { + if (slf->init_write != nullptr && strcmp(s, slf->name) == 0) { *compression_level = slf->default_compression; - if (complevel != NULL) { + if (complevel != nullptr) { /* There is a compression level in the string. * First restore the : we removed to do proper name matching, * then move the the begin of the actual version. */ @@ -2363,7 +2366,7 @@ static const SaveLoadFormat *GetSavegameFormat(char *s, byte *compression_level) ShowErrorMessage(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_SAVEGAME_COMPRESSION_ALGORITHM, WL_CRITICAL); /* Restore the string by adding the : back */ - if (complevel != NULL) *complevel = ':'; + if (complevel != nullptr) *complevel = ':'; } *compression_level = def->default_compression; return def; @@ -2374,22 +2377,32 @@ void InitializeGame(uint size_x, uint size_y, bool reset_date, bool reset_settin extern bool AfterLoadGame(); extern bool LoadOldSaveGame(const char *file); +/** + * Clear temporary data that is passed between various saveload phases. + */ +static void ResetSaveloadData() +{ + ResetTempEngineData(); + ResetLabelMaps(); + ResetOldWaypoints(); +} + /** * Clear/free saveload state. */ static inline void ClearSaveLoadState() { delete _sl.dumper; - _sl.dumper = NULL; + _sl.dumper = nullptr; delete _sl.sf; - _sl.sf = NULL; + _sl.sf = nullptr; delete _sl.reader; - _sl.reader = NULL; + _sl.reader = nullptr; delete _sl.lf; - _sl.lf = NULL; + _sl.lf = nullptr; } /** @@ -2486,19 +2499,11 @@ static SaveOrLoadResult SaveFileToDisk(bool threaded) } } -/** Thread run function for saving the file to disk. */ -static void SaveFileToDiskThread(void *arg) -{ - SaveFileToDisk(true); -} - void WaitTillSaved() { - if (_save_thread == NULL) return; + if (!_save_thread.joinable()) return; - _save_thread->Join(); - delete _save_thread; - _save_thread = NULL; + _save_thread.join(); /* Make sure every other state is handled properly as well. */ ProcessAsyncSaveFinish(); @@ -2525,7 +2530,8 @@ static SaveOrLoadResult DoSave(SaveFilter *writer, bool threaded) SlSaveChunks(); SaveFileStart(); - if (!threaded || !ThreadObject::New(&SaveFileToDiskThread, NULL, &_save_thread, "ottd:savegame")) { + + if (!threaded || !StartNewThread(&_save_thread, "ottd:savegame", &SaveFileToDisk, true)) { if (threaded) DEBUG(sl, 1, "Cannot create savegame thread, reverting to single-threaded mode..."); SaveOrLoadResult result = SaveFileToDisk(false); @@ -2616,7 +2622,7 @@ static SaveOrLoadResult DoLoad(LoadFilter *reader, bool load_check) } /* loader for this savegame type is not implemented? */ - if (fmt->init_load == NULL) { + if (fmt->init_load == nullptr) { char err_str[64]; seprintf(err_str, lastof(err_str), "Loader for '%s' is not available.", fmt->name); SlError(STR_GAME_SAVELOAD_ERROR_BROKEN_INTERNAL_ERROR, err_str); @@ -2627,6 +2633,8 @@ static SaveOrLoadResult DoLoad(LoadFilter *reader, bool load_check) _next_offs = 0; if (!load_check) { + ResetSaveloadData(); + /* Old maps were hardcoded to 256x256 and thus did not contain * any mapsize information. Pre-initialize to 256x256 to not to * confuse old games */ @@ -2731,6 +2739,8 @@ SaveOrLoadResult SaveOrLoad(const char *filename, SaveLoadOperation fop, Detaile try { /* Load a TTDLX or TTDPatch game */ if (fop == SLO_LOAD && dft == DFT_OLD_GAME_FILE) { + ResetSaveloadData(); + InitializeGame(256, 256, true, true); // set a mapsize of 256x256 for TTDPatch games or it might get confused /* TTD/TTO savegames have no NewGRFs, TTDP savegame have them @@ -2771,11 +2781,11 @@ SaveOrLoadResult SaveOrLoad(const char *filename, SaveLoadOperation fop, Detaile FILE *fh = (fop == SLO_SAVE) ? FioFOpenFile(filename, "wb", sb) : FioFOpenFile(filename, "rb", sb); /* Make it a little easier to load savegames from the console */ - if (fh == NULL && fop != SLO_SAVE) fh = FioFOpenFile(filename, "rb", SAVE_DIR); - if (fh == NULL && fop != SLO_SAVE) fh = FioFOpenFile(filename, "rb", BASE_DIR); - if (fh == NULL && fop != SLO_SAVE) fh = FioFOpenFile(filename, "rb", SCENARIO_DIR); + if (fh == nullptr && fop != SLO_SAVE) fh = FioFOpenFile(filename, "rb", SAVE_DIR); + if (fh == nullptr && fop != SLO_SAVE) fh = FioFOpenFile(filename, "rb", BASE_DIR); + if (fh == nullptr && fop != SLO_SAVE) fh = FioFOpenFile(filename, "rb", SCENARIO_DIR); - if (fh == NULL) { + if (fh == nullptr) { SlError(fop == SLO_SAVE ? STR_GAME_SAVELOAD_ERROR_FILE_NOT_WRITEABLE : STR_GAME_SAVELOAD_ERROR_FILE_NOT_READABLE); } @@ -2820,8 +2830,7 @@ void GenerateDefaultSaveName(char *buf, const char *last) * 'Spectator' as "company" name. */ CompanyID cid = _local_company; if (!Company::IsValidID(cid)) { - const Company *c; - FOR_ALL_COMPANIES(c) { + for (const Company *c : Company::Iterate()) { cid = c->index; break; } @@ -2889,36 +2898,3 @@ void FileToSaveLoad::SetTitle(const char *title) { strecpy(this->title, title, lastof(this->title)); } - -#if 0 -/** - * Function to get the type of the savegame by looking at the file header. - * NOTICE: Not used right now, but could be used if extensions of savegames are garbled - * @param file Savegame to be checked - * @return SL_OLD_LOAD or SL_LOAD of the file - */ -int GetSavegameType(char *file) -{ - const SaveLoadFormat *fmt; - uint32 hdr; - FILE *f; - int mode = SL_OLD_LOAD; - - f = fopen(file, "rb"); - if (fread(&hdr, sizeof(hdr), 1, f) != 1) { - DEBUG(sl, 0, "Savegame is obsolete or invalid format"); - mode = SL_LOAD; // don't try to get filename, just show name as it is written - } else { - /* see if we have any loader for this type. */ - for (fmt = _saveload_formats; fmt != endof(_saveload_formats); fmt++) { - if (fmt->tag == hdr) { - mode = SL_LOAD; // new type of savegame - break; - } - } - } - - fclose(f); - return mode; -} -#endif diff --git a/src/saveload/saveload.h b/src/saveload/saveload.h index ad6b76e05e..14c8c32315 100644 --- a/src/saveload/saveload.h +++ b/src/saveload/saveload.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. @@ -266,8 +264,8 @@ enum SaveLoadVersion : uint16 { SLV_185, ///< 185 25620 Storybooks SLV_186, ///< 186 25833 Objects storage SLV_187, ///< 187 25899 Linkgraph - restricted flows - SLV_188, ///< 188 26169 FS#5831 Unify RV travel time - SLV_189, ///< 189 26450 Heirarchical vehicle subgroups + SLV_188, ///< 188 26169 v1.4 FS#5831 Unify RV travel time + SLV_189, ///< 189 26450 Hierarchical vehicle subgroups SLV_190, ///< 190 26547 Separate order travel and wait times SLV_191, ///< 191 26636 FS#6026 Fix disaster vehicle storage (No bump) @@ -283,14 +281,27 @@ enum SaveLoadVersion : uint16 { SLV_EXTEND_CARGOTYPES, ///< 199 PR#6802 Extend cargotypes to 64 SLV_EXTEND_RAILTYPES, ///< 200 PR#6805 Extend railtypes to 64, adding uint16 to map array. - SLV_EXTEND_PERSISTENT_STORAGE, ///< 201 PR#6885 Extend NewGRF persistant storages. + SLV_EXTEND_PERSISTENT_STORAGE, ///< 201 PR#6885 Extend NewGRF persistent storages. SLV_EXTEND_INDUSTRY_CARGO_SLOTS, ///< 202 PR#6867 Increase industry cargo slots to 16 in, 16 out SLV_SHIP_PATH_CACHE, ///< 203 PR#7072 Add path cache for ships SLV_SHIP_ROTATION, ///< 204 PR#7065 Add extra rotation stages for ships. SLV_GROUP_LIVERIES, ///< 205 PR#7108 Livery storage change and group liveries. SLV_SHIPS_STOP_IN_LOCKS, ///< 206 PR#7150 Ship/lock movement changes. - SLV_FIX_CARGO_MONITOR, ///< 207 PR#7175 Cargo monitor data packing fix to support 64 cargotypes. + SLV_FIX_CARGO_MONITOR, ///< 207 PR#7175 v1.9 Cargo monitor data packing fix to support 64 cargotypes. + SLV_TOWN_CARGOGEN, ///< 208 PR#6965 New algorithms for town building cargo generation. + SLV_SHIP_CURVE_PENALTY, ///< 209 PR#7289 Configurable ship curve penalties. + + SLV_SERVE_NEUTRAL_INDUSTRIES, ///< 210 PR#7234 Company stations can serve industries with attached neutral stations. + SLV_ROADVEH_PATH_CACHE, ///< 211 PR#7261 Add path cache for road vehicles. + SLV_REMOVE_OPF, ///< 212 PR#7245 Remove OPF. + SLV_TREES_WATER_CLASS, ///< 213 PR#7405 WaterClass update for tree tiles. + SLV_ROAD_TYPES, ///< 214 PR#6811 NewGRF road types. + + SLV_SCRIPT_MEMLIMIT, ///< 215 PR#7516 Limit on AI/GS memory consumption. + SLV_MULTITILE_DOCKS, ///< 216 PR#7380 Multiple docks per station. + SLV_TRADING_AGE, ///< 217 PR#7780 Configurable company trading age. + SLV_ENDING_YEAR, ///< 218 PR#7747 Configurable ending year. SL_MAX_VERSION, ///< Highest possible saveload version }; @@ -460,7 +471,8 @@ enum VarTypes { SLF_NO_NETWORK_SYNC = 1 << 10, ///< do not synchronize over network (but it is saved if SLF_NOT_IN_SAVE is not set) SLF_ALLOW_CONTROL = 1 << 11, ///< allow control codes in the strings SLF_ALLOW_NEWLINE = 1 << 12, ///< allow new lines in the strings - /* 3 more possible flags */ + SLF_HEX = 1 << 13, ///< print numbers as hex in the config file (only useful for unsigned) + /* 2 more possible flags */ }; typedef uint32 VarType; @@ -634,11 +646,11 @@ typedef SaveLoad SaveLoadGlobVarList; /** Translate values ingame to different values in the savegame and vv. */ #define SLE_WRITEBYTE(base, variable) SLE_GENERAL(SL_WRITEBYTE, base, variable, 0, 0, SL_MIN_VERSION, SL_MAX_VERSION) -#define SLE_VEH_INCLUDE() {false, SL_VEH_INCLUDE, 0, 0, SL_MIN_VERSION, SL_MAX_VERSION, NULL, 0} -#define SLE_ST_INCLUDE() {false, SL_ST_INCLUDE, 0, 0, SL_MIN_VERSION, SL_MAX_VERSION, NULL, 0} +#define SLE_VEH_INCLUDE() {false, SL_VEH_INCLUDE, 0, 0, SL_MIN_VERSION, SL_MAX_VERSION, nullptr, 0} +#define SLE_ST_INCLUDE() {false, SL_ST_INCLUDE, 0, 0, SL_MIN_VERSION, SL_MAX_VERSION, nullptr, 0} /** End marker of a struct/class save or load. */ -#define SLE_END() {false, SL_END, 0, 0, SL_MIN_VERSION, SL_MIN_VERSION, NULL, 0} +#define SLE_END() {false, SL_END, 0, 0, SL_MIN_VERSION, SL_MIN_VERSION, nullptr, 0} /** * Storage of global simple variables, references (pointers), and arrays. @@ -739,10 +751,10 @@ typedef SaveLoad SaveLoadGlobVarList; * @param from First savegame version that has the empty space. * @param to Last savegame version that has the empty space. */ -#define SLEG_CONDNULL(length, from, to) {true, SL_ARR, SLE_FILE_U8 | SLE_VAR_NULL | SLF_NOT_IN_CONFIG, length, from, to, (void*)NULL} +#define SLEG_CONDNULL(length, from, to) {true, SL_ARR, SLE_FILE_U8 | SLE_VAR_NULL | SLF_NOT_IN_CONFIG, length, from, to, (void*)nullptr} /** End marker of global variables save or load. */ -#define SLEG_END() {true, SL_END, 0, 0, SL_MIN_VERSION, SL_MIN_VERSION, NULL, 0} +#define SLEG_END() {true, SL_END, 0, 0, SL_MIN_VERSION, SL_MIN_VERSION, nullptr, 0} /** * Checks whether the savegame is below \a major.\a minor. @@ -806,13 +818,13 @@ static inline bool IsNumericType(VarType conv) /** * Get the address of the variable. Which one to pick depends on the object - * pointer. If it is NULL we are dealing with global variables so the address + * pointer. If it is nullptr we are dealing with global variables so the address * is taken. If non-null only the offset is stored in the union and we need * to add this to the address of the object */ static inline void *GetVariableAddress(const void *object, const SaveLoad *sld) { - return const_cast((const byte*)(sld->global ? NULL : object) + (ptrdiff_t)sld->address); + return const_cast((const byte*)(sld->global ? nullptr : object) + (ptrdiff_t)sld->address); } int64 ReadValue(const void *ptr, VarType conv); @@ -834,7 +846,7 @@ void SlGlobList(const SaveLoadGlobVarList *sldg); void SlArray(void *array, size_t length, VarType conv); void SlObject(void *object, const SaveLoad *sld); bool SlObjectMember(void *object, const SaveLoad *sld); -void NORETURN SlError(StringID string, const char *extra_msg = NULL); +void NORETURN SlError(StringID string, const char *extra_msg = nullptr); void NORETURN SlErrorCorrupt(const char *msg); void NORETURN SlErrorCorruptFmt(const char *format, ...); diff --git a/src/saveload/saveload_filter.h b/src/saveload/saveload_filter.h index 0cb5c86955..490daec872 100644 --- a/src/saveload/saveload_filter.h +++ b/src/saveload/saveload_filter.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. @@ -89,7 +87,7 @@ struct SaveFilter { */ virtual void Finish() { - if (this->chain != NULL) this->chain->Finish(); + if (this->chain != nullptr) this->chain->Finish(); } }; diff --git a/src/saveload/saveload_internal.h b/src/saveload/saveload_internal.h index 74e5b9936d..8a3f433c22 100644 --- a/src/saveload/saveload_internal.h +++ b/src/saveload/saveload_internal.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. @@ -22,6 +20,7 @@ StringID RemapOldStringID(StringID s); char *CopyFromOldName(StringID id); void ResetOldNames(); +void ResetOldWaypoints(); void MoveBuoysToWaypoints(); void MoveWaypointsToBaseStations(); const SaveLoad *GetBaseStationDescription(); @@ -30,6 +29,7 @@ void AfterLoadVehicles(bool part_of_load); void FixupTrainLengths(); void AfterLoadStations(); void AfterLoadRoadStops(); +void ResetLabelMaps(); void AfterLoadLabelMaps(); void AfterLoadStoryBook(); void AfterLoadLinkGraphs(); @@ -44,12 +44,13 @@ void ResetViewportAfterLoadGame(); void ConvertOldMultiheadToNew(); void ConnectMultiheadedTrains(); +void ResetTempEngineData(); Engine *GetTempDataEngine(EngineID index); void CopyTempEngineData(); extern int32 _saved_scrollpos_x; extern int32 _saved_scrollpos_y; -extern ZoomLevelByte _saved_scrollpos_zoom; +extern ZoomLevel _saved_scrollpos_zoom; extern SavegameType _savegame_type; extern uint32 _ttdp_version; diff --git a/src/saveload/signs_sl.cpp b/src/saveload/signs_sl.cpp index 545c628b36..0be96e9821 100644 --- a/src/saveload/signs_sl.cpp +++ b/src/saveload/signs_sl.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. @@ -34,9 +32,7 @@ static const SaveLoad _sign_desc[] = { /** Save all signs */ static void Save_SIGN() { - Sign *si; - - FOR_ALL_SIGNS(si) { + for (Sign *si : Sign::Iterate()) { SlSetArrayIndex(si->index); SlObject(si, _sign_desc); } @@ -68,5 +64,5 @@ static void Load_SIGN() /** Chunk handlers related to signs. */ extern const ChunkHandler _sign_chunk_handlers[] = { - { 'SIGN', Save_SIGN, Load_SIGN, NULL, NULL, CH_ARRAY | CH_LAST}, + { 'SIGN', Save_SIGN, Load_SIGN, nullptr, nullptr, CH_ARRAY | CH_LAST}, }; diff --git a/src/saveload/station_sl.cpp b/src/saveload/station_sl.cpp index 995483ee6d..1d3612ae31 100644 --- a/src/saveload/station_sl.cpp +++ b/src/saveload/station_sl.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. @@ -42,16 +40,14 @@ static void UpdateWaypointOrder(Order *o) void MoveBuoysToWaypoints() { /* Buoy orders become waypoint orders */ - OrderList *ol; - FOR_ALL_ORDER_LISTS(ol) { + for (OrderList *ol : OrderList::Iterate()) { VehicleType vt = ol->GetFirstSharedVehicle()->type; if (vt != VEH_SHIP && vt != VEH_TRAIN) continue; - for (Order *o = ol->GetFirstOrder(); o != NULL; o = o->next) UpdateWaypointOrder(o); + for (Order *o = ol->GetFirstOrder(); o != nullptr; o = o->next) UpdateWaypointOrder(o); } - Vehicle *v; - FOR_ALL_VEHICLES(v) { + for (Vehicle *v : Vehicle::Iterate()) { VehicleType vt = v->type; if (vt != VEH_SHIP && vt != VEH_TRAIN) continue; @@ -59,8 +55,7 @@ void MoveBuoysToWaypoints() } /* Now make the stations waypoints */ - Station *st; - FOR_ALL_STATIONS(st) { + for (Station *st : Station::Iterate()) { if ((st->had_vehicle_of_type & HVOT_WAYPOINT) == 0) continue; StationID index = st->index; @@ -68,7 +63,7 @@ void MoveBuoysToWaypoints() Town *town = st->town; StringID string_id = st->string_id; char *name = st->name; - st->name = NULL; + st->name = nullptr; Date build_date = st->build_date; /* TTDPatch could use "buoys with rail station" for rail waypoints */ bool train = st->train_station.tile != INVALID_TILE; @@ -111,18 +106,17 @@ void MoveBuoysToWaypoints() void AfterLoadStations() { /* Update the speclists of all stations to point to the currently loaded custom stations. */ - BaseStation *st; - FOR_ALL_BASE_STATIONS(st) { + for (BaseStation *st : BaseStation::Iterate()) { for (uint i = 0; i < st->num_specs; i++) { if (st->speclist[i].grfid == 0) continue; - st->speclist[i].spec = StationClass::GetByGrf(st->speclist[i].grfid, st->speclist[i].localidx, NULL); + st->speclist[i].spec = StationClass::GetByGrf(st->speclist[i].grfid, st->speclist[i].localidx, nullptr); } if (Station::IsExpected(st)) { Station *sta = Station::From(st); - for (const RoadStop *rs = sta->bus_stops; rs != NULL; rs = rs->next) sta->bus_station.Add(rs->xy); - for (const RoadStop *rs = sta->truck_stops; rs != NULL; rs = rs->next) sta->truck_station.Add(rs->xy); + for (const RoadStop *rs = sta->bus_stops; rs != nullptr; rs = rs->next) sta->bus_station.Add(rs->xy); + for (const RoadStop *rs = sta->truck_stops; rs != nullptr; rs = rs->next) sta->truck_station.Add(rs->xy); } StationUpdateCachedTriggers(st); @@ -135,12 +129,11 @@ void AfterLoadStations() void AfterLoadRoadStops() { /* First construct the drive through entries */ - RoadStop *rs; - FOR_ALL_ROADSTOPS(rs) { + for (RoadStop *rs : RoadStop::Iterate()) { if (IsDriveThroughStopTile(rs->xy)) rs->MakeDriveThrough(); } /* And then rebuild the data in those entries */ - FOR_ALL_ROADSTOPS(rs) { + for (RoadStop *rs : RoadStop::Iterate()) { if (!HasBit(rs->status, RoadStop::RSSFB_BASE_ENTRY)) continue; rs->GetEntry(DIAGDIR_NE)->Rebuild(rs); @@ -174,8 +167,8 @@ static const SaveLoad _old_station_desc[] = { SLE_CONDVAR(Station, train_station.tile, SLE_UINT32, SLV_6, SL_MAX_VERSION), SLE_CONDVAR(Station, airport.tile, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6), SLE_CONDVAR(Station, airport.tile, SLE_UINT32, SLV_6, SL_MAX_VERSION), - SLE_CONDVAR(Station, dock_tile, SLE_FILE_U16 | SLE_VAR_U32, SL_MIN_VERSION, SLV_6), - SLE_CONDVAR(Station, dock_tile, SLE_UINT32, SLV_6, SL_MAX_VERSION), + SLE_CONDNULL(2, SL_MIN_VERSION, SLV_6), + SLE_CONDNULL(4, SLV_6, SLV_MULTITILE_DOCKS), SLE_REF(Station, town, REF_TOWN), SLE_VAR(Station, train_station.w, SLE_FILE_U8 | SLE_VAR_U16), SLE_CONDVAR(Station, train_station.h, SLE_FILE_U8 | SLE_VAR_U16, SLV_2, SL_MAX_VERSION), @@ -378,8 +371,7 @@ static void Ptrs_STNS() if (!IsSavegameVersionBefore(SLV_123)) return; uint num_cargo = IsSavegameVersionBefore(SLV_EXTEND_CARGOTYPES) ? 32 : NUM_CARGO; - Station *st; - FOR_ALL_STATIONS(st) { + for (Station *st : Station::Iterate()) { if (!IsSavegameVersionBefore(SLV_68)) { for (CargoID i = 0; i < num_cargo; i++) { GoodsEntry *ge = &st->goods[i]; @@ -423,7 +415,13 @@ static const SaveLoad _station_desc[] = { SLE_REF(Station, bus_stops, REF_ROADSTOPS), SLE_REF(Station, truck_stops, REF_ROADSTOPS), - SLE_VAR(Station, dock_tile, SLE_UINT32), + SLE_CONDNULL(4, SL_MIN_VERSION, SLV_MULTITILE_DOCKS), + SLE_CONDVAR(Station, ship_station.tile, SLE_UINT32, SLV_MULTITILE_DOCKS, SL_MAX_VERSION), + SLE_CONDVAR(Station, ship_station.w, SLE_FILE_U8 | SLE_VAR_U16, SLV_MULTITILE_DOCKS, SL_MAX_VERSION), + SLE_CONDVAR(Station, ship_station.h, SLE_FILE_U8 | SLE_VAR_U16, SLV_MULTITILE_DOCKS, SL_MAX_VERSION), + SLE_CONDVAR(Station, docking_station.tile, SLE_UINT32, SLV_MULTITILE_DOCKS, SL_MAX_VERSION), + SLE_CONDVAR(Station, docking_station.w, SLE_FILE_U8 | SLE_VAR_U16, SLV_MULTITILE_DOCKS, SL_MAX_VERSION), + SLE_CONDVAR(Station, docking_station.h, SLE_FILE_U8 | SLE_VAR_U16, SLV_MULTITILE_DOCKS, SL_MAX_VERSION), SLE_VAR(Station, airport.tile, SLE_UINT32), SLE_CONDVAR(Station, airport.w, SLE_FILE_U8 | SLE_VAR_U16, SLV_140, SL_MAX_VERSION), SLE_CONDVAR(Station, airport.h, SLE_FILE_U8 | SLE_VAR_U16, SLV_140, SL_MAX_VERSION), @@ -510,9 +508,8 @@ static void RealSave_STNN(BaseStation *bst) static void Save_STNN() { - BaseStation *st; /* Write the stations */ - FOR_ALL_BASE_STATIONS(st) { + for (BaseStation *st : BaseStation::Iterate()) { SlSetArrayIndex(st->index); SlAutolength((AutolengthProc*)RealSave_STNN, st); } @@ -544,11 +541,11 @@ static void Load_STNN() for (CargoID i = 0; i < num_cargo; i++) { SlObject(&st->goods[i], GetGoodsDesc()); FlowSaveLoad flow; - FlowStat *fs = NULL; + FlowStat *fs = nullptr; StationID prev_source = INVALID_STATION; for (uint32 j = 0; j < _num_flows; ++j) { SlObject(&flow, _flow_desc); - if (fs == NULL || prev_source != flow.source) { + if (fs == nullptr || prev_source != flow.source) { fs = &(st->goods[i].flows.insert(std::make_pair(flow.source, FlowStat(flow.via, flow.share, flow.restricted))).first->second); } else { fs->AppendShare(flow.via, flow.share, flow.restricted); @@ -584,8 +581,7 @@ static void Ptrs_STNN() if (IsSavegameVersionBefore(SLV_123)) return; uint num_cargo = IsSavegameVersionBefore(SLV_EXTEND_CARGOTYPES) ? 32 : NUM_CARGO; - Station *st; - FOR_ALL_STATIONS(st) { + for (Station *st : Station::Iterate()) { for (CargoID i = 0; i < num_cargo; i++) { GoodsEntry *ge = &st->goods[i]; if (IsSavegameVersionBefore(SLV_183)) { @@ -602,17 +598,14 @@ static void Ptrs_STNN() SlObject(st, _station_desc); } - Waypoint *wp; - FOR_ALL_WAYPOINTS(wp) { + for (Waypoint *wp : Waypoint::Iterate()) { SlObject(wp, _waypoint_desc); } } static void Save_ROADSTOP() { - RoadStop *rs; - - FOR_ALL_ROADSTOPS(rs) { + for (RoadStop *rs : RoadStop::Iterate()) { SlSetArrayIndex(rs->index); SlObject(rs, _roadstop_desc); } @@ -631,14 +624,13 @@ static void Load_ROADSTOP() static void Ptrs_ROADSTOP() { - RoadStop *rs; - FOR_ALL_ROADSTOPS(rs) { + for (RoadStop *rs : RoadStop::Iterate()) { SlObject(rs, _roadstop_desc); } } extern const ChunkHandler _station_chunk_handlers[] = { - { 'STNS', NULL, Load_STNS, Ptrs_STNS, NULL, CH_ARRAY }, - { 'STNN', Save_STNN, Load_STNN, Ptrs_STNN, NULL, CH_ARRAY }, - { 'ROAD', Save_ROADSTOP, Load_ROADSTOP, Ptrs_ROADSTOP, NULL, CH_ARRAY | CH_LAST}, + { 'STNS', nullptr, Load_STNS, Ptrs_STNS, nullptr, CH_ARRAY }, + { 'STNN', Save_STNN, Load_STNN, Ptrs_STNN, nullptr, CH_ARRAY }, + { 'ROAD', Save_ROADSTOP, Load_ROADSTOP, Ptrs_ROADSTOP, nullptr, CH_ARRAY | CH_LAST}, }; diff --git a/src/saveload/storage_sl.cpp b/src/saveload/storage_sl.cpp index 1396d25aee..7abe396f38 100644 --- a/src/saveload/storage_sl.cpp +++ b/src/saveload/storage_sl.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. @@ -38,10 +36,8 @@ static void Load_PSAC() /** Save persistent storage data. */ static void Save_PSAC() { - PersistentStorage *ps; - /* Write the industries */ - FOR_ALL_STORAGES(ps) { + for (PersistentStorage *ps : PersistentStorage::Iterate()) { ps->ClearChanges(); SlSetArrayIndex(ps->index); SlObject(ps, _storage_desc); @@ -50,5 +46,5 @@ static void Save_PSAC() /** Chunk handler for persistent storages. */ extern const ChunkHandler _persistent_storage_chunk_handlers[] = { - { 'PSAC', Save_PSAC, Load_PSAC, NULL, NULL, CH_ARRAY | CH_LAST}, + { 'PSAC', Save_PSAC, Load_PSAC, nullptr, nullptr, CH_ARRAY | CH_LAST}, }; diff --git a/src/saveload/story_sl.cpp b/src/saveload/story_sl.cpp index f9bbf34b9b..dba2a064f5 100644 --- a/src/saveload/story_sl.cpp +++ b/src/saveload/story_sl.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. @@ -41,8 +39,7 @@ static const SaveLoad _story_page_elements_desc[] = { static void Save_STORY_PAGE_ELEMENT() { - StoryPageElement *s; - FOR_ALL_STORY_PAGE_ELEMENTS(s) { + for (StoryPageElement *s : StoryPageElement::Iterate()) { SlSetArrayIndex(s->index); SlObject(s, _story_page_elements_desc); } @@ -77,8 +74,7 @@ static const SaveLoad _story_pages_desc[] = { static void Save_STORY_PAGE() { - StoryPage *s; - FOR_ALL_STORY_PAGES(s) { + for (StoryPage *s : StoryPage::Iterate()) { SlSetArrayIndex(s->index); SlObject(s, _story_pages_desc); } @@ -102,6 +98,6 @@ static void Load_STORY_PAGE() } extern const ChunkHandler _story_page_chunk_handlers[] = { - { 'STPE', Save_STORY_PAGE_ELEMENT, Load_STORY_PAGE_ELEMENT, NULL, NULL, CH_ARRAY}, - { 'STPA', Save_STORY_PAGE, Load_STORY_PAGE, NULL, NULL, CH_ARRAY | CH_LAST}, + { 'STPE', Save_STORY_PAGE_ELEMENT, Load_STORY_PAGE_ELEMENT, nullptr, nullptr, CH_ARRAY}, + { 'STPA', Save_STORY_PAGE, Load_STORY_PAGE, nullptr, nullptr, CH_ARRAY | CH_LAST}, }; diff --git a/src/saveload/strings_sl.cpp b/src/saveload/strings_sl.cpp index d8fe81d113..dce8fdedb7 100644 --- a/src/saveload/strings_sl.cpp +++ b/src/saveload/strings_sl.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. @@ -49,7 +47,7 @@ StringID RemapOldStringID(StringID s) } /** Location to load the old names to. */ -char *_old_name_array = NULL; +char *_old_name_array = nullptr; /** * Copy and convert old custom names to UTF-8. @@ -61,7 +59,7 @@ char *_old_name_array = NULL; char *CopyFromOldName(StringID id) { /* Is this name an (old) custom name? */ - if (GetStringTab(id) != TEXT_TAB_OLD_CUSTOM) return NULL; + if (GetStringTab(id) != TEXT_TAB_OLD_CUSTOM) return nullptr; if (IsSavegameVersionBefore(SLV_37)) { /* Allow for expansion when converted to UTF-8. */ @@ -82,7 +80,7 @@ char *CopyFromOldName(StringID id) case 0xB8: c = 0x017E; break; // z with caron case 0xBC: c = 0x0152; break; // OE ligature case 0xBD: c = 0x0153; break; // oe ligature - case 0xBE: c = 0x0178; break; // Y with diaresis + case 0xBE: c = 0x0178; break; // Y with diaeresis default: break; } @@ -109,7 +107,7 @@ char *CopyFromOldName(StringID id) void ResetOldNames() { free(_old_name_array); - _old_name_array = NULL; + _old_name_array = nullptr; } /** @@ -140,5 +138,5 @@ static void Load_NAME() /** Chunk handlers related to strings. */ extern const ChunkHandler _name_chunk_handlers[] = { - { 'NAME', NULL, Load_NAME, NULL, NULL, CH_ARRAY | CH_LAST}, + { 'NAME', nullptr, Load_NAME, nullptr, nullptr, CH_ARRAY | CH_LAST}, }; diff --git a/src/saveload/subsidy_sl.cpp b/src/saveload/subsidy_sl.cpp index 6f10ec8d09..d0db78b61d 100644 --- a/src/saveload/subsidy_sl.cpp +++ b/src/saveload/subsidy_sl.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. @@ -31,8 +29,7 @@ static const SaveLoad _subsidies_desc[] = { static void Save_SUBS() { - Subsidy *s; - FOR_ALL_SUBSIDIES(s) { + for (Subsidy *s : Subsidy::Iterate()) { SlSetArrayIndex(s->index); SlObject(s, _subsidies_desc); } @@ -48,5 +45,5 @@ static void Load_SUBS() } extern const ChunkHandler _subsidy_chunk_handlers[] = { - { 'SUBS', Save_SUBS, Load_SUBS, NULL, NULL, CH_ARRAY | CH_LAST}, + { 'SUBS', Save_SUBS, Load_SUBS, nullptr, nullptr, CH_ARRAY | CH_LAST}, }; diff --git a/src/saveload/town_sl.cpp b/src/saveload/town_sl.cpp index a31c886ec2..6fe1439b4e 100644 --- a/src/saveload/town_sl.cpp +++ b/src/saveload/town_sl.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. @@ -26,11 +24,11 @@ */ void RebuildTownCaches() { - Town *town; InitializeBuildingCounts(); + RebuildTownKdtree(); /* Reset town population and num_houses */ - FOR_ALL_TOWNS(town) { + for (Town *town : Town::Iterate()) { town->cache.population = 0; town->cache.num_houses = 0; } @@ -39,7 +37,7 @@ void RebuildTownCaches() if (!IsTileType(t, MP_HOUSE)) continue; HouseID house_id = GetHouseType(t); - town = Town::GetByTile(t); + Town *town = Town::GetByTile(t); IncreaseBuildingCount(town, house_id); if (IsHouseCompleted(t)) town->cache.population += HouseSpec::Get(house_id)->population; @@ -48,7 +46,7 @@ void RebuildTownCaches() } /* Update the population and num_house dependent values */ - FOR_ALL_TOWNS(town) { + for (Town *town : Town::Iterate()) { UpdateTownRadius(town); UpdateTownCargoes(town); } @@ -264,9 +262,7 @@ static void RealSave_Town(Town *t) static void Save_TOWN() { - Town *t; - - FOR_ALL_TOWNS(t) { + for (Town *t : Town::Iterate()) { SlSetArrayIndex(t->index); SlAutolength((AutolengthProc*)RealSave_Town, t); } @@ -312,14 +308,13 @@ static void Ptrs_TOWN() /* Don't run when savegame version lower than 161. */ if (IsSavegameVersionBefore(SLV_161)) return; - Town *t; - FOR_ALL_TOWNS(t) { + for (Town *t : Town::Iterate()) { SlObject(t, _town_desc); } } /** Chunk handler for towns. */ extern const ChunkHandler _town_chunk_handlers[] = { - { 'HIDS', Save_HIDS, Load_HIDS, NULL, NULL, CH_ARRAY }, - { 'CITY', Save_TOWN, Load_TOWN, Ptrs_TOWN, NULL, CH_ARRAY | CH_LAST}, + { 'HIDS', Save_HIDS, Load_HIDS, nullptr, nullptr, CH_ARRAY }, + { 'CITY', Save_TOWN, Load_TOWN, Ptrs_TOWN, nullptr, CH_ARRAY | CH_LAST}, }; diff --git a/src/saveload/vehicle_sl.cpp b/src/saveload/vehicle_sl.cpp index 540416586c..3569507c79 100644 --- a/src/saveload/vehicle_sl.cpp +++ b/src/saveload/vehicle_sl.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,13 +31,11 @@ */ void ConnectMultiheadedTrains() { - Train *v; - - FOR_ALL_TRAINS(v) { - v->other_multiheaded_part = NULL; + for (Train *v : Train::Iterate()) { + v->other_multiheaded_part = nullptr; } - FOR_ALL_TRAINS(v) { + for (Train *v : Train::Iterate()) { if (v->IsFrontEngine() || v->IsFreeWagon()) { /* Two ways to associate multiheaded parts to each other: * sequential-matching: Trains shall be arranged to look like <..>..<..>..<..>.. @@ -56,8 +52,8 @@ void ConnectMultiheadedTrains() bool sequential_matching = v->IsFrontEngine(); - for (Train *u = v; u != NULL; u = u->GetNextVehicle()) { - if (u->other_multiheaded_part != NULL) continue; // we already linked this one + for (Train *u = v; u != nullptr; u = u->GetNextVehicle()) { + if (u->other_multiheaded_part != nullptr) continue; // we already linked this one if (u->IsMultiheaded()) { if (!u->IsEngine()) { @@ -70,8 +66,8 @@ void ConnectMultiheadedTrains() EngineID eid = u->engine_type; Train *w; if (sequential_matching) { - for (w = u->GetNextVehicle(); w != NULL; w = w->GetNextVehicle()) { - if (w->engine_type != eid || w->other_multiheaded_part != NULL || !w->IsMultiheaded()) continue; + for (w = u->GetNextVehicle(); w != nullptr; w = w->GetNextVehicle()) { + if (w->engine_type != eid || w->other_multiheaded_part != nullptr || !w->IsMultiheaded()) continue; /* we found a car to partner with this engine. Now we will make sure it face the right way */ if (w->IsEngine()) { @@ -82,8 +78,8 @@ void ConnectMultiheadedTrains() } } else { uint stack_pos = 0; - for (w = u->GetNextVehicle(); w != NULL; w = w->GetNextVehicle()) { - if (w->engine_type != eid || w->other_multiheaded_part != NULL || !w->IsMultiheaded()) continue; + for (w = u->GetNextVehicle(); w != nullptr; w = w->GetNextVehicle()) { + if (w->engine_type != eid || w->other_multiheaded_part != nullptr || !w->IsMultiheaded()) continue; if (w->IsEngine()) { stack_pos++; @@ -94,7 +90,7 @@ void ConnectMultiheadedTrains() } } - if (w != NULL) { + if (w != nullptr) { w->other_multiheaded_part = u; u->other_multiheaded_part = w; } else { @@ -113,12 +109,11 @@ void ConnectMultiheadedTrains() */ void ConvertOldMultiheadToNew() { - Train *t; - FOR_ALL_TRAINS(t) SetBit(t->subtype, 7); // indicates that it's the old format and needs to be converted in the next loop + for (Train *t : Train::Iterate()) SetBit(t->subtype, 7); // indicates that it's the old format and needs to be converted in the next loop - FOR_ALL_TRAINS(t) { + for (Train *t : Train::Iterate()) { if (HasBit(t->subtype, 7) && ((t->subtype & ~0x80) == 0 || (t->subtype & ~0x80) == 4)) { - for (Train *u = t; u != NULL; u = u->Next()) { + for (Train *u = t; u != nullptr; u = u->Next()) { const RailVehicleInfo *rvi = RailVehInfo(u->engine_type); ClrBit(u->subtype, 7); @@ -167,13 +162,11 @@ void ConvertOldMultiheadToNew() void UpdateOldAircraft() { /* set airport_flags to 0 for all airports just to be sure */ - Station *st; - FOR_ALL_STATIONS(st) { + for (Station *st : Station::Iterate()) { st->airport.flags = 0; // reset airport } - Aircraft *a; - FOR_ALL_AIRCRAFT(a) { + for (Aircraft *a : Aircraft::Iterate()) { /* airplane has another vehicle with subtype 4 (shadow), helicopter also has 3 (rotor) * skip those */ if (a->IsNormalAircraft()) { @@ -200,7 +193,7 @@ void UpdateOldAircraft() if (a->subtype == AIR_HELICOPTER) a->Next()->Next()->cur_speed = 32; /* set new position x,y,z */ - GetAircraftFlightLevelBounds(a, &a->z_pos, NULL); + GetAircraftFlightLevelBounds(a, &a->z_pos, nullptr); SetAircraftPosition(a, gp.x, gp.y, GetAircraftFlightLevel(a)); } } @@ -218,14 +211,12 @@ static void CheckValidVehicles() size_t total_engines = Engine::GetPoolSize(); EngineID first_engine[4] = { INVALID_ENGINE, INVALID_ENGINE, INVALID_ENGINE, INVALID_ENGINE }; - Engine *e; - FOR_ALL_ENGINES_OF_TYPE(e, VEH_TRAIN) { first_engine[VEH_TRAIN] = e->index; break; } - FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) { first_engine[VEH_ROAD] = e->index; break; } - FOR_ALL_ENGINES_OF_TYPE(e, VEH_SHIP) { first_engine[VEH_SHIP] = e->index; break; } - FOR_ALL_ENGINES_OF_TYPE(e, VEH_AIRCRAFT) { first_engine[VEH_AIRCRAFT] = e->index; break; } + for (const Engine *e : Engine::IterateType(VEH_TRAIN)) { first_engine[VEH_TRAIN] = e->index; break; } + for (const Engine *e : Engine::IterateType(VEH_ROAD)) { first_engine[VEH_ROAD] = e->index; break; } + for (const Engine *e : Engine::IterateType(VEH_SHIP)) { first_engine[VEH_SHIP] = e->index; break; } + for (const Engine *e : Engine::IterateType(VEH_AIRCRAFT)) { first_engine[VEH_AIRCRAFT] = e->index; break; } - Vehicle *v; - FOR_ALL_VEHICLES(v) { + for (Vehicle *v : Vehicle::Iterate()) { /* Test if engine types match */ switch (v->type) { case VEH_TRAIN: @@ -248,15 +239,13 @@ extern byte _age_cargo_skip_counter; // From misc_sl.cpp /** Called after load to update coordinates */ void AfterLoadVehicles(bool part_of_load) { - Vehicle *v; - - FOR_ALL_VEHICLES(v) { + for (Vehicle *v : Vehicle::Iterate()) { /* Reinstate the previous pointer */ - if (v->Next() != NULL) v->Next()->previous = v; - if (v->NextShared() != NULL) v->NextShared()->previous_shared = v; + if (v->Next() != nullptr) v->Next()->previous = v; + if (v->NextShared() != nullptr) v->NextShared()->previous_shared = v; if (part_of_load) v->fill_percent_te_id = INVALID_TE_ID; - v->first = NULL; + v->first = nullptr; if (v->IsGroundVehicle()) v->GetGroundVehicleCache()->first_engine = INVALID_ENGINE; } @@ -271,10 +260,10 @@ void AfterLoadVehicles(bool part_of_load) */ std::map mapping; - FOR_ALL_VEHICLES(v) { - if (v->orders.old != NULL) { + for (Vehicle *v : Vehicle::Iterate()) { + if (v->orders.old != nullptr) { if (IsSavegameVersionBefore(SLV_105)) { // Pre-105 didn't save an OrderList - if (mapping[v->orders.old] == NULL) { + if (mapping[v->orders.old] == nullptr) { /* This adds the whole shared vehicle chain for case b */ /* Creating an OrderList here is safe because the number of vehicles @@ -290,7 +279,7 @@ void AfterLoadVehicles(bool part_of_load) } } } else { // OrderList was saved as such, only recalculate not saved values - if (v->PreviousShared() == NULL) { + if (v->PreviousShared() == nullptr) { v->orders.list->Initialize(v->orders.list->first, v); } } @@ -298,10 +287,10 @@ void AfterLoadVehicles(bool part_of_load) } } - FOR_ALL_VEHICLES(v) { + for (Vehicle *v : Vehicle::Iterate()) { /* Fill the first pointers */ - if (v->Previous() == NULL) { - for (Vehicle *u = v; u != NULL; u = u->Next()) { + if (v->Previous() == nullptr) { + for (Vehicle *u = v; u != nullptr; u = u->Next()) { u->first = v; } } @@ -310,13 +299,13 @@ void AfterLoadVehicles(bool part_of_load) if (part_of_load) { if (IsSavegameVersionBefore(SLV_105)) { /* Before 105 there was no order for shared orders, thus it messed up horribly */ - FOR_ALL_VEHICLES(v) { - if (v->First() != v || v->orders.list != NULL || v->previous_shared != NULL || v->next_shared == NULL) continue; + for (Vehicle *v : Vehicle::Iterate()) { + if (v->First() != v || v->orders.list != nullptr || v->previous_shared != nullptr || v->next_shared == nullptr) continue; /* As above, allocating OrderList here is safe. */ assert(OrderList::CanAllocateItem()); - v->orders.list = new OrderList(NULL, v); - for (Vehicle *u = v; u != NULL; u = u->next_shared) { + v->orders.list = new OrderList(nullptr, v); + for (Vehicle *u = v; u != nullptr; u = u->next_shared) { u->orders.list = v->orders.list; } } @@ -324,8 +313,7 @@ void AfterLoadVehicles(bool part_of_load) if (IsSavegameVersionBefore(SLV_157)) { /* The road vehicle subtype was converted to a flag. */ - RoadVehicle *rv; - FOR_ALL_ROADVEHICLES(rv) { + for (RoadVehicle *rv : RoadVehicle::Iterate()) { if (rv->subtype == 0) { /* The road vehicle is at the front. */ rv->SetFrontEngine(); @@ -341,7 +329,7 @@ void AfterLoadVehicles(bool part_of_load) if (IsSavegameVersionBefore(SLV_160)) { /* In some old savegames there might be some "crap" stored. */ - FOR_ALL_VEHICLES(v) { + for (Vehicle *v : Vehicle::Iterate()) { if (!v->IsPrimaryVehicle() && v->type != VEH_DISASTER) { v->current_order.Free(); v->unitnumber = 0; @@ -351,14 +339,14 @@ void AfterLoadVehicles(bool part_of_load) if (IsSavegameVersionBefore(SLV_162)) { /* Set the vehicle-local cargo age counter from the old global counter. */ - FOR_ALL_VEHICLES(v) { + for (Vehicle *v : Vehicle::Iterate()) { v->cargo_age_counter = _age_cargo_skip_counter; } } if (IsSavegameVersionBefore(SLV_180)) { /* Set service interval flags */ - FOR_ALL_VEHICLES(v) { + for (Vehicle *v : Vehicle::Iterate()) { if (!v->IsPrimaryVehicle()) continue; const Company *c = Company::Get(v->owner); @@ -371,13 +359,11 @@ void AfterLoadVehicles(bool part_of_load) if (IsSavegameVersionBefore(SLV_SHIP_ROTATION)) { /* Ship rotation added */ - Ship *s; - FOR_ALL_SHIPS(s) { + for (Ship *s : Ship::Iterate()) { s->rotation = s->direction; } } else { - Ship *s; - FOR_ALL_SHIPS(s) { + for (Ship *s : Ship::Iterate()) { if (s->rotation == s->direction) continue; /* In case we are rotating on gameload, set the rotation position to * the current position, otherwise the applied workaround offset would @@ -391,10 +377,10 @@ void AfterLoadVehicles(bool part_of_load) CheckValidVehicles(); - FOR_ALL_VEHICLES(v) { - assert(v->first != NULL); + for (Vehicle *v : Vehicle::Iterate()) { + assert(v->first != nullptr); - v->trip_occupancy = CalcPercentVehicleFilled(v, NULL); + v->trip_occupancy = CalcPercentVehicleFilled(v, nullptr); switch (v->type) { case VEH_TRAIN: { @@ -410,6 +396,14 @@ void AfterLoadVehicles(bool part_of_load) RoadVehicle *rv = RoadVehicle::From(v); if (rv->IsFrontEngine()) { rv->gcache.last_speed = rv->cur_speed; // update displayed road vehicle speed + + rv->roadtype = Engine::Get(rv->engine_type)->u.road.roadtype; + rv->compatible_roadtypes = GetRoadTypeInfo(rv->roadtype)->powered_roadtypes; + for (RoadVehicle *u = rv; u != nullptr; u = u->Next()) { + u->roadtype = rv->roadtype; + u->compatible_roadtypes = rv->compatible_roadtypes; + } + RoadVehUpdateCache(rv); if (_settings_game.vehicle.roadveh_acceleration_model != AM_ORIGINAL) { rv->CargoChanged(); @@ -428,7 +422,7 @@ void AfterLoadVehicles(bool part_of_load) /* Stop non-front engines */ if (part_of_load && IsSavegameVersionBefore(SLV_112)) { - FOR_ALL_VEHICLES(v) { + for (Vehicle *v : Vehicle::Iterate()) { if (v->type == VEH_TRAIN) { Train *t = Train::From(v); if (!t->IsFrontEngine()) { @@ -446,15 +440,9 @@ void AfterLoadVehicles(bool part_of_load) } } - FOR_ALL_VEHICLES(v) { + for (Vehicle *v : Vehicle::Iterate()) { switch (v->type) { - case VEH_ROAD: { - RoadVehicle *rv = RoadVehicle::From(v); - rv->roadtype = HasBit(EngInfo(v->First()->engine_type)->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD; - rv->compatible_roadtypes = RoadTypeToRoadTypes(rv->roadtype); - FALLTHROUGH; - } - + case VEH_ROAD: case VEH_TRAIN: case VEH_SHIP: v->GetImage(v->direction, EIT_ON_MAP, &v->sprite_seq); @@ -496,13 +484,12 @@ void FixupTrainLengths() { /* Vehicle center was moved from 4 units behind the front to half the length * behind the front. Move vehicles so they end up on the same spot. */ - Vehicle *v; - FOR_ALL_VEHICLES(v) { + for (Vehicle *v : Vehicle::Iterate()) { if (v->type == VEH_TRAIN && v->IsPrimaryVehicle()) { /* The vehicle center is now more to the front depending on vehicle length, * so we need to move all vehicles forward to cover the difference to the * old center, otherwise wagon spacing in trains would be broken upon load. */ - for (Train *u = Train::From(v); u != NULL; u = u->Next()) { + for (Train *u = Train::From(v); u != nullptr; u = u->Next()) { if (u->track == TRACK_BIT_DEPOT || (u->vehstatus & VS_CRASHED)) continue; Train *next = u->Next(); @@ -514,7 +501,7 @@ void FixupTrainLengths() if (!TrainController(u, next, false)) break; } - if (next != NULL && done < diff && u->IsFrontEngine()) { + if (next != nullptr && done < diff && u->IsFrontEngine()) { /* Pulling the front vehicle forwards failed, we either encountered a dead-end * or a red signal. To fix this, we try to move the whole train the required * space backwards and re-do the fix up of the front vehicle. */ @@ -530,14 +517,14 @@ void FixupTrainLengths() /* We moved the first vehicle which is now the last. Move it back to the * original position as we will fix up the last vehicle later in the loop. */ - for (int i = 0; i < done; i++) TrainController(u->Last(), NULL); + for (int i = 0; i < done; i++) TrainController(u->Last(), nullptr); /* Move the train backwards to get space for the first vehicle. As the stopping * distance from a line end is rounded up, move the train one unit more to cater * for front vehicles with odd lengths. */ int moved; for (moved = 0; moved < diff + 1; moved++) { - if (!TrainController(u, NULL, false)) break; + if (!TrainController(u, nullptr, false)) break; } /* Swap start<>end, start+1<>end-1, ... again. */ @@ -556,17 +543,17 @@ void FixupTrainLengths() /* We moved one unit more backwards than needed for even-length front vehicles, * try to move that unit forward again. We don't care if this step fails. */ - TrainController(u, NULL, false); + TrainController(u, nullptr, false); } /* If the next wagon is still in a depot, check if it shouldn't be outside already. */ - if (next != NULL && next->track == TRACK_BIT_DEPOT) { + if (next != nullptr && next->track == TRACK_BIT_DEPOT) { int d = TicksToLeaveDepot(u); if (d <= 0) { /* Next vehicle should have left the depot already, show it and pull forward. */ next->vehstatus &= ~VS_HIDDEN; next->track = TrackToTrackBits(GetRailDepotTrack(next->tile)); - for (int i = 0; i >= d; i--) TrainController(next, NULL); + for (int i = 0; i >= d; i--) TrainController(next, nullptr); } } } @@ -752,21 +739,23 @@ const SaveLoad *GetVehicleDescription(VehicleType vt) static const SaveLoad _roadveh_desc[] = { SLE_WRITEBYTE(Vehicle, type), SLE_VEH_INCLUDE(), - SLE_VAR(RoadVehicle, state, SLE_UINT8), - SLE_VAR(RoadVehicle, frame, SLE_UINT8), - SLE_VAR(RoadVehicle, blocked_ctr, SLE_UINT16), - SLE_VAR(RoadVehicle, overtaking, SLE_UINT8), - SLE_VAR(RoadVehicle, overtaking_ctr, SLE_UINT8), - SLE_VAR(RoadVehicle, crashed_ctr, SLE_UINT16), - SLE_VAR(RoadVehicle, reverse_ctr, SLE_UINT8), + SLE_VAR(RoadVehicle, state, SLE_UINT8), + SLE_VAR(RoadVehicle, frame, SLE_UINT8), + SLE_VAR(RoadVehicle, blocked_ctr, SLE_UINT16), + SLE_VAR(RoadVehicle, overtaking, SLE_UINT8), + SLE_VAR(RoadVehicle, overtaking_ctr, SLE_UINT8), + SLE_VAR(RoadVehicle, crashed_ctr, SLE_UINT16), + SLE_VAR(RoadVehicle, reverse_ctr, SLE_UINT8), + SLE_CONDDEQUE(RoadVehicle, path.td, SLE_UINT8, SLV_ROADVEH_PATH_CACHE, SL_MAX_VERSION), + SLE_CONDDEQUE(RoadVehicle, path.tile, SLE_UINT32, SLV_ROADVEH_PATH_CACHE, SL_MAX_VERSION), - SLE_CONDNULL(2, SLV_6, SLV_69), - SLE_CONDVAR(RoadVehicle, gv_flags, SLE_UINT16, SLV_139, SL_MAX_VERSION), - SLE_CONDNULL(4, SLV_69, SLV_131), - SLE_CONDNULL(2, SLV_6, SLV_131), - SLE_CONDNULL(16, SLV_2, SLV_144), // old reserved space + SLE_CONDNULL(2, SLV_6, SLV_69), + SLE_CONDVAR(RoadVehicle, gv_flags, SLE_UINT16, SLV_139, SL_MAX_VERSION), + SLE_CONDNULL(4, SLV_69, SLV_131), + SLE_CONDNULL(2, SLV_6, SLV_131), + SLE_CONDNULL(16, SLV_2, SLV_144), // old reserved space - SLE_END() + SLE_END() }; static const SaveLoad _ship_desc[] = { @@ -892,9 +881,8 @@ const SaveLoad *GetVehicleDescription(VehicleType vt) /** Will be called when the vehicles need to be saved. */ static void Save_VEHS() { - Vehicle *v; /* Write the vehicles */ - FOR_ALL_VEHICLES(v) { + for (Vehicle *v : Vehicle::Iterate()) { SlSetArrayIndex(v->index); SlObject(v, GetVehicleDescription(v->type)); } @@ -951,12 +939,11 @@ void Load_VEHS() static void Ptrs_VEHS() { - Vehicle *v; - FOR_ALL_VEHICLES(v) { + for (Vehicle *v : Vehicle::Iterate()) { SlObject(v, GetVehicleDescription(v->type)); } } extern const ChunkHandler _veh_chunk_handlers[] = { - { 'VEHS', Save_VEHS, Load_VEHS, Ptrs_VEHS, NULL, CH_SPARSE_ARRAY | CH_LAST}, + { 'VEHS', Save_VEHS, Load_VEHS, Ptrs_VEHS, nullptr, CH_SPARSE_ARRAY | CH_LAST}, }; diff --git a/src/saveload/waypoint_sl.cpp b/src/saveload/waypoint_sl.cpp index ae74d812b1..5336d247b4 100644 --- a/src/saveload/waypoint_sl.cpp +++ b/src/saveload/waypoint_sl.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. @@ -11,6 +9,7 @@ #include "../stdafx.h" #include "../waypoint_base.h" +#include "../debug.h" #include "../newgrf_station.h" #include "../vehicle_base.h" #include "../town.h" @@ -36,13 +35,13 @@ struct OldWaypoint { uint8 localidx; uint32 grfid; const StationSpec *spec; - OwnerByte owner; + Owner owner; size_t new_index; }; /** Temporary array with old waypoints. */ -static SmallVector _old_waypoints; +static std::vector _old_waypoints; /** * Update the waypoint orders to get the new waypoint ID. @@ -52,10 +51,10 @@ static void UpdateWaypointOrder(Order *o) { if (!o->IsType(OT_GOTO_WAYPOINT)) return; - for (OldWaypoint *wp = _old_waypoints.Begin(); wp != _old_waypoints.End(); wp++) { - if (wp->index != o->GetDestination()) continue; + for (OldWaypoint &wp : _old_waypoints) { + if (wp.index != o->GetDestination()) continue; - o->SetDestination((DestinationID)wp->new_index); + o->SetDestination((DestinationID)wp.new_index); return; } } @@ -71,82 +70,98 @@ void MoveWaypointsToBaseStations() * id which was stored in m4 is now saved as a grf/id reference in the * waypoint struct. */ if (IsSavegameVersionBefore(SLV_17)) { - for (OldWaypoint *wp = _old_waypoints.Begin(); wp != _old_waypoints.End(); wp++) { - if (wp->delete_ctr != 0) continue; // The waypoint was deleted + for (OldWaypoint &wp : _old_waypoints) { + 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; + _m[wp.xy].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(_m[wp.xy].m3, 4)) { + wp.spec = StationClass::Get(STAT_CLASS_WAYP)->GetSpec(_m[wp.xy].m4 + 1); } } } else { /* As of version 17, we recalculate the custom graphic ID of waypoints * from the GRF ID / station index. */ - for (OldWaypoint *wp = _old_waypoints.Begin(); wp != _old_waypoints.End(); wp++) { + for (OldWaypoint &wp : _old_waypoints) { StationClass* stclass = StationClass::Get(STAT_CLASS_WAYP); for (uint i = 0; i < stclass->GetSpecCount(); i++) { const StationSpec *statspec = stclass->GetSpec(i); - if (statspec != NULL && statspec->grf_prop.grffile->grfid == wp->grfid && statspec->grf_prop.local_id == wp->localidx) { - wp->spec = statspec; + if (statspec != nullptr && statspec->grf_prop.grffile->grfid == wp.grfid && statspec->grf_prop.local_id == wp.localidx) { + wp.spec = statspec; break; } } } } - if (!Waypoint::CanAllocateItem(_old_waypoints.Length())) SlError(STR_ERROR_TOO_MANY_STATIONS_LOADING); + if (!Waypoint::CanAllocateItem(_old_waypoints.size())) SlError(STR_ERROR_TOO_MANY_STATIONS_LOADING); /* All saveload conversions have been done. Create the new waypoints! */ - for (OldWaypoint *wp = _old_waypoints.Begin(); wp != _old_waypoints.End(); wp++) { - Waypoint *new_wp = new Waypoint(wp->xy); - new_wp->town = wp->town; - new_wp->town_cn = wp->town_cn; - new_wp->name = wp->name; - new_wp->delete_ctr = 0; // Just reset delete counter for once. - new_wp->build_date = wp->build_date; - new_wp->owner = wp->owner; - - new_wp->string_id = STR_SV_STNAME_WAYPOINT; - - TileIndex t = wp->xy; - if (IsTileType(t, MP_RAILWAY) && GetRailTileType(t) == 2 /* RAIL_TILE_WAYPOINT */ && _m[t].m2 == wp->index) { - /* The tile might've been reserved! */ - bool reserved = !IsSavegameVersionBefore(SLV_100) && HasBit(_m[t].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)); - new_wp->facilities |= FACIL_TRAIN; - new_wp->owner = GetTileOwner(t); - - SetRailStationReservation(t, reserved); - - if (wp->spec != NULL) { - SetCustomStationSpecIndex(t, AllocateSpecToStation(wp->spec, new_wp, true)); + for (OldWaypoint &wp : _old_waypoints) { + 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) { + DEBUG(sl, 0, "Found waypoint tile %u 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) { + DEBUG(sl, 0, "Found actual waypoint position at %u", t); + break; + } } - new_wp->rect.BeforeAddTile(t, StationRect::ADD_FORCE); + } + if (t == MapSize()) { + SlErrorCorrupt("Waypoint with invalid tile"); } - wp->new_index = new_wp->index; + Waypoint *new_wp = new Waypoint(t); + new_wp->town = wp.town; + new_wp->town_cn = wp.town_cn; + new_wp->name = wp.name; + new_wp->delete_ctr = 0; // Just reset delete counter for once. + new_wp->build_date = wp.build_date; + new_wp->owner = wp.owner; + new_wp->string_id = STR_SV_STNAME_WAYPOINT; + + /* The tile might've been reserved! */ + bool reserved = !IsSavegameVersionBefore(SLV_100) && HasBit(_m[t].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)); + new_wp->facilities |= FACIL_TRAIN; + new_wp->owner = GetTileOwner(t); + + SetRailStationReservation(t, reserved); + + if (wp.spec != nullptr) { + SetCustomStationSpecIndex(t, AllocateSpecToStation(wp.spec, new_wp, true)); + } + new_wp->rect.BeforeAddTile(t, StationRect::ADD_FORCE); + + wp.new_index = new_wp->index; } /* Update the orders of vehicles */ - OrderList *ol; - FOR_ALL_ORDER_LISTS(ol) { + for (OrderList *ol : OrderList::Iterate()) { if (ol->GetFirstSharedVehicle()->type != VEH_TRAIN) continue; - for (Order *o = ol->GetFirstOrder(); o != NULL; o = o->next) UpdateWaypointOrder(o); + for (Order *o = ol->GetFirstOrder(); o != nullptr; o = o->next) UpdateWaypointOrder(o); } - Vehicle *v; - FOR_ALL_VEHICLES(v) { + for (Vehicle *v : Vehicle::Iterate()) { if (v->type != VEH_TRAIN) continue; UpdateWaypointOrder(&v->current_order); } - _old_waypoints.Reset(); + ResetOldWaypoints(); +} + +void ResetOldWaypoints() +{ + _old_waypoints.clear(); + _old_waypoints.shrink_to_fit(); } static const SaveLoad _old_waypoint_desc[] = { @@ -172,12 +187,13 @@ static const SaveLoad _old_waypoint_desc[] = { static void Load_WAYP() { /* Precaution for when loading failed and it didn't get cleared */ - _old_waypoints.Clear(); + ResetOldWaypoints(); int index; while ((index = SlIterateArray()) != -1) { - OldWaypoint *wp = _old_waypoints.Append(); + /*C++17: OldWaypoint *wp = &*/ _old_waypoints.emplace_back(); + OldWaypoint *wp = &_old_waypoints.back(); memset(wp, 0, sizeof(*wp)); wp->index = index; @@ -187,31 +203,31 @@ static void Load_WAYP() static void Ptrs_WAYP() { - for (OldWaypoint *wp = _old_waypoints.Begin(); wp != _old_waypoints.End(); wp++) { - SlObject(wp, _old_waypoint_desc); + for (OldWaypoint &wp : _old_waypoints) { + SlObject(&wp, _old_waypoint_desc); if (IsSavegameVersionBefore(SLV_12)) { - wp->town_cn = (wp->string_id & 0xC000) == 0xC000 ? (wp->string_id >> 8) & 0x3F : 0; - wp->town = ClosestTownFromTile(wp->xy, UINT_MAX); + wp.town_cn = (wp.string_id & 0xC000) == 0xC000 ? (wp.string_id >> 8) & 0x3F : 0; + wp.town = ClosestTownFromTile(wp.xy, UINT_MAX); } else if (IsSavegameVersionBefore(SLV_122)) { /* Only for versions 12 .. 122 */ - if (!Town::IsValidID(wp->town_index)) { + if (!Town::IsValidID(wp.town_index)) { /* Upon a corrupted waypoint we'll likely get here. The next step will be to - * loop over all Ptrs procs to NULL the pointers. However, we don't know - * whether we're in the NULL or "normal" Ptrs proc. So just clear the list + * loop over all Ptrs procs to nullptr the pointers. However, we don't know + * whether we're in the nullptr or "normal" Ptrs proc. So just clear the list * of old waypoints we constructed and then this waypoint (and the other - * possibly corrupt ones) will not be queried in the NULL Ptrs proc run. */ - _old_waypoints.Clear(); + * possibly corrupt ones) will not be queried in the nullptr Ptrs proc run. */ + _old_waypoints.clear(); SlErrorCorrupt("Referencing invalid Town"); } - wp->town = Town::Get(wp->town_index); + wp.town = Town::Get(wp.town_index); } if (IsSavegameVersionBefore(SLV_84)) { - wp->name = CopyFromOldName(wp->string_id); + wp.name = CopyFromOldName(wp.string_id); } } } extern const ChunkHandler _waypoint_chunk_handlers[] = { - { 'CHKP', NULL, Load_WAYP, Ptrs_WAYP, NULL, CH_ARRAY | CH_LAST}, + { 'CHKP', nullptr, Load_WAYP, Ptrs_WAYP, nullptr, CH_ARRAY | CH_LAST}, }; diff --git a/src/screenshot.cpp b/src/screenshot.cpp index f413ec149c..b2e534d1d2 100644 --- a/src/screenshot.cpp +++ b/src/screenshot.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. @@ -18,6 +16,7 @@ #include "zoom_func.h" #include "core/endian_func.hpp" #include "saveload/saveload.h" +#include "company_base.h" #include "company_func.h" #include "strings_func.h" #include "error.h" @@ -69,6 +68,8 @@ struct ScreenshotFormat { ScreenshotHandlerProc *proc; ///< Function for writing the screenshot. }; +#define MKCOLOUR(x) TO_LE32X(x) + /************************************************* **** SCREENSHOT CODE FOR WINDOWS BITMAP (.BMP) *************************************************/ @@ -121,7 +122,7 @@ static bool MakeBMPImage(const char *name, ScreenshotCallback *callb, void *user } FILE *f = fopen(name, "wb"); - if (f == NULL) return false; + if (f == nullptr) return false; /* Each scanline must be aligned on a 32bit boundary */ uint bytewidth = Align(w * bpp, 4); // bytes per line in file @@ -270,18 +271,18 @@ static bool MakePNGImage(const char *name, ScreenshotCallback *callb, void *user if (pixelformat == 16) bpp = 3; f = fopen(name, "wb"); - if (f == NULL) return false; + if (f == nullptr) return false; png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING, const_cast(name), png_my_error, png_my_warning); - if (png_ptr == NULL) { + if (png_ptr == nullptr) { fclose(f); return false; } info_ptr = png_create_info_struct(png_ptr); - if (info_ptr == NULL) { - png_destroy_write_struct(&png_ptr, (png_infopp)NULL); + if (info_ptr == nullptr) { + png_destroy_write_struct(&png_ptr, (png_infopp)nullptr); fclose(f); return false; } @@ -313,15 +314,14 @@ static bool MakePNGImage(const char *name, ScreenshotCallback *callb, void *user char *p = buf; p += seprintf(p, lastof(buf), "Graphics set: %s (%u)\n", BaseGraphics::GetUsedSet()->name, BaseGraphics::GetUsedSet()->version); p = strecpy(p, "NewGRFs:\n", lastof(buf)); - for (const GRFConfig *c = _game_mode == GM_MENU ? NULL : _grfconfig; c != NULL; c = c->next) { + for (const GRFConfig *c = _game_mode == GM_MENU ? nullptr : _grfconfig; c != nullptr; c = c->next) { p += seprintf(p, lastof(buf), "%08X ", BSWAP32(c->ident.grfid)); p = md5sumToString(p, lastof(buf), c->ident.md5sum); p += seprintf(p, lastof(buf), " %s\n", c->filename); } p = strecpy(p, "\nCompanies:\n", lastof(buf)); - const Company *c; - FOR_ALL_COMPANIES(c) { - if (c->ai_info == NULL) { + for (const Company *c : Company::Iterate()) { + if (c->ai_info == nullptr) { p += seprintf(p, lastof(buf), "%2i: Human\n", (int)c->index); } else { p += seprintf(p, lastof(buf), "%2i: %s (v%d)\n", (int)c->index, c->ai_info->GetName(), c->ai_info->GetVersion()); @@ -460,7 +460,7 @@ static bool MakePCXImage(const char *name, ScreenshotCallback *callb, void *user if (pixelformat != 8 || w == 0) return false; f = fopen(name, "wb"); - if (f == NULL) return false; + if (f == nullptr) return false; memset(&pcx, 0, sizeof(pcx)); @@ -714,7 +714,7 @@ static const char *MakeScreenshotName(const char *default_fn, const char *ext, b static bool MakeSmallScreenshot(bool crashlog) { const ScreenshotFormat *sf = _screenshot_formats + _cur_screenshot_format; - return sf->proc(MakeScreenshotName(SCREENSHOT_NAME, sf->extension, crashlog), CurrentScreenCallback, NULL, _screen.width, _screen.height, + return sf->proc(MakeScreenshotName(SCREENSHOT_NAME, sf->extension, crashlog), CurrentScreenCallback, nullptr, _screen.width, _screen.height, BlitterFactory::GetCurrentBlitter()->GetScreenDepth(), _cur_palette.palette); } @@ -725,38 +725,66 @@ static bool MakeSmallScreenshot(bool crashlog) */ void SetupScreenshotViewport(ScreenshotType t, ViewPort *vp) { - /* Determine world coordinates of screenshot */ - if (t == SC_WORLD) { - vp->zoom = ZOOM_LVL_WORLD_SCREENSHOT; + switch(t) { + case SC_VIEWPORT: + case SC_CRASHLOG: { + Window *w = FindWindowById(WC_MAIN_WINDOW, 0); + vp->virtual_left = w->viewport->virtual_left; + vp->virtual_top = w->viewport->virtual_top; + vp->virtual_width = w->viewport->virtual_width; + vp->virtual_height = w->viewport->virtual_height; - TileIndex north_tile = _settings_game.construction.freeform_edges ? TileXY(1, 1) : TileXY(0, 0); - TileIndex south_tile = MapSize() - 1; + /* Compute pixel coordinates */ + vp->left = 0; + vp->top = 0; + vp->width = _screen.width; + vp->height = _screen.height; + vp->overlay = w->viewport->overlay; + break; + } + case SC_WORLD: { + /* Determine world coordinates of screenshot */ + vp->zoom = ZOOM_LVL_WORLD_SCREENSHOT; - /* We need to account for a hill or high building at tile 0,0. */ - int extra_height_top = TilePixelHeight(north_tile) + 150; - /* If there is a hill at the bottom don't create a large black area. */ - int reclaim_height_bottom = TilePixelHeight(south_tile); + TileIndex north_tile = _settings_game.construction.freeform_edges ? TileXY(1, 1) : TileXY(0, 0); + TileIndex south_tile = MapSize() - 1; - vp->virtual_left = RemapCoords(TileX(south_tile) * TILE_SIZE, TileY(north_tile) * TILE_SIZE, 0).x; - vp->virtual_top = RemapCoords(TileX(north_tile) * TILE_SIZE, TileY(north_tile) * TILE_SIZE, extra_height_top).y; - vp->virtual_width = RemapCoords(TileX(north_tile) * TILE_SIZE, TileY(south_tile) * TILE_SIZE, 0).x - vp->virtual_left + 1; - vp->virtual_height = RemapCoords(TileX(south_tile) * TILE_SIZE, TileY(south_tile) * TILE_SIZE, reclaim_height_bottom).y - vp->virtual_top + 1; - } else { - vp->zoom = (t == SC_ZOOMEDIN) ? _settings_client.gui.zoom_min : ZOOM_LVL_VIEWPORT; + /* We need to account for a hill or high building at tile 0,0. */ + int extra_height_top = TilePixelHeight(north_tile) + 150; + /* If there is a hill at the bottom don't create a large black area. */ + int reclaim_height_bottom = TilePixelHeight(south_tile); - Window *w = FindWindowById(WC_MAIN_WINDOW, 0); - vp->virtual_left = w->viewport->virtual_left; - vp->virtual_top = w->viewport->virtual_top; - vp->virtual_width = w->viewport->virtual_width; - vp->virtual_height = w->viewport->virtual_height; + vp->virtual_left = RemapCoords(TileX(south_tile) * TILE_SIZE, TileY(north_tile) * TILE_SIZE, 0).x; + vp->virtual_top = RemapCoords(TileX(north_tile) * TILE_SIZE, TileY(north_tile) * TILE_SIZE, extra_height_top).y; + vp->virtual_width = RemapCoords(TileX(north_tile) * TILE_SIZE, TileY(south_tile) * TILE_SIZE, 0).x - vp->virtual_left + 1; + vp->virtual_height = RemapCoords(TileX(south_tile) * TILE_SIZE, TileY(south_tile) * TILE_SIZE, reclaim_height_bottom).y - vp->virtual_top + 1; + + /* Compute pixel coordinates */ + vp->left = 0; + vp->top = 0; + vp->width = UnScaleByZoom(vp->virtual_width, vp->zoom); + vp->height = UnScaleByZoom(vp->virtual_height, vp->zoom); + vp->overlay = nullptr; + break; + } + default: { + vp->zoom = (t == SC_ZOOMEDIN) ? _settings_client.gui.zoom_min : ZOOM_LVL_VIEWPORT; + + Window *w = FindWindowById(WC_MAIN_WINDOW, 0); + vp->virtual_left = w->viewport->virtual_left; + vp->virtual_top = w->viewport->virtual_top; + vp->virtual_width = w->viewport->virtual_width; + vp->virtual_height = w->viewport->virtual_height; + + /* Compute pixel coordinates */ + vp->left = 0; + vp->top = 0; + vp->width = UnScaleByZoom(vp->virtual_width, vp->zoom); + vp->height = UnScaleByZoom(vp->virtual_height, vp->zoom); + vp->overlay = nullptr; + break; + } } - - /* Compute pixel coordinates */ - vp->left = 0; - vp->top = 0; - vp->width = UnScaleByZoom(vp->virtual_width, vp->zoom); - vp->height = UnScaleByZoom(vp->virtual_height, vp->zoom); - vp->overlay = NULL; } /** @@ -813,7 +841,7 @@ bool MakeHeightmapScreenshot(const char *filename) palette[i].b = i; } const ScreenshotFormat *sf = _screenshot_formats + _cur_screenshot_format; - return sf->proc(filename, HeightmapCallback, NULL, MapSizeX(), MapSizeY(), 8, palette); + return sf->proc(filename, HeightmapCallback, nullptr, MapSizeX(), MapSizeY(), 8, palette); } /** @@ -834,7 +862,7 @@ bool MakeScreenshot(ScreenshotType t, const char *name) } _screenshot_name[0] = '\0'; - if (name != NULL) strecpy(_screenshot_name, name, lastof(_screenshot_name)); + if (name != nullptr) strecpy(_screenshot_name, name, lastof(_screenshot_name)); bool ret; switch (t) { @@ -858,6 +886,10 @@ bool MakeScreenshot(ScreenshotType t, const char *name) break; } + case SC_MINIMAP: + ret = MakeMinimapWorldScreenshot(); + break; + default: NOT_REACHED(); } @@ -871,3 +903,75 @@ bool MakeScreenshot(ScreenshotType t, const char *name) return ret; } + + +/** + * 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); + + TileIndex tile = TileXY(col, row); + Owner o = GetMinimapOwner(tile); + byte val = owner_colours[o]; + + uint32 colour_buf = 0; + colour_buf = (_cur_palette.palette[val].b << 0); + colour_buf |= (_cur_palette.palette[val].g << 8); + colour_buf |= (_cur_palette.palette[val].r << 16); + + *ubuf = colour_buf; + ubuf++; // Skip alpha + } +} + +/** + * Make a minimap screenshot. + */ +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); +} diff --git a/src/screenshot.h b/src/screenshot.h index ee03d8aff7..aea08a8d5f 100644 --- a/src/screenshot.h +++ b/src/screenshot.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. @@ -24,11 +22,13 @@ enum ScreenshotType { SC_DEFAULTZOOM, ///< Zoomed to default zoom level screenshot of the visible area. SC_WORLD, ///< World screenshot. SC_HEIGHTMAP, ///< Heightmap of the world. + SC_MINIMAP, ///< Minimap screenshot. }; void SetupScreenshotViewport(ScreenshotType t, struct ViewPort *vp); bool MakeHeightmapScreenshot(const char *filename); bool MakeScreenshot(ScreenshotType t, const char *name); +bool MakeMinimapWorldScreenshot(); extern char _screenshot_format_name[8]; extern uint _num_screenshot_formats; diff --git a/src/screenshot_gui.cpp b/src/screenshot_gui.cpp new file mode 100644 index 0000000000..3230020245 --- /dev/null +++ b/src/screenshot_gui.cpp @@ -0,0 +1,108 @@ +/* + * 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 screenshot_gui.cpp GUI functions related to screenshots. */ + +#include "stdafx.h" +#include "gui.h" +#include "viewport_func.h" +#include "window_func.h" +#include "window_gui.h" +#include "screenshot.h" +#include "textbuf_gui.h" +#include "strings_func.h" + +#include "widgets/screenshot_widget.h" + +#include "table/strings.h" + +static ScreenshotType _screenshot_type; + +struct ScreenshotWindow : Window { + ScreenshotWindow(WindowDesc *desc) : Window(desc) { + this->CreateNestedTree(); + this->FinishInitNested(); + } + + void OnPaint() override { + this->DrawWidgets(); + } + + void OnClick(Point pt, int widget, int click_count) override { + if (widget < 0) return; + ScreenshotType st; + switch (widget) { + default: + case WID_SC_TAKE: st = SC_VIEWPORT; break; + case WID_SC_TAKE_ZOOMIN: st = SC_ZOOMEDIN; break; + case WID_SC_TAKE_DEFAULTZOOM: st = SC_DEFAULTZOOM; break; + case WID_SC_TAKE_WORLD: st = SC_WORLD; break; + case WID_SC_TAKE_HEIGHTMAP: st = SC_HEIGHTMAP; break; + case WID_SC_TAKE_MINIMAP: st = SC_MINIMAP; break; + } + TakeScreenshot(st); + } + + /** + * Make a screenshot. + * Ask for confirmation if the screenshot will be huge. + * @param t Screenshot type: World, defaultzoom, heightmap or viewport screenshot + */ + static void TakeScreenshot(ScreenshotType st) { + ViewPort vp; + SetupScreenshotViewport(st, &vp); + if ((uint64)vp.width * (uint64)vp.height > 8192 * 8192) { + /* Ask for confirmation */ + _screenshot_type = st; + SetDParam(0, vp.width); + SetDParam(1, vp.height); + ShowQuery(STR_WARNING_SCREENSHOT_SIZE_CAPTION, STR_WARNING_SCREENSHOT_SIZE_MESSAGE, nullptr, ScreenshotConfirmationCallback); + } + else { + /* Less than 64M pixels, just do it */ + MakeScreenshot(st, nullptr); + } + } + + /** + * Callback on the confirmation window for huge screenshots. + * @param w Window with viewport + * @param confirmed true on confirmation + */ + static void ScreenshotConfirmationCallback(Window *w, bool confirmed) { + if (confirmed) MakeScreenshot(_screenshot_type, nullptr); + } +}; + +static const NWidgetPart _nested_screenshot[] = { + NWidget(NWID_HORIZONTAL), + NWidget(WWT_CLOSEBOX, COLOUR_GREY), + NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_SCREENSHOT_CAPTION, 0), + NWidget(WWT_SHADEBOX, COLOUR_GREY), + NWidget(WWT_STICKYBOX, COLOUR_GREY), + EndContainer(), + NWidget(NWID_VERTICAL, NC_EQUALSIZE), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SC_TAKE), SetFill(1, 1), SetDataTip(STR_SCREENSHOT_SCREENSHOT, 0), SetMinimalTextLines(2, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SC_TAKE_ZOOMIN), SetFill(1, 1), SetDataTip(STR_SCREENSHOT_ZOOMIN_SCREENSHOT, 0), SetMinimalTextLines(2, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SC_TAKE_DEFAULTZOOM), SetFill(1, 1), SetDataTip(STR_SCREENSHOT_DEFAULTZOOM_SCREENSHOT, 0), SetMinimalTextLines(2, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SC_TAKE_WORLD), SetFill(1, 1), SetDataTip(STR_SCREENSHOT_WORLD_SCREENSHOT, 0), SetMinimalTextLines(2, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SC_TAKE_HEIGHTMAP), SetFill(1, 1), SetDataTip(STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT, 0), SetMinimalTextLines(2, 0), + NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SC_TAKE_MINIMAP), SetFill(1, 1), SetDataTip(STR_SCREENSHOT_MINIMAP_SCREENSHOT, 0), SetMinimalTextLines(2, 0), + EndContainer(), +}; + +static WindowDesc _screenshot_window_desc( + WDP_AUTO, "take_a_screenshot", 200, 100, + WC_SCREENSHOT, WC_NONE, + 0, + _nested_screenshot, lengthof(_nested_screenshot) +); + +void ShowScreenshotWindow() { + DeleteWindowById(WC_SCREENSHOT, 0); + new ScreenshotWindow(&_screenshot_window_desc); +} diff --git a/src/screenshot_gui.h b/src/screenshot_gui.h new file mode 100644 index 0000000000..44a395edb1 --- /dev/null +++ b/src/screenshot_gui.h @@ -0,0 +1,15 @@ +/* + * 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 screenshot_gui.h GUI functions related to screenshots. */ + +#ifndef SCREENSHOT_GUI_H +#define SCREENSHOT_GUI_H + +void ShowScreenshotWindow(); + +#endif /* SCREENSHOT_GUI_H */ diff --git a/src/script/api/Doxyfile_AI b/src/script/api/Doxyfile_AI index 568859bff8..d882599152 100644 --- a/src/script/api/Doxyfile_AI +++ b/src/script/api/Doxyfile_AI @@ -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. # 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. @@ -11,8 +9,8 @@ # Project related configuration options #--------------------------------------------------------------------------- DOXYFILE_ENCODING = UTF-8 -PROJECT_NAME = "OpenTTD NoAI API" -PROJECT_NUMBER = +PROJECT_NAME = "OpenTTD AI API" +PROJECT_NUMBER = $(VERSION) OUTPUT_DIRECTORY = ../../../docs/aidocs/ CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English diff --git a/src/script/api/Doxyfile_Game b/src/script/api/Doxyfile_Game index 1edfe42c7b..99b2ab05eb 100644 --- a/src/script/api/Doxyfile_Game +++ b/src/script/api/Doxyfile_Game @@ -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. # 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. @@ -11,8 +9,8 @@ # Project related configuration options #--------------------------------------------------------------------------- DOXYFILE_ENCODING = UTF-8 -PROJECT_NAME = "OpenTTD Game API" -PROJECT_NUMBER = +PROJECT_NAME = "OpenTTD GameScript API" +PROJECT_NUMBER = $(VERSION) OUTPUT_DIRECTORY = ../../../docs/gamedocs/ CREATE_SUBDIRS = NO OUTPUT_LANGUAGE = English diff --git a/src/script/api/ai/ai_accounting.hpp.sq b/src/script/api/ai/ai_accounting.hpp.sq index fd68e4e7e7..d2bfbb04f5 100644 --- a/src/script/api/ai/ai_accounting.hpp.sq +++ b/src/script/api/ai/ai_accounting.hpp.sq @@ -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/script/api/ai/ai_airport.hpp.sq b/src/script/api/ai/ai_airport.hpp.sq index 89e7ba1258..2d7daeef73 100644 --- a/src/script/api/ai/ai_airport.hpp.sq +++ b/src/script/api/ai/ai_airport.hpp.sq @@ -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/script/api/ai/ai_base.hpp.sq b/src/script/api/ai/ai_base.hpp.sq index 68cc4a58e2..a03566b4e3 100644 --- a/src/script/api/ai/ai_base.hpp.sq +++ b/src/script/api/ai/ai_base.hpp.sq @@ -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/script/api/ai/ai_basestation.hpp.sq b/src/script/api/ai/ai_basestation.hpp.sq index 42cc184609..13a351b8ea 100644 --- a/src/script/api/ai/ai_basestation.hpp.sq +++ b/src/script/api/ai/ai_basestation.hpp.sq @@ -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/script/api/ai/ai_bridge.hpp.sq b/src/script/api/ai/ai_bridge.hpp.sq index 9a9b223009..0d026673f9 100644 --- a/src/script/api/ai/ai_bridge.hpp.sq +++ b/src/script/api/ai/ai_bridge.hpp.sq @@ -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/script/api/ai/ai_bridgelist.hpp.sq b/src/script/api/ai/ai_bridgelist.hpp.sq index b5618e3337..35d33f544a 100644 --- a/src/script/api/ai/ai_bridgelist.hpp.sq +++ b/src/script/api/ai/ai_bridgelist.hpp.sq @@ -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/script/api/ai/ai_cargo.hpp.sq b/src/script/api/ai/ai_cargo.hpp.sq index 6478d44b81..119328e411 100644 --- a/src/script/api/ai/ai_cargo.hpp.sq +++ b/src/script/api/ai/ai_cargo.hpp.sq @@ -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/script/api/ai/ai_cargolist.hpp.sq b/src/script/api/ai/ai_cargolist.hpp.sq index cc1bbc6a28..d1c1b0b981 100644 --- a/src/script/api/ai/ai_cargolist.hpp.sq +++ b/src/script/api/ai/ai_cargolist.hpp.sq @@ -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/script/api/ai/ai_company.hpp.sq b/src/script/api/ai/ai_company.hpp.sq index ecab99c915..156b6fcb70 100644 --- a/src/script/api/ai/ai_company.hpp.sq +++ b/src/script/api/ai/ai_company.hpp.sq @@ -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/script/api/ai/ai_controller.hpp.sq b/src/script/api/ai/ai_controller.hpp.sq index 2aefdd68ef..ba1cc3fa57 100644 --- a/src/script/api/ai/ai_controller.hpp.sq +++ b/src/script/api/ai/ai_controller.hpp.sq @@ -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/script/api/ai/ai_date.hpp.sq b/src/script/api/ai/ai_date.hpp.sq index 7bdf9519d6..2f98a29189 100644 --- a/src/script/api/ai/ai_date.hpp.sq +++ b/src/script/api/ai/ai_date.hpp.sq @@ -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/script/api/ai/ai_depotlist.hpp.sq b/src/script/api/ai/ai_depotlist.hpp.sq index 528683ce37..72668a4d7f 100644 --- a/src/script/api/ai/ai_depotlist.hpp.sq +++ b/src/script/api/ai/ai_depotlist.hpp.sq @@ -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/script/api/ai/ai_engine.hpp.sq b/src/script/api/ai/ai_engine.hpp.sq index 6dbde29099..fa49f919d6 100644 --- a/src/script/api/ai/ai_engine.hpp.sq +++ b/src/script/api/ai/ai_engine.hpp.sq @@ -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. @@ -41,6 +39,8 @@ void SQAIEngine_Register(Squirrel *engine) SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::IsWagon, "IsWagon", 2, ".i"); SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::CanRunOnRail, "CanRunOnRail", 3, ".ii"); SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::HasPowerOnRail, "HasPowerOnRail", 3, ".ii"); + SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::CanRunOnRoad, "CanRunOnRoad", 3, ".ii"); + SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::HasPowerOnRoad, "HasPowerOnRoad", 3, ".ii"); SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::GetRoadType, "GetRoadType", 2, ".i"); SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::GetRailType, "GetRailType", 2, ".i"); SQAIEngine.DefSQStaticMethod(engine, &ScriptEngine::IsArticulated, "IsArticulated", 2, ".i"); diff --git a/src/script/api/ai/ai_enginelist.hpp.sq b/src/script/api/ai/ai_enginelist.hpp.sq index 8ddc2e7ad1..1c1c4cfedb 100644 --- a/src/script/api/ai/ai_enginelist.hpp.sq +++ b/src/script/api/ai/ai_enginelist.hpp.sq @@ -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/script/api/ai/ai_error.hpp.sq b/src/script/api/ai/ai_error.hpp.sq index 54636d3a1f..792a21f1d8 100644 --- a/src/script/api/ai/ai_error.hpp.sq +++ b/src/script/api/ai/ai_error.hpp.sq @@ -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. @@ -58,8 +56,10 @@ void SQAIError_Register(Squirrel *engine) ScriptError::RegisterErrorMap(STR_ERROR_NOT_ENOUGH_CASH_REQUIRES_CURRENCY, ScriptError::ERR_NOT_ENOUGH_CASH); ScriptError::RegisterErrorMap(STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS, ScriptError::ERR_LOCAL_AUTHORITY_REFUSES); + ScriptError::RegisterErrorMap(STR_ERROR_LOCAL_AUTHORITY_REFUSES_NOISE, ScriptError::ERR_LOCAL_AUTHORITY_REFUSES); ScriptError::RegisterErrorMap(STR_ERROR_ALREADY_BUILT, ScriptError::ERR_ALREADY_BUILT); ScriptError::RegisterErrorMap(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST, ScriptError::ERR_ALREADY_BUILT); + ScriptError::RegisterErrorMap(STR_ERROR_TREE_ALREADY_HERE, ScriptError::ERR_ALREADY_BUILT); ScriptError::RegisterErrorMap(STR_ERROR_BUILDING_MUST_BE_DEMOLISHED, ScriptError::ERR_AREA_NOT_CLEAR); ScriptError::RegisterErrorMap(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST, ScriptError::ERR_AREA_NOT_CLEAR); ScriptError::RegisterErrorMap(STR_ERROR_MUST_DEMOLISH_RAILROAD, ScriptError::ERR_AREA_NOT_CLEAR); @@ -88,6 +88,7 @@ void SQAIError_Register(Squirrel *engine) ScriptError::RegisterErrorMap(STR_ERROR_SHIP_IN_THE_WAY, ScriptError::ERR_VEHICLE_IN_THE_WAY); ScriptError::RegisterErrorMap(STR_ERROR_AIRCRAFT_IN_THE_WAY, ScriptError::ERR_VEHICLE_IN_THE_WAY); ScriptError::RegisterErrorMap(STR_ERROR_SITE_UNSUITABLE, ScriptError::ERR_SITE_UNSUITABLE); + ScriptError::RegisterErrorMap(STR_ERROR_TREE_WRONG_TERRAIN_FOR_TREE_TYPE, ScriptError::ERR_SITE_UNSUITABLE); ScriptError::RegisterErrorMap(STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP, ScriptError::ERR_TOO_CLOSE_TO_EDGE); ScriptError::RegisterErrorMap(STR_ERROR_STATION_TOO_SPREAD_OUT, ScriptError::ERR_STATION_TOO_SPREAD_OUT); diff --git a/src/script/api/ai/ai_event.hpp.sq b/src/script/api/ai/ai_event.hpp.sq index 75098625a3..6061eeed52 100644 --- a/src/script/api/ai/ai_event.hpp.sq +++ b/src/script/api/ai/ai_event.hpp.sq @@ -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,6 +48,7 @@ void SQAIEvent_Register(Squirrel *engine) SQAIEvent.DefSQConst(engine, ScriptEvent::ET_GOAL_QUESTION_ANSWER, "ET_GOAL_QUESTION_ANSWER"); SQAIEvent.DefSQConst(engine, ScriptEvent::ET_EXCLUSIVE_TRANSPORT_RIGHTS, "ET_EXCLUSIVE_TRANSPORT_RIGHTS"); SQAIEvent.DefSQConst(engine, ScriptEvent::ET_ROAD_RECONSTRUCTION, "ET_ROAD_RECONSTRUCTION"); + SQAIEvent.DefSQConst(engine, ScriptEvent::ET_VEHICLE_AUTOREPLACED, "ET_VEHICLE_AUTOREPLACED"); SQAIEvent.DefSQMethod(engine, &ScriptEvent::GetEventType, "GetEventType", 1, "x"); diff --git a/src/script/api/ai/ai_event_types.hpp.sq b/src/script/api/ai/ai_event_types.hpp.sq index f3468d14ba..21d0b663a1 100644 --- a/src/script/api/ai/ai_event_types.hpp.sq +++ b/src/script/api/ai/ai_event_types.hpp.sq @@ -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. @@ -405,3 +403,19 @@ void SQAIEventRoadReconstruction_Register(Squirrel *engine) SQAIEventRoadReconstruction.PostRegister(engine); } + + +template <> const char *GetClassName() { return "AIEventVehicleAutoReplaced"; } + +void SQAIEventVehicleAutoReplaced_Register(Squirrel *engine) +{ + DefSQClass SQAIEventVehicleAutoReplaced("AIEventVehicleAutoReplaced"); + SQAIEventVehicleAutoReplaced.PreRegister(engine, "AIEvent"); + + SQAIEventVehicleAutoReplaced.DefSQStaticMethod(engine, &ScriptEventVehicleAutoReplaced::Convert, "Convert", 2, ".x"); + + SQAIEventVehicleAutoReplaced.DefSQMethod(engine, &ScriptEventVehicleAutoReplaced::GetOldVehicleID, "GetOldVehicleID", 1, "x"); + SQAIEventVehicleAutoReplaced.DefSQMethod(engine, &ScriptEventVehicleAutoReplaced::GetNewVehicleID, "GetNewVehicleID", 1, "x"); + + SQAIEventVehicleAutoReplaced.PostRegister(engine); +} diff --git a/src/script/api/ai/ai_execmode.hpp.sq b/src/script/api/ai/ai_execmode.hpp.sq index 869f3fe932..fa7d8a2c24 100644 --- a/src/script/api/ai/ai_execmode.hpp.sq +++ b/src/script/api/ai/ai_execmode.hpp.sq @@ -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/script/api/ai/ai_gamesettings.hpp.sq b/src/script/api/ai/ai_gamesettings.hpp.sq index 1459b031d7..e5ff4ce17f 100644 --- a/src/script/api/ai/ai_gamesettings.hpp.sq +++ b/src/script/api/ai/ai_gamesettings.hpp.sq @@ -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/script/api/ai/ai_group.hpp.sq b/src/script/api/ai/ai_group.hpp.sq index 5fa50ae1be..2a221df62a 100644 --- a/src/script/api/ai/ai_group.hpp.sq +++ b/src/script/api/ai/ai_group.hpp.sq @@ -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. @@ -45,6 +43,10 @@ void SQAIGroup_Register(Squirrel *engine) SQAIGroup.DefSQStaticMethod(engine, &ScriptGroup::GetProfitThisYear, "GetProfitThisYear", 2, ".i"); SQAIGroup.DefSQStaticMethod(engine, &ScriptGroup::GetProfitLastYear, "GetProfitLastYear", 2, ".i"); SQAIGroup.DefSQStaticMethod(engine, &ScriptGroup::GetCurrentUsage, "GetCurrentUsage", 2, ".i"); + SQAIGroup.DefSQStaticMethod(engine, &ScriptGroup::SetPrimaryColour, "SetPrimaryColour", 3, ".ii"); + SQAIGroup.DefSQStaticMethod(engine, &ScriptGroup::SetSecondaryColour, "SetSecondaryColour", 3, ".ii"); + SQAIGroup.DefSQStaticMethod(engine, &ScriptGroup::GetPrimaryColour, "GetPrimaryColour", 2, ".i"); + SQAIGroup.DefSQStaticMethod(engine, &ScriptGroup::GetSecondaryColour, "GetSecondaryColour", 2, ".i"); SQAIGroup.PostRegister(engine); } diff --git a/src/script/api/ai/ai_grouplist.hpp.sq b/src/script/api/ai/ai_grouplist.hpp.sq index 9f9f2dab25..3977a92c81 100644 --- a/src/script/api/ai/ai_grouplist.hpp.sq +++ b/src/script/api/ai/ai_grouplist.hpp.sq @@ -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/script/api/ai/ai_industry.hpp.sq b/src/script/api/ai/ai_industry.hpp.sq index 4de03f1dab..833c6a9e80 100644 --- a/src/script/api/ai/ai_industry.hpp.sq +++ b/src/script/api/ai/ai_industry.hpp.sq @@ -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/script/api/ai/ai_industrylist.hpp.sq b/src/script/api/ai/ai_industrylist.hpp.sq index 0ae7e97799..11a4696dc8 100644 --- a/src/script/api/ai/ai_industrylist.hpp.sq +++ b/src/script/api/ai/ai_industrylist.hpp.sq @@ -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/script/api/ai/ai_industrytype.hpp.sq b/src/script/api/ai/ai_industrytype.hpp.sq index 7c56acee9f..1d6648d993 100644 --- a/src/script/api/ai/ai_industrytype.hpp.sq +++ b/src/script/api/ai/ai_industrytype.hpp.sq @@ -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/script/api/ai/ai_industrytypelist.hpp.sq b/src/script/api/ai/ai_industrytypelist.hpp.sq index 6ac836b390..104a78ddf0 100644 --- a/src/script/api/ai/ai_industrytypelist.hpp.sq +++ b/src/script/api/ai/ai_industrytypelist.hpp.sq @@ -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/script/api/ai/ai_infrastructure.hpp.sq b/src/script/api/ai/ai_infrastructure.hpp.sq index 55a1e4743c..f16f4b2810 100644 --- a/src/script/api/ai/ai_infrastructure.hpp.sq +++ b/src/script/api/ai/ai_infrastructure.hpp.sq @@ -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/script/api/ai/ai_list.hpp.sq b/src/script/api/ai/ai_list.hpp.sq index 201113823d..ec66200b5e 100644 --- a/src/script/api/ai/ai_list.hpp.sq +++ b/src/script/api/ai/ai_list.hpp.sq @@ -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/script/api/ai/ai_log.hpp.sq b/src/script/api/ai/ai_log.hpp.sq index 174ac2b929..de86769640 100644 --- a/src/script/api/ai/ai_log.hpp.sq +++ b/src/script/api/ai/ai_log.hpp.sq @@ -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/script/api/ai/ai_map.hpp.sq b/src/script/api/ai/ai_map.hpp.sq index f0f1cbed0c..3280e7f510 100644 --- a/src/script/api/ai/ai_map.hpp.sq +++ b/src/script/api/ai/ai_map.hpp.sq @@ -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/script/api/ai/ai_marine.hpp.sq b/src/script/api/ai/ai_marine.hpp.sq index 843c3d8746..d23fe09992 100644 --- a/src/script/api/ai/ai_marine.hpp.sq +++ b/src/script/api/ai/ai_marine.hpp.sq @@ -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/script/api/ai/ai_order.hpp.sq b/src/script/api/ai/ai_order.hpp.sq index ab25e4810d..19664ee1eb 100644 --- a/src/script/api/ai/ai_order.hpp.sq +++ b/src/script/api/ai/ai_order.hpp.sq @@ -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/script/api/ai/ai_rail.hpp.sq b/src/script/api/ai/ai_rail.hpp.sq index ba9d7e6564..f7de00cffd 100644 --- a/src/script/api/ai/ai_rail.hpp.sq +++ b/src/script/api/ai/ai_rail.hpp.sq @@ -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. @@ -56,7 +54,7 @@ void SQAIRail_Register(Squirrel *engine) ScriptError::RegisterErrorMap(STR_ERROR_THERE_IS_NO_RAILROAD_TRACK, ScriptRail::ERR_UNSUITABLE_TRACK); ScriptError::RegisterErrorMap(STR_ERROR_THERE_ARE_NO_SIGNALS, ScriptRail::ERR_UNSUITABLE_TRACK); ScriptError::RegisterErrorMap(STR_ERROR_THERE_IS_NO_STATION, ScriptRail::ERR_UNSUITABLE_TRACK); - ScriptError::RegisterErrorMap(STR_ERROR_CROSSING_DISALLOWED, ScriptRail::ERR_RAILTYPE_DISALLOWS_CROSSING); + ScriptError::RegisterErrorMap(STR_ERROR_CROSSING_DISALLOWED_RAIL, ScriptRail::ERR_RAILTYPE_DISALLOWS_CROSSING); ScriptError::RegisterErrorMapString(ScriptRail::ERR_CROSSING_ON_ONEWAY_ROAD, "ERR_CROSSING_ON_ONEWAY_ROAD"); ScriptError::RegisterErrorMapString(ScriptRail::ERR_UNSUITABLE_TRACK, "ERR_UNSUITABLE_TRACK"); diff --git a/src/script/api/ai/ai_railtypelist.hpp.sq b/src/script/api/ai/ai_railtypelist.hpp.sq index 0f05df239a..b676f6e8fe 100644 --- a/src/script/api/ai/ai_railtypelist.hpp.sq +++ b/src/script/api/ai/ai_railtypelist.hpp.sq @@ -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/script/api/ai/ai_road.hpp.sq b/src/script/api/ai/ai_road.hpp.sq index 3da4607c90..99b1d1dd0b 100644 --- a/src/script/api/ai/ai_road.hpp.sq +++ b/src/script/api/ai/ai_road.hpp.sq @@ -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. @@ -26,9 +24,13 @@ void SQAIRoad_Register(Squirrel *engine) SQAIRoad.DefSQConst(engine, ScriptRoad::ERR_ROAD_DRIVE_THROUGH_WRONG_DIRECTION, "ERR_ROAD_DRIVE_THROUGH_WRONG_DIRECTION"); SQAIRoad.DefSQConst(engine, ScriptRoad::ERR_ROAD_CANNOT_BUILD_ON_TOWN_ROAD, "ERR_ROAD_CANNOT_BUILD_ON_TOWN_ROAD"); SQAIRoad.DefSQConst(engine, ScriptRoad::ERR_ROAD_ONE_WAY_ROADS_CANNOT_HAVE_JUNCTIONS, "ERR_ROAD_ONE_WAY_ROADS_CANNOT_HAVE_JUNCTIONS"); + SQAIRoad.DefSQConst(engine, ScriptRoad::ERR_ROADTYPE_DISALLOWS_CROSSING, "ERR_ROADTYPE_DISALLOWS_CROSSING"); + SQAIRoad.DefSQConst(engine, ScriptRoad::ERR_UNSUITABLE_ROAD, "ERR_UNSUITABLE_ROAD"); SQAIRoad.DefSQConst(engine, ScriptRoad::ROADTYPE_ROAD, "ROADTYPE_ROAD"); SQAIRoad.DefSQConst(engine, ScriptRoad::ROADTYPE_TRAM, "ROADTYPE_TRAM"); SQAIRoad.DefSQConst(engine, ScriptRoad::ROADTYPE_INVALID, "ROADTYPE_INVALID"); + SQAIRoad.DefSQConst(engine, ScriptRoad::ROADTRAMTYPES_ROAD, "ROADTRAMTYPES_ROAD"); + SQAIRoad.DefSQConst(engine, ScriptRoad::ROADTRAMTYPES_TRAM, "ROADTRAMTYPES_TRAM"); SQAIRoad.DefSQConst(engine, ScriptRoad::ROADVEHTYPE_BUS, "ROADVEHTYPE_BUS"); SQAIRoad.DefSQConst(engine, ScriptRoad::ROADVEHTYPE_TRUCK, "ROADVEHTYPE_TRUCK"); SQAIRoad.DefSQConst(engine, ScriptRoad::BT_ROAD, "BT_ROAD"); @@ -40,12 +42,19 @@ void SQAIRoad_Register(Squirrel *engine) ScriptError::RegisterErrorMap(STR_ERROR_DRIVE_THROUGH_DIRECTION, ScriptRoad::ERR_ROAD_DRIVE_THROUGH_WRONG_DIRECTION); ScriptError::RegisterErrorMap(STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD, ScriptRoad::ERR_ROAD_CANNOT_BUILD_ON_TOWN_ROAD); ScriptError::RegisterErrorMap(STR_ERROR_ONEWAY_ROADS_CAN_T_HAVE_JUNCTION, ScriptRoad::ERR_ROAD_ONE_WAY_ROADS_CANNOT_HAVE_JUNCTIONS); + ScriptError::RegisterErrorMap(STR_ERROR_CROSSING_DISALLOWED_ROAD, ScriptRoad::ERR_ROADTYPE_DISALLOWS_CROSSING); + ScriptError::RegisterErrorMap(STR_ERROR_NO_SUITABLE_ROAD, ScriptRoad::ERR_UNSUITABLE_ROAD); + ScriptError::RegisterErrorMap(STR_ERROR_NO_SUITABLE_TRAMWAY, ScriptRoad::ERR_UNSUITABLE_ROAD); + ScriptError::RegisterErrorMap(STR_ERROR_INCOMPATIBLE_ROAD, ScriptRoad::ERR_UNSUITABLE_ROAD); ScriptError::RegisterErrorMapString(ScriptRoad::ERR_ROAD_WORKS_IN_PROGRESS, "ERR_ROAD_WORKS_IN_PROGRESS"); ScriptError::RegisterErrorMapString(ScriptRoad::ERR_ROAD_DRIVE_THROUGH_WRONG_DIRECTION, "ERR_ROAD_DRIVE_THROUGH_WRONG_DIRECTION"); ScriptError::RegisterErrorMapString(ScriptRoad::ERR_ROAD_CANNOT_BUILD_ON_TOWN_ROAD, "ERR_ROAD_CANNOT_BUILD_ON_TOWN_ROAD"); ScriptError::RegisterErrorMapString(ScriptRoad::ERR_ROAD_ONE_WAY_ROADS_CANNOT_HAVE_JUNCTIONS, "ERR_ROAD_ONE_WAY_ROADS_CANNOT_HAVE_JUNCTIONS"); + ScriptError::RegisterErrorMapString(ScriptRoad::ERR_ROADTYPE_DISALLOWS_CROSSING, "ERR_ROADTYPE_DISALLOWS_CROSSING"); + ScriptError::RegisterErrorMapString(ScriptRoad::ERR_UNSUITABLE_ROAD, "ERR_UNSUITABLE_ROAD"); + SQAIRoad.DefSQStaticMethod(engine, &ScriptRoad::GetName, "GetName", 2, ".i"); SQAIRoad.DefSQStaticMethod(engine, &ScriptRoad::GetRoadVehicleTypeForCargo, "GetRoadVehicleTypeForCargo", 2, ".i"); SQAIRoad.DefSQStaticMethod(engine, &ScriptRoad::IsRoadTile, "IsRoadTile", 2, ".i"); SQAIRoad.DefSQStaticMethod(engine, &ScriptRoad::IsRoadDepotTile, "IsRoadDepotTile", 2, ".i"); @@ -54,6 +63,9 @@ void SQAIRoad_Register(Squirrel *engine) SQAIRoad.DefSQStaticMethod(engine, &ScriptRoad::IsRoadTypeAvailable, "IsRoadTypeAvailable", 2, ".i"); SQAIRoad.DefSQStaticMethod(engine, &ScriptRoad::GetCurrentRoadType, "GetCurrentRoadType", 1, "."); SQAIRoad.DefSQStaticMethod(engine, &ScriptRoad::SetCurrentRoadType, "SetCurrentRoadType", 2, ".i"); + SQAIRoad.DefSQStaticMethod(engine, &ScriptRoad::RoadVehCanRunOnRoad, "RoadVehCanRunOnRoad", 3, ".ii"); + SQAIRoad.DefSQStaticMethod(engine, &ScriptRoad::RoadVehHasPowerOnRoad, "RoadVehHasPowerOnRoad", 3, ".ii"); + SQAIRoad.DefSQStaticMethod(engine, &ScriptRoad::ConvertRoadType, "ConvertRoadType", 4, ".iii"); SQAIRoad.DefSQStaticMethod(engine, &ScriptRoad::HasRoadType, "HasRoadType", 3, ".ii"); SQAIRoad.DefSQStaticMethod(engine, &ScriptRoad::AreRoadTilesConnected, "AreRoadTilesConnected", 3, ".ii"); SQAIRoad.DefSQStaticMethod(engine, &ScriptRoad::CanBuildConnectedRoadParts, "CanBuildConnectedRoadParts", 5, ".iaii"); @@ -74,6 +86,8 @@ void SQAIRoad_Register(Squirrel *engine) SQAIRoad.DefSQStaticMethod(engine, &ScriptRoad::RemoveRoadDepot, "RemoveRoadDepot", 2, ".i"); SQAIRoad.DefSQStaticMethod(engine, &ScriptRoad::RemoveRoadStation, "RemoveRoadStation", 2, ".i"); SQAIRoad.DefSQStaticMethod(engine, &ScriptRoad::GetBuildCost, "GetBuildCost", 3, ".ii"); + SQAIRoad.DefSQStaticMethod(engine, &ScriptRoad::GetRoadTramType, "GetRoadTramType", 2, ".i"); + SQAIRoad.DefSQStaticMethod(engine, &ScriptRoad::GetMaxSpeed, "GetMaxSpeed", 2, ".i"); SQAIRoad.DefSQStaticMethod(engine, &ScriptRoad::GetMaintenanceCostFactor, "GetMaintenanceCostFactor", 2, ".i"); SQAIRoad.PostRegister(engine); diff --git a/src/script/api/ai/ai_roadtypelist.hpp.sq b/src/script/api/ai/ai_roadtypelist.hpp.sq new file mode 100644 index 0000000000..43224eea52 --- /dev/null +++ b/src/script/api/ai/ai_roadtypelist.hpp.sq @@ -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 . + */ + +/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */ + +#include "../script_roadtypelist.hpp" +#include "../template/template_roadtypelist.hpp.sq" + + +template <> const char *GetClassName() { return "AIRoadTypeList"; } + +void SQAIRoadTypeList_Register(Squirrel *engine) +{ + DefSQClass SQAIRoadTypeList("AIRoadTypeList"); + SQAIRoadTypeList.PreRegister(engine, "AIList"); + SQAIRoadTypeList.AddConstructor(engine, "xi"); + + SQAIRoadTypeList.PostRegister(engine); +} diff --git a/src/script/api/ai/ai_sign.hpp.sq b/src/script/api/ai/ai_sign.hpp.sq index e3c9005e76..e6c78c9344 100644 --- a/src/script/api/ai/ai_sign.hpp.sq +++ b/src/script/api/ai/ai_sign.hpp.sq @@ -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/script/api/ai/ai_signlist.hpp.sq b/src/script/api/ai/ai_signlist.hpp.sq index 8f4f97c0c8..9fbf42ddf4 100644 --- a/src/script/api/ai/ai_signlist.hpp.sq +++ b/src/script/api/ai/ai_signlist.hpp.sq @@ -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/script/api/ai/ai_station.hpp.sq b/src/script/api/ai/ai_station.hpp.sq index 1850c1e740..2278faf238 100644 --- a/src/script/api/ai/ai_station.hpp.sq +++ b/src/script/api/ai/ai_station.hpp.sq @@ -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/script/api/ai/ai_stationlist.hpp.sq b/src/script/api/ai/ai_stationlist.hpp.sq index 93a8c6e767..d7a63212c3 100644 --- a/src/script/api/ai/ai_stationlist.hpp.sq +++ b/src/script/api/ai/ai_stationlist.hpp.sq @@ -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/script/api/ai/ai_subsidy.hpp.sq b/src/script/api/ai/ai_subsidy.hpp.sq index ea9743dace..34a8173e51 100644 --- a/src/script/api/ai/ai_subsidy.hpp.sq +++ b/src/script/api/ai/ai_subsidy.hpp.sq @@ -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/script/api/ai/ai_subsidylist.hpp.sq b/src/script/api/ai/ai_subsidylist.hpp.sq index f58165f556..c1a39238a5 100644 --- a/src/script/api/ai/ai_subsidylist.hpp.sq +++ b/src/script/api/ai/ai_subsidylist.hpp.sq @@ -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/script/api/ai/ai_testmode.hpp.sq b/src/script/api/ai/ai_testmode.hpp.sq index 6072706f73..e80952a610 100644 --- a/src/script/api/ai/ai_testmode.hpp.sq +++ b/src/script/api/ai/ai_testmode.hpp.sq @@ -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/script/api/ai/ai_tile.hpp.sq b/src/script/api/ai/ai_tile.hpp.sq index 570e88cd28..4d4f0fe37e 100644 --- a/src/script/api/ai/ai_tile.hpp.sq +++ b/src/script/api/ai/ai_tile.hpp.sq @@ -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. @@ -26,6 +24,7 @@ void SQAITile_Register(Squirrel *engine) SQAITile.DefSQConst(engine, ScriptTile::ERR_TILE_TOO_LOW, "ERR_TILE_TOO_LOW"); SQAITile.DefSQConst(engine, ScriptTile::ERR_AREA_ALREADY_FLAT, "ERR_AREA_ALREADY_FLAT"); SQAITile.DefSQConst(engine, ScriptTile::ERR_EXCAVATION_WOULD_DAMAGE, "ERR_EXCAVATION_WOULD_DAMAGE"); + SQAITile.DefSQConst(engine, ScriptTile::ERR_LIMIT_REACHED, "ERR_LIMIT_REACHED"); SQAITile.DefSQConst(engine, ScriptTile::CORNER_W, "CORNER_W"); SQAITile.DefSQConst(engine, ScriptTile::CORNER_S, "CORNER_S"); SQAITile.DefSQConst(engine, ScriptTile::CORNER_E, "CORNER_E"); @@ -71,15 +70,19 @@ void SQAITile_Register(Squirrel *engine) SQAITile.DefSQConst(engine, ScriptTile::TERRAIN_RAINFOREST, "TERRAIN_RAINFOREST"); SQAITile.DefSQConst(engine, ScriptTile::TERRAIN_SNOW, "TERRAIN_SNOW"); - ScriptError::RegisterErrorMap(STR_ERROR_ALREADY_AT_SEA_LEVEL, ScriptTile::ERR_TILE_TOO_HIGH); - ScriptError::RegisterErrorMap(STR_ERROR_ALREADY_AT_SEA_LEVEL, ScriptTile::ERR_TILE_TOO_LOW); - ScriptError::RegisterErrorMap(STR_ERROR_ALREADY_LEVELLED, ScriptTile::ERR_AREA_ALREADY_FLAT); - ScriptError::RegisterErrorMap(STR_ERROR_EXCAVATION_WOULD_DAMAGE, ScriptTile::ERR_EXCAVATION_WOULD_DAMAGE); + ScriptError::RegisterErrorMap(STR_ERROR_ALREADY_AT_SEA_LEVEL, ScriptTile::ERR_TILE_TOO_HIGH); + ScriptError::RegisterErrorMap(STR_ERROR_ALREADY_AT_SEA_LEVEL, ScriptTile::ERR_TILE_TOO_LOW); + ScriptError::RegisterErrorMap(STR_ERROR_ALREADY_LEVELLED, ScriptTile::ERR_AREA_ALREADY_FLAT); + ScriptError::RegisterErrorMap(STR_ERROR_EXCAVATION_WOULD_DAMAGE, ScriptTile::ERR_EXCAVATION_WOULD_DAMAGE); + ScriptError::RegisterErrorMap(STR_ERROR_TERRAFORM_LIMIT_REACHED, ScriptTile::ERR_LIMIT_REACHED); + ScriptError::RegisterErrorMap(STR_ERROR_CLEARING_LIMIT_REACHED, ScriptTile::ERR_LIMIT_REACHED); + ScriptError::RegisterErrorMap(STR_ERROR_TREE_PLANT_LIMIT_REACHED, ScriptTile::ERR_LIMIT_REACHED); ScriptError::RegisterErrorMapString(ScriptTile::ERR_TILE_TOO_HIGH, "ERR_TILE_TOO_HIGH"); ScriptError::RegisterErrorMapString(ScriptTile::ERR_TILE_TOO_LOW, "ERR_TILE_TOO_LOW"); ScriptError::RegisterErrorMapString(ScriptTile::ERR_AREA_ALREADY_FLAT, "ERR_AREA_ALREADY_FLAT"); ScriptError::RegisterErrorMapString(ScriptTile::ERR_EXCAVATION_WOULD_DAMAGE, "ERR_EXCAVATION_WOULD_DAMAGE"); + ScriptError::RegisterErrorMapString(ScriptTile::ERR_LIMIT_REACHED, "ERR_LIMIT_REACHED"); SQAITile.DefSQStaticMethod(engine, &ScriptTile::IsBuildable, "IsBuildable", 2, ".i"); SQAITile.DefSQStaticMethod(engine, &ScriptTile::IsBuildableRectangle, "IsBuildableRectangle", 4, ".iii"); diff --git a/src/script/api/ai/ai_tilelist.hpp.sq b/src/script/api/ai/ai_tilelist.hpp.sq index 4675e98fe9..64f666f6c7 100644 --- a/src/script/api/ai/ai_tilelist.hpp.sq +++ b/src/script/api/ai/ai_tilelist.hpp.sq @@ -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/script/api/ai/ai_town.hpp.sq b/src/script/api/ai/ai_town.hpp.sq index 6b09190be8..8cae7f11a2 100644 --- a/src/script/api/ai/ai_town.hpp.sq +++ b/src/script/api/ai/ai_town.hpp.sq @@ -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/script/api/ai/ai_townlist.hpp.sq b/src/script/api/ai/ai_townlist.hpp.sq index 74af6f45bb..7efaa298da 100644 --- a/src/script/api/ai/ai_townlist.hpp.sq +++ b/src/script/api/ai/ai_townlist.hpp.sq @@ -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/script/api/ai/ai_tunnel.hpp.sq b/src/script/api/ai/ai_tunnel.hpp.sq index 91eb432a05..7c72e83862 100644 --- a/src/script/api/ai/ai_tunnel.hpp.sq +++ b/src/script/api/ai/ai_tunnel.hpp.sq @@ -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/script/api/ai/ai_vehicle.hpp.sq b/src/script/api/ai/ai_vehicle.hpp.sq index 0eb21ed672..20c66254ca 100644 --- a/src/script/api/ai/ai_vehicle.hpp.sq +++ b/src/script/api/ai/ai_vehicle.hpp.sq @@ -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. @@ -122,6 +120,8 @@ void SQAIVehicle_Register(Squirrel *engine) SQAIVehicle.DefSQStaticMethod(engine, &ScriptVehicle::IsInDepot, "IsInDepot", 2, ".i"); SQAIVehicle.DefSQStaticMethod(engine, &ScriptVehicle::IsStoppedInDepot, "IsStoppedInDepot", 2, ".i"); SQAIVehicle.DefSQStaticMethod(engine, &ScriptVehicle::BuildVehicle, "BuildVehicle", 3, ".ii"); + SQAIVehicle.DefSQStaticMethod(engine, &ScriptVehicle::BuildVehicleWithRefit, "BuildVehicleWithRefit", 4, ".iii"); + SQAIVehicle.DefSQStaticMethod(engine, &ScriptVehicle::GetBuildWithRefitCapacity, "GetBuildWithRefitCapacity", 4, ".iii"); SQAIVehicle.DefSQStaticMethod(engine, &ScriptVehicle::CloneVehicle, "CloneVehicle", 4, ".iib"); SQAIVehicle.DefSQStaticMethod(engine, &ScriptVehicle::MoveWagon, "MoveWagon", 5, ".iiii"); SQAIVehicle.DefSQStaticMethod(engine, &ScriptVehicle::MoveWagonChain, "MoveWagonChain", 5, ".iiii"); diff --git a/src/script/api/ai/ai_vehiclelist.hpp.sq b/src/script/api/ai/ai_vehiclelist.hpp.sq index 39e5cb4598..25a8610c39 100644 --- a/src/script/api/ai/ai_vehiclelist.hpp.sq +++ b/src/script/api/ai/ai_vehiclelist.hpp.sq @@ -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/script/api/ai/ai_waypoint.hpp.sq b/src/script/api/ai/ai_waypoint.hpp.sq index b9edc40bf7..3e2b64b465 100644 --- a/src/script/api/ai/ai_waypoint.hpp.sq +++ b/src/script/api/ai/ai_waypoint.hpp.sq @@ -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/script/api/ai/ai_waypointlist.hpp.sq b/src/script/api/ai/ai_waypointlist.hpp.sq index 464c07071f..c8359baedf 100644 --- a/src/script/api/ai/ai_waypointlist.hpp.sq +++ b/src/script/api/ai/ai_waypointlist.hpp.sq @@ -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/script/api/ai_changelog.hpp b/src/script/api/ai_changelog.hpp index 0afe4e08c4..9eea9ab152 100644 --- a/src/script/api/ai_changelog.hpp +++ b/src/script/api/ai_changelog.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. @@ -15,9 +13,32 @@ * functions may still be available if you return an older API version * in GetAPIVersion() in info.nut. * + * \b 1.10.0 + * + * This version is not yet released. The following changes are not set in stone yet. + * + * API additions: + * \li AIGroup::SetPrimaryColour + * \li AIGroup::SetSecondaryColour + * \li AIGroup::GetPrimaryColour + * \li AIGroup::GetSecondaryColour + * \li AIVehicle::BuildVehicleWithRefit + * \li AIVehicle::GetBuildWithRefitCapacity + * \li AIRoad::GetName + * \li AIRoad::RoadVehCanRunOnRoad + * \li AIRoad::RoadVehHasPowerOnRoad + * \li AIRoad::ConvertRoadType + * \li AIRoad::GetMaxSpeed + * \li AIEngine::CanRunOnRoad + * \li AIEngine::HasPowerOnRoad + * \li AIRoadTypeList::RoadTypeList + * \li AIEventVehicleAutoReplaced + * + * Other changes: + * \li AITile::DemolishTile works without a selected company + * * \b 1.9.0 * - * 1.9.0 is not yet released. The following changes are not set in stone yet. * API additions: * \li AIAirport::GetMonthlyMaintenanceCost * \li AIGroup::SetParent @@ -35,6 +56,9 @@ * * No changes * + * API additions: + * \li AIRoad::ERR_ROADTYPE_DISALLOWS_CROSSING + * * \b 1.7.0 - 1.7.2 * * No changes @@ -288,7 +312,7 @@ * destination it its catchment area. One industry tile or one town house * is enough as long as station accepts the cargo. Awarded subsidies are no * longer bound to stations used for first delivery, any station can be - * used for loading and unloading as long as cargo is transfered from + * used for loading and unloading as long as cargo is transferred from * source to destination. * \li Make AIEngine:CanRefitCargo() not report refittability to mail by * default for aircraft. It is not necessarily true. This means that even diff --git a/src/script/api/doxygen_filter.awk b/src/script/api/doxygen_filter.awk index 3a321fb5bf..7e3f387a0d 100644 --- a/src/script/api/doxygen_filter.awk +++ b/src/script/api/doxygen_filter.awk @@ -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. # 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. diff --git a/src/script/api/doxygen_filter.sh b/src/script/api/doxygen_filter.sh index 31c34d4abc..e63c7183d8 100755 --- a/src/script/api/doxygen_filter.sh +++ b/src/script/api/doxygen_filter.sh @@ -1,7 +1,5 @@ #!/bin/bash -# $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. # 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. diff --git a/src/script/api/game/game_accounting.hpp.sq b/src/script/api/game/game_accounting.hpp.sq index 0e78172c0a..5b78909bde 100644 --- a/src/script/api/game/game_accounting.hpp.sq +++ b/src/script/api/game/game_accounting.hpp.sq @@ -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/script/api/game/game_admin.hpp.sq b/src/script/api/game/game_admin.hpp.sq index f8b994e809..6616f2706e 100644 --- a/src/script/api/game/game_admin.hpp.sq +++ b/src/script/api/game/game_admin.hpp.sq @@ -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/script/api/game/game_airport.hpp.sq b/src/script/api/game/game_airport.hpp.sq index d8f3a2a64c..32e0c12a1b 100644 --- a/src/script/api/game/game_airport.hpp.sq +++ b/src/script/api/game/game_airport.hpp.sq @@ -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/script/api/game/game_base.hpp.sq b/src/script/api/game/game_base.hpp.sq index 0301b05478..01791e186e 100644 --- a/src/script/api/game/game_base.hpp.sq +++ b/src/script/api/game/game_base.hpp.sq @@ -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/script/api/game/game_basestation.hpp.sq b/src/script/api/game/game_basestation.hpp.sq index f1e1797e90..91f7b575e1 100644 --- a/src/script/api/game/game_basestation.hpp.sq +++ b/src/script/api/game/game_basestation.hpp.sq @@ -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/script/api/game/game_bridge.hpp.sq b/src/script/api/game/game_bridge.hpp.sq index df0a945024..be9ef4bdf1 100644 --- a/src/script/api/game/game_bridge.hpp.sq +++ b/src/script/api/game/game_bridge.hpp.sq @@ -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/script/api/game/game_bridgelist.hpp.sq b/src/script/api/game/game_bridgelist.hpp.sq index d40c2c1e09..36a18bc221 100644 --- a/src/script/api/game/game_bridgelist.hpp.sq +++ b/src/script/api/game/game_bridgelist.hpp.sq @@ -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/script/api/game/game_cargo.hpp.sq b/src/script/api/game/game_cargo.hpp.sq index 515d5ff28f..0f018bc579 100644 --- a/src/script/api/game/game_cargo.hpp.sq +++ b/src/script/api/game/game_cargo.hpp.sq @@ -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/script/api/game/game_cargolist.hpp.sq b/src/script/api/game/game_cargolist.hpp.sq index 00b22b3d75..f1fd3ef846 100644 --- a/src/script/api/game/game_cargolist.hpp.sq +++ b/src/script/api/game/game_cargolist.hpp.sq @@ -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/script/api/game/game_cargomonitor.hpp.sq b/src/script/api/game/game_cargomonitor.hpp.sq index b3638c4def..ccf9f3d164 100644 --- a/src/script/api/game/game_cargomonitor.hpp.sq +++ b/src/script/api/game/game_cargomonitor.hpp.sq @@ -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/script/api/game/game_client.hpp.sq b/src/script/api/game/game_client.hpp.sq index b4230a6d05..3a7f8491f5 100644 --- a/src/script/api/game/game_client.hpp.sq +++ b/src/script/api/game/game_client.hpp.sq @@ -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/script/api/game/game_clientlist.hpp.sq b/src/script/api/game/game_clientlist.hpp.sq index ef02586474..c341786f1d 100644 --- a/src/script/api/game/game_clientlist.hpp.sq +++ b/src/script/api/game/game_clientlist.hpp.sq @@ -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/script/api/game/game_company.hpp.sq b/src/script/api/game/game_company.hpp.sq index 626664484a..5bce4065cd 100644 --- a/src/script/api/game/game_company.hpp.sq +++ b/src/script/api/game/game_company.hpp.sq @@ -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/script/api/game/game_companymode.hpp.sq b/src/script/api/game/game_companymode.hpp.sq index 038e234fa1..73eb5e26b4 100644 --- a/src/script/api/game/game_companymode.hpp.sq +++ b/src/script/api/game/game_companymode.hpp.sq @@ -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/script/api/game/game_controller.hpp.sq b/src/script/api/game/game_controller.hpp.sq index 7cae77de36..e7f7c58306 100644 --- a/src/script/api/game/game_controller.hpp.sq +++ b/src/script/api/game/game_controller.hpp.sq @@ -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/script/api/game/game_date.hpp.sq b/src/script/api/game/game_date.hpp.sq index dc40989da0..10dc2ad24d 100644 --- a/src/script/api/game/game_date.hpp.sq +++ b/src/script/api/game/game_date.hpp.sq @@ -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/script/api/game/game_depotlist.hpp.sq b/src/script/api/game/game_depotlist.hpp.sq index 59257cdad2..e01aa99a0b 100644 --- a/src/script/api/game/game_depotlist.hpp.sq +++ b/src/script/api/game/game_depotlist.hpp.sq @@ -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/script/api/game/game_engine.hpp.sq b/src/script/api/game/game_engine.hpp.sq index 4881755473..2efa1414a9 100644 --- a/src/script/api/game/game_engine.hpp.sq +++ b/src/script/api/game/game_engine.hpp.sq @@ -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. @@ -41,11 +39,15 @@ void SQGSEngine_Register(Squirrel *engine) SQGSEngine.DefSQStaticMethod(engine, &ScriptEngine::IsWagon, "IsWagon", 2, ".i"); SQGSEngine.DefSQStaticMethod(engine, &ScriptEngine::CanRunOnRail, "CanRunOnRail", 3, ".ii"); SQGSEngine.DefSQStaticMethod(engine, &ScriptEngine::HasPowerOnRail, "HasPowerOnRail", 3, ".ii"); + SQGSEngine.DefSQStaticMethod(engine, &ScriptEngine::CanRunOnRoad, "CanRunOnRoad", 3, ".ii"); + SQGSEngine.DefSQStaticMethod(engine, &ScriptEngine::HasPowerOnRoad, "HasPowerOnRoad", 3, ".ii"); SQGSEngine.DefSQStaticMethod(engine, &ScriptEngine::GetRoadType, "GetRoadType", 2, ".i"); SQGSEngine.DefSQStaticMethod(engine, &ScriptEngine::GetRailType, "GetRailType", 2, ".i"); SQGSEngine.DefSQStaticMethod(engine, &ScriptEngine::IsArticulated, "IsArticulated", 2, ".i"); SQGSEngine.DefSQStaticMethod(engine, &ScriptEngine::GetPlaneType, "GetPlaneType", 2, ".i"); SQGSEngine.DefSQStaticMethod(engine, &ScriptEngine::GetMaximumOrderDistance, "GetMaximumOrderDistance", 2, ".i"); + SQGSEngine.DefSQStaticMethod(engine, &ScriptEngine::EnableForCompany, "EnableForCompany", 3, ".ii"); + SQGSEngine.DefSQStaticMethod(engine, &ScriptEngine::DisableForCompany, "DisableForCompany", 3, ".ii"); SQGSEngine.PostRegister(engine); } diff --git a/src/script/api/game/game_enginelist.hpp.sq b/src/script/api/game/game_enginelist.hpp.sq index 1f052b8333..9ffbba636e 100644 --- a/src/script/api/game/game_enginelist.hpp.sq +++ b/src/script/api/game/game_enginelist.hpp.sq @@ -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/script/api/game/game_error.hpp.sq b/src/script/api/game/game_error.hpp.sq index 7718f14348..f1f88b3373 100644 --- a/src/script/api/game/game_error.hpp.sq +++ b/src/script/api/game/game_error.hpp.sq @@ -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. @@ -58,8 +56,10 @@ void SQGSError_Register(Squirrel *engine) ScriptError::RegisterErrorMap(STR_ERROR_NOT_ENOUGH_CASH_REQUIRES_CURRENCY, ScriptError::ERR_NOT_ENOUGH_CASH); ScriptError::RegisterErrorMap(STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS, ScriptError::ERR_LOCAL_AUTHORITY_REFUSES); + ScriptError::RegisterErrorMap(STR_ERROR_LOCAL_AUTHORITY_REFUSES_NOISE, ScriptError::ERR_LOCAL_AUTHORITY_REFUSES); ScriptError::RegisterErrorMap(STR_ERROR_ALREADY_BUILT, ScriptError::ERR_ALREADY_BUILT); ScriptError::RegisterErrorMap(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST, ScriptError::ERR_ALREADY_BUILT); + ScriptError::RegisterErrorMap(STR_ERROR_TREE_ALREADY_HERE, ScriptError::ERR_ALREADY_BUILT); ScriptError::RegisterErrorMap(STR_ERROR_BUILDING_MUST_BE_DEMOLISHED, ScriptError::ERR_AREA_NOT_CLEAR); ScriptError::RegisterErrorMap(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST, ScriptError::ERR_AREA_NOT_CLEAR); ScriptError::RegisterErrorMap(STR_ERROR_MUST_DEMOLISH_RAILROAD, ScriptError::ERR_AREA_NOT_CLEAR); @@ -88,6 +88,7 @@ void SQGSError_Register(Squirrel *engine) ScriptError::RegisterErrorMap(STR_ERROR_SHIP_IN_THE_WAY, ScriptError::ERR_VEHICLE_IN_THE_WAY); ScriptError::RegisterErrorMap(STR_ERROR_AIRCRAFT_IN_THE_WAY, ScriptError::ERR_VEHICLE_IN_THE_WAY); ScriptError::RegisterErrorMap(STR_ERROR_SITE_UNSUITABLE, ScriptError::ERR_SITE_UNSUITABLE); + ScriptError::RegisterErrorMap(STR_ERROR_TREE_WRONG_TERRAIN_FOR_TREE_TYPE, ScriptError::ERR_SITE_UNSUITABLE); ScriptError::RegisterErrorMap(STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP, ScriptError::ERR_TOO_CLOSE_TO_EDGE); ScriptError::RegisterErrorMap(STR_ERROR_STATION_TOO_SPREAD_OUT, ScriptError::ERR_STATION_TOO_SPREAD_OUT); diff --git a/src/script/api/game/game_event.hpp.sq b/src/script/api/game/game_event.hpp.sq index 53b9b2ce9e..42ea11b8ba 100644 --- a/src/script/api/game/game_event.hpp.sq +++ b/src/script/api/game/game_event.hpp.sq @@ -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,6 +48,7 @@ void SQGSEvent_Register(Squirrel *engine) SQGSEvent.DefSQConst(engine, ScriptEvent::ET_GOAL_QUESTION_ANSWER, "ET_GOAL_QUESTION_ANSWER"); SQGSEvent.DefSQConst(engine, ScriptEvent::ET_EXCLUSIVE_TRANSPORT_RIGHTS, "ET_EXCLUSIVE_TRANSPORT_RIGHTS"); SQGSEvent.DefSQConst(engine, ScriptEvent::ET_ROAD_RECONSTRUCTION, "ET_ROAD_RECONSTRUCTION"); + SQGSEvent.DefSQConst(engine, ScriptEvent::ET_VEHICLE_AUTOREPLACED, "ET_VEHICLE_AUTOREPLACED"); SQGSEvent.DefSQMethod(engine, &ScriptEvent::GetEventType, "GetEventType", 1, "x"); diff --git a/src/script/api/game/game_event_types.hpp.sq b/src/script/api/game/game_event_types.hpp.sq index 56acdd30fd..62e4f6a089 100644 --- a/src/script/api/game/game_event_types.hpp.sq +++ b/src/script/api/game/game_event_types.hpp.sq @@ -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/script/api/game/game_execmode.hpp.sq b/src/script/api/game/game_execmode.hpp.sq index 93d980312a..14946ba127 100644 --- a/src/script/api/game/game_execmode.hpp.sq +++ b/src/script/api/game/game_execmode.hpp.sq @@ -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/script/api/game/game_game.hpp.sq b/src/script/api/game/game_game.hpp.sq index ca7bb7a1d1..8c889a05b1 100644 --- a/src/script/api/game/game_game.hpp.sq +++ b/src/script/api/game/game_game.hpp.sq @@ -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/script/api/game/game_gamesettings.hpp.sq b/src/script/api/game/game_gamesettings.hpp.sq index 9aeba71994..a1dbcf7914 100644 --- a/src/script/api/game/game_gamesettings.hpp.sq +++ b/src/script/api/game/game_gamesettings.hpp.sq @@ -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/script/api/game/game_goal.hpp.sq b/src/script/api/game/game_goal.hpp.sq index 4cf15b3fc4..9f0384c554 100644 --- a/src/script/api/game/game_goal.hpp.sq +++ b/src/script/api/game/game_goal.hpp.sq @@ -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/script/api/game/game_industry.hpp.sq b/src/script/api/game/game_industry.hpp.sq index 5d50c90fa2..281ee638fa 100644 --- a/src/script/api/game/game_industry.hpp.sq +++ b/src/script/api/game/game_industry.hpp.sq @@ -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/script/api/game/game_industrylist.hpp.sq b/src/script/api/game/game_industrylist.hpp.sq index fbfc5347bf..71ea5633b0 100644 --- a/src/script/api/game/game_industrylist.hpp.sq +++ b/src/script/api/game/game_industrylist.hpp.sq @@ -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/script/api/game/game_industrytype.hpp.sq b/src/script/api/game/game_industrytype.hpp.sq index 460cc513c7..67b9a2470c 100644 --- a/src/script/api/game/game_industrytype.hpp.sq +++ b/src/script/api/game/game_industrytype.hpp.sq @@ -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/script/api/game/game_industrytypelist.hpp.sq b/src/script/api/game/game_industrytypelist.hpp.sq index d2ee7d28d1..365bba6e89 100644 --- a/src/script/api/game/game_industrytypelist.hpp.sq +++ b/src/script/api/game/game_industrytypelist.hpp.sq @@ -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/script/api/game/game_infrastructure.hpp.sq b/src/script/api/game/game_infrastructure.hpp.sq index 9608013b18..d241a8223e 100644 --- a/src/script/api/game/game_infrastructure.hpp.sq +++ b/src/script/api/game/game_infrastructure.hpp.sq @@ -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/script/api/game/game_list.hpp.sq b/src/script/api/game/game_list.hpp.sq index a46696def5..9b9e614ced 100644 --- a/src/script/api/game/game_list.hpp.sq +++ b/src/script/api/game/game_list.hpp.sq @@ -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/script/api/game/game_log.hpp.sq b/src/script/api/game/game_log.hpp.sq index 1eb44d955d..c2c387489b 100644 --- a/src/script/api/game/game_log.hpp.sq +++ b/src/script/api/game/game_log.hpp.sq @@ -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/script/api/game/game_map.hpp.sq b/src/script/api/game/game_map.hpp.sq index e43edb1467..139b2e4d6e 100644 --- a/src/script/api/game/game_map.hpp.sq +++ b/src/script/api/game/game_map.hpp.sq @@ -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/script/api/game/game_marine.hpp.sq b/src/script/api/game/game_marine.hpp.sq index 0da8513202..4029f78db1 100644 --- a/src/script/api/game/game_marine.hpp.sq +++ b/src/script/api/game/game_marine.hpp.sq @@ -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/script/api/game/game_news.hpp.sq b/src/script/api/game/game_news.hpp.sq index 3d7022e10e..5a3c7f9739 100644 --- a/src/script/api/game/game_news.hpp.sq +++ b/src/script/api/game/game_news.hpp.sq @@ -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/script/api/game/game_order.hpp.sq b/src/script/api/game/game_order.hpp.sq index e2126c603d..77a44acde6 100644 --- a/src/script/api/game/game_order.hpp.sq +++ b/src/script/api/game/game_order.hpp.sq @@ -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/script/api/game/game_rail.hpp.sq b/src/script/api/game/game_rail.hpp.sq index c057360300..cd32d5d254 100644 --- a/src/script/api/game/game_rail.hpp.sq +++ b/src/script/api/game/game_rail.hpp.sq @@ -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. @@ -56,7 +54,7 @@ void SQGSRail_Register(Squirrel *engine) ScriptError::RegisterErrorMap(STR_ERROR_THERE_IS_NO_RAILROAD_TRACK, ScriptRail::ERR_UNSUITABLE_TRACK); ScriptError::RegisterErrorMap(STR_ERROR_THERE_ARE_NO_SIGNALS, ScriptRail::ERR_UNSUITABLE_TRACK); ScriptError::RegisterErrorMap(STR_ERROR_THERE_IS_NO_STATION, ScriptRail::ERR_UNSUITABLE_TRACK); - ScriptError::RegisterErrorMap(STR_ERROR_CROSSING_DISALLOWED, ScriptRail::ERR_RAILTYPE_DISALLOWS_CROSSING); + ScriptError::RegisterErrorMap(STR_ERROR_CROSSING_DISALLOWED_RAIL, ScriptRail::ERR_RAILTYPE_DISALLOWS_CROSSING); ScriptError::RegisterErrorMapString(ScriptRail::ERR_CROSSING_ON_ONEWAY_ROAD, "ERR_CROSSING_ON_ONEWAY_ROAD"); ScriptError::RegisterErrorMapString(ScriptRail::ERR_UNSUITABLE_TRACK, "ERR_UNSUITABLE_TRACK"); diff --git a/src/script/api/game/game_railtypelist.hpp.sq b/src/script/api/game/game_railtypelist.hpp.sq index caa036aca6..b829724bb5 100644 --- a/src/script/api/game/game_railtypelist.hpp.sq +++ b/src/script/api/game/game_railtypelist.hpp.sq @@ -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/script/api/game/game_road.hpp.sq b/src/script/api/game/game_road.hpp.sq index 51da4144eb..938dd5eabb 100644 --- a/src/script/api/game/game_road.hpp.sq +++ b/src/script/api/game/game_road.hpp.sq @@ -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. @@ -26,9 +24,13 @@ void SQGSRoad_Register(Squirrel *engine) SQGSRoad.DefSQConst(engine, ScriptRoad::ERR_ROAD_DRIVE_THROUGH_WRONG_DIRECTION, "ERR_ROAD_DRIVE_THROUGH_WRONG_DIRECTION"); SQGSRoad.DefSQConst(engine, ScriptRoad::ERR_ROAD_CANNOT_BUILD_ON_TOWN_ROAD, "ERR_ROAD_CANNOT_BUILD_ON_TOWN_ROAD"); SQGSRoad.DefSQConst(engine, ScriptRoad::ERR_ROAD_ONE_WAY_ROADS_CANNOT_HAVE_JUNCTIONS, "ERR_ROAD_ONE_WAY_ROADS_CANNOT_HAVE_JUNCTIONS"); + SQGSRoad.DefSQConst(engine, ScriptRoad::ERR_ROADTYPE_DISALLOWS_CROSSING, "ERR_ROADTYPE_DISALLOWS_CROSSING"); + SQGSRoad.DefSQConst(engine, ScriptRoad::ERR_UNSUITABLE_ROAD, "ERR_UNSUITABLE_ROAD"); SQGSRoad.DefSQConst(engine, ScriptRoad::ROADTYPE_ROAD, "ROADTYPE_ROAD"); SQGSRoad.DefSQConst(engine, ScriptRoad::ROADTYPE_TRAM, "ROADTYPE_TRAM"); SQGSRoad.DefSQConst(engine, ScriptRoad::ROADTYPE_INVALID, "ROADTYPE_INVALID"); + SQGSRoad.DefSQConst(engine, ScriptRoad::ROADTRAMTYPES_ROAD, "ROADTRAMTYPES_ROAD"); + SQGSRoad.DefSQConst(engine, ScriptRoad::ROADTRAMTYPES_TRAM, "ROADTRAMTYPES_TRAM"); SQGSRoad.DefSQConst(engine, ScriptRoad::ROADVEHTYPE_BUS, "ROADVEHTYPE_BUS"); SQGSRoad.DefSQConst(engine, ScriptRoad::ROADVEHTYPE_TRUCK, "ROADVEHTYPE_TRUCK"); SQGSRoad.DefSQConst(engine, ScriptRoad::BT_ROAD, "BT_ROAD"); @@ -40,12 +42,19 @@ void SQGSRoad_Register(Squirrel *engine) ScriptError::RegisterErrorMap(STR_ERROR_DRIVE_THROUGH_DIRECTION, ScriptRoad::ERR_ROAD_DRIVE_THROUGH_WRONG_DIRECTION); ScriptError::RegisterErrorMap(STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD, ScriptRoad::ERR_ROAD_CANNOT_BUILD_ON_TOWN_ROAD); ScriptError::RegisterErrorMap(STR_ERROR_ONEWAY_ROADS_CAN_T_HAVE_JUNCTION, ScriptRoad::ERR_ROAD_ONE_WAY_ROADS_CANNOT_HAVE_JUNCTIONS); + ScriptError::RegisterErrorMap(STR_ERROR_CROSSING_DISALLOWED_ROAD, ScriptRoad::ERR_ROADTYPE_DISALLOWS_CROSSING); + ScriptError::RegisterErrorMap(STR_ERROR_NO_SUITABLE_ROAD, ScriptRoad::ERR_UNSUITABLE_ROAD); + ScriptError::RegisterErrorMap(STR_ERROR_NO_SUITABLE_TRAMWAY, ScriptRoad::ERR_UNSUITABLE_ROAD); + ScriptError::RegisterErrorMap(STR_ERROR_INCOMPATIBLE_ROAD, ScriptRoad::ERR_UNSUITABLE_ROAD); ScriptError::RegisterErrorMapString(ScriptRoad::ERR_ROAD_WORKS_IN_PROGRESS, "ERR_ROAD_WORKS_IN_PROGRESS"); ScriptError::RegisterErrorMapString(ScriptRoad::ERR_ROAD_DRIVE_THROUGH_WRONG_DIRECTION, "ERR_ROAD_DRIVE_THROUGH_WRONG_DIRECTION"); ScriptError::RegisterErrorMapString(ScriptRoad::ERR_ROAD_CANNOT_BUILD_ON_TOWN_ROAD, "ERR_ROAD_CANNOT_BUILD_ON_TOWN_ROAD"); ScriptError::RegisterErrorMapString(ScriptRoad::ERR_ROAD_ONE_WAY_ROADS_CANNOT_HAVE_JUNCTIONS, "ERR_ROAD_ONE_WAY_ROADS_CANNOT_HAVE_JUNCTIONS"); + ScriptError::RegisterErrorMapString(ScriptRoad::ERR_ROADTYPE_DISALLOWS_CROSSING, "ERR_ROADTYPE_DISALLOWS_CROSSING"); + ScriptError::RegisterErrorMapString(ScriptRoad::ERR_UNSUITABLE_ROAD, "ERR_UNSUITABLE_ROAD"); + SQGSRoad.DefSQStaticMethod(engine, &ScriptRoad::GetName, "GetName", 2, ".i"); SQGSRoad.DefSQStaticMethod(engine, &ScriptRoad::GetRoadVehicleTypeForCargo, "GetRoadVehicleTypeForCargo", 2, ".i"); SQGSRoad.DefSQStaticMethod(engine, &ScriptRoad::IsRoadTile, "IsRoadTile", 2, ".i"); SQGSRoad.DefSQStaticMethod(engine, &ScriptRoad::IsRoadDepotTile, "IsRoadDepotTile", 2, ".i"); @@ -54,6 +63,9 @@ void SQGSRoad_Register(Squirrel *engine) SQGSRoad.DefSQStaticMethod(engine, &ScriptRoad::IsRoadTypeAvailable, "IsRoadTypeAvailable", 2, ".i"); SQGSRoad.DefSQStaticMethod(engine, &ScriptRoad::GetCurrentRoadType, "GetCurrentRoadType", 1, "."); SQGSRoad.DefSQStaticMethod(engine, &ScriptRoad::SetCurrentRoadType, "SetCurrentRoadType", 2, ".i"); + SQGSRoad.DefSQStaticMethod(engine, &ScriptRoad::RoadVehCanRunOnRoad, "RoadVehCanRunOnRoad", 3, ".ii"); + SQGSRoad.DefSQStaticMethod(engine, &ScriptRoad::RoadVehHasPowerOnRoad, "RoadVehHasPowerOnRoad", 3, ".ii"); + SQGSRoad.DefSQStaticMethod(engine, &ScriptRoad::ConvertRoadType, "ConvertRoadType", 4, ".iii"); SQGSRoad.DefSQStaticMethod(engine, &ScriptRoad::HasRoadType, "HasRoadType", 3, ".ii"); SQGSRoad.DefSQStaticMethod(engine, &ScriptRoad::AreRoadTilesConnected, "AreRoadTilesConnected", 3, ".ii"); SQGSRoad.DefSQStaticMethod(engine, &ScriptRoad::CanBuildConnectedRoadParts, "CanBuildConnectedRoadParts", 5, ".iaii"); @@ -74,6 +86,8 @@ void SQGSRoad_Register(Squirrel *engine) SQGSRoad.DefSQStaticMethod(engine, &ScriptRoad::RemoveRoadDepot, "RemoveRoadDepot", 2, ".i"); SQGSRoad.DefSQStaticMethod(engine, &ScriptRoad::RemoveRoadStation, "RemoveRoadStation", 2, ".i"); SQGSRoad.DefSQStaticMethod(engine, &ScriptRoad::GetBuildCost, "GetBuildCost", 3, ".ii"); + SQGSRoad.DefSQStaticMethod(engine, &ScriptRoad::GetRoadTramType, "GetRoadTramType", 2, ".i"); + SQGSRoad.DefSQStaticMethod(engine, &ScriptRoad::GetMaxSpeed, "GetMaxSpeed", 2, ".i"); SQGSRoad.DefSQStaticMethod(engine, &ScriptRoad::GetMaintenanceCostFactor, "GetMaintenanceCostFactor", 2, ".i"); SQGSRoad.PostRegister(engine); diff --git a/src/script/api/game/game_roadtypelist.hpp.sq b/src/script/api/game/game_roadtypelist.hpp.sq new file mode 100644 index 0000000000..0c5a74c577 --- /dev/null +++ b/src/script/api/game/game_roadtypelist.hpp.sq @@ -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 . + */ + +/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */ + +#include "../script_roadtypelist.hpp" +#include "../template/template_roadtypelist.hpp.sq" + + +template <> const char *GetClassName() { return "GSRoadTypeList"; } + +void SQGSRoadTypeList_Register(Squirrel *engine) +{ + DefSQClass SQGSRoadTypeList("GSRoadTypeList"); + SQGSRoadTypeList.PreRegister(engine, "GSList"); + SQGSRoadTypeList.AddConstructor(engine, "xi"); + + SQGSRoadTypeList.PostRegister(engine); +} diff --git a/src/script/api/game/game_sign.hpp.sq b/src/script/api/game/game_sign.hpp.sq index 0fba369cff..0ae48f1c00 100644 --- a/src/script/api/game/game_sign.hpp.sq +++ b/src/script/api/game/game_sign.hpp.sq @@ -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/script/api/game/game_signlist.hpp.sq b/src/script/api/game/game_signlist.hpp.sq index 9fc7ed7f2d..15a9d6903d 100644 --- a/src/script/api/game/game_signlist.hpp.sq +++ b/src/script/api/game/game_signlist.hpp.sq @@ -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/script/api/game/game_station.hpp.sq b/src/script/api/game/game_station.hpp.sq index 4c2f63b384..5c412850a4 100644 --- a/src/script/api/game/game_station.hpp.sq +++ b/src/script/api/game/game_station.hpp.sq @@ -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/script/api/game/game_stationlist.hpp.sq b/src/script/api/game/game_stationlist.hpp.sq index a3cdfaa967..e783778712 100644 --- a/src/script/api/game/game_stationlist.hpp.sq +++ b/src/script/api/game/game_stationlist.hpp.sq @@ -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/script/api/game/game_story_page.hpp.sq b/src/script/api/game/game_story_page.hpp.sq index 621399bb03..99bc237bf8 100644 --- a/src/script/api/game/game_story_page.hpp.sq +++ b/src/script/api/game/game_story_page.hpp.sq @@ -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/script/api/game/game_storypageelementlist.hpp.sq b/src/script/api/game/game_storypageelementlist.hpp.sq index 5ef3e6ed38..3c70a196cb 100644 --- a/src/script/api/game/game_storypageelementlist.hpp.sq +++ b/src/script/api/game/game_storypageelementlist.hpp.sq @@ -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/script/api/game/game_storypagelist.hpp.sq b/src/script/api/game/game_storypagelist.hpp.sq index 99b25a30ac..b6577e3b8a 100644 --- a/src/script/api/game/game_storypagelist.hpp.sq +++ b/src/script/api/game/game_storypagelist.hpp.sq @@ -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/script/api/game/game_subsidy.hpp.sq b/src/script/api/game/game_subsidy.hpp.sq index 2d636f74dc..8d2c4b200b 100644 --- a/src/script/api/game/game_subsidy.hpp.sq +++ b/src/script/api/game/game_subsidy.hpp.sq @@ -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/script/api/game/game_subsidylist.hpp.sq b/src/script/api/game/game_subsidylist.hpp.sq index 73dcbd4112..ff68ae3221 100644 --- a/src/script/api/game/game_subsidylist.hpp.sq +++ b/src/script/api/game/game_subsidylist.hpp.sq @@ -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/script/api/game/game_testmode.hpp.sq b/src/script/api/game/game_testmode.hpp.sq index 6e1175f061..8b6ab26fef 100644 --- a/src/script/api/game/game_testmode.hpp.sq +++ b/src/script/api/game/game_testmode.hpp.sq @@ -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/script/api/game/game_text.hpp.sq b/src/script/api/game/game_text.hpp.sq index 8a35279d0b..b0563eaba7 100644 --- a/src/script/api/game/game_text.hpp.sq +++ b/src/script/api/game/game_text.hpp.sq @@ -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/script/api/game/game_tile.hpp.sq b/src/script/api/game/game_tile.hpp.sq index 6224919ffb..694708c8eb 100644 --- a/src/script/api/game/game_tile.hpp.sq +++ b/src/script/api/game/game_tile.hpp.sq @@ -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. @@ -26,6 +24,7 @@ void SQGSTile_Register(Squirrel *engine) SQGSTile.DefSQConst(engine, ScriptTile::ERR_TILE_TOO_LOW, "ERR_TILE_TOO_LOW"); SQGSTile.DefSQConst(engine, ScriptTile::ERR_AREA_ALREADY_FLAT, "ERR_AREA_ALREADY_FLAT"); SQGSTile.DefSQConst(engine, ScriptTile::ERR_EXCAVATION_WOULD_DAMAGE, "ERR_EXCAVATION_WOULD_DAMAGE"); + SQGSTile.DefSQConst(engine, ScriptTile::ERR_LIMIT_REACHED, "ERR_LIMIT_REACHED"); SQGSTile.DefSQConst(engine, ScriptTile::CORNER_W, "CORNER_W"); SQGSTile.DefSQConst(engine, ScriptTile::CORNER_S, "CORNER_S"); SQGSTile.DefSQConst(engine, ScriptTile::CORNER_E, "CORNER_E"); @@ -71,15 +70,19 @@ void SQGSTile_Register(Squirrel *engine) SQGSTile.DefSQConst(engine, ScriptTile::TERRAIN_RAINFOREST, "TERRAIN_RAINFOREST"); SQGSTile.DefSQConst(engine, ScriptTile::TERRAIN_SNOW, "TERRAIN_SNOW"); - ScriptError::RegisterErrorMap(STR_ERROR_ALREADY_AT_SEA_LEVEL, ScriptTile::ERR_TILE_TOO_HIGH); - ScriptError::RegisterErrorMap(STR_ERROR_ALREADY_AT_SEA_LEVEL, ScriptTile::ERR_TILE_TOO_LOW); - ScriptError::RegisterErrorMap(STR_ERROR_ALREADY_LEVELLED, ScriptTile::ERR_AREA_ALREADY_FLAT); - ScriptError::RegisterErrorMap(STR_ERROR_EXCAVATION_WOULD_DAMAGE, ScriptTile::ERR_EXCAVATION_WOULD_DAMAGE); + ScriptError::RegisterErrorMap(STR_ERROR_ALREADY_AT_SEA_LEVEL, ScriptTile::ERR_TILE_TOO_HIGH); + ScriptError::RegisterErrorMap(STR_ERROR_ALREADY_AT_SEA_LEVEL, ScriptTile::ERR_TILE_TOO_LOW); + ScriptError::RegisterErrorMap(STR_ERROR_ALREADY_LEVELLED, ScriptTile::ERR_AREA_ALREADY_FLAT); + ScriptError::RegisterErrorMap(STR_ERROR_EXCAVATION_WOULD_DAMAGE, ScriptTile::ERR_EXCAVATION_WOULD_DAMAGE); + ScriptError::RegisterErrorMap(STR_ERROR_TERRAFORM_LIMIT_REACHED, ScriptTile::ERR_LIMIT_REACHED); + ScriptError::RegisterErrorMap(STR_ERROR_CLEARING_LIMIT_REACHED, ScriptTile::ERR_LIMIT_REACHED); + ScriptError::RegisterErrorMap(STR_ERROR_TREE_PLANT_LIMIT_REACHED, ScriptTile::ERR_LIMIT_REACHED); ScriptError::RegisterErrorMapString(ScriptTile::ERR_TILE_TOO_HIGH, "ERR_TILE_TOO_HIGH"); ScriptError::RegisterErrorMapString(ScriptTile::ERR_TILE_TOO_LOW, "ERR_TILE_TOO_LOW"); ScriptError::RegisterErrorMapString(ScriptTile::ERR_AREA_ALREADY_FLAT, "ERR_AREA_ALREADY_FLAT"); ScriptError::RegisterErrorMapString(ScriptTile::ERR_EXCAVATION_WOULD_DAMAGE, "ERR_EXCAVATION_WOULD_DAMAGE"); + ScriptError::RegisterErrorMapString(ScriptTile::ERR_LIMIT_REACHED, "ERR_LIMIT_REACHED"); SQGSTile.DefSQStaticMethod(engine, &ScriptTile::IsBuildable, "IsBuildable", 2, ".i"); SQGSTile.DefSQStaticMethod(engine, &ScriptTile::IsBuildableRectangle, "IsBuildableRectangle", 4, ".iii"); diff --git a/src/script/api/game/game_tilelist.hpp.sq b/src/script/api/game/game_tilelist.hpp.sq index a4ade9cc50..5cf05e785f 100644 --- a/src/script/api/game/game_tilelist.hpp.sq +++ b/src/script/api/game/game_tilelist.hpp.sq @@ -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/script/api/game/game_town.hpp.sq b/src/script/api/game/game_town.hpp.sq index 30eec6928a..5cf394ca1c 100644 --- a/src/script/api/game/game_town.hpp.sq +++ b/src/script/api/game/game_town.hpp.sq @@ -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. @@ -81,6 +79,8 @@ void SQGSTown_Register(Squirrel *engine) SQGSTown.DefSQStaticMethod(engine, &ScriptTown::ExpandTown, "ExpandTown", 3, ".ii"); SQGSTown.DefSQStaticMethod(engine, &ScriptTown::FoundTown, "FoundTown", 6, ".iibi."); SQGSTown.DefSQStaticMethod(engine, &ScriptTown::GetRating, "GetRating", 3, ".ii"); + SQGSTown.DefSQStaticMethod(engine, &ScriptTown::GetDetailedRating, "GetDetailedRating", 3, ".ii"); + SQGSTown.DefSQStaticMethod(engine, &ScriptTown::ChangeRating, "ChangeRating", 4, ".iii"); SQGSTown.DefSQStaticMethod(engine, &ScriptTown::GetAllowedNoise, "GetAllowedNoise", 2, ".i"); SQGSTown.DefSQStaticMethod(engine, &ScriptTown::GetRoadLayout, "GetRoadLayout", 2, ".i"); diff --git a/src/script/api/game/game_townlist.hpp.sq b/src/script/api/game/game_townlist.hpp.sq index a0d8c7f1da..2445305b98 100644 --- a/src/script/api/game/game_townlist.hpp.sq +++ b/src/script/api/game/game_townlist.hpp.sq @@ -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/script/api/game/game_tunnel.hpp.sq b/src/script/api/game/game_tunnel.hpp.sq index cea1cf11c8..8639036796 100644 --- a/src/script/api/game/game_tunnel.hpp.sq +++ b/src/script/api/game/game_tunnel.hpp.sq @@ -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/script/api/game/game_vehicle.hpp.sq b/src/script/api/game/game_vehicle.hpp.sq index 3dc9fe67ad..de58e05e64 100644 --- a/src/script/api/game/game_vehicle.hpp.sq +++ b/src/script/api/game/game_vehicle.hpp.sq @@ -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. @@ -123,6 +121,8 @@ void SQGSVehicle_Register(Squirrel *engine) SQGSVehicle.DefSQStaticMethod(engine, &ScriptVehicle::IsInDepot, "IsInDepot", 2, ".i"); SQGSVehicle.DefSQStaticMethod(engine, &ScriptVehicle::IsStoppedInDepot, "IsStoppedInDepot", 2, ".i"); SQGSVehicle.DefSQStaticMethod(engine, &ScriptVehicle::BuildVehicle, "BuildVehicle", 3, ".ii"); + SQGSVehicle.DefSQStaticMethod(engine, &ScriptVehicle::BuildVehicleWithRefit, "BuildVehicleWithRefit", 4, ".iii"); + SQGSVehicle.DefSQStaticMethod(engine, &ScriptVehicle::GetBuildWithRefitCapacity, "GetBuildWithRefitCapacity", 4, ".iii"); SQGSVehicle.DefSQStaticMethod(engine, &ScriptVehicle::CloneVehicle, "CloneVehicle", 4, ".iib"); SQGSVehicle.DefSQStaticMethod(engine, &ScriptVehicle::MoveWagon, "MoveWagon", 5, ".iiii"); SQGSVehicle.DefSQStaticMethod(engine, &ScriptVehicle::MoveWagonChain, "MoveWagonChain", 5, ".iiii"); diff --git a/src/script/api/game/game_vehiclelist.hpp.sq b/src/script/api/game/game_vehiclelist.hpp.sq index c5c6a18a72..b4dcf4b82c 100644 --- a/src/script/api/game/game_vehiclelist.hpp.sq +++ b/src/script/api/game/game_vehiclelist.hpp.sq @@ -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/script/api/game/game_viewport.hpp.sq b/src/script/api/game/game_viewport.hpp.sq index 357357ae39..6d7d2a8a96 100644 --- a/src/script/api/game/game_viewport.hpp.sq +++ b/src/script/api/game/game_viewport.hpp.sq @@ -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/script/api/game/game_waypoint.hpp.sq b/src/script/api/game/game_waypoint.hpp.sq index 984e1fa2f5..f74902c97f 100644 --- a/src/script/api/game/game_waypoint.hpp.sq +++ b/src/script/api/game/game_waypoint.hpp.sq @@ -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/script/api/game/game_waypointlist.hpp.sq b/src/script/api/game/game_waypointlist.hpp.sq index ccb428ce6b..92827c89be 100644 --- a/src/script/api/game/game_waypointlist.hpp.sq +++ b/src/script/api/game/game_waypointlist.hpp.sq @@ -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/script/api/game/game_window.hpp.sq b/src/script/api/game/game_window.hpp.sq index 6d03b460ad..32ada0d896 100644 --- a/src/script/api/game/game_window.hpp.sq +++ b/src/script/api/game/game_window.hpp.sq @@ -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. @@ -140,6 +138,7 @@ void SQGSWindow_Register(Squirrel *engine) SQGSWindow.DefSQConst(engine, ScriptWindow::WC_SAVE_PRESET, "WC_SAVE_PRESET"); SQGSWindow.DefSQConst(engine, ScriptWindow::WC_FRAMERATE_DISPLAY, "WC_FRAMERATE_DISPLAY"); SQGSWindow.DefSQConst(engine, ScriptWindow::WC_FRAMETIME_GRAPH, "WC_FRAMETIME_GRAPH"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WC_SCREENSHOT, "WC_SCREENSHOT"); SQGSWindow.DefSQConst(engine, ScriptWindow::WC_INVALID, "WC_INVALID"); SQGSWindow.DefSQConst(engine, ScriptWindow::TC_BLUE, "TC_BLUE"); SQGSWindow.DefSQConst(engine, ScriptWindow::TC_SILVER, "TC_SILVER"); @@ -227,8 +226,8 @@ void SQGSWindow_Register(Squirrel *engine) SQGSWindow.DefSQConst(engine, ScriptWindow::WID_RV_START_REPLACE, "WID_RV_START_REPLACE"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_RV_INFO_TAB, "WID_RV_INFO_TAB"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_RV_STOP_REPLACE, "WID_RV_STOP_REPLACE"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_RV_RAIL_ROAD_TYPE_DROPDOWN, "WID_RV_RAIL_ROAD_TYPE_DROPDOWN"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_RV_TRAIN_ENGINEWAGON_DROPDOWN, "WID_RV_TRAIN_ENGINEWAGON_DROPDOWN"); - SQGSWindow.DefSQConst(engine, ScriptWindow::WID_RV_TRAIN_RAILTYPE_DROPDOWN, "WID_RV_TRAIN_RAILTYPE_DROPDOWN"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_RV_TRAIN_WAGONREMOVE_TOGGLE, "WID_RV_TRAIN_WAGONREMOVE_TOGGLE"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_BB_BACKGROUND, "WID_BB_BACKGROUND"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_BAFD_QUESTION, "WID_BAFD_QUESTION"); @@ -385,6 +384,8 @@ void SQGSWindow_Register(Squirrel *engine) SQGSWindow.DefSQConst(engine, ScriptWindow::WID_CI_RAIL_COUNT, "WID_CI_RAIL_COUNT"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_CI_ROAD_DESC, "WID_CI_ROAD_DESC"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_CI_ROAD_COUNT, "WID_CI_ROAD_COUNT"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_CI_TRAM_DESC, "WID_CI_TRAM_DESC"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_CI_TRAM_COUNT, "WID_CI_TRAM_COUNT"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_CI_WATER_DESC, "WID_CI_WATER_DESC"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_CI_WATER_COUNT, "WID_CI_WATER_COUNT"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_CI_STATION_DESC, "WID_CI_STATION_DESC"); @@ -466,6 +467,8 @@ void SQGSWindow_Register(Squirrel *engine) SQGSWindow.DefSQConst(engine, ScriptWindow::WID_FRW_TIMES_NAMES, "WID_FRW_TIMES_NAMES"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_FRW_TIMES_CURRENT, "WID_FRW_TIMES_CURRENT"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_FRW_TIMES_AVERAGE, "WID_FRW_TIMES_AVERAGE"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_FRW_ALLOCSIZE, "WID_FRW_ALLOCSIZE"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_FRW_SEL_MEMORY, "WID_FRW_SEL_MEMORY"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_FRW_SCROLLBAR, "WID_FRW_SCROLLBAR"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_FGW_CAPTION, "WID_FGW_CAPTION"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_FGW_GRAPH, "WID_FGW_GRAPH"); @@ -586,6 +589,8 @@ void SQGSWindow_Register(Squirrel *engine) SQGSWindow.DefSQConst(engine, ScriptWindow::WID_IV_DISPLAY, "WID_IV_DISPLAY"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_ID_DROPDOWN_ORDER, "WID_ID_DROPDOWN_ORDER"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_ID_DROPDOWN_CRITERIA, "WID_ID_DROPDOWN_CRITERIA"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_ID_FILTER_BY_ACC_CARGO, "WID_ID_FILTER_BY_ACC_CARGO"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_ID_FILTER_BY_PROD_CARGO, "WID_ID_FILTER_BY_PROD_CARGO"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_ID_INDUSTRY_LIST, "WID_ID_INDUSTRY_LIST"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_ID_SCROLLBAR, "WID_ID_SCROLLBAR"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_IC_CAPTION, "WID_IC_CAPTION"); @@ -636,6 +641,7 @@ void SQGSWindow_Register(Squirrel *engine) SQGSWindow.DefSQConst(engine, ScriptWindow::WID_A_WEBSITE, "WID_A_WEBSITE"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_QS_CAPTION, "WID_QS_CAPTION"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_QS_TEXT, "WID_QS_TEXT"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_QS_WARNING, "WID_QS_WARNING"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_QS_DEFAULT, "WID_QS_DEFAULT"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_QS_CANCEL, "WID_QS_CANCEL"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_QS_OK, "WID_QS_OK"); @@ -782,6 +788,7 @@ void SQGSWindow_Register(Squirrel *engine) SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NCP_LABEL, "WID_NCP_LABEL"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NCP_PASSWORD, "WID_NCP_PASSWORD"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NCP_SAVE_AS_DEFAULT_PASSWORD, "WID_NCP_SAVE_AS_DEFAULT_PASSWORD"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NCP_WARNING, "WID_NCP_WARNING"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NCP_CANCEL, "WID_NCP_CANCEL"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NCP_OK, "WID_NCP_OK"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_NGRFI_CAPTION, "WID_NGRFI_CAPTION"); @@ -868,6 +875,7 @@ void SQGSWindow_Register(Squirrel *engine) SQGSWindow.DefSQConst(engine, ScriptWindow::WID_N_VEH_NAME, "WID_N_VEH_NAME"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_N_VEH_SPR, "WID_N_VEH_SPR"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_N_VEH_INFO, "WID_N_VEH_INFO"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_N_SHOW_GROUP, "WID_N_SHOW_GROUP"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_MH_STICKYBOX, "WID_MH_STICKYBOX"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_MH_BACKGROUND, "WID_MH_BACKGROUND"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_MH_SCROLLBAR, "WID_MH_SCROLLBAR"); @@ -996,6 +1004,7 @@ void SQGSWindow_Register(Squirrel *engine) SQGSWindow.DefSQConst(engine, ScriptWindow::WID_BRW_WAYPOINT_MATRIX, "WID_BRW_WAYPOINT_MATRIX"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_BRW_WAYPOINT, "WID_BRW_WAYPOINT"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_BRW_SCROLL, "WID_BRW_SCROLL"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_ROT_CAPTION, "WID_ROT_CAPTION"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_ROT_ROAD_X, "WID_ROT_ROAD_X"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_ROT_ROAD_Y, "WID_ROT_ROAD_Y"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_ROT_AUTOROAD, "WID_ROT_AUTOROAD"); @@ -1007,6 +1016,7 @@ void SQGSWindow_Register(Squirrel *engine) SQGSWindow.DefSQConst(engine, ScriptWindow::WID_ROT_BUILD_BRIDGE, "WID_ROT_BUILD_BRIDGE"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_ROT_BUILD_TUNNEL, "WID_ROT_BUILD_TUNNEL"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_ROT_REMOVE, "WID_ROT_REMOVE"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_ROT_CONVERT_ROAD, "WID_ROT_CONVERT_ROAD"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_BROD_CAPTION, "WID_BROD_CAPTION"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_BROD_DEPOT_NE, "WID_BROD_DEPOT_NE"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_BROD_DEPOT_SE, "WID_BROD_DEPOT_SE"); @@ -1023,6 +1033,12 @@ void SQGSWindow_Register(Squirrel *engine) SQGSWindow.DefSQConst(engine, ScriptWindow::WID_BROS_LT_OFF, "WID_BROS_LT_OFF"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_BROS_LT_ON, "WID_BROS_LT_ON"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_BROS_INFO, "WID_BROS_INFO"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SC_TAKE, "WID_SC_TAKE"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SC_TAKE_ZOOMIN, "WID_SC_TAKE_ZOOMIN"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SC_TAKE_DEFAULTZOOM, "WID_SC_TAKE_DEFAULTZOOM"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SC_TAKE_WORLD, "WID_SC_TAKE_WORLD"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SC_TAKE_HEIGHTMAP, "WID_SC_TAKE_HEIGHTMAP"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SC_TAKE_MINIMAP, "WID_SC_TAKE_MINIMAP"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_GO_BACKGROUND, "WID_GO_BACKGROUND"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_GO_CURRENCY_DROPDOWN, "WID_GO_CURRENCY_DROPDOWN"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_GO_DISTANCE_DROPDOWN, "WID_GO_DISTANCE_DROPDOWN"); @@ -1117,6 +1133,7 @@ void SQGSWindow_Register(Squirrel *engine) SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SV_ROADVEHS, "WID_SV_ROADVEHS"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SV_SHIPS, "WID_SV_SHIPS"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SV_PLANES, "WID_SV_PLANES"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_SV_CATCHMENT, "WID_SV_CATCHMENT"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_STL_CAPTION, "WID_STL_CAPTION"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_STL_LIST, "WID_STL_LIST"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_STL_SCROLLBAR, "WID_STL_SCROLLBAR"); @@ -1213,6 +1230,7 @@ void SQGSWindow_Register(Squirrel *engine) SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TN_BUILDING_TOOLS_START, "WID_TN_BUILDING_TOOLS_START"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TN_RAILS, "WID_TN_RAILS"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TN_ROADS, "WID_TN_ROADS"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TN_TRAMS, "WID_TN_TRAMS"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TN_WATER, "WID_TN_WATER"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TN_AIR, "WID_TN_AIR"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TN_LANDSCAPE, "WID_TN_LANDSCAPE"); @@ -1239,6 +1257,7 @@ void SQGSWindow_Register(Squirrel *engine) SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TE_TOWN_GENERATE, "WID_TE_TOWN_GENERATE"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TE_INDUSTRY, "WID_TE_INDUSTRY"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TE_ROADS, "WID_TE_ROADS"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TE_TRAMS, "WID_TE_TRAMS"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TE_WATER, "WID_TE_WATER"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TE_TREES, "WID_TE_TREES"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TE_SIGNS, "WID_TE_SIGNS"); @@ -1248,10 +1267,12 @@ void SQGSWindow_Register(Squirrel *engine) SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TE_SWITCH_BAR, "WID_TE_SWITCH_BAR"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TD_SORT_ORDER, "WID_TD_SORT_ORDER"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TD_SORT_CRITERIA, "WID_TD_SORT_CRITERIA"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TD_FILTER, "WID_TD_FILTER"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TD_LIST, "WID_TD_LIST"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TD_SCROLLBAR, "WID_TD_SCROLLBAR"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TD_WORLD_POPULATION, "WID_TD_WORLD_POPULATION"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TA_CAPTION, "WID_TA_CAPTION"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TA_ZONE_BUTTON, "WID_TA_ZONE_BUTTON"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TA_RATING_INFO, "WID_TA_RATING_INFO"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TA_COMMAND_LIST, "WID_TA_COMMAND_LIST"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TA_SCROLLBAR, "WID_TA_SCROLLBAR"); @@ -1263,6 +1284,7 @@ void SQGSWindow_Register(Squirrel *engine) SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TV_CENTER_VIEW, "WID_TV_CENTER_VIEW"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TV_SHOW_AUTHORITY, "WID_TV_SHOW_AUTHORITY"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TV_CHANGE_NAME, "WID_TV_CHANGE_NAME"); + SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TV_CATCHMENT, "WID_TV_CATCHMENT"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TV_EXPAND, "WID_TV_EXPAND"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TV_DELETE, "WID_TV_DELETE"); SQGSWindow.DefSQConst(engine, ScriptWindow::WID_TF_NEW_TOWN, "WID_TF_NEW_TOWN"); diff --git a/src/script/api/game_changelog.hpp b/src/script/api/game_changelog.hpp index 094449d73b..235dcee986 100644 --- a/src/script/api/game_changelog.hpp +++ b/src/script/api/game_changelog.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. @@ -15,9 +13,23 @@ * functions may still be available if you return an older API version * in GetAPIVersion() in info.nut. * + * \b 1.10.0 + * + * This version is not yet released. The following changes are not set in stone yet. + * + * API additions: + * \li GSVehicle::BuildVehicleWithRefit + * \li GSVehicle::GetBuildWithRefitCapacity + * \li GSRoad::GetName + * \li GSRoad::RoadVehCanRunOnRoad + * \li GSRoad::RoadVehHasPowerOnRoad + * \li GSRoad::ConvertRoadType + * \li GSRoad::GetMaxSpeed + * \li GSEngine::EnableForCompany + * \li GSEngine::DisableForCompany + * * \b 1.9.0 * - * 1.9.0 is not yet released. The following changes are not set in stone yet. * API additions: * \li GSAirport::GetMonthlyMaintenanceCost * \li GSClient @@ -35,6 +47,9 @@ * * No changes * + * API additions: + * \li GSRoad::ERR_ROADTYPE_DISALLOWS_CROSSING + * * \b 1.7.0 - 1.7.2 * * No changes diff --git a/src/script/api/generate_widget.awk b/src/script/api/generate_widget.awk index cdbe59d970..fe9fbe8345 100644 --- a/src/script/api/generate_widget.awk +++ b/src/script/api/generate_widget.awk @@ -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. # 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. diff --git a/src/script/api/generate_widget.sh b/src/script/api/generate_widget.sh index 96ef5dfb3a..bd5fdab1d4 100755 --- a/src/script/api/generate_widget.sh +++ b/src/script/api/generate_widget.sh @@ -1,7 +1,5 @@ #!/bin/bash -# $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. # 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. diff --git a/src/script/api/generate_widget.vbs b/src/script/api/generate_widget.vbs index 0bd38bb299..c737bcf4de 100644 --- a/src/script/api/generate_widget.vbs +++ b/src/script/api/generate_widget.vbs @@ -1,7 +1,5 @@ Option Explicit -' $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. ' 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. diff --git a/src/script/api/script_accounting.cpp b/src/script/api/script_accounting.cpp index e6fddf9e8c..1564c2e1ef 100644 --- a/src/script/api/script_accounting.cpp +++ b/src/script/api/script_accounting.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. diff --git a/src/script/api/script_accounting.hpp b/src/script/api/script_accounting.hpp index aa438ab54f..04c022e735 100644 --- a/src/script/api/script_accounting.hpp +++ b/src/script/api/script_accounting.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/script/api/script_admin.cpp b/src/script/api/script_admin.cpp index f66d9fc8a8..8f7371266d 100644 --- a/src/script/api/script_admin.cpp +++ b/src/script/api/script_admin.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. @@ -135,7 +133,6 @@ std::string json; ScriptAdmin::MakeJSON(vm, -1, SQUIRREL_MAX_DEPTH, json); -#ifdef ENABLE_NETWORK if (json.length() > NETWORK_GAMESCRIPT_JSON_LENGTH) { ScriptLog::Error("You are trying to send a table that is too large to the AdminPort. No data sent."); sq_pushinteger(vm, 0); @@ -143,7 +140,6 @@ } NetworkAdminGameScript(json.c_str()); -#endif /* ENABLE_NETWORK */ sq_pushinteger(vm, 1); return 1; diff --git a/src/script/api/script_admin.hpp b/src/script/api/script_admin.hpp index 48126eac0b..95b7218eb0 100644 --- a/src/script/api/script_admin.hpp +++ b/src/script/api/script_admin.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/script/api/script_airport.cpp b/src/script/api/script_airport.cpp index 8e19d257df..9477191724 100644 --- a/src/script/api/script_airport.cpp +++ b/src/script/api/script_airport.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. @@ -130,17 +128,20 @@ /* static */ int ScriptAirport::GetNoiseLevelIncrease(TileIndex tile, AirportType type) { - extern Town *AirportGetNearestTown(const AirportSpec *as, const TileIterator &it); - extern uint8 GetAirportNoiseLevelForTown(const AirportSpec *as, TileIterator &it, TileIndex town_tile); + 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; + const AirportSpec *as = ::AirportSpec::Get(type); + if (!as->IsWithinMapBounds(0, tile)) return -1; + if (_settings_game.economy.station_noise_level) { - const AirportSpec *as = ::AirportSpec::Get(type); AirportTileTableIterator it(as->table[0], tile); - const Town *t = AirportGetNearestTown(as, it); - return GetAirportNoiseLevelForTown(as, it, t->xy); + uint dist; + AirportGetNearestTown(as, it, dist); + return GetAirportNoiseLevelForDistance(as, dist); } return 1; @@ -148,13 +149,16 @@ /* static */ TownID ScriptAirport::GetNearestTown(TileIndex tile, AirportType type) { - extern Town *AirportGetNearestTown(const AirportSpec *as, const TileIterator &it); + extern Town *AirportGetNearestTown(const AirportSpec *as, const TileIterator &it, uint &mindist); if (!::IsValidTile(tile)) return INVALID_TOWN; if (!IsAirportInformationAvailable(type)) return INVALID_TOWN; const AirportSpec *as = AirportSpec::Get(type); - return AirportGetNearestTown(as, AirportTileTableIterator(as->table[0], tile))->index; + if (!as->IsWithinMapBounds(0, tile)) return INVALID_TOWN; + + uint dist; + return AirportGetNearestTown(as, AirportTileTableIterator(as->table[0], tile), dist)->index; } /* static */ uint16 ScriptAirport::GetMaintenanceCostFactor(AirportType type) diff --git a/src/script/api/script_airport.hpp b/src/script/api/script_airport.hpp index 6073a2bdd6..0748fa67fc 100644 --- a/src/script/api/script_airport.hpp +++ b/src/script/api/script_airport.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/script/api/script_base.cpp b/src/script/api/script_base.cpp index 5b2d550b8c..996d4d488f 100644 --- a/src/script/api/script_base.cpp +++ b/src/script/api/script_base.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. diff --git a/src/script/api/script_base.hpp b/src/script/api/script_base.hpp index 936dee77d9..b8eebdf1b0 100644 --- a/src/script/api/script_base.hpp +++ b/src/script/api/script_base.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/script/api/script_basestation.cpp b/src/script/api/script_basestation.cpp index 229abf8657..860e54c787 100644 --- a/src/script/api/script_basestation.cpp +++ b/src/script/api/script_basestation.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. @@ -22,12 +20,12 @@ /* static */ bool ScriptBaseStation::IsValidBaseStation(StationID station_id) { const BaseStation *st = ::BaseStation::GetIfValid(station_id); - return st != NULL && (st->owner == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY || st->owner == OWNER_NONE); + return st != nullptr && (st->owner == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY || st->owner == OWNER_NONE); } /* static */ char *ScriptBaseStation::GetName(StationID station_id) { - if (!IsValidBaseStation(station_id)) return NULL; + if (!IsValidBaseStation(station_id)) return nullptr; ::SetDParam(0, station_id); return GetString(::Station::IsValidID(station_id) ? STR_STATION_NAME : STR_WAYPOINT_NAME); @@ -39,7 +37,7 @@ EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); EnforcePrecondition(false, IsValidBaseStation(station_id)); - EnforcePrecondition(false, name != NULL); + EnforcePrecondition(false, name != nullptr); const char *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 9676829f67..85a34eac4f 100644 --- a/src/script/api/script_basestation.hpp +++ b/src/script/api/script_basestation.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. @@ -52,7 +50,7 @@ public: * @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 != NULL && len(name) != 0. + * @pre name != nullptr && len(name) != 0. * @game @pre Valid ScriptCompanyMode active in scope. * @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 f532f11b73..0a7c185524 100644 --- a/src/script/api/script_bridge.cpp +++ b/src/script/api/script_bridge.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. @@ -83,7 +81,7 @@ static void _DoCommandReturnBuildBridge1(class ScriptInstance *instance) switch (vehicle_type) { case ScriptVehicle::VT_ROAD: type |= (TRANSPORT_ROAD << 15); - type |= (::RoadTypeToRoadTypes((::RoadType)ScriptObject::GetRoadType()) << 8); + type |= (ScriptRoad::GetCurrentRoadType() << 8); break; case ScriptVehicle::VT_RAIL: type |= (TRANSPORT_RAIL << 15); @@ -102,7 +100,7 @@ static void _DoCommandReturnBuildBridge1(class ScriptInstance *instance) ScriptObject::SetCallbackVariable(0, start); ScriptObject::SetCallbackVariable(1, end); - return ScriptObject::DoCommand(end, start, type | bridge_id, CMD_BUILD_BRIDGE, NULL, &::_DoCommandReturnBuildBridge1); + return ScriptObject::DoCommand(end, start, type | bridge_id, CMD_BUILD_BRIDGE, nullptr, &::_DoCommandReturnBuildBridge1); } /* static */ bool ScriptBridge::_BuildBridgeRoad1() @@ -114,7 +112,7 @@ static void _DoCommandReturnBuildBridge1(class ScriptInstance *instance) DiagDirection dir_1 = ::DiagdirBetweenTiles(end, start); DiagDirection dir_2 = ::ReverseDiagDir(dir_1); - return ScriptObject::DoCommand(start + ::TileOffsByDiagDir(dir_1), ::DiagDirToRoadBits(dir_2) | (ScriptObject::GetRoadType() << 4), 0, CMD_BUILD_ROAD, NULL, &::_DoCommandReturnBuildBridge2); + return ScriptObject::DoCommand(start + ::TileOffsByDiagDir(dir_1), ::DiagDirToRoadBits(dir_2) | (ScriptRoad::GetCurrentRoadType() << 4), 0, CMD_BUILD_ROAD, nullptr, &::_DoCommandReturnBuildBridge2); } /* static */ bool ScriptBridge::_BuildBridgeRoad2() @@ -126,7 +124,7 @@ static void _DoCommandReturnBuildBridge1(class ScriptInstance *instance) DiagDirection dir_1 = ::DiagdirBetweenTiles(end, start); DiagDirection dir_2 = ::ReverseDiagDir(dir_1); - return ScriptObject::DoCommand(end + ::TileOffsByDiagDir(dir_2), ::DiagDirToRoadBits(dir_1) | (ScriptObject::GetRoadType() << 4), 0, CMD_BUILD_ROAD); + return ScriptObject::DoCommand(end + ::TileOffsByDiagDir(dir_2), ::DiagDirToRoadBits(dir_1) | (ScriptRoad::GetCurrentRoadType() << 4), 0, CMD_BUILD_ROAD); } /* static */ bool ScriptBridge::RemoveBridge(TileIndex tile) @@ -138,8 +136,8 @@ static void _DoCommandReturnBuildBridge1(class ScriptInstance *instance) /* static */ char *ScriptBridge::GetName(BridgeID bridge_id, ScriptVehicle::VehicleType vehicle_type) { - EnforcePrecondition(NULL, vehicle_type == ScriptVehicle::VT_ROAD || vehicle_type == ScriptVehicle::VT_RAIL || vehicle_type == ScriptVehicle::VT_WATER); - if (!IsValidBridge(bridge_id)) return NULL; + EnforcePrecondition(nullptr, vehicle_type == ScriptVehicle::VT_ROAD || vehicle_type == ScriptVehicle::VT_RAIL || vehicle_type == ScriptVehicle::VT_WATER); + if (!IsValidBridge(bridge_id)) return nullptr; return GetString(vehicle_type == ScriptVehicle::VT_WATER ? STR_LAI_BRIDGE_DESCRIPTION_AQUEDUCT : ::GetBridgeSpec(bridge_id)->transport_name[vehicle_type]); } diff --git a/src/script/api/script_bridge.hpp b/src/script/api/script_bridge.hpp index 5327d42062..26d7e11619 100644 --- a/src/script/api/script_bridge.hpp +++ b/src/script/api/script_bridge.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/script/api/script_bridgelist.cpp b/src/script/api/script_bridgelist.cpp index 0969342ecb..a81c186edb 100644 --- a/src/script/api/script_bridgelist.cpp +++ b/src/script/api/script_bridgelist.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. diff --git a/src/script/api/script_bridgelist.hpp b/src/script/api/script_bridgelist.hpp index ed09af8b16..78088fe695 100644 --- a/src/script/api/script_bridgelist.hpp +++ b/src/script/api/script_bridgelist.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/script/api/script_cargo.cpp b/src/script/api/script_cargo.cpp index a2643f897f..67cbc1930c 100644 --- a/src/script/api/script_cargo.cpp +++ b/src/script/api/script_cargo.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. @@ -29,7 +27,7 @@ /* static */ char *ScriptCargo::GetCargoLabel(CargoID cargo_type) { - if (!IsValidCargo(cargo_type)) return NULL; + if (!IsValidCargo(cargo_type)) return nullptr; const CargoSpec *cargo = ::CargoSpec::Get(cargo_type); /* cargo->label is a uint32 packing a 4 character non-terminated string, diff --git a/src/script/api/script_cargo.hpp b/src/script/api/script_cargo.hpp index d1bfdd1fcc..4aab97c70e 100644 --- a/src/script/api/script_cargo.hpp +++ b/src/script/api/script_cargo.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. @@ -36,7 +34,7 @@ public: CC_LIQUID = ::CC_LIQUID, ///< Liquids (Oil, Water, Rubber) CC_REFRIGERATED = ::CC_REFRIGERATED, ///< Refrigerated cargo (Food, Fruit) CC_HAZARDOUS = ::CC_HAZARDOUS, ///< Hazardous cargo (Nuclear Fuel, Explosives, etc.) - CC_COVERED = ::CC_COVERED, ///< Covered/Sheltered Freight (Transporation in Box Vans, Silo Wagons, etc.) + CC_COVERED = ::CC_COVERED, ///< Covered/Sheltered Freight (Transportation in Box Vans, Silo Wagons, etc.) }; /** diff --git a/src/script/api/script_cargolist.cpp b/src/script/api/script_cargolist.cpp index b96cd721e9..fbd150c6cf 100644 --- a/src/script/api/script_cargolist.cpp +++ b/src/script/api/script_cargolist.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. diff --git a/src/script/api/script_cargolist.hpp b/src/script/api/script_cargolist.hpp index a7cd8b69b5..11223debc1 100644 --- a/src/script/api/script_cargolist.hpp +++ b/src/script/api/script_cargolist.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/script/api/script_cargomonitor.cpp b/src/script/api/script_cargomonitor.cpp index 3cb9b4a8e7..dcb18b1ddb 100644 --- a/src/script/api/script_cargomonitor.cpp +++ b/src/script/api/script_cargomonitor.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. @@ -20,7 +18,7 @@ /* static */ int32 ScriptCargoMonitor::GetTownDeliveryAmount(ScriptCompany::CompanyID company, CargoID cargo, TownID town_id, bool keep_monitoring) { CompanyID cid = static_cast(company); - if (cid < OWNER_BEGIN || cid >= MAX_COMPANIES) return -1; + if (cid >= MAX_COMPANIES) return -1; if (!ScriptCargo::IsValidCargo(cargo)) return -1; if (!::Town::IsValidID(town_id)) return -1; @@ -31,7 +29,7 @@ /* static */ int32 ScriptCargoMonitor::GetIndustryDeliveryAmount(ScriptCompany::CompanyID company, CargoID cargo, IndustryID industry_id, bool keep_monitoring) { CompanyID cid = static_cast(company); - if (cid < OWNER_BEGIN || cid >= MAX_COMPANIES) return -1; + if (cid >= MAX_COMPANIES) return -1; if (!ScriptCargo::IsValidCargo(cargo)) return -1; if (!::Industry::IsValidID(industry_id)) return -1; @@ -42,7 +40,7 @@ /* static */ int32 ScriptCargoMonitor::GetTownPickupAmount(ScriptCompany::CompanyID company, CargoID cargo, TownID town_id, bool keep_monitoring) { CompanyID cid = static_cast(company); - if (cid < OWNER_BEGIN || cid >= MAX_COMPANIES) return -1; + if (cid >= MAX_COMPANIES) return -1; if (!ScriptCargo::IsValidCargo(cargo)) return -1; if (!::Town::IsValidID(town_id)) return -1; @@ -53,7 +51,7 @@ /* static */ int32 ScriptCargoMonitor::GetIndustryPickupAmount(ScriptCompany::CompanyID company, CargoID cargo, IndustryID industry_id, bool keep_monitoring) { CompanyID cid = static_cast(company); - if (cid < OWNER_BEGIN || cid >= MAX_COMPANIES) return -1; + if (cid >= MAX_COMPANIES) return -1; if (!ScriptCargo::IsValidCargo(cargo)) return -1; if (!::Industry::IsValidID(industry_id)) return -1; diff --git a/src/script/api/script_cargomonitor.hpp b/src/script/api/script_cargomonitor.hpp index 175936db26..58ed427bea 100644 --- a/src/script/api/script_cargomonitor.hpp +++ b/src/script/api/script_cargomonitor.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/script/api/script_client.cpp b/src/script/api/script_client.cpp index 771a0ae4ec..da646516bc 100644 --- a/src/script/api/script_client.cpp +++ b/src/script/api/script_client.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. @@ -16,59 +14,41 @@ #include "../../safeguards.h" -#ifdef ENABLE_NETWORK /** * Finds NetworkClientInfo given client-identifier, * is used by other methods to resolve client-identifier. * @param client The client to get info structure for - * @return A pointer to corresponding CI struct or NULL when not found. + * @return A pointer to corresponding CI struct or nullptr when not found. */ static NetworkClientInfo *FindClientInfo(ScriptClient::ClientID client) { - if (client == ScriptClient::CLIENT_INVALID) return NULL; - if (!_networking) return NULL; + if (client == ScriptClient::CLIENT_INVALID) return nullptr; + if (!_networking) return nullptr; return NetworkClientInfo::GetByClientID((::ClientID)client); } -#endif /* static */ ScriptClient::ClientID ScriptClient::ResolveClientID(ScriptClient::ClientID client) { -#ifdef ENABLE_NETWORK - return (FindClientInfo(client) == NULL ? ScriptClient::CLIENT_INVALID : client); -#else - return CLIENT_INVALID; -#endif + return (FindClientInfo(client) == nullptr ? ScriptClient::CLIENT_INVALID : client); } /* static */ char *ScriptClient::GetName(ScriptClient::ClientID client) { -#ifdef ENABLE_NETWORK NetworkClientInfo *ci = FindClientInfo(client); - if (ci == NULL) return NULL; + if (ci == nullptr) return nullptr; return stredup(ci->client_name); -#else - return NULL; -#endif } /* static */ ScriptCompany::CompanyID ScriptClient::GetCompany(ScriptClient::ClientID client) { -#ifdef ENABLE_NETWORK NetworkClientInfo *ci = FindClientInfo(client); - if (ci == NULL) return ScriptCompany::COMPANY_INVALID; + if (ci == nullptr) return ScriptCompany::COMPANY_INVALID; return (ScriptCompany::CompanyID)ci->client_playas; -#else - return ScriptCompany::COMPANY_INVALID; -#endif } /* static */ ScriptDate::Date ScriptClient::GetJoinDate(ScriptClient::ClientID client) { -#ifdef ENABLE_NETWORK NetworkClientInfo *ci = FindClientInfo(client); - if (ci == NULL) return ScriptDate::DATE_INVALID; + if (ci == nullptr) return ScriptDate::DATE_INVALID; return (ScriptDate::Date)ci->join_date; -#else - return ScriptDate::DATE_INVALID; -#endif } diff --git a/src/script/api/script_client.hpp b/src/script/api/script_client.hpp index 423f134c07..7400e7247c 100644 --- a/src/script/api/script_client.hpp +++ b/src/script/api/script_client.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. @@ -26,7 +24,7 @@ class ScriptClient : public ScriptObject { public: /** Different constants related to ClientID. */ - enum ClientID { + enum ClientID : uint32 { CLIENT_INVALID = 0, ///< Client is not part of anything CLIENT_SERVER = 1, ///< Servers always have this ID CLIENT_FIRST = 2, ///< The first client ID diff --git a/src/script/api/script_clientlist.cpp b/src/script/api/script_clientlist.cpp index 2f7a19a9ff..eb57d8e44a 100644 --- a/src/script/api/script_clientlist.cpp +++ b/src/script/api/script_clientlist.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. @@ -19,18 +17,14 @@ ScriptClientList::ScriptClientList() { -#ifdef ENABLE_NETWORK if (!_networking) return; - NetworkClientInfo *ci; - FOR_ALL_CLIENT_INFOS(ci) { + for (const NetworkClientInfo *ci : NetworkClientInfo::Iterate()) { this->AddItem(ci->client_id); } -#endif } ScriptClientList_Company::ScriptClientList_Company(ScriptCompany::CompanyID company) { -#ifdef ENABLE_NETWORK if (!_networking) return; CompanyID c; if (company == ScriptCompany::COMPANY_SPECTATOR) { @@ -41,9 +35,7 @@ ScriptClientList_Company::ScriptClientList_Company(ScriptCompany::CompanyID comp c = (CompanyID)company; } - NetworkClientInfo *ci; - FOR_ALL_CLIENT_INFOS(ci) { + for (const NetworkClientInfo *ci : NetworkClientInfo::Iterate()) { if (ci->client_playas == c) this->AddItem(ci->client_id); } -#endif } diff --git a/src/script/api/script_clientlist.hpp b/src/script/api/script_clientlist.hpp index 58d0177b21..39a85fd6e0 100644 --- a/src/script/api/script_clientlist.hpp +++ b/src/script/api/script_clientlist.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/script/api/script_company.cpp b/src/script/api/script_company.cpp index 54888c33cb..873475f0aa 100644 --- a/src/script/api/script_company.cpp +++ b/src/script/api/script_company.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. @@ -45,7 +43,7 @@ { CCountedPtr counter(name); - EnforcePrecondition(false, name != NULL); + EnforcePrecondition(false, name != nullptr); const char *text = name->GetDecodedText(); EnforcePreconditionEncodedText(false, text); EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_COMPANY_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG); @@ -56,7 +54,7 @@ /* static */ char *ScriptCompany::GetName(ScriptCompany::CompanyID company) { company = ResolveCompanyID(company); - if (company == COMPANY_INVALID) return NULL; + if (company == COMPANY_INVALID) return nullptr; ::SetDParam(0, company); return GetString(STR_COMPANY_NAME); @@ -66,7 +64,7 @@ { CCountedPtr counter(name); - EnforcePrecondition(false, name != NULL); + EnforcePrecondition(false, name != nullptr); const char *text = name->GetDecodedText(); EnforcePreconditionEncodedText(false, text); EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_PRESIDENT_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG); @@ -312,7 +310,7 @@ if ((::LiveryScheme)scheme < LS_BEGIN || (::LiveryScheme)scheme >= LS_END) return COLOUR_INVALID; const Company *c = ::Company::GetIfValid(_current_company); - if (c == NULL) return COLOUR_INVALID; + if (c == nullptr) return COLOUR_INVALID; return (ScriptCompany::Colours)c->livery[scheme].colour1; } @@ -322,7 +320,7 @@ if ((::LiveryScheme)scheme < LS_BEGIN || (::LiveryScheme)scheme >= LS_END) return COLOUR_INVALID; const Company *c = ::Company::GetIfValid(_current_company); - if (c == NULL) return COLOUR_INVALID; + if (c == nullptr) return COLOUR_INVALID; return (ScriptCompany::Colours)c->livery[scheme].colour2; } diff --git a/src/script/api/script_company.hpp b/src/script/api/script_company.hpp index 55cb7a9300..ed1d78f1e1 100644 --- a/src/script/api/script_company.hpp +++ b/src/script/api/script_company.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. @@ -139,7 +137,7 @@ public: /** * 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 != NULL && len(name) != 0. + * @pre name != nullptr && len(name) != 0. * @exception ScriptError::ERR_NAME_IS_NOT_UNIQUE * @return True if the name was changed. */ @@ -156,7 +154,7 @@ public: /** * 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 != NULL && len(name) != 0. + * @pre name != nullptr && len(name) != 0. * @exception ScriptError::ERR_NAME_IS_NOT_UNIQUE * @return True if the name was changed. */ diff --git a/src/script/api/script_companymode.cpp b/src/script/api/script_companymode.cpp index a5d3963a2d..83beec5ebb 100644 --- a/src/script/api/script_companymode.cpp +++ b/src/script/api/script_companymode.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. diff --git a/src/script/api/script_companymode.hpp b/src/script/api/script_companymode.hpp index 67787f2584..4eba2dd9f7 100644 --- a/src/script/api/script_companymode.hpp +++ b/src/script/api/script_companymode.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/script/api/script_controller.cpp b/src/script/api/script_controller.cpp index a42c8ede9b..461a6c61be 100644 --- a/src/script/api/script_controller.cpp +++ b/src/script/api/script_controller.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. @@ -43,7 +41,7 @@ ticks = 1; } - throw Script_Suspend(ticks, NULL); + throw Script_Suspend(ticks, nullptr); } /* static */ void ScriptController::Break(const char* message) @@ -119,7 +117,7 @@ ScriptController::~ScriptController() strtolower(library_name); ScriptInfo *lib = ScriptObject::GetActiveInstance()->FindLibrary(library, version); - if (lib == NULL) { + if (lib == nullptr) { char error[1024]; seprintf(error, lastof(error), "couldn't find library '%s' with version %d", library, version); throw sq_throwerror(vm, error); diff --git a/src/script/api/script_controller.hpp b/src/script/api/script_controller.hpp index 9bdbe9ab79..79cb65a74f 100644 --- a/src/script/api/script_controller.hpp +++ b/src/script/api/script_controller.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/script/api/script_date.cpp b/src/script/api/script_date.cpp index 4290a4feb5..57415ecb94 100644 --- a/src/script/api/script_date.cpp +++ b/src/script/api/script_date.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. diff --git a/src/script/api/script_date.hpp b/src/script/api/script_date.hpp index b402b0a2b2..5daa5fb03f 100644 --- a/src/script/api/script_date.hpp +++ b/src/script/api/script_date.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/script/api/script_depotlist.cpp b/src/script/api/script_depotlist.cpp index 05bb4ccd04..4b07636ce5 100644 --- a/src/script/api/script_depotlist.cpp +++ b/src/script/api/script_depotlist.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. @@ -28,8 +26,7 @@ ScriptDepotList::ScriptDepotList(ScriptTile::TransportType transport_type) case ScriptTile::TRANSPORT_AIR: { /* Hangars are not seen as real depots by the depot code. */ - const Station *st; - FOR_ALL_STATIONS(st) { + for (const Station *st : Station::Iterate()) { if (st->owner == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY) { for (uint i = 0; i < st->airport.GetNumHangars(); i++) { this->AddItem(st->airport.GetHangarTile(i)); @@ -41,8 +38,7 @@ ScriptDepotList::ScriptDepotList(ScriptTile::TransportType transport_type) } /* Handle 'standard' depots. */ - const Depot *depot; - FOR_ALL_DEPOTS(depot) { + 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); } } diff --git a/src/script/api/script_depotlist.hpp b/src/script/api/script_depotlist.hpp index c516ac758e..efbe701bda 100644 --- a/src/script/api/script_depotlist.hpp +++ b/src/script/api/script_depotlist.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/script/api/script_engine.cpp b/src/script/api/script_engine.cpp index 1fe16321b5..1ec1b23a8e 100644 --- a/src/script/api/script_engine.cpp +++ b/src/script/api/script_engine.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. @@ -15,6 +13,7 @@ #include "../../company_base.h" #include "../../strings_func.h" #include "../../rail.h" +#include "../../road.h" #include "../../engine_base.h" #include "../../engine_func.h" #include "../../articulated_vehicles.h" @@ -25,7 +24,7 @@ /* static */ bool ScriptEngine::IsValidEngine(EngineID engine_id) { const Engine *e = ::Engine::GetIfValid(engine_id); - if (e == NULL || !e->IsEnabled()) return false; + 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. */ @@ -36,12 +35,12 @@ /* static */ bool ScriptEngine::IsBuildable(EngineID engine_id) { const Engine *e = ::Engine::GetIfValid(engine_id); - return e != NULL && ::IsEngineBuildable(engine_id, e->type, ScriptObject::GetCompany()); + return e != nullptr && ::IsEngineBuildable(engine_id, e->type, ScriptObject::GetCompany()); } /* static */ char *ScriptEngine::GetName(EngineID engine_id) { - if (!IsValidEngine(engine_id)) return NULL; + if (!IsValidEngine(engine_id)) return nullptr; ::SetDParam(0, engine_id); return GetString(STR_ENGINE_NAME); @@ -219,12 +218,26 @@ return ::HasPowerOnRail((::RailType)::RailVehInfo(engine_id)->railtype, (::RailType)track_rail_type); } +/* static */ bool ScriptEngine::CanRunOnRoad(EngineID engine_id, ScriptRoad::RoadType road_type) +{ + return HasPowerOnRoad(engine_id, road_type); +} + +/* static */ bool ScriptEngine::HasPowerOnRoad(EngineID engine_id, ScriptRoad::RoadType road_type) +{ + if (!IsValidEngine(engine_id)) return false; + if (GetVehicleType(engine_id) != ScriptVehicle::VT_ROAD) return false; + if (!ScriptRoad::IsRoadTypeAvailable(road_type)) return false; + + return ::HasPowerOnRoad((::RoadType)::RoadVehInfo(engine_id)->roadtype, (::RoadType)road_type); +} + /* static */ ScriptRoad::RoadType ScriptEngine::GetRoadType(EngineID engine_id) { if (!IsValidEngine(engine_id)) return ScriptRoad::ROADTYPE_INVALID; if (GetVehicleType(engine_id) != ScriptVehicle::VT_ROAD) return ScriptRoad::ROADTYPE_INVALID; - return HasBit(::EngInfo(engine_id)->misc_flags, EF_ROAD_TRAM) ? ScriptRoad::ROADTYPE_TRAM : ScriptRoad::ROADTYPE_ROAD; + return (ScriptRoad::RoadType)(uint)::RoadVehInfo(engine_id)->roadtype; } /* static */ ScriptRail::RailType ScriptEngine::GetRailType(EngineID engine_id) @@ -256,9 +269,6 @@ if (!IsValidEngine(engine_id)) return 0; switch (GetVehicleType(engine_id)) { - case ScriptVehicle::VT_WATER: - return _settings_game.pf.pathfinder_for_ships != VPF_NPF ? 129 : 0; - case ScriptVehicle::VT_AIR: return ::Engine::Get(engine_id)->GetRange() * ::Engine::Get(engine_id)->GetRange(); @@ -266,3 +276,25 @@ return 0; } } + +/* static */ bool ScriptEngine::EnableForCompany(EngineID engine_id, ScriptCompany::CompanyID company) +{ + company = ScriptCompany::ResolveCompanyID(company); + + EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); + EnforcePrecondition(false, IsValidEngine(engine_id)); + EnforcePrecondition(false, company != ScriptCompany::COMPANY_INVALID); + + return ScriptObject::DoCommand(0, engine_id, (uint32)company | (1 << 31), CMD_ENGINE_CTRL); +} + +/* static */ bool ScriptEngine::DisableForCompany(EngineID engine_id, ScriptCompany::CompanyID company) +{ + company = ScriptCompany::ResolveCompanyID(company); + + EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); + EnforcePrecondition(false, IsValidEngine(engine_id)); + EnforcePrecondition(false, company != ScriptCompany::COMPANY_INVALID); + + return ScriptObject::DoCommand(0, engine_id, company, CMD_ENGINE_CTRL); +} diff --git a/src/script/api/script_engine.hpp b/src/script/api/script_engine.hpp index 173377742d..f6bdbedbf2 100644 --- a/src/script/api/script_engine.hpp +++ b/src/script/api/script_engine.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. @@ -217,6 +215,28 @@ public: */ static bool HasPowerOnRail(EngineID engine_id, ScriptRail::RailType track_rail_type); + /** + * Check if a road vehicle can run on a RoadType. + * @param engine_id The engine to check. + * @param road_type Another RoadType. + * @pre IsValidEngine(engine_id). + * @pre GetVehicleType(engine_id) == ScriptVehicle::VT_ROAD. + * @pre ScriptRoad::IsRoadTypeAvailable(road_type). + * @return Whether an engine of type 'engine_id' can run on 'road_type'. + */ + static bool CanRunOnRoad(EngineID engine_id, ScriptRoad::RoadType road_type); + + /** + * Check if a road vehicle has power on a RoadType. + * @param engine_id The engine to check. + * @param road_type Another RoadType. + * @pre IsValidEngine(engine_id). + * @pre GetVehicleType(engine_id) == ScriptVehicle::VT_ROAD. + * @pre ScriptRoad::IsRoadTypeAvailable(road_type). + * @return Whether an engine of type 'engine_id' has power on 'road_type'. + */ + static bool HasPowerOnRoad(EngineID engine_id, ScriptRoad::RoadType road_type); + /** * Get the RoadType of the engine. * @param engine_id The engine to get the RoadType of. @@ -267,6 +287,29 @@ public: * @see ScriptOrder::GetOrderDistance */ static uint GetMaximumOrderDistance(EngineID engine_id); + + /** + * Allows a company to use an engine before its intro date or after retirement. + * @param engine_id The engine to enable. + * @param company_id The company to allow using the engine. + * @pre IsValidEngine(engine_id). + * @pre ScriptCompany.ResolveCompanyID(company_id) != ScriptCompany::COMPANY_INVALID. + * @return True if the action succeeded. + * @api -ai + */ + static bool EnableForCompany(EngineID engine_id, ScriptCompany::CompanyID company_id); + + /** + * Forbids a company to use an engine before its natural retirement. + * @param engine_id The engine to disable. + * @param company_id The company to forbid using the engine. + * @pre IsValidEngine(engine_id). + * @pre ScriptCompany.ResolveCompanyID(company_id) != ScriptCompany::COMPANY_INVALID. + * @return True if the action succeeded. + * @api -ai + */ + static bool DisableForCompany(EngineID engine_id, ScriptCompany::CompanyID company_id); + }; #endif /* SCRIPT_ENGINE_HPP */ diff --git a/src/script/api/script_enginelist.cpp b/src/script/api/script_enginelist.cpp index 99ab9537be..c6f594cc7e 100644 --- a/src/script/api/script_enginelist.cpp +++ b/src/script/api/script_enginelist.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. @@ -17,8 +15,7 @@ ScriptEngineList::ScriptEngineList(ScriptVehicle::VehicleType vehicle_type) { - Engine *e; - FOR_ALL_ENGINES_OF_TYPE(e, (::VehicleType)vehicle_type) { + for (const Engine *e : Engine::IterateType((::VehicleType)vehicle_type)) { if (ScriptObject::GetCompany() == OWNER_DEITY || HasBit(e->company_avail, ScriptObject::GetCompany())) this->AddItem(e->index); } } diff --git a/src/script/api/script_enginelist.hpp b/src/script/api/script_enginelist.hpp index 1fe2c4bc18..05cfc03853 100644 --- a/src/script/api/script_enginelist.hpp +++ b/src/script/api/script_enginelist.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/script/api/script_error.cpp b/src/script/api/script_error.cpp index 87d2906c55..318a6ff494 100644 --- a/src/script/api/script_error.cpp +++ b/src/script/api/script_error.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. diff --git a/src/script/api/script_error.hpp b/src/script/api/script_error.hpp index 1817cdb7d9..87d4196fdd 100644 --- a/src/script/api/script_error.hpp +++ b/src/script/api/script_error.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. @@ -44,7 +42,7 @@ * @param string The string that is checked. */ #define EnforcePreconditionEncodedText(returnval, string) \ - if ((string) == NULL) { \ + if ((string) == nullptr) { \ ScriptObject::SetLastError(ScriptError::ERR_PRECONDITION_TOO_MANY_PARAMETERS); \ return returnval; \ } \ @@ -110,10 +108,10 @@ public: ERR_NOT_ENOUGH_CASH, // [STR_ERROR_NOT_ENOUGH_CASH_REQUIRES_CURRENCY] /** Local authority won't allow the previous action */ - ERR_LOCAL_AUTHORITY_REFUSES, // [STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS] + ERR_LOCAL_AUTHORITY_REFUSES, // [STR_ERROR_LOCAL_AUTHORITY_REFUSES_TO_ALLOW_THIS, STR_ERROR_LOCAL_AUTHORITY_REFUSES_NOISE] /** The piece of infrastructure you tried to build is already in place */ - ERR_ALREADY_BUILT, // [STR_ERROR_ALREADY_BUILT, STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST] + ERR_ALREADY_BUILT, // [STR_ERROR_ALREADY_BUILT, STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST, STR_ERROR_TREE_ALREADY_HERE] /** Area isn't clear, try to demolish the building on it */ ERR_AREA_NOT_CLEAR, // [STR_ERROR_BUILDING_MUST_BE_DEMOLISHED, STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST, STR_ERROR_MUST_DEMOLISH_RAILROAD, STR_ERROR_MUST_DEMOLISH_AIRPORT_FIRST, STR_ERROR_MUST_DEMOLISH_CARGO_TRAM_STATION_FIRST, STR_ERROR_MUST_DEMOLISH_TRUCK_STATION_FIRST, STR_ERROR_MUST_DEMOLISH_PASSENGER_TRAM_STATION_FIRST, STR_ERROR_MUST_DEMOLISH_BUS_STATION_FIRST, STR_ERROR_BUOY_IN_THE_WAY, STR_ERROR_MUST_DEMOLISH_DOCK_FIRST, STR_ERROR_GENERIC_OBJECT_IN_THE_WAY, STR_ERROR_COMPANY_HEADQUARTERS_IN, STR_ERROR_OBJECT_IN_THE_WAY, STR_ERROR_MUST_REMOVE_ROAD_FIRST, STR_ERROR_MUST_REMOVE_RAILROAD_TRACK, STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST, STR_ERROR_MUST_DEMOLISH_TUNNEL_FIRST, STR_ERROR_EXCAVATION_WOULD_DAMAGE] @@ -134,7 +132,7 @@ public: ERR_VEHICLE_IN_THE_WAY, // [STR_ERROR_TRAIN_IN_THE_WAY, STR_ERROR_ROAD_VEHICLE_IN_THE_WAY, STR_ERROR_SHIP_IN_THE_WAY, STR_ERROR_AIRCRAFT_IN_THE_WAY] /** Site is unsuitable */ - ERR_SITE_UNSUITABLE, // [STR_ERROR_SITE_UNSUITABLE] + ERR_SITE_UNSUITABLE, // [STR_ERROR_SITE_UNSUITABLE, STR_ERROR_TREE_WRONG_TERRAIN_FOR_TREE_TYPE] /** Too close to the edge of the map */ ERR_TOO_CLOSE_TO_EDGE, // [STR_ERROR_TOO_CLOSE_TO_EDGE_OF_MAP] diff --git a/src/script/api/script_event.cpp b/src/script/api/script_event.cpp index 0e711ca416..efdc720cf3 100644 --- a/src/script/api/script_event.cpp +++ b/src/script/api/script_event.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. @@ -23,7 +21,7 @@ struct ScriptEventData { /* static */ void ScriptEventController::CreateEventPointer() { - assert(ScriptObject::GetEventPointer() == NULL); + assert(ScriptObject::GetEventPointer() == nullptr); ScriptObject::GetEventPointer() = new ScriptEventData(); } @@ -45,7 +43,7 @@ struct ScriptEventData { /* static */ bool ScriptEventController::IsEventWaiting() { - if (ScriptObject::GetEventPointer() == NULL) ScriptEventController::CreateEventPointer(); + if (ScriptObject::GetEventPointer() == nullptr) ScriptEventController::CreateEventPointer(); ScriptEventData *data = (ScriptEventData *)ScriptObject::GetEventPointer(); return !data->stack.empty(); @@ -53,10 +51,10 @@ struct ScriptEventData { /* static */ ScriptEvent *ScriptEventController::GetNextEvent() { - if (ScriptObject::GetEventPointer() == NULL) ScriptEventController::CreateEventPointer(); + if (ScriptObject::GetEventPointer() == nullptr) ScriptEventController::CreateEventPointer(); ScriptEventData *data = (ScriptEventData *)ScriptObject::GetEventPointer(); - if (data->stack.empty()) return NULL; + if (data->stack.empty()) return nullptr; ScriptEvent *e = data->stack.front(); data->stack.pop(); @@ -65,7 +63,7 @@ struct ScriptEventData { /* static */ void ScriptEventController::InsertEvent(ScriptEvent *event) { - if (ScriptObject::GetEventPointer() == NULL) ScriptEventController::CreateEventPointer(); + if (ScriptObject::GetEventPointer() == nullptr) ScriptEventController::CreateEventPointer(); ScriptEventData *data = (ScriptEventData *)ScriptObject::GetEventPointer(); event->AddRef(); diff --git a/src/script/api/script_event.hpp b/src/script/api/script_event.hpp index b2dddebd67..886e4f1db8 100644 --- a/src/script/api/script_event.hpp +++ b/src/script/api/script_event.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. @@ -55,6 +53,7 @@ public: ET_GOAL_QUESTION_ANSWER, ET_EXCLUSIVE_TRANSPORT_RIGHTS, ET_ROAD_RECONSTRUCTION, + ET_VEHICLE_AUTOREPLACED, }; /** diff --git a/src/script/api/script_event_types.cpp b/src/script/api/script_event_types.cpp index d424e6feff..84c001836d 100644 --- a/src/script/api/script_event_types.cpp +++ b/src/script/api/script_event_types.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. @@ -25,12 +23,12 @@ bool ScriptEventEnginePreview::IsEngineValid() const { const Engine *e = ::Engine::GetIfValid(this->engine); - return e != NULL && e->IsEnabled(); + return e != nullptr && e->IsEnabled(); } char *ScriptEventEnginePreview::GetName() { - if (!this->IsEngineValid()) return NULL; + if (!this->IsEngineValid()) return nullptr; ::SetDParam(0, this->engine); return GetString(STR_ENGINE_NAME); @@ -132,13 +130,13 @@ ScriptEventAdminPort::~ScriptEventAdminPort() } #define SKIP_EMPTY(p) while (*(p) == ' ' || *(p) == '\n' || *(p) == '\r') (p)++; -#define RETURN_ERROR(stack) { ScriptLog::Error("Received invalid JSON data from AdminPort."); if (stack != 0) sq_pop(vm, stack); return NULL; } +#define RETURN_ERROR(stack) { ScriptLog::Error("Received invalid JSON data from AdminPort."); if (stack != 0) sq_pop(vm, stack); return nullptr; } SQInteger ScriptEventAdminPort::GetObject(HSQUIRRELVM vm) { char *p = this->json; - if (this->ReadTable(vm, p) == NULL) { + if (this->ReadTable(vm, p) == nullptr) { sq_pushnull(vm); return 1; } @@ -189,18 +187,18 @@ char *ScriptEventAdminPort::ReadTable(HSQUIRRELVM vm, char *p) if (*p++ != '"') RETURN_ERROR(1); p = ReadString(vm, p); - if (p == NULL) { + if (p == nullptr) { sq_pop(vm, 1); - return NULL; + return nullptr; } SKIP_EMPTY(p); if (*p++ != ':') RETURN_ERROR(2); p = this->ReadValue(vm, p); - if (p == NULL) { + if (p == nullptr) { sq_pop(vm, 2); - return NULL; + return nullptr; } sq_rawset(vm, -3); @@ -241,7 +239,7 @@ char *ScriptEventAdminPort::ReadValue(HSQUIRRELVM vm, char *p) case '"': { /* String */ p = ReadString(vm, ++p); - if (p == NULL) return NULL; + if (p == nullptr) return nullptr; break; } @@ -249,7 +247,7 @@ char *ScriptEventAdminPort::ReadValue(HSQUIRRELVM vm, char *p) case '{': { /* Table */ p = this->ReadTable(vm, p); - if (p == NULL) return NULL; + if (p == nullptr) return nullptr; break; } @@ -268,9 +266,9 @@ char *ScriptEventAdminPort::ReadValue(HSQUIRRELVM vm, char *p) while (*p++ != ']') { p = this->ReadValue(vm, p); - if (p == NULL) { + if (p == nullptr) { sq_pop(vm, 1); - return NULL; + return nullptr; } sq_arrayappend(vm, -2); diff --git a/src/script/api/script_event_types.hpp b/src/script/api/script_event_types.hpp index f13e588eed..98cca7f502 100644 --- a/src/script/api/script_event_types.hpp +++ b/src/script/api/script_event_types.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. @@ -799,8 +797,8 @@ private: /** * Event AircraftDestTooFar, indicating the next destination of an aircraft is too far away. - * This event can be trigger when the current oder of an aircraft changes, usually either when - * loading is done or when switch manually. + * This event can be triggered when the current order of an aircraft changes, usually either when + * loading is done or when switched manually. * @api ai */ class ScriptEventAircraftDestTooFar : public ScriptEvent { @@ -1060,4 +1058,44 @@ public: static ScriptEventRoadReconstruction *Convert(ScriptEventCompanyTown *instance) { return (ScriptEventRoadReconstruction *)instance; } }; +/** + * Event VehicleAutoReplaced, indicating a vehicle has been auto replaced. + * @api ai + */ +class ScriptEventVehicleAutoReplaced : public ScriptEvent { +public: + /** + * @param old_id The vehicle that has been replaced. + * @param new_id The vehicle that has been created in replacement. + */ + ScriptEventVehicleAutoReplaced(VehicleID old_id, VehicleID new_id) : + ScriptEvent(ET_VEHICLE_AUTOREPLACED), + old_id(old_id), + new_id(new_id) + {} + + /** + * Convert an ScriptEvent to the real instance. + * @param instance The instance to convert. + * @return The converted instance. + */ + static ScriptEventVehicleAutoReplaced *Convert(ScriptEvent *instance) { return (ScriptEventVehicleAutoReplaced *)instance; } + + /** + * Get the VehicleID of the vehicle that has been replaced. + * @return The VehicleID of the vehicle that has been replaced. This ID is no longer valid for referencing the vehicle. + */ + VehicleID GetOldVehicleID() { return this->old_id; } + + /** + * Get the VehicleID of the vehicle that has been created in replacement. + * @return The VehicleID of the vehicle that has been created in replacement. + */ + VehicleID GetNewVehicleID() { return this->new_id; } + +private: + VehicleID old_id; ///< The vehicle that has been replaced. + VehicleID new_id; ///< The vehicle that has been created in replacement. +}; + #endif /* SCRIPT_EVENT_TYPES_HPP */ diff --git a/src/script/api/script_execmode.cpp b/src/script/api/script_execmode.cpp index 1bbce807a4..6a34288cb2 100644 --- a/src/script/api/script_execmode.cpp +++ b/src/script/api/script_execmode.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. diff --git a/src/script/api/script_execmode.hpp b/src/script/api/script_execmode.hpp index 96d30d1e4a..8e4fd71578 100644 --- a/src/script/api/script_execmode.hpp +++ b/src/script/api/script_execmode.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/script/api/script_game.cpp b/src/script/api/script_game.cpp index c24757a3cc..43674c6f37 100644 --- a/src/script/api/script_game.cpp +++ b/src/script/api/script_game.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. @@ -39,9 +37,5 @@ /* static */ bool ScriptGame::IsMultiplayer() { -#ifdef ENABLE_NETWORK return _network_server; -#else - return false; -#endif } diff --git a/src/script/api/script_game.hpp b/src/script/api/script_game.hpp index 3531c9de8f..a9e5b7a258 100644 --- a/src/script/api/script_game.hpp +++ b/src/script/api/script_game.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/script/api/script_gamesettings.cpp b/src/script/api/script_gamesettings.cpp index 1f8ded877e..bdaeb6c93e 100644 --- a/src/script/api/script_gamesettings.cpp +++ b/src/script/api/script_gamesettings.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. @@ -21,7 +19,7 @@ { uint i; const SettingDesc *sd = GetSettingFromName(setting, &i); - return sd != NULL && sd->desc.cmd != SDT_STRING; + return sd != nullptr && sd->desc.cmd != SDT_STRING; } /* static */ int32 ScriptGameSettings::GetValue(const char *setting) diff --git a/src/script/api/script_gamesettings.hpp b/src/script/api/script_gamesettings.hpp index 6f92ca758b..14b30e5c4d 100644 --- a/src/script/api/script_gamesettings.hpp +++ b/src/script/api/script_gamesettings.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/script/api/script_goal.cpp b/src/script/api/script_goal.cpp index c183b75834..ca2b165740 100644 --- a/src/script/api/script_goal.cpp +++ b/src/script/api/script_goal.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. @@ -34,14 +32,14 @@ CCountedPtr counter(goal); EnforcePrecondition(GOAL_INVALID, ScriptObject::GetCompany() == OWNER_DEITY); - EnforcePrecondition(GOAL_INVALID, goal != NULL); + EnforcePrecondition(GOAL_INVALID, goal != nullptr); const char *text = goal->GetEncodedText(); EnforcePreconditionEncodedText(GOAL_INVALID, text); EnforcePrecondition(GOAL_INVALID, company == ScriptCompany::COMPANY_INVALID || ScriptCompany::ResolveCompanyID(company) != ScriptCompany::COMPANY_INVALID); uint8 c = company; if (company == ScriptCompany::COMPANY_INVALID) c = INVALID_COMPANY; - StoryPage *story_page = NULL; + StoryPage *story_page = nullptr; if (type == GT_STORY_PAGE && ScriptStoryPage::IsValidStoryPage((ScriptStoryPage::StoryPageID)destination)) story_page = ::StoryPage::Get((ScriptStoryPage::StoryPageID)destination); EnforcePrecondition(GOAL_INVALID, (type == GT_NONE && destination == 0) || @@ -49,7 +47,7 @@ (type == GT_INDUSTRY && ScriptIndustry::IsValidIndustry(destination)) || (type == GT_TOWN && ScriptTown::IsValidTown(destination)) || (type == GT_COMPANY && ScriptCompany::ResolveCompanyID((ScriptCompany::CompanyID)destination) != ScriptCompany::COMPANY_INVALID) || - (type == GT_STORY_PAGE && story_page != NULL && (c == INVALID_COMPANY ? story_page->company == INVALID_COMPANY : story_page->company == INVALID_COMPANY || story_page->company == c))); + (type == GT_STORY_PAGE && story_page != nullptr && (c == INVALID_COMPANY ? story_page->company == INVALID_COMPANY : story_page->company == INVALID_COMPANY || story_page->company == c))); if (!ScriptObject::DoCommand(0, type | (c << 8), destination, CMD_CREATE_GOAL, text, &ScriptInstance::DoCommandReturnGoalID)) return GOAL_INVALID; @@ -71,7 +69,7 @@ EnforcePrecondition(false, IsValidGoal(goal_id)); EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); - EnforcePrecondition(false, goal != NULL); + EnforcePrecondition(false, goal != nullptr); EnforcePrecondition(false, !StrEmpty(goal->GetEncodedText())); return ScriptObject::DoCommand(0, goal_id, 0, CMD_SET_GOAL_TEXT, goal->GetEncodedText()); @@ -84,12 +82,12 @@ EnforcePrecondition(false, IsValidGoal(goal_id)); EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); - /* Ensure null as used for emtpy string. */ - if (progress != NULL && StrEmpty(progress->GetEncodedText())) { - progress = NULL; + /* Ensure null as used for empty string. */ + if (progress != nullptr && StrEmpty(progress->GetEncodedText())) { + progress = nullptr; } - return ScriptObject::DoCommand(0, goal_id, 0, CMD_SET_GOAL_PROGRESS, progress != NULL ? progress->GetEncodedText() : NULL); + return ScriptObject::DoCommand(0, goal_id, 0, CMD_SET_GOAL_PROGRESS, progress != nullptr ? progress->GetEncodedText() : nullptr); } /* static */ bool ScriptGoal::SetCompleted(GoalID goal_id, bool completed) @@ -106,22 +104,22 @@ EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); Goal *g = Goal::Get(goal_id); - return g != NULL && g->completed; + return g != nullptr && g->completed; } -/* static */ bool ScriptGoal::DoQuestion(uint16 uniqueid, uint8 target, bool is_client, Text *question, QuestionType type, int buttons) +/* static */ bool ScriptGoal::DoQuestion(uint16 uniqueid, uint32 target, bool is_client, Text *question, QuestionType type, uint32 buttons) { CCountedPtr counter(question); EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); - EnforcePrecondition(false, question != NULL); + EnforcePrecondition(false, question != nullptr); const char *text = question->GetEncodedText(); EnforcePreconditionEncodedText(false, text); EnforcePrecondition(false, CountBits(buttons) >= 1 && CountBits(buttons) <= 3); EnforcePrecondition(false, buttons < (1 << ::GOAL_QUESTION_BUTTON_COUNT)); EnforcePrecondition(false, (int)type < ::GOAL_QUESTION_TYPE_COUNT); - return ScriptObject::DoCommand(0, uniqueid | (target << 16) | (type << 24) | (is_client ? (1 << 31) : 0), buttons, CMD_GOAL_QUESTION, text); + return ScriptObject::DoCommand(0, uniqueid | (target << 16), buttons | (type << 29) | (is_client ? (1 << 31) : 0), CMD_GOAL_QUESTION, text); } /* static */ bool ScriptGoal::Question(uint16 uniqueid, ScriptCompany::CompanyID company, Text *question, QuestionType type, int buttons) @@ -137,12 +135,9 @@ { EnforcePrecondition(false, ScriptGame::IsMultiplayer()); EnforcePrecondition(false, ScriptClient::ResolveClientID(client) != ScriptClient::CLIENT_INVALID); -#ifdef ENABLE_NETWORK - ClientIndex c = NetworkClientInfo::GetByClientID((::ClientID)client)->index; - return DoQuestion(uniqueid, c, true, question, type, buttons); -#else - return false; -#endif + /* 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) diff --git a/src/script/api/script_goal.hpp b/src/script/api/script_goal.hpp index f5dfba095f..372d6e8b49 100644 --- a/src/script/api/script_goal.hpp +++ b/src/script/api/script_goal.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. @@ -99,7 +97,7 @@ public: * @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 != NULL && len(goal) != 0. + * @pre goal != nullptr && 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. @@ -122,7 +120,7 @@ public: * @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 != NULL && len(goal) != 0. + * @pre goal != nullptr && len(goal) != 0. * @pre IsValidGoal(goal_id). */ static bool SetText(GoalID goal_id, Text *goal); @@ -133,7 +131,7 @@ public: * 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 NULL or an + * or a ScriptText object). To clear the progress string you can pass nullptr or an * empty string. * @return True if the action succeeded. * @pre No ScriptCompanyMode may be in scope. @@ -169,7 +167,7 @@ public: * @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 != NULL && len(question) != 0. + * @pre question != nullptr && 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. @@ -187,7 +185,7 @@ public: * @return True if the action succeeded. * @pre No ScriptCompanyMode may be in scope. * @pre ScriptGame::IsMultiplayer() - * @pre question != NULL && len(question) != 0. + * @pre question != nullptr && 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. @@ -211,7 +209,7 @@ protected: /** * Does common checks and asks the question. */ - static bool DoQuestion(uint16 uniqueid, uint8 target, bool is_client, Text *question, QuestionType type, int buttons); + static bool DoQuestion(uint16 uniqueid, uint32 target, bool is_client, Text *question, QuestionType type, uint32 buttons); }; #endif /* SCRIPT_GOAL_HPP */ diff --git a/src/script/api/script_group.cpp b/src/script/api/script_group.cpp index 16a50bc17c..7f80815864 100644 --- a/src/script/api/script_group.cpp +++ b/src/script/api/script_group.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. @@ -25,12 +23,12 @@ /* static */ bool ScriptGroup::IsValidGroup(GroupID group_id) { const Group *g = ::Group::GetIfValid(group_id); - return g != NULL && g->owner == ScriptObject::GetCompany(); + return g != nullptr && g->owner == ScriptObject::GetCompany(); } /* static */ ScriptGroup::GroupID ScriptGroup::CreateGroup(ScriptVehicle::VehicleType vehicle_type, GroupID parent_group_id) { - if (!ScriptObject::DoCommand(0, (::VehicleType)vehicle_type, parent_group_id, CMD_CREATE_GROUP, NULL, &ScriptInstance::DoCommandReturnGroupID)) return GROUP_INVALID; + if (!ScriptObject::DoCommand(0, (::VehicleType)vehicle_type, parent_group_id, CMD_CREATE_GROUP, nullptr, &ScriptInstance::DoCommandReturnGroupID)) return GROUP_INVALID; /* In case of test-mode, we return GroupID 0 */ return (ScriptGroup::GroupID)0; @@ -55,7 +53,7 @@ CCountedPtr counter(name); EnforcePrecondition(false, IsValidGroup(group_id)); - EnforcePrecondition(false, name != NULL); + EnforcePrecondition(false, name != nullptr); const char *text = name->GetDecodedText(); EnforcePreconditionEncodedText(false, text); EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_GROUP_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG); @@ -65,7 +63,7 @@ /* static */ char *ScriptGroup::GetName(GroupID group_id) { - if (!IsValidGroup(group_id)) return NULL; + if (!IsValidGroup(group_id)) return nullptr; ::SetDParam(0, group_id); return GetString(STR_GROUP_NAME); @@ -156,8 +154,7 @@ Money profit = 0; - const Vehicle *v; - FOR_ALL_VEHICLES(v) { + for (const Vehicle *v : Vehicle::Iterate()) { if (v->group_id != group_id) continue; if (!v->IsPrimaryVehicle()) continue; @@ -181,8 +178,7 @@ uint32 occupancy = 0; uint32 vehicle_count = 0; - const Vehicle *v; - FOR_ALL_VEHICLES(v) { + for (const Vehicle *v : Vehicle::Iterate()) { if (v->group_id != group_id) continue; if (!v->IsPrimaryVehicle()) continue; @@ -194,3 +190,35 @@ return occupancy / vehicle_count; } + +/* static */ bool ScriptGroup::SetPrimaryColour(GroupID group_id, ScriptCompany::Colours colour) +{ + EnforcePrecondition(false, IsValidGroup(group_id)); + + return ScriptObject::DoCommand(0, group_id, colour << 16, CMD_SET_GROUP_LIVERY); +} + +/* static */ bool ScriptGroup::SetSecondaryColour(GroupID group_id, ScriptCompany::Colours colour) +{ + EnforcePrecondition(false, IsValidGroup(group_id)); + + return ScriptObject::DoCommand(0, group_id, (1 << 8) | (colour << 16), CMD_SET_GROUP_LIVERY); +} + +/* static */ ScriptCompany::Colours ScriptGroup::GetPrimaryColour(GroupID group_id) +{ + EnforcePrecondition(ScriptCompany::Colours::COLOUR_INVALID, IsValidGroup(group_id)); + + const Group *g = ::Group::GetIfValid(group_id); + if (!HasBit(g->livery.in_use, 0)) return ScriptCompany::Colours::COLOUR_INVALID; + return (ScriptCompany::Colours)g->livery.colour1; +} + +/* static */ ScriptCompany::Colours ScriptGroup::GetSecondaryColour(GroupID group_id) +{ + EnforcePrecondition(ScriptCompany::Colours::COLOUR_INVALID, IsValidGroup(group_id)); + + const Group *g = ::Group::GetIfValid(group_id); + if (!HasBit(g->livery.in_use, 1)) return ScriptCompany::Colours::COLOUR_INVALID; + return (ScriptCompany::Colours)g->livery.colour2; +} diff --git a/src/script/api/script_group.hpp b/src/script/api/script_group.hpp index 9e88eaff1c..2c27b81c6e 100644 --- a/src/script/api/script_group.hpp +++ b/src/script/api/script_group.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. @@ -71,7 +69,7 @@ public: * @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 != NULL && len(name) != 0 + * @pre name != nullptr && len(name) != 0 * @exception ScriptError::ERR_NAME_IS_NOT_UNIQUE * @return True if and only if the name was changed. */ @@ -214,6 +212,36 @@ public: * @return The current usage of the group. */ static uint32 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). + */ + static bool SetPrimaryColour(GroupID group_id, ScriptCompany::Colours colour); + + /** + * Set secondary colour for a group. + * @param group_id The group id to set the colour of. + * @param colour Colour to set. + * @pre IsValidGroup(group_id). + */ + static bool SetSecondaryColour(GroupID group_id, ScriptCompany::Colours colour); + + /** + * Get primary colour of a group. + * @param group_id The group id to get the colour of. + * @pre IsValidGroup(group_id). + */ + static ScriptCompany::Colours GetPrimaryColour(GroupID group_id); + + /** + * Get secondary colour for a group. + * @param group_id The group id to get the colour of. + * @pre IsValidGroup(group_id). + */ + static ScriptCompany::Colours GetSecondaryColour(GroupID group_id); }; #endif /* SCRIPT_GROUP_HPP */ diff --git a/src/script/api/script_grouplist.cpp b/src/script/api/script_grouplist.cpp index d1071c36c6..569b44634c 100644 --- a/src/script/api/script_grouplist.cpp +++ b/src/script/api/script_grouplist.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. @@ -17,8 +15,7 @@ ScriptGroupList::ScriptGroupList() { - Group *g; - FOR_ALL_GROUPS(g) { + for (const Group *g : Group::Iterate()) { if (g->owner == ScriptObject::GetCompany()) this->AddItem(g->index); } } diff --git a/src/script/api/script_grouplist.hpp b/src/script/api/script_grouplist.hpp index 32e94d6494..d8195ed96a 100644 --- a/src/script/api/script_grouplist.hpp +++ b/src/script/api/script_grouplist.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/script/api/script_industry.cpp b/src/script/api/script_industry.cpp index c536ec5590..4d1e91a3ce 100644 --- a/src/script/api/script_industry.cpp +++ b/src/script/api/script_industry.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. @@ -39,7 +37,7 @@ /* static */ char *ScriptIndustry::GetName(IndustryID industry_id) { - if (!IsValidIndustry(industry_id)) return NULL; + if (!IsValidIndustry(industry_id)) return nullptr; ::SetDParam(0, industry_id); return GetString(STR_INDUSTRY_NAME); @@ -132,9 +130,7 @@ if (!IsValidIndustry(industry_id)) return -1; Industry *ind = ::Industry::Get(industry_id); - StationList stations; - ::FindStationsAroundTiles(ind->location, &stations); - return (int32)stations.Length(); + return (int32)ind->stations_near.size(); } /* static */ int32 ScriptIndustry::GetDistanceManhattanToTile(IndustryID industry_id, TileIndex tile) diff --git a/src/script/api/script_industry.hpp b/src/script/api/script_industry.hpp index 83c249f9aa..98c7d33ac3 100644 --- a/src/script/api/script_industry.hpp +++ b/src/script/api/script_industry.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/script/api/script_industrylist.cpp b/src/script/api/script_industrylist.cpp index d2d298fa3f..de28f418d4 100644 --- a/src/script/api/script_industrylist.cpp +++ b/src/script/api/script_industrylist.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. @@ -17,17 +15,14 @@ ScriptIndustryList::ScriptIndustryList() { - Industry *i; - FOR_ALL_INDUSTRIES(i) { + for (const Industry *i : Industry::Iterate()) { this->AddItem(i->index); } } ScriptIndustryList_CargoAccepting::ScriptIndustryList_CargoAccepting(CargoID cargo_id) { - const Industry *i; - - FOR_ALL_INDUSTRIES(i) { + for (const Industry *i : Industry::Iterate()) { for (byte j = 0; j < lengthof(i->accepts_cargo); j++) { if (i->accepts_cargo[j] == cargo_id) this->AddItem(i->index); } @@ -36,9 +31,7 @@ ScriptIndustryList_CargoAccepting::ScriptIndustryList_CargoAccepting(CargoID car ScriptIndustryList_CargoProducing::ScriptIndustryList_CargoProducing(CargoID cargo_id) { - const Industry *i; - - FOR_ALL_INDUSTRIES(i) { + for (const Industry *i : Industry::Iterate()) { for (byte j = 0; j < lengthof(i->produced_cargo); j++) { if (i->produced_cargo[j] == cargo_id) this->AddItem(i->index); } diff --git a/src/script/api/script_industrylist.hpp b/src/script/api/script_industrylist.hpp index a9ef85ecea..ff7210d682 100644 --- a/src/script/api/script_industrylist.hpp +++ b/src/script/api/script_industrylist.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/script/api/script_industrytype.cpp b/src/script/api/script_industrytype.cpp index 1ac59975dc..ad1ee4feda 100644 --- a/src/script/api/script_industrytype.cpp +++ b/src/script/api/script_industrytype.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. @@ -59,14 +57,14 @@ /* static */ char *ScriptIndustryType::GetName(IndustryType industry_type) { - if (!IsValidIndustryType(industry_type)) return NULL; + if (!IsValidIndustryType(industry_type)) return nullptr; return GetString(::GetIndustrySpec(industry_type)->name); } /* static */ ScriptList *ScriptIndustryType::GetProducedCargo(IndustryType industry_type) { - if (!IsValidIndustryType(industry_type)) return NULL; + if (!IsValidIndustryType(industry_type)) return nullptr; const IndustrySpec *ins = ::GetIndustrySpec(industry_type); @@ -80,7 +78,7 @@ /* static */ ScriptList *ScriptIndustryType::GetAcceptedCargo(IndustryType industry_type) { - if (!IsValidIndustryType(industry_type)) return NULL; + if (!IsValidIndustryType(industry_type)) return nullptr; const IndustrySpec *ins = ::GetIndustrySpec(industry_type); @@ -123,7 +121,8 @@ EnforcePrecondition(false, ScriptMap::IsValidTile(tile)); uint32 seed = ::InteractiveRandom(); - return ScriptObject::DoCommand(tile, (1 << 16) | (::InteractiveRandomRange(::GetIndustrySpec(industry_type)->num_table) << 8) | industry_type, seed, CMD_BUILD_INDUSTRY); + uint32 layout_index = ::InteractiveRandomRange((uint32)::GetIndustrySpec(industry_type)->layouts.size()); + return ScriptObject::DoCommand(tile, (1 << 16) | (layout_index << 8) | industry_type, seed, CMD_BUILD_INDUSTRY); } /* static */ bool ScriptIndustryType::ProspectIndustry(IndustryType industry_type) diff --git a/src/script/api/script_industrytype.hpp b/src/script/api/script_industrytype.hpp index 8dccc68c91..3314cb053f 100644 --- a/src/script/api/script_industrytype.hpp +++ b/src/script/api/script_industrytype.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/script/api/script_industrytypelist.cpp b/src/script/api/script_industrytypelist.cpp index b60361578b..c8986f675a 100644 --- a/src/script/api/script_industrytypelist.cpp +++ b/src/script/api/script_industrytypelist.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. diff --git a/src/script/api/script_industrytypelist.hpp b/src/script/api/script_industrytypelist.hpp index efb2a4a611..2d2f8775be 100644 --- a/src/script/api/script_industrytypelist.hpp +++ b/src/script/api/script_industrytypelist.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/script/api/script_info_docs.hpp b/src/script/api/script_info_docs.hpp index e12a6a45c5..be5d0cec6f 100644 --- a/src/script/api/script_info_docs.hpp +++ b/src/script/api/script_info_docs.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/script/api/script_infrastructure.cpp b/src/script/api/script_infrastructure.cpp index d7da2747e1..5ef5470c53 100644 --- a/src/script/api/script_infrastructure.cpp +++ b/src/script/api/script_infrastructure.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. @@ -90,7 +88,8 @@ company = ScriptCompany::ResolveCompanyID(company); if (company == ScriptCompany::COMPANY_INVALID || (::RoadType)roadtype >= ROADTYPE_END || !_settings_game.economy.infrastructure_maintenance) return 0; - return ::RoadMaintenanceCost((::RoadType)roadtype, ::Company::Get((::CompanyID)company)->infrastructure.road[roadtype]); + const ::Company *c = ::Company::Get((::CompanyID)company); + return ::RoadMaintenanceCost((::RoadType)roadtype, c->infrastructure.road[roadtype], RoadTypeIsRoad((::RoadType)roadtype) ? c->infrastructure.GetRoadTotal() : c->infrastructure.GetTramTotal()); } /* static */ Money ScriptInfrastructure::GetMonthlyInfrastructureCosts(ScriptCompany::CompanyID company, Infrastructure infra_type) @@ -114,8 +113,9 @@ case INFRASTRUCTURE_ROAD: { Money cost; + uint32 road_total = c->infrastructure.GetRoadTotal(); for (::RoadType rt = ::ROADTYPE_BEGIN; rt != ::ROADTYPE_END; rt++) { - cost += RoadMaintenanceCost(rt, c->infrastructure.road[rt]); + cost += RoadMaintenanceCost(rt, c->infrastructure.road[rt], road_total); } return cost; } diff --git a/src/script/api/script_infrastructure.hpp b/src/script/api/script_infrastructure.hpp index f2ef641eea..8f2d283137 100644 --- a/src/script/api/script_infrastructure.hpp +++ b/src/script/api/script_infrastructure.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/script/api/script_list.cpp b/src/script/api/script_list.cpp index d0c72b5bb1..2fb2a8d6b9 100644 --- a/src/script/api/script_list.cpp +++ b/src/script/api/script_list.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. @@ -109,7 +107,7 @@ public: void End() { - this->bucket_list = NULL; + this->bucket_list = nullptr; this->has_no_more_items = true; this->item_next = 0; } @@ -119,7 +117,7 @@ public: */ void FindNext() { - if (this->bucket_list == NULL) { + if (this->bucket_list == nullptr) { this->has_no_more_items = true; return; } @@ -128,7 +126,7 @@ public: if (this->bucket_list_iter == this->bucket_list->end()) { this->bucket_iter++; if (this->bucket_iter == this->list->buckets.end()) { - this->bucket_list = NULL; + this->bucket_list = nullptr; return; } this->bucket_list = &(*this->bucket_iter).second; @@ -203,7 +201,7 @@ public: void End() { - this->bucket_list = NULL; + this->bucket_list = nullptr; this->has_no_more_items = true; this->item_next = 0; } @@ -213,14 +211,14 @@ public: */ void FindNext() { - if (this->bucket_list == NULL) { + if (this->bucket_list == nullptr) { this->has_no_more_items = true; return; } if (this->bucket_list_iter == this->bucket_list->begin()) { if (this->bucket_iter == this->list->buckets.begin()) { - this->bucket_list = NULL; + this->bucket_list = nullptr; return; } this->bucket_iter--; @@ -845,7 +843,7 @@ SQInteger ScriptList::Valuate(HSQUIRRELVM vm) int nparam = sq_gettop(vm) - 1; if (nparam < 1) { - return sq_throwerror(vm, "You need to give a least a Valuator as parameter to ScriptList::Valuate"); + return sq_throwerror(vm, "You need to give at least a Valuator as parameter to ScriptList::Valuate"); } /* Make sure the valuator function is really a function, and not any diff --git a/src/script/api/script_list.hpp b/src/script/api/script_list.hpp index 1fbafe3d9f..0dbb2c45d7 100644 --- a/src/script/api/script_list.hpp +++ b/src/script/api/script_list.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. @@ -198,7 +196,7 @@ public: /** * 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 != NULL + * @pre list != nullptr */ void RemoveList(ScriptList *list); @@ -242,7 +240,7 @@ public: /** * 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 != NULL + * @pre list != nullptr */ void KeepList(ScriptList *list); diff --git a/src/script/api/script_log.cpp b/src/script/api/script_log.cpp index d9fbbde982..38a9a87d94 100644 --- a/src/script/api/script_log.cpp +++ b/src/script/api/script_log.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. @@ -35,7 +33,7 @@ /* static */ void ScriptLog::Log(ScriptLog::ScriptLogType level, const char *message) { - if (ScriptObject::GetLogPointer() == NULL) { + if (ScriptObject::GetLogPointer() == nullptr) { ScriptObject::GetLogPointer() = new LogData(); LogData *log = (LogData *)ScriptObject::GetLogPointer(); @@ -59,7 +57,7 @@ /* Cut string after first \n */ char *p; - while ((p = strchr(log->lines[log->pos], '\n')) != NULL) { + while ((p = strchr(log->lines[log->pos], '\n')) != nullptr) { *p = '\0'; break; } diff --git a/src/script/api/script_log.hpp b/src/script/api/script_log.hpp index def37c938e..a71e09c2ef 100644 --- a/src/script/api/script_log.hpp +++ b/src/script/api/script_log.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/script/api/script_map.cpp b/src/script/api/script_map.cpp index 6334089fdb..da66de10f3 100644 --- a/src/script/api/script_map.cpp +++ b/src/script/api/script_map.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. diff --git a/src/script/api/script_map.hpp b/src/script/api/script_map.hpp index 3648ae7f39..30acdb9176 100644 --- a/src/script/api/script_map.hpp +++ b/src/script/api/script_map.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/script/api/script_marine.cpp b/src/script/api/script_marine.cpp index 434ec11acc..c175adf066 100644 --- a/src/script/api/script_marine.cpp +++ b/src/script/api/script_marine.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. @@ -166,9 +164,9 @@ /* static */ Money ScriptMarine::GetBuildCost(BuildType build_type) { switch (build_type) { - case BT_DOCK: return ::GetPrice(PR_BUILD_STATION_DOCK, 1, NULL); - case BT_DEPOT: return ::GetPrice(PR_BUILD_DEPOT_SHIP, 1, NULL); - case BT_BUOY: return ::GetPrice(PR_BUILD_WAYPOINT_BUOY, 1, NULL); + case BT_DOCK: return ::GetPrice(PR_BUILD_STATION_DOCK, 1, nullptr); + case BT_DEPOT: return ::GetPrice(PR_BUILD_DEPOT_SHIP, 1, nullptr); + case BT_BUOY: return ::GetPrice(PR_BUILD_WAYPOINT_BUOY, 1, nullptr); default: return -1; } } diff --git a/src/script/api/script_marine.hpp b/src/script/api/script_marine.hpp index d70121029f..324ed8f3e9 100644 --- a/src/script/api/script_marine.hpp +++ b/src/script/api/script_marine.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/script/api/script_news.cpp b/src/script/api/script_news.cpp index 5f84f96d69..678cc69852 100644 --- a/src/script/api/script_news.cpp +++ b/src/script/api/script_news.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. @@ -25,7 +23,7 @@ { CCountedPtr counter(text); - EnforcePrecondition(false, text != NULL); + EnforcePrecondition(false, text != nullptr); const char *encoded = text->GetEncodedText(); EnforcePreconditionEncodedText(false, encoded); EnforcePrecondition(false, type == NT_ECONOMY || type == NT_SUBSIDIES || type == NT_GENERAL); diff --git a/src/script/api/script_news.hpp b/src/script/api/script_news.hpp index ca0656608f..6b7b39af01 100644 --- a/src/script/api/script_news.hpp +++ b/src/script/api/script_news.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. @@ -61,7 +59,7 @@ public: * - 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 != NULL. + * @pre text != nullptr. * @pre company == COMPANY_INVALID || ResolveCompanyID(company) != COMPANY_INVALID. * @pre The \a reference condition must be fulfilled. */ diff --git a/src/script/api/script_object.cpp b/src/script/api/script_object.cpp index 49dba6bb73..6275d1be38 100644 --- a/src/script/api/script_object.cpp +++ b/src/script/api/script_object.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. @@ -23,6 +21,7 @@ #include "../script_instance.hpp" #include "../script_fatalerror.hpp" #include "script_error.hpp" +#include "../../debug.h" #include "../../safeguards.h" @@ -36,9 +35,9 @@ static ScriptStorage *GetStorage() } -/* static */ ScriptInstance *ScriptObject::ActiveInstance::active = NULL; +/* static */ ScriptInstance *ScriptObject::ActiveInstance::active = nullptr; -ScriptObject::ActiveInstance::ActiveInstance(ScriptInstance *instance) +ScriptObject::ActiveInstance::ActiveInstance(ScriptInstance *instance) : alc_scope(instance->engine) { this->last_active = ScriptObject::ActiveInstance::active; ScriptObject::ActiveInstance::active = instance; @@ -51,7 +50,7 @@ ScriptObject::ActiveInstance::~ActiveInstance() /* static */ ScriptInstance *ScriptObject::GetActiveInstance() { - assert(ScriptObject::ActiveInstance::active != NULL); + assert(ScriptObject::ActiveInstance::active != nullptr); return ScriptObject::ActiveInstance::active; } @@ -83,6 +82,27 @@ ScriptObject::ActiveInstance::~ActiveInstance() return GetStorage()->mode_instance; } +/* static */ void ScriptObject::SetLastCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) +{ + ScriptStorage *s = GetStorage(); + DEBUG(script, 6, "SetLastCommand company=%02d tile=%06x p1=%08x p2=%08x cmd=%d", s->root_company, tile, p1, p2, cmd); + s->last_tile = tile; + s->last_p1 = p1; + s->last_p2 = p2; + s->last_cmd = cmd & CMD_ID_MASK; +} + +/* static */ bool ScriptObject::CheckLastCommand(TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) +{ + ScriptStorage *s = GetStorage(); + DEBUG(script, 6, "CheckLastCommand company=%02d tile=%06x p1=%08x p2=%08x cmd=%d", s->root_company, tile, p1, p2, cmd); + if (s->last_tile != tile) return false; + if (s->last_p1 != p1) return false; + if (s->last_p2 != p2) return false; + if (s->last_cmd != (cmd & CMD_ID_MASK)) return false; + return true; +} + /* static */ void ScriptObject::SetDoCommandCosts(Money value) { GetStorage()->costs = CommandCost(value); @@ -296,18 +316,19 @@ ScriptObject::ActiveInstance::~ActiveInstance() } /* Set the default callback to return a true/false result of the DoCommand */ - if (callback == NULL) callback = &ScriptInstance::DoCommandReturn; + if (callback == nullptr) callback = &ScriptInstance::DoCommandReturn; /* Are we only interested in the estimate costs? */ - bool estimate_only = GetDoCommandMode() != NULL && !GetDoCommandMode()(); + bool estimate_only = GetDoCommandMode() != nullptr && !GetDoCommandMode()(); -#ifdef ENABLE_NETWORK /* Only set p2 when the command does not come from the network. */ if (GetCommandFlags(cmd) & CMD_CLIENT_ID && p2 == 0) p2 = UINT32_MAX; -#endif + + /* Store the command for command callback validation. */ + if (!estimate_only && _networking && !_generating_world) SetLastCommand(tile, p1, p2, cmd); /* Try to perform the command. */ - CommandCost res = ::DoCommandPInternal(tile, p1, p2, cmd, (_networking && !_generating_world) ? ScriptObject::GetActiveInstance()->GetDoCommandCallback() : NULL, text, false, estimate_only); + CommandCost res = ::DoCommandPInternal(tile, p1, p2, cmd, (_networking && !_generating_world) ? ScriptObject::GetActiveInstance()->GetDoCommandCallback() : nullptr, text, false, estimate_only); /* We failed; set the error and bail out */ if (res.Failed()) { @@ -330,7 +351,7 @@ ScriptObject::ActiveInstance::~ActiveInstance() if (_generating_world) { IncreaseDoCommandCosts(res.GetCost()); - if (callback != NULL) { + if (callback != nullptr) { /* Insert return value into to stack and throw a control code that * the return value in the stack should be used. */ callback(GetActiveInstance()); diff --git a/src/script/api/script_object.hpp b/src/script/api/script_object.hpp index 482e76f663..f953b20e47 100644 --- a/src/script/api/script_object.hpp +++ b/src/script/api/script_object.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. @@ -18,6 +16,7 @@ #include "script_types.hpp" #include "../script_suspend.hpp" +#include "../squirrel.hpp" /** * The callback function for Mode-classes. @@ -48,6 +47,7 @@ protected: ~ActiveInstance(); private: ScriptInstance *last_active; ///< The active instance before we go instantiated. + ScriptAllocatorScope alc_scope; ///< Keep the correct allocator for the script instance activated static ScriptInstance *active; ///< The global current active instance. }; @@ -69,7 +69,17 @@ protected: /** * Executes a raw DoCommand for the script. */ - static bool DoCommand(TileIndex tile, uint32 p1, uint32 p2, uint cmd, const char *text = NULL, Script_SuspendCallbackProc *callback = NULL); + static bool DoCommand(TileIndex tile, uint32 p1, uint32 p2, uint cmd, const char *text = nullptr, Script_SuspendCallbackProc *callback = nullptr); + + /** + * Store the latest command executed by the script. + */ + static void SetLastCommand(TileIndex tile, uint32 p1, uint32 p2, uint cmd); + + /** + * Check if it's the latest command executed by the script. + */ + static bool CheckLastCommand(TileIndex tile, uint32 p1, uint32 p2, uint cmd); /** * Sets the DoCommand costs counter to a value. diff --git a/src/script/api/script_order.cpp b/src/script/api/script_order.cpp index a1390bf8f5..3290e51034 100644 --- a/src/script/api/script_order.cpp +++ b/src/script/api/script_order.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. @@ -66,7 +64,7 @@ static const Order *ResolveOrder(VehicleID vehicle_id, ScriptOrder::OrderPositio const Order *order = &v->current_order; if (order->GetType() == OT_GOTO_DEPOT && !(order->GetDepotOrderType() & ODTFB_PART_OF_ORDERS)) return order; order_position = ScriptOrder::ResolveOrderPosition(vehicle_id, order_position); - if (order_position == ScriptOrder::ORDER_INVALID) return NULL; + if (order_position == ScriptOrder::ORDER_INVALID) return nullptr; } const Order *order = v->GetFirstOrder(); while (order->GetType() == OT_IMPLICIT) order = order->next; @@ -108,7 +106,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr if (!IsValidVehicleOrder(vehicle_id, order_position)) return false; const Order *order = ::ResolveOrder(vehicle_id, order_position); - return order != NULL && order->GetType() == OT_GOTO_STATION; + return order != nullptr && order->GetType() == OT_GOTO_STATION; } /* static */ bool ScriptOrder::IsGotoDepotOrder(VehicleID vehicle_id, OrderPosition order_position) @@ -116,7 +114,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr if (!IsValidVehicleOrder(vehicle_id, order_position)) return false; const Order *order = ::ResolveOrder(vehicle_id, order_position); - return order != NULL && order->GetType() == OT_GOTO_DEPOT; + return order != nullptr && order->GetType() == OT_GOTO_DEPOT; } /* static */ bool ScriptOrder::IsGotoWaypointOrder(VehicleID vehicle_id, OrderPosition order_position) @@ -124,7 +122,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr if (!IsValidVehicleOrder(vehicle_id, order_position)) return false; const Order *order = ::ResolveOrder(vehicle_id, order_position); - return order != NULL && order->GetType() == OT_GOTO_WAYPOINT; + return order != nullptr && order->GetType() == OT_GOTO_WAYPOINT; } /* static */ bool ScriptOrder::IsConditionalOrder(VehicleID vehicle_id, OrderPosition order_position) @@ -150,7 +148,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr if (!IsValidVehicleOrder(vehicle_id, order_position)) return false; const Order *order = ::ResolveOrder(vehicle_id, order_position); - return order != NULL && order->IsRefit(); + return order != nullptr && order->IsRefit(); } /* static */ bool ScriptOrder::IsCurrentOrderPartOfOrderList(VehicleID vehicle_id) @@ -240,7 +238,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr if (!IsValidVehicleOrder(vehicle_id, order_position)) return INVALID_TILE; const Order *order = ::ResolveOrder(vehicle_id, order_position); - if (order == NULL || order->GetType() == OT_CONDITIONAL) return INVALID_TILE; + if (order == nullptr || order->GetType() == OT_CONDITIONAL) return INVALID_TILE; const Vehicle *v = ::Vehicle::Get(vehicle_id); switch (order->GetType()) { @@ -261,11 +259,13 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr TILE_AREA_LOOP(t, st->train_station) { if (st->TileBelongsToRailStation(t)) return t; } - } else if (st->dock_tile != INVALID_TILE) { - return st->dock_tile; - } else if (st->bus_stops != NULL) { + } else if (st->ship_station.tile != INVALID_TILE) { + TILE_AREA_LOOP(t, st->ship_station) { + if (IsDockTile(t) && GetStationIndex(t) == st->index) return t; + } + } else if (st->bus_stops != nullptr) { return st->bus_stops->xy; - } else if (st->truck_stops != NULL) { + } else if (st->truck_stops != nullptr) { return st->truck_stops->xy; } else if (st->airport.tile != INVALID_TILE) { TILE_AREA_LOOP(tile, st->airport) { @@ -294,7 +294,7 @@ static int ScriptOrderPositionToRealOrderPosition(VehicleID vehicle_id, ScriptOr if (!IsValidVehicleOrder(vehicle_id, order_position)) return OF_INVALID; const Order *order = ::ResolveOrder(vehicle_id, order_position); - if (order == NULL || order->GetType() == OT_CONDITIONAL || order->GetType() == OT_DUMMY) return OF_INVALID; + if (order == nullptr || order->GetType() == OT_CONDITIONAL || order->GetType() == OT_DUMMY) return OF_INVALID; ScriptOrderFlags order_flags = OF_NONE; order_flags |= (ScriptOrderFlags)order->GetNonStopType(); @@ -586,7 +586,7 @@ static void _DoCommandReturnSetOrderFlags(class ScriptInstance *instance) EnforcePrecondition(false, (order_flags & OF_GOTO_NEAREST_DEPOT) == (current & OF_GOTO_NEAREST_DEPOT)); if ((current & OF_NON_STOP_FLAGS) != (order_flags & OF_NON_STOP_FLAGS)) { - return ScriptObject::DoCommand(0, vehicle_id | (order_pos << 20), (order_flags & OF_NON_STOP_FLAGS) << 4 | MOF_NON_STOP, CMD_MODIFY_ORDER, NULL, &::_DoCommandReturnSetOrderFlags); + return ScriptObject::DoCommand(0, vehicle_id | (order_pos << 20), (order_flags & OF_NON_STOP_FLAGS) << 4 | MOF_NON_STOP, CMD_MODIFY_ORDER, nullptr, &::_DoCommandReturnSetOrderFlags); } switch (order->GetType()) { @@ -595,16 +595,16 @@ static void _DoCommandReturnSetOrderFlags(class ScriptInstance *instance) uint data = DA_ALWAYS_GO; if (order_flags & OF_SERVICE_IF_NEEDED) data = DA_SERVICE; if (order_flags & OF_STOP_IN_DEPOT) data = DA_STOP; - return ScriptObject::DoCommand(0, vehicle_id | (order_pos << 20), (data << 4) | MOF_DEPOT_ACTION, CMD_MODIFY_ORDER, NULL, &::_DoCommandReturnSetOrderFlags); + return ScriptObject::DoCommand(0, vehicle_id | (order_pos << 20), (data << 4) | MOF_DEPOT_ACTION, CMD_MODIFY_ORDER, nullptr, &::_DoCommandReturnSetOrderFlags); } break; case OT_GOTO_STATION: if ((current & OF_UNLOAD_FLAGS) != (order_flags & OF_UNLOAD_FLAGS)) { - return ScriptObject::DoCommand(0, vehicle_id | (order_pos << 20), (order_flags & OF_UNLOAD_FLAGS) << 2 | MOF_UNLOAD, CMD_MODIFY_ORDER, NULL, &::_DoCommandReturnSetOrderFlags); + return ScriptObject::DoCommand(0, vehicle_id | (order_pos << 20), (order_flags & OF_UNLOAD_FLAGS) << 2 | MOF_UNLOAD, CMD_MODIFY_ORDER, nullptr, &::_DoCommandReturnSetOrderFlags); } if ((current & OF_LOAD_FLAGS) != (order_flags & OF_LOAD_FLAGS)) { - return ScriptObject::DoCommand(0, vehicle_id | (order_pos << 20), (order_flags & OF_LOAD_FLAGS) >> 1 | MOF_LOAD, CMD_MODIFY_ORDER, NULL, &::_DoCommandReturnSetOrderFlags); + return ScriptObject::DoCommand(0, vehicle_id | (order_pos << 20), (order_flags & OF_LOAD_FLAGS) >> 1 | MOF_LOAD, CMD_MODIFY_ORDER, nullptr, &::_DoCommandReturnSetOrderFlags); } break; @@ -667,8 +667,14 @@ static void _DoCommandReturnSetOrderFlags(class ScriptInstance *instance) /* static */ uint ScriptOrder::GetOrderDistance(ScriptVehicle::VehicleType vehicle_type, TileIndex origin_tile, TileIndex dest_tile) { if (vehicle_type == ScriptVehicle::VT_AIR) { - if (ScriptTile::IsStationTile(origin_tile) && ::Station::GetByTile(origin_tile)->airport.tile != INVALID_TILE) origin_tile = ::Station::GetByTile(origin_tile)->airport.tile; - if (ScriptTile::IsStationTile(dest_tile) && ::Station::GetByTile(dest_tile)->airport.tile != INVALID_TILE) dest_tile = ::Station::GetByTile(dest_tile)->airport.tile; + if (ScriptTile::IsStationTile(origin_tile)) { + Station *orig_station = ::Station::GetByTile(origin_tile); + if (orig_station != nullptr && orig_station->airport.tile != INVALID_TILE) origin_tile = orig_station->airport.tile; + } + if (ScriptTile::IsStationTile(dest_tile)) { + Station *dest_station = ::Station::GetByTile(dest_tile); + if (dest_station != nullptr && dest_station->airport.tile != INVALID_TILE) dest_tile = dest_station->airport.tile; + } return ScriptMap::DistanceSquare(origin_tile, dest_tile); } else { diff --git a/src/script/api/script_order.hpp b/src/script/api/script_order.hpp index 9161478867..cce74fa5dc 100644 --- a/src/script/api/script_order.hpp +++ b/src/script/api/script_order.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/script/api/script_rail.cpp b/src/script/api/script_rail.cpp index f7682cfd8f..aedb4a364a 100644 --- a/src/script/api/script_rail.cpp +++ b/src/script/api/script_rail.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. @@ -25,7 +23,7 @@ /* static */ char *ScriptRail::GetName(RailType rail_type) { - if (!IsRailTypeAvailable(rail_type)) return NULL; + if (!IsRailTypeAvailable(rail_type)) return nullptr; return GetString(GetRailTypeInfo((::RailType)rail_type)->strings.menu_text); } @@ -68,7 +66,7 @@ /* static */ bool ScriptRail::IsRailTypeAvailable(RailType rail_type) { - if ((::RailType)rail_type < RAILTYPE_BEGIN || (::RailType)rail_type >= RAILTYPE_END) return false; + if ((::RailType)rail_type >= RAILTYPE_END) return false; return ScriptObject::GetCompany() == OWNER_DEITY || ::HasRailtypeAvail(ScriptObject::GetCompany(), (::RailType)rail_type); } @@ -185,7 +183,7 @@ if (res != CALLBACK_FAILED) { int index = 0; const StationSpec *spec = StationClass::GetByGrf(file->grfid, res, &index); - if (spec == NULL) { + if (spec == nullptr) { DEBUG(grf, 1, "%s returned an invalid station ID for 'AI construction/purchase selection (18)' callback", file->filename); } else { /* We might have gotten an usable station spec. Try to build it, but if it fails we'll fall back to the original station. */ @@ -487,10 +485,10 @@ static bool IsValidSignalType(int signal_type) switch (build_type) { case BT_TRACK: return ::RailBuildCost((::RailType)railtype); - case BT_SIGNAL: return ::GetPrice(PR_BUILD_SIGNALS, 1, NULL); - case BT_DEPOT: return ::GetPrice(PR_BUILD_DEPOT_TRAIN, 1, NULL); - case BT_STATION: return ::GetPrice(PR_BUILD_STATION_RAIL, 1, NULL) + ::GetPrice(PR_BUILD_STATION_RAIL_LENGTH, 1, NULL); - case BT_WAYPOINT: return ::GetPrice(PR_BUILD_WAYPOINT_RAIL, 1, NULL); + case BT_SIGNAL: return ::GetPrice(PR_BUILD_SIGNALS, 1, nullptr); + case BT_DEPOT: return ::GetPrice(PR_BUILD_DEPOT_TRAIN, 1, nullptr); + case BT_STATION: return ::GetPrice(PR_BUILD_STATION_RAIL, 1, nullptr) + ::GetPrice(PR_BUILD_STATION_RAIL_LENGTH, 1, nullptr); + case BT_WAYPOINT: return ::GetPrice(PR_BUILD_WAYPOINT_RAIL, 1, nullptr); default: return -1; } } diff --git a/src/script/api/script_rail.hpp b/src/script/api/script_rail.hpp index 7e2a59e7f7..f82765a706 100644 --- a/src/script/api/script_rail.hpp +++ b/src/script/api/script_rail.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. @@ -36,7 +34,7 @@ public: ERR_UNSUITABLE_TRACK, // [STR_ERROR_NO_SUITABLE_RAILROAD_TRACK, STR_ERROR_THERE_IS_NO_RAILROAD_TRACK, STR_ERROR_THERE_ARE_NO_SIGNALS, STR_ERROR_THERE_IS_NO_STATION] /** This railtype cannot have crossings */ - ERR_RAILTYPE_DISALLOWS_CROSSING, // [STR_ERROR_CROSSING_DISALLOWED] + ERR_RAILTYPE_DISALLOWS_CROSSING, // [STR_ERROR_CROSSING_DISALLOWED_RAIL] }; /** diff --git a/src/script/api/script_railtypelist.cpp b/src/script/api/script_railtypelist.cpp index 016145b764..ccbbe97095 100644 --- a/src/script/api/script_railtypelist.cpp +++ b/src/script/api/script_railtypelist.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. diff --git a/src/script/api/script_railtypelist.hpp b/src/script/api/script_railtypelist.hpp index 478fd0d5e3..78c7f9ecff 100644 --- a/src/script/api/script_railtypelist.hpp +++ b/src/script/api/script_railtypelist.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/script/api/script_road.cpp b/src/script/api/script_road.cpp index 3dd1453b68..f842581784 100644 --- a/src/script/api/script_road.cpp +++ b/src/script/api/script_road.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. @@ -23,6 +21,13 @@ return ScriptCargo::HasCargoClass(cargo_type, ScriptCargo::CC_PASSENGERS) ? ROADVEHTYPE_BUS : ROADVEHTYPE_TRUCK; } +/* static */ char *ScriptRoad::GetName(RoadType road_type) +{ + if (!IsRoadTypeAvailable(road_type)) return nullptr; + + return GetString(GetRoadTypeInfo((::RoadType)road_type)->strings.name); +} + /* static */ bool ScriptRoad::IsRoadTile(TileIndex tile) { if (!::IsValidTile(tile)) return false; @@ -37,7 +42,7 @@ if (!IsRoadTypeAvailable(GetCurrentRoadType())) return false; return ::IsTileType(tile, MP_ROAD) && ::GetRoadTileType(tile) == ROAD_TILE_DEPOT && - (::RoadTypeToRoadTypes((::RoadType)GetCurrentRoadType()) & ::GetRoadTypes(tile)) != 0; + HasBit(::GetPresentRoadTypes(tile), (::RoadType)GetCurrentRoadType()); } /* static */ bool ScriptRoad::IsRoadStationTile(TileIndex tile) @@ -45,7 +50,7 @@ if (!::IsValidTile(tile)) return false; if (!IsRoadTypeAvailable(GetCurrentRoadType())) return false; - return ::IsRoadStopTile(tile) && (::RoadTypeToRoadTypes((::RoadType)GetCurrentRoadType()) & ::GetRoadTypes(tile)) != 0; + return ::IsRoadStopTile(tile) && HasBit(::GetPresentRoadTypes(tile), (::RoadType)GetCurrentRoadType()); } /* static */ bool ScriptRoad::IsDriveThroughRoadStationTile(TileIndex tile) @@ -53,12 +58,12 @@ if (!::IsValidTile(tile)) return false; if (!IsRoadTypeAvailable(GetCurrentRoadType())) return false; - return ::IsDriveThroughStopTile(tile) && (::RoadTypeToRoadTypes((::RoadType)GetCurrentRoadType()) & ::GetRoadTypes(tile)) != 0; + return ::IsDriveThroughStopTile(tile) && HasBit(::GetPresentRoadTypes(tile), (::RoadType)GetCurrentRoadType()); } /* static */ bool ScriptRoad::IsRoadTypeAvailable(RoadType road_type) { - return ::IsValidRoadType((::RoadType)road_type) && ::HasRoadTypesAvail(ScriptObject::GetCompany(), ::RoadTypeToRoadTypes((::RoadType)road_type)); + return (::RoadType)road_type < ROADTYPE_END && ::HasRoadTypeAvail(ScriptObject::GetCompany(), (::RoadType)road_type); } /* static */ ScriptRoad::RoadType ScriptRoad::GetCurrentRoadType() @@ -73,11 +78,24 @@ ScriptObject::SetRoadType((::RoadType)road_type); } +/* static */ bool ScriptRoad::RoadVehCanRunOnRoad(RoadType engine_road_type, RoadType road_road_type) +{ + return RoadVehHasPowerOnRoad(engine_road_type, road_road_type); +} + +/* static */ bool ScriptRoad::RoadVehHasPowerOnRoad(RoadType engine_road_type, RoadType road_road_type) +{ + if (!IsRoadTypeAvailable(engine_road_type)) return false; + if (!IsRoadTypeAvailable(road_road_type)) return false; + + return ::HasPowerOnRoad((::RoadType)engine_road_type, (::RoadType)road_road_type); +} + /* static */ bool ScriptRoad::HasRoadType(TileIndex tile, RoadType road_type) { if (!ScriptMap::IsValidTile(tile)) return false; if (!IsRoadTypeAvailable(road_type)) return false; - return ::GetAnyRoadBits(tile, (::RoadType)road_type, false) != ROAD_NONE; + return ::GetAnyRoadBits(tile, ::GetRoadTramType((::RoadType)road_type), false) != ROAD_NONE; } /* static */ bool ScriptRoad::AreRoadTilesConnected(TileIndex t1, TileIndex t2) @@ -89,8 +107,9 @@ /* Tiles not neighbouring */ if ((abs((int)::TileX(t1) - (int)::TileX(t2)) + abs((int)::TileY(t1) - (int)::TileY(t2))) != 1) return false; - RoadBits r1 = ::GetAnyRoadBits(t1, ScriptObject::GetRoadType()); - RoadBits r2 = ::GetAnyRoadBits(t2, ScriptObject::GetRoadType()); + RoadTramType rtt = ::GetRoadTramType(ScriptObject::GetRoadType()); + RoadBits r1 = ::GetAnyRoadBits(t1, rtt); // TODO + RoadBits r2 = ::GetAnyRoadBits(t2, rtt); // TODO uint dir_1 = (::TileX(t1) == ::TileX(t2)) ? (::TileY(t1) < ::TileY(t2) ? 2 : 0) : (::TileX(t1) < ::TileX(t2) ? 1 : 3); uint dir_2 = 2 ^ dir_1; @@ -100,6 +119,16 @@ return HasBit(r1, dir_1) && HasBit(r2, dir_2) && drd2 != DRD_BOTH && drd2 != (dir_1 > dir_2 ? DRD_SOUTHBOUND : DRD_NORTHBOUND); } +/* static */ bool ScriptRoad::ConvertRoadType(TileIndex start_tile, TileIndex end_tile, RoadType road_type) +{ + EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforcePrecondition(false, ::IsValidTile(start_tile)); + EnforcePrecondition(false, ::IsValidTile(end_tile)); + EnforcePrecondition(false, IsRoadTypeAvailable(road_type)); + + return ScriptObject::DoCommand(start_tile, end_tile, (::RoadType)road_type, CMD_CONVERT_ROAD); +} + /* Helper functions for ScriptRoad::CanBuildConnectedRoadParts(). */ /** @@ -245,7 +274,7 @@ static int32 LookupWithBuildOnSlopes(::Slope slope, Array *existing, int32 start /* Now perform the actual rotation. */ for (int j = 0; j < base_rotate; j++) { - for (int i = 0; i < existing->size; i++) { + for (size_t i = 0; i < existing->size; i++) { existing->array[i] = RotateNeighbour(existing->array[i]); } start = RotateNeighbour(start); @@ -256,7 +285,7 @@ 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 (int i = 0; i < existing->size; i++) { + for (size_t i = 0; i < existing->size; i++) { existing_roadbits |= NeighbourToRoadBits(existing->array[i]); } @@ -354,7 +383,7 @@ static bool NormaliseTileOffset(int32 *tile) /* The start tile and end tile cannot be the same tile either. */ if (start == end) return -1; - for (int i = 0; i < existing->size; i++) { + for (size_t i = 0; i < existing->size; i++) { if (!NormaliseTileOffset(&existing->array[i])) return -1; } @@ -380,7 +409,7 @@ static bool NormaliseTileOffset(int32 *tile) if (::IsNormalRoadTile(tile)) { rb = ::GetAllRoadBits(tile); } else { - for (::RoadType rt = ::ROADTYPE_BEGIN; rt < ::ROADTYPE_END; rt++) rb |= ::GetAnyRoadBits(tile, rt); + rb = ::GetAnyRoadBits(tile, RTT_ROAD) | ::GetAnyRoadBits(tile, RTT_TRAM); } for (uint i = 0; i < lengthof(neighbours); i++) { if (HasBit(rb, i)) existing->array[existing->size++] = neighbours[i]; @@ -392,15 +421,15 @@ static bool NormaliseTileOffset(int32 *tile) /** * Check whether one can reach (possibly by building) a road piece the center * of the neighbouring tile. This includes roads and (drive through) stations. - * @param rts The road type we want to know reachability for + * @param rt The road type we want to know reachability for * @param start_tile The tile to "enter" the neighbouring tile. * @param neighbour The direction to the neighbouring tile to "enter". * @return true if and only if the tile is reachable. */ -static bool NeighbourHasReachableRoad(::RoadTypes rts, TileIndex start_tile, DiagDirection neighbour) +static bool NeighbourHasReachableRoad(::RoadType rt, TileIndex start_tile, DiagDirection neighbour) { TileIndex neighbour_tile = ::TileAddByDiagDir(start_tile, neighbour); - if ((rts & ::GetRoadTypes(neighbour_tile)) == 0) return false; + if (!HasBit(::GetPresentRoadTypes(neighbour_tile), rt)) return false; switch (::GetTileType(neighbour_tile)) { case MP_ROAD: @@ -422,13 +451,13 @@ static bool NeighbourHasReachableRoad(::RoadTypes rts, TileIndex start_tile, Dia if (!::IsValidTile(tile)) return false; if (!IsRoadTypeAvailable(GetCurrentRoadType())) return false; - ::RoadTypes rts = ::RoadTypeToRoadTypes((::RoadType)GetCurrentRoadType()); + ::RoadType rt = (::RoadType)GetCurrentRoadType(); int32 neighbour = 0; - if (TileX(tile) > 0 && NeighbourHasReachableRoad(rts, tile, DIAGDIR_NE)) neighbour++; - if (NeighbourHasReachableRoad(rts, tile, DIAGDIR_SE)) neighbour++; - if (NeighbourHasReachableRoad(rts, tile, DIAGDIR_SW)) neighbour++; - if (TileY(tile) > 0 && NeighbourHasReachableRoad(rts, tile, DIAGDIR_NW)) neighbour++; + if (TileX(tile) > 0 && NeighbourHasReachableRoad(rt, tile, DIAGDIR_NE)) neighbour++; + if (NeighbourHasReachableRoad(rt, tile, DIAGDIR_SE)) neighbour++; + if (NeighbourHasReachableRoad(rt, tile, DIAGDIR_SW)) neighbour++; + if (TileY(tile) > 0 && NeighbourHasReachableRoad(rt, tile, DIAGDIR_NW)) neighbour++; return neighbour; } @@ -460,10 +489,10 @@ static bool NeighbourHasReachableRoad(::RoadTypes rts, TileIndex start_tile, Dia EnforcePrecondition(false, ::IsValidTile(start)); EnforcePrecondition(false, ::IsValidTile(end)); EnforcePrecondition(false, ::TileX(start) == ::TileX(end) || ::TileY(start) == ::TileY(end)); - EnforcePrecondition(false, !one_way || ScriptObject::GetRoadType() == ::ROADTYPE_ROAD); + EnforcePrecondition(false, !one_way || RoadTypeIsRoad(ScriptObject::GetRoadType())); EnforcePrecondition(false, IsRoadTypeAvailable(GetCurrentRoadType())); - return ScriptObject::DoCommand(start, end, (::TileY(start) != ::TileY(end) ? 4 : 0) | (((start < end) == !full) ? 1 : 2) | (ScriptObject::GetRoadType() << 3) | ((one_way ? 1 : 0) << 5) | 1 << 6, CMD_BUILD_LONG_ROAD); + return ScriptObject::DoCommand(start, end, (::TileY(start) != ::TileY(end) ? 4 : 0) | (((start < end) == !full) ? 1 : 2) | (ScriptObject::GetRoadType() << 3) | ((one_way ? 1 : 0) << 10) | 1 << 11, CMD_BUILD_LONG_ROAD); } /* static */ bool ScriptRoad::BuildRoad(TileIndex start, TileIndex end) @@ -520,11 +549,11 @@ static bool NeighbourHasReachableRoad(::RoadTypes rts, TileIndex start_tile, Dia entrance_dir = (::TileX(tile) == ::TileX(front)) ? (::TileY(tile) < ::TileY(front) ? 1 : 3) : (::TileX(tile) < ::TileX(front) ? 2 : 0); } - uint p2 = station_id == ScriptStation::STATION_JOIN_ADJACENT ? 0 : 32; + uint p2 = station_id == ScriptStation::STATION_JOIN_ADJACENT ? 0 : 4; p2 |= drive_through ? 2 : 0; p2 |= road_veh_type == ROADVEHTYPE_TRUCK ? 1 : 0; - p2 |= ::RoadTypeToRoadTypes(ScriptObject::GetRoadType()) << 2; - p2 |= entrance_dir << 6; + p2 |= ScriptObject::GetRoadType() << 5; + p2 |= entrance_dir << 3; p2 |= (ScriptStation::IsValidStation(station_id) ? station_id : INVALID_STATION) << 16; return ScriptObject::DoCommand(tile, 1 | 1 << 8, p2, CMD_BUILD_ROAD_STOP); } @@ -588,17 +617,29 @@ static bool NeighbourHasReachableRoad(::RoadTypes rts, TileIndex start_tile, Dia if (!ScriptRoad::IsRoadTypeAvailable(roadtype)) return -1; switch (build_type) { - case BT_ROAD: return ::GetPrice(PR_BUILD_ROAD, 1, NULL); - case BT_DEPOT: return ::GetPrice(PR_BUILD_DEPOT_ROAD, 1, NULL); - case BT_BUS_STOP: return ::GetPrice(PR_BUILD_STATION_BUS, 1, NULL); - case BT_TRUCK_STOP: return ::GetPrice(PR_BUILD_STATION_TRUCK, 1, NULL); + case BT_ROAD: return ::RoadBuildCost((::RoadType)roadtype); + case BT_DEPOT: return ::GetPrice(PR_BUILD_DEPOT_ROAD, 1, nullptr); + case BT_BUS_STOP: return ::GetPrice(PR_BUILD_STATION_BUS, 1, nullptr); + case BT_TRUCK_STOP: return ::GetPrice(PR_BUILD_STATION_TRUCK, 1, nullptr); default: return -1; } } +/* static */ ScriptRoad::RoadTramTypes ScriptRoad::GetRoadTramType(RoadType roadtype) +{ + return (RoadTramTypes)(1 << ::GetRoadTramType((::RoadType)roadtype)); +} + +/* static */ int32 ScriptRoad::GetMaxSpeed(RoadType road_type) +{ + if (!ScriptRoad::IsRoadTypeAvailable(road_type)) return 0; + + return GetRoadTypeInfo((::RoadType)road_type)->max_speed; +} + /* static */ uint16 ScriptRoad::GetMaintenanceCostFactor(RoadType roadtype) { if (!ScriptRoad::IsRoadTypeAvailable(roadtype)) return 0; - return roadtype == ROADTYPE_TRAM ? 3 : 2; + return GetRoadTypeInfo((::RoadType)roadtype)->maintenance_multiplier; } diff --git a/src/script/api/script_road.hpp b/src/script/api/script_road.hpp index ed4058f973..5a952d91a2 100644 --- a/src/script/api/script_road.hpp +++ b/src/script/api/script_road.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. @@ -13,6 +11,7 @@ #define SCRIPT_ROAD_HPP #include "script_tile.hpp" +#include "../../../road.h" /** * Class that handles all road related functions. @@ -36,16 +35,21 @@ public: /** Drive through roads can't be build on town owned roads */ ERR_ROAD_CANNOT_BUILD_ON_TOWN_ROAD, // [STR_ERROR_DRIVE_THROUGH_ON_TOWN_ROAD] - /** One way roads can't have junctions */ ERR_ROAD_ONE_WAY_ROADS_CANNOT_HAVE_JUNCTIONS, // [STR_ERROR_ONEWAY_ROADS_CAN_T_HAVE_JUNCTION] + + /** This roadtype cannot have crossings */ + ERR_ROADTYPE_DISALLOWS_CROSSING, // [STR_ERROR_CROSSING_DISALLOWED_ROAD] + + /** No suitable road could be found */ + ERR_UNSUITABLE_ROAD, // [STR_ERROR_NO_SUITABLE_ROAD, STR_ERROR_NO_SUITABLE_TRAMWAY, STR_ERROR_INCOMPATIBLE_ROAD] }; /** * Types of road known to the game. */ enum RoadType { - /* Note: these values represent part of the in-game RoadType enum */ + /* Note: these values represent part of the in-game static values */ ROADTYPE_ROAD = ::ROADTYPE_ROAD, ///< Build road objects. ROADTYPE_TRAM = ::ROADTYPE_TRAM, ///< Build tram objects. @@ -53,6 +57,14 @@ public: ROADTYPE_INVALID = -1, ///< Invalid RoadType. }; + /** + * Road/tram types + */ + enum RoadTramTypes { + ROADTRAMTYPES_ROAD = ::RTTB_ROAD, ///< Road road types. + ROADTRAMTYPES_TRAM = ::RTTB_TRAM, ///< Tram road types. + }; + /** * Type of road station. */ @@ -71,6 +83,14 @@ public: BT_TRUCK_STOP, ///< Build a truck stop }; + /** + * Get the name of a road type. + * @param road_type The road type to get the name of. + * @pre IsRoadTypeAvailable(road_type). + * @return The name the road type has. + */ + static char *GetName(RoadType road_type); + /** * Determines whether a busstop or a truckstop is needed to transport a certain cargo. * @param cargo_type The cargo to test. @@ -137,6 +157,41 @@ public: */ static void SetCurrentRoadType(RoadType road_type); + /** + * 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. + * @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'. + */ + static bool RoadVehCanRunOnRoad(ScriptRoad::RoadType engine_road_type, ScriptRoad::RoadType road_road_type); + + /** + * Check if a road vehicle built for a road type has power on another road type. + * @param engine_road_type The road type the road vehicle is built for. + * @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' has power on 'road_road_type'. + */ + static bool RoadVehHasPowerOnRoad(ScriptRoad::RoadType engine_road_type, ScriptRoad::RoadType road_road_type); + + + /** + * Convert the road on all tiles within a rectangle to another RoadType. + * @param start_tile One corner of the rectangle. + * @param end_tile The opposite corner of the rectangle. + * @param road_type The RoadType you want to convert. + * @pre ScriptMap::IsValidTile(start_tile). + * @pre ScriptMap::IsValidTile(end_tile). + * @pre IsRoadTypeAvailable(road_type). + * @game @pre Valid ScriptCompanyMode active in scope. + * @exception ScriptRoad::ERR_UNSUITABLE_ROAD + * @return Whether at least some road has been converted successfully. + */ + static bool ConvertRoadType(TileIndex start_tile, TileIndex end_tile, RoadType road_type); + /** * Check if a given tile has RoadType. * @param tile The tile to check. @@ -162,7 +217,7 @@ public: static bool AreRoadTilesConnected(TileIndex tile_from, TileIndex tile_to); /** - * Lookup function for building road parts independend on whether the + * Lookup function for building road parts independent of whether the * "building on slopes" setting is enabled or not. * This implementation can be used for abstract reasoning about a tile as * it needs the slope and existing road parts of the tile as information. @@ -193,10 +248,10 @@ public: static int32 CanBuildConnectedRoadParts(ScriptTile::Slope slope, struct Array *existing, TileIndex start, TileIndex end); /** - * Lookup function for building road parts independend on whether the + * Lookup function for building road parts independent of whether the * "building on slopes" setting is enabled or not. * This implementation can be used for reasoning about an existing tile. - * @param tile The the tile to examine. + * @param tile The tile to examine. * @param start The tile from where "tile" will be entered. * @param end The tile from where "tile" will be exited. * @pre start != end. @@ -482,16 +537,35 @@ public: /** * Get the baseprice of building a road-related object. - * @param roadtype the roadtype that is build (on) + * @param roadtype the roadtype of the object to build * @param build_type the type of object to build - * @pre IsRoadTypeAvailable(railtype) + * @pre IsRoadTypeAvailable(roadtype) * @return The baseprice of building the given object. */ static Money GetBuildCost(RoadType roadtype, BuildType build_type); /** - * Get the maintenance cost factor of a roadtype. - * @param roadtype The roadtype to get the maintenance factor of. + * Test if a road type is for road or trams. + * @param roadtype the roadtype to test. + * @return RoadTramTypes of the road types. + */ + static RoadTramTypes GetRoadTramType(RoadType roadtype); + + /** + * Get the maximum speed of road vehicles running on this roadtype. + * @param road_type The roadtype to get the maximum speed of. + * @pre IsRoadTypeAvailable(road_type) + * @return The maximum speed road vehicles can run on this roadtype + * or 0 if there is no limit. + * @note The speed is in OpenTTD's internal speed unit. + * 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); + + /** + * Get the maintenance cost factor of a road type. + * @param roadtype The road type to get the maintenance factor of. * @pre IsRoadTypeAvailable(roadtype) * @return Maintenance cost factor of the roadtype. */ diff --git a/src/script/api/script_roadtypelist.cpp b/src/script/api/script_roadtypelist.cpp new file mode 100644 index 0000000000..6ada0cb6b3 --- /dev/null +++ b/src/script/api/script_roadtypelist.cpp @@ -0,0 +1,22 @@ +/* + * 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_roadtypelist.cpp Implementation of ScriptRoadTypeList and friends. */ + +#include "../../stdafx.h" +#include "script_roadtypelist.hpp" +#include "../../road_func.h" + +#include "../../safeguards.h" + +ScriptRoadTypeList::ScriptRoadTypeList(ScriptRoad::RoadTramTypes rtts) +{ + 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); + } +} diff --git a/src/script/api/script_roadtypelist.hpp b/src/script/api/script_roadtypelist.hpp new file mode 100644 index 0000000000..41cf9fe2e8 --- /dev/null +++ b/src/script/api/script_roadtypelist.hpp @@ -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 script_roadtypelist.hpp List all available roadtypes. */ + +#ifndef SCRIPT_ROADTYPELIST_HPP +#define SCRIPT_ROADTYPELIST_HPP + +#include "script_list.hpp" +#include "script_road.hpp" + +/** + * Creates a list of all available roadtypes. + * @api ai game + * @ingroup ScriptList + */ +class ScriptRoadTypeList : public ScriptList { +public: + /** + * @param rtts Bitmask of road/tram types to list. + */ + ScriptRoadTypeList(ScriptRoad::RoadTramTypes rtts); +}; + +#endif /* SCRIPT_ROADTYPELIST_HPP */ diff --git a/src/script/api/script_sign.cpp b/src/script/api/script_sign.cpp index 236e1df7ef..8908941cf7 100644 --- a/src/script/api/script_sign.cpp +++ b/src/script/api/script_sign.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. @@ -23,7 +21,7 @@ /* static */ bool ScriptSign::IsValidSign(SignID sign_id) { const Sign *si = ::Sign::GetIfValid(sign_id); - return si != NULL && (si->owner == ScriptObject::GetCompany() || si->owner == OWNER_DEITY); + return si != nullptr && (si->owner == ScriptObject::GetCompany() || si->owner == OWNER_DEITY); } /* static */ ScriptCompany::CompanyID ScriptSign::GetOwner(SignID sign_id) @@ -38,7 +36,7 @@ CCountedPtr counter(name); EnforcePrecondition(false, IsValidSign(sign_id)); - EnforcePrecondition(false, name != NULL); + EnforcePrecondition(false, name != nullptr); const char *text = name->GetDecodedText(); EnforcePreconditionEncodedText(false, text); EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_SIGN_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG); @@ -48,7 +46,7 @@ /* static */ char *ScriptSign::GetName(SignID sign_id) { - if (!IsValidSign(sign_id)) return NULL; + if (!IsValidSign(sign_id)) return nullptr; ::SetDParam(0, sign_id); return GetString(STR_SIGN_NAME); @@ -73,7 +71,7 @@ CCountedPtr counter(name); EnforcePrecondition(INVALID_SIGN, ::IsValidTile(location)); - EnforcePrecondition(INVALID_SIGN, name != NULL); + EnforcePrecondition(INVALID_SIGN, name != nullptr); const char *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 e5c2164da8..5913e45a4f 100644 --- a/src/script/api/script_sign.hpp +++ b/src/script/api/script_sign.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. @@ -45,7 +43,7 @@ public: * @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 != NULL && len(name) != 0. + * @pre name != nullptr && len(name) != 0. * @exception ScriptError::ERR_NAME_IS_NOT_UNIQUE * @return True if and only if the name was changed. */ @@ -81,7 +79,7 @@ public: * @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 != NULL && len(name) != 0. + * @pre name != nullptr && 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_signlist.cpp b/src/script/api/script_signlist.cpp index 61ab9665aa..c64891a903 100644 --- a/src/script/api/script_signlist.cpp +++ b/src/script/api/script_signlist.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. @@ -18,8 +16,7 @@ ScriptSignList::ScriptSignList() { - Sign *s; - FOR_ALL_SIGNS(s) { + for (const Sign *s : Sign::Iterate()) { if (ScriptSign::IsValidSign(s->index)) this->AddItem(s->index); } } diff --git a/src/script/api/script_signlist.hpp b/src/script/api/script_signlist.hpp index 3b90a23ad6..125b06cce8 100644 --- a/src/script/api/script_signlist.hpp +++ b/src/script/api/script_signlist.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/script/api/script_station.cpp b/src/script/api/script_station.cpp index 5ed43e0a67..a45c19d0d9 100644 --- a/src/script/api/script_station.cpp +++ b/src/script/api/script_station.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. @@ -23,7 +21,7 @@ /* static */ bool ScriptStation::IsValidStation(StationID station_id) { const Station *st = ::Station::GetIfValid(station_id); - return st != NULL && (st->owner == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY || st->owner == OWNER_NONE); + return st != nullptr && (st->owner == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY || st->owner == OWNER_NONE); } /* static */ ScriptCompany::CompanyID ScriptStation::GetOwner(StationID station_id) @@ -211,13 +209,11 @@ template if (!IsValidStation(station_id)) return false; if (!ScriptRoad::IsRoadTypeAvailable(road_type)) return false; - ::RoadTypes r = RoadTypeToRoadTypes((::RoadType)road_type); - - for (const RoadStop *rs = ::Station::Get(station_id)->GetPrimaryRoadStop(ROADSTOP_BUS); rs != NULL; rs = rs->next) { - if ((::GetRoadTypes(rs->xy) & r) != 0) return true; + for (const RoadStop *rs = ::Station::Get(station_id)->GetPrimaryRoadStop(ROADSTOP_BUS); rs != nullptr; rs = rs->next) { + if (HasBit(::GetPresentRoadTypes(rs->xy), (::RoadType)road_type)) return true; } - for (const RoadStop *rs = ::Station::Get(station_id)->GetPrimaryRoadStop(ROADSTOP_TRUCK); rs != NULL; rs = rs->next) { - if ((::GetRoadTypes(rs->xy) & r) != 0) return true; + for (const RoadStop *rs = ::Station::Get(station_id)->GetPrimaryRoadStop(ROADSTOP_TRUCK); rs != nullptr; rs = rs->next) { + if (HasBit(::GetPresentRoadTypes(rs->xy), (::RoadType)road_type)) return true; } return false; diff --git a/src/script/api/script_station.hpp b/src/script/api/script_station.hpp index 42ea412d08..848cc1f27c 100644 --- a/src/script/api/script_station.hpp +++ b/src/script/api/script_station.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/script/api/script_stationlist.cpp b/src/script/api/script_stationlist.cpp index 51a06b5a74..9b9e67e7a6 100644 --- a/src/script/api/script_stationlist.cpp +++ b/src/script/api/script_stationlist.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. @@ -20,8 +18,7 @@ ScriptStationList::ScriptStationList(ScriptStation::StationType station_type) { - Station *st; - FOR_ALL_STATIONS(st) { + for (Station *st : Station::Iterate()) { if ((st->owner == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY) && (st->facilities & station_type) != 0) this->AddItem(st->index); } } @@ -32,7 +29,7 @@ ScriptStationList_Vehicle::ScriptStationList_Vehicle(VehicleID vehicle_id) Vehicle *v = ::Vehicle::Get(vehicle_id); - for (Order *o = v->GetFirstOrder(); o != NULL; o = o->next) { + for (Order *o = v->GetFirstOrder(); o != nullptr; o = o->next) { if (o->IsType(OT_GOTO_STATION)) this->AddItem(o->GetDestination()); } } @@ -120,7 +117,7 @@ private: CargoCollector::CargoCollector(ScriptStationList_Cargo *parent, StationID station_id, CargoID cargo, StationID other) : - list(parent), ge(NULL), other_station(other), last_key(INVALID_STATION), amount(0) + list(parent), ge(nullptr), other_station(other), last_key(INVALID_STATION), amount(0) { if (!ScriptStation::IsValidStation(station_id)) return; if (!ScriptCargo::IsValidCargo(cargo)) return; @@ -176,7 +173,7 @@ template void ScriptStationList_CargoWaiting::Add(StationID station_id, CargoID cargo, StationID other_station) { CargoCollector collector(this, station_id, cargo, other_station); - if (collector.GE() == NULL) return; + if (collector.GE() == nullptr) return; StationCargoList::ConstIterator iter = collector.GE()->cargo.Packets()->begin(); StationCargoList::ConstIterator end = collector.GE()->cargo.Packets()->end(); @@ -190,7 +187,7 @@ template void ScriptStationList_CargoPlanned::Add(StationID station_id, CargoID cargo, StationID other_station) { CargoCollector collector(this, station_id, cargo, other_station); - if (collector.GE() == NULL) return; + if (collector.GE() == nullptr) return; FlowStatMap::const_iterator iter = collector.GE()->flows.begin(); FlowStatMap::const_iterator end = collector.GE()->flows.end(); @@ -215,7 +212,7 @@ ScriptStationList_CargoWaitingViaByFrom::ScriptStationList_CargoWaitingViaByFrom StationID station_id, CargoID cargo, StationID via) { CargoCollector collector(this, station_id, cargo, via); - if (collector.GE() == NULL) return; + if (collector.GE() == nullptr) return; std::pair range = collector.GE()->cargo.Packets()->equal_range(via); @@ -261,7 +258,7 @@ ScriptStationList_CargoPlannedFromByVia::ScriptStationList_CargoPlannedFromByVia StationID station_id, CargoID cargo, StationID from) { CargoCollector collector(this, station_id, cargo, from); - if (collector.GE() == NULL) return; + if (collector.GE() == nullptr) return; FlowStatMap::const_iterator iter = collector.GE()->flows.find(from); if (iter == collector.GE()->flows.end()) return; diff --git a/src/script/api/script_stationlist.hpp b/src/script/api/script_stationlist.hpp index 720a43639b..ee862cb935 100644 --- a/src/script/api/script_stationlist.hpp +++ b/src/script/api/script_stationlist.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/script/api/script_story_page.cpp b/src/script/api/script_story_page.cpp index 11820ec3f6..87b81268c1 100644 --- a/src/script/api/script_story_page.cpp +++ b/src/script/api/script_story_page.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. @@ -48,7 +46,7 @@ c, 0, CMD_CREATE_STORY_PAGE, - title != NULL? title->GetEncodedText() : NULL, + title != nullptr? title->GetEncodedText() : nullptr, &ScriptInstance::DoCommandReturnStoryPageID)) return STORY_PAGE_INVALID; /* In case of test-mode, we return StoryPageID 0 */ @@ -61,7 +59,7 @@ EnforcePrecondition(STORY_PAGE_ELEMENT_INVALID, ScriptObject::GetCompany() == OWNER_DEITY); EnforcePrecondition(STORY_PAGE_ELEMENT_INVALID, IsValidStoryPage(story_page_id)); - EnforcePrecondition(STORY_PAGE_ELEMENT_INVALID, (type != SPET_TEXT && type != SPET_LOCATION) || (text != NULL && !StrEmpty(text->GetEncodedText()))); + EnforcePrecondition(STORY_PAGE_ELEMENT_INVALID, (type != SPET_TEXT && type != SPET_LOCATION) || (text != nullptr && !StrEmpty(text->GetEncodedText()))); EnforcePrecondition(STORY_PAGE_ELEMENT_INVALID, type != SPET_LOCATION || ::IsValidTile(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)); @@ -70,7 +68,7 @@ story_page_id + (type << 16), type == SPET_GOAL ? reference : 0, CMD_CREATE_STORY_PAGE_ELEMENT, - type == SPET_TEXT || type == SPET_LOCATION ? text->GetEncodedText() : NULL, + type == SPET_TEXT || type == SPET_LOCATION ? text->GetEncodedText() : nullptr, &ScriptInstance::DoCommandReturnStoryPageElementID)) return STORY_PAGE_ELEMENT_INVALID; /* In case of test-mode, we return StoryPageElementID 0 */ @@ -88,7 +86,7 @@ StoryPage *p = StoryPage::Get(pe->page); ::StoryPageElementType type = pe->type; - EnforcePrecondition(false, (type != ::SPET_TEXT && type != ::SPET_LOCATION) || (text != NULL && !StrEmpty(text->GetEncodedText()))); + EnforcePrecondition(false, (type != ::SPET_TEXT && type != ::SPET_LOCATION) || (text != nullptr && !StrEmpty(text->GetEncodedText()))); EnforcePrecondition(false, type != ::SPET_LOCATION || ::IsValidTile(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)); @@ -97,7 +95,7 @@ story_page_element_id, type == ::SPET_GOAL ? reference : 0, CMD_UPDATE_STORY_PAGE_ELEMENT, - type == ::SPET_TEXT || type == ::SPET_LOCATION ? text->GetEncodedText() : NULL); + type == ::SPET_TEXT || type == ::SPET_LOCATION ? text->GetEncodedText() : nullptr); } /* static */ uint32 ScriptStoryPage::GetPageSortValue(StoryPageID story_page_id) @@ -121,7 +119,7 @@ EnforcePrecondition(false, IsValidStoryPage(story_page_id)); EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); - return ScriptObject::DoCommand(0, story_page_id, 0, CMD_SET_STORY_PAGE_TITLE, title != NULL? title->GetEncodedText() : NULL); + return ScriptObject::DoCommand(0, story_page_id, 0, CMD_SET_STORY_PAGE_TITLE, title != nullptr? title->GetEncodedText() : nullptr); } /* static */ ScriptCompany::CompanyID ScriptStoryPage::GetCompany(StoryPageID story_page_id) @@ -147,7 +145,7 @@ EnforcePrecondition(false, IsValidStoryPage(story_page_id)); EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); - return ScriptObject::DoCommand(0, story_page_id, date, CMD_SET_STORY_PAGE_DATE, NULL); + return ScriptObject::DoCommand(0, story_page_id, date, CMD_SET_STORY_PAGE_DATE, nullptr); } diff --git a/src/script/api/script_story_page.hpp b/src/script/api/script_story_page.hpp index c22d4c198e..d7e44fee49 100644 --- a/src/script/api/script_story_page.hpp +++ b/src/script/api/script_story_page.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. @@ -92,12 +90,12 @@ public: * Create a new story page element. * @param story_page_id The page id of the story page which the page element should be appended to. * @param type Which page element type to create. - * @param reference A reference value to the object that is refered to by some page element types. When type is SPET_GOAL, this is the goal ID. When type is SPET_LOCATION, this is the TileIndex. + * @param reference A reference value to the object that is referred to by some page element types. When type is SPET_GOAL, this is the goal ID. When type is SPET_LOCATION, this is the TileIndex. * @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 IsValidStoryPage(story_page). - * @pre (type != SPET_TEXT && type != SPET_LOCATION) || (text != NULL && len(text) != 0). + * @pre (type != SPET_TEXT && type != SPET_LOCATION) || (text != nullptr && 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. @@ -107,12 +105,12 @@ public: /** * Update the content of a page element * @param story_page_element_id The page id of the story page which the page element should be appended to. - * @param reference A reference value to the object that is refered to by some page element types. See also NewElement. + * @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 IsValidStoryPage(story_page). - * @pre (type != SPET_TEXT && type != SPET_LOCATION) || (text != NULL && len(text) != 0). + * @pre (type != SPET_TEXT && type != SPET_LOCATION) || (text != nullptr && 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. diff --git a/src/script/api/script_storypageelementlist.cpp b/src/script/api/script_storypageelementlist.cpp index 3f1fa4ebbe..ce60963f24 100644 --- a/src/script/api/script_storypageelementlist.cpp +++ b/src/script/api/script_storypageelementlist.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. @@ -19,8 +17,7 @@ ScriptStoryPageElementList::ScriptStoryPageElementList(ScriptStoryPage::StoryPag { if (!ScriptStoryPage::IsValidStoryPage(story_page_id)) return; - StoryPageElement *pe; - FOR_ALL_STORY_PAGE_ELEMENTS(pe) { + for (StoryPageElement *pe : StoryPageElement::Iterate()) { if (pe->page == story_page_id) { this->AddItem(pe->index); } diff --git a/src/script/api/script_storypageelementlist.hpp b/src/script/api/script_storypageelementlist.hpp index 6aa2faf2d9..5bd1adab5f 100644 --- a/src/script/api/script_storypageelementlist.hpp +++ b/src/script/api/script_storypageelementlist.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/script/api/script_storypagelist.cpp b/src/script/api/script_storypagelist.cpp index fc32e80a37..63f835ada9 100644 --- a/src/script/api/script_storypagelist.cpp +++ b/src/script/api/script_storypagelist.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. @@ -21,8 +19,7 @@ ScriptStoryPageList::ScriptStoryPageList(ScriptCompany::CompanyID company) uint8 c = company; if (company == ScriptCompany::COMPANY_INVALID) c = INVALID_COMPANY; - StoryPage *p; - FOR_ALL_STORY_PAGES(p) { + for (StoryPage *p : StoryPage::Iterate()) { if (p->company == c || p->company == INVALID_COMPANY) { this->AddItem(p->index); } diff --git a/src/script/api/script_storypagelist.hpp b/src/script/api/script_storypagelist.hpp index 7aa3389f32..b491907c53 100644 --- a/src/script/api/script_storypagelist.hpp +++ b/src/script/api/script_storypagelist.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/script/api/script_subsidy.cpp b/src/script/api/script_subsidy.cpp index 640f7ab0a0..c8ca6e3e35 100644 --- a/src/script/api/script_subsidy.cpp +++ b/src/script/api/script_subsidy.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. diff --git a/src/script/api/script_subsidy.hpp b/src/script/api/script_subsidy.hpp index 16a6794409..a4f9fa6867 100644 --- a/src/script/api/script_subsidy.hpp +++ b/src/script/api/script_subsidy.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/script/api/script_subsidylist.cpp b/src/script/api/script_subsidylist.cpp index fd7d947799..b92f1398c3 100644 --- a/src/script/api/script_subsidylist.cpp +++ b/src/script/api/script_subsidylist.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. @@ -17,8 +15,7 @@ ScriptSubsidyList::ScriptSubsidyList() { - const Subsidy *s; - FOR_ALL_SUBSIDIES(s) { + for (const Subsidy *s : Subsidy::Iterate()) { this->AddItem(s->index); } } diff --git a/src/script/api/script_subsidylist.hpp b/src/script/api/script_subsidylist.hpp index 7080ac6d88..2d245bec9c 100644 --- a/src/script/api/script_subsidylist.hpp +++ b/src/script/api/script_subsidylist.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/script/api/script_testmode.cpp b/src/script/api/script_testmode.cpp index ed643c2d95..70055586fe 100644 --- a/src/script/api/script_testmode.cpp +++ b/src/script/api/script_testmode.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. diff --git a/src/script/api/script_testmode.hpp b/src/script/api/script_testmode.hpp index 699d4db18b..eddd9340a7 100644 --- a/src/script/api/script_testmode.hpp +++ b/src/script/api/script_testmode.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/script/api/script_text.cpp b/src/script/api/script_text.cpp index e692be0ae2..36f9417930 100644 --- a/src/script/api/script_text.cpp +++ b/src/script/api/script_text.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. @@ -63,7 +61,7 @@ ScriptText::~ScriptText() { for (int i = 0; i < SCRIPT_TEXT_MAX_PARAMETERS; i++) { free(this->params[i]); - if (this->paramt[i] != NULL) this->paramt[i]->Release(); + if (this->paramt[i] != nullptr) this->paramt[i]->Release(); } } @@ -72,11 +70,11 @@ SQInteger ScriptText::_SetParam(int parameter, HSQUIRRELVM vm) if (parameter >= SCRIPT_TEXT_MAX_PARAMETERS) return SQ_ERROR; free(this->params[parameter]); - if (this->paramt[parameter] != NULL) this->paramt[parameter]->Release(); + if (this->paramt[parameter] != nullptr) this->paramt[parameter]->Release(); this->parami[parameter] = 0; - this->params[parameter] = NULL; - this->paramt[parameter] = NULL; + this->params[parameter] = nullptr; + this->paramt[parameter] = nullptr; switch (sq_gettype(vm, -1)) { case OT_STRING: { @@ -97,7 +95,7 @@ SQInteger ScriptText::_SetParam(int parameter, HSQUIRRELVM vm) } case OT_INSTANCE: { - SQUserPointer real_instance = NULL; + SQUserPointer real_instance = nullptr; HSQOBJECT instance; sq_getstackobj(vm, -1, &instance); @@ -112,7 +110,7 @@ SQInteger ScriptText::_SetParam(int parameter, HSQUIRRELVM vm) /* Get the 'real' instance of this class */ sq_getinstanceup(vm, -1, &real_instance, 0); - if (real_instance == NULL) return SQ_ERROR; + if (real_instance == nullptr) return SQ_ERROR; ScriptText *value = static_cast(real_instance); value->AddRef(); @@ -183,7 +181,7 @@ const char *ScriptText::GetEncodedText() static char buf[1024]; int param_count = 0; this->_GetEncodedText(buf, lastof(buf), param_count); - return (param_count > SCRIPT_TEXT_MAX_PARAMETERS) ? NULL : buf; + return (param_count > SCRIPT_TEXT_MAX_PARAMETERS) ? nullptr : buf; } char *ScriptText::_GetEncodedText(char *p, char *lastofp, int ¶m_count) @@ -191,12 +189,12 @@ char *ScriptText::_GetEncodedText(char *p, char *lastofp, int ¶m_count) p += Utf8Encode(p, SCC_ENCODED); p += seprintf(p, lastofp, "%X", this->string); for (int i = 0; i < this->paramc; i++) { - if (this->params[i] != NULL) { + if (this->params[i] != nullptr) { p += seprintf(p, lastofp, ":\"%s\"", this->params[i]); param_count++; continue; } - if (this->paramt[i] != NULL) { + if (this->paramt[i] != nullptr) { p += seprintf(p, lastofp, ":"); p = this->paramt[i]->_GetEncodedText(p, lastofp, param_count); continue; @@ -211,7 +209,7 @@ char *ScriptText::_GetEncodedText(char *p, char *lastofp, int ¶m_count) const char *Text::GetDecodedText() { const char *encoded_text = this->GetEncodedText(); - if (encoded_text == NULL) return NULL; + if (encoded_text == nullptr) return nullptr; 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 ed14e391d0..2553695377 100644 --- a/src/script/api/script_text.hpp +++ b/src/script/api/script_text.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. @@ -23,14 +21,14 @@ class Text : public ScriptObject { public: /** * Convert a ScriptText to a normal string. - * @return A string (in a static buffer), or NULL. + * @return A string (in a static buffer), or nullptr. * @api -all */ virtual const char *GetEncodedText() = 0; /** * Convert a #ScriptText into a decoded normal string. - * @return A string (in a static buffer), or NULL. + * @return A string (in a static buffer), or nullptr. * @api -all */ const char *GetDecodedText(); @@ -45,7 +43,7 @@ public: RawText(const char *text); ~RawText(); - /* virtual */ const char *GetEncodedText() { return this->text; } + const char *GetEncodedText() override { return this->text; } private: const char *text; }; diff --git a/src/script/api/script_tile.cpp b/src/script/api/script_tile.cpp index db9220acd6..360b32c025 100644 --- a/src/script/api/script_tile.cpp +++ b/src/script/api/script_tile.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,12 +31,12 @@ case MP_WATER: return IsCoast(tile); case MP_ROAD: /* Tram bits aren't considered buildable */ - if (::GetRoadTypes(tile) != ROADTYPES_ROAD) return false; + if (::GetRoadTypeTram(tile) != INVALID_ROADTYPE) return false; /* Depots and crossings aren't considered buildable */ if (::GetRoadTileType(tile) != ROAD_TILE_NORMAL) return false; - if (!HasExactlyOneBit(::GetRoadBits(tile, ROADTYPE_ROAD))) return false; - if (::IsRoadOwner(tile, ROADTYPE_ROAD, OWNER_TOWN)) return true; - if (::IsRoadOwner(tile, ROADTYPE_ROAD, ScriptObject::GetCompany())) return true; + if (!HasExactlyOneBit(::GetRoadBits(tile, RTT_ROAD))) return false; + if (::IsRoadOwner(tile, RTT_ROAD, OWNER_TOWN)) return true; + if (::IsRoadOwner(tile, RTT_ROAD, ScriptObject::GetCompany())) return true; return false; } } @@ -201,7 +199,12 @@ { if (!::IsValidTile(tile)) return false; - return ::TrackStatusToTrackdirBits(::GetTileTrackStatus(tile, (::TransportType)transport_type, UINT32_MAX)) != TRACKDIR_BIT_NONE; + if (transport_type == TRANSPORT_ROAD) { + return ::TrackStatusToTrackdirBits(::GetTileTrackStatus(tile, (::TransportType)transport_type, 0)) != TRACKDIR_BIT_NONE || + ::TrackStatusToTrackdirBits(::GetTileTrackStatus(tile, (::TransportType)transport_type, 1)) != TRACKDIR_BIT_NONE; + } else { + return ::TrackStatusToTrackdirBits(::GetTileTrackStatus(tile, (::TransportType)transport_type, 0)) != TRACKDIR_BIT_NONE; + } } /* static */ int32 ScriptTile::GetCargoAcceptance(TileIndex tile, CargoID cargo_type, int width, int height, int radius) @@ -257,7 +260,6 @@ /* static */ bool ScriptTile::DemolishTile(TileIndex tile) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); EnforcePrecondition(false, ::IsValidTile(tile)); return ScriptObject::DoCommand(tile, 0, 0, CMD_LANDSCAPE_CLEAR); @@ -292,7 +294,7 @@ if (!::IsValidTile(tile)) return INVALID_TOWN; Town *town = ::ClosestTownFromTile(tile, _settings_game.economy.dist_local_authority); - if (town == NULL) return INVALID_TOWN; + if (town == nullptr) return INVALID_TOWN; return town->index; } @@ -302,7 +304,7 @@ if (!::IsValidTile(tile)) return INVALID_TOWN; Town *town = ::ClosestTownFromTile(tile, UINT_MAX); - if (town == NULL) return INVALID_TOWN; + if (town == nullptr) return INVALID_TOWN; return town->index; } @@ -310,14 +312,14 @@ /* static */ Money ScriptTile::GetBuildCost(BuildType build_type) { switch (build_type) { - case BT_FOUNDATION: return ::GetPrice(PR_BUILD_FOUNDATION, 1, NULL); - case BT_TERRAFORM: return ::GetPrice(PR_TERRAFORM, 1, NULL); - case BT_BUILD_TREES: return ::GetPrice(PR_BUILD_TREES, 1, NULL); - case BT_CLEAR_GRASS: return ::GetPrice(PR_CLEAR_GRASS, 1, NULL); - case BT_CLEAR_ROUGH: return ::GetPrice(PR_CLEAR_ROUGH, 1, NULL); - case BT_CLEAR_ROCKY: return ::GetPrice(PR_CLEAR_ROCKS, 1, NULL); - case BT_CLEAR_FIELDS: return ::GetPrice(PR_CLEAR_FIELDS, 1, NULL); - case BT_CLEAR_HOUSE: return ::GetPrice(PR_CLEAR_HOUSE, 1, NULL); + case BT_FOUNDATION: return ::GetPrice(PR_BUILD_FOUNDATION, 1, nullptr); + case BT_TERRAFORM: return ::GetPrice(PR_TERRAFORM, 1, nullptr); + case BT_BUILD_TREES: return ::GetPrice(PR_BUILD_TREES, 1, nullptr); + case BT_CLEAR_GRASS: return ::GetPrice(PR_CLEAR_GRASS, 1, nullptr); + case BT_CLEAR_ROUGH: return ::GetPrice(PR_CLEAR_ROUGH, 1, nullptr); + case BT_CLEAR_ROCKY: return ::GetPrice(PR_CLEAR_ROCKS, 1, nullptr); + case BT_CLEAR_FIELDS: return ::GetPrice(PR_CLEAR_FIELDS, 1, nullptr); + case BT_CLEAR_HOUSE: return ::GetPrice(PR_CLEAR_HOUSE, 1, nullptr); default: return -1; } } diff --git a/src/script/api/script_tile.hpp b/src/script/api/script_tile.hpp index f4a2f0970e..423044b21a 100644 --- a/src/script/api/script_tile.hpp +++ b/src/script/api/script_tile.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. @@ -40,8 +38,11 @@ public: /** The area was already flat */ ERR_AREA_ALREADY_FLAT, // [STR_ERROR_ALREADY_LEVELLED] - /** There is a tunnel underneed */ + /** There is a tunnel underneath */ ERR_EXCAVATION_WOULD_DAMAGE, // [STR_ERROR_EXCAVATION_WOULD_DAMAGE] + + /** Reached the limit for terraforming/clearing/planting */ + ERR_LIMIT_REACHED, // [STR_ERROR_TERRAFORM_LIMIT_REACHED, STR_ERROR_CLEARING_LIMIT_REACHED, STR_ERROR_TREE_PLANT_LIMIT_REACHED] }; /** @@ -351,7 +352,7 @@ public: * @pre width > 0. * @pre height > 0. * @pre radius >= 0. - * @return Value below 8 means no acceptance; the more the better. + * @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); @@ -445,7 +446,6 @@ public: * Destroy everything on the given tile. * @param tile The tile to demolish. * @pre ScriptMap::IsValidTile(tile). - * @game @pre Valid ScriptCompanyMode active in scope. * @exception ScriptError::ERR_AREA_NOT_CLEAR * @return True if and only if the tile was demolished. */ diff --git a/src/script/api/script_tilelist.cpp b/src/script/api/script_tilelist.cpp index 933a92c4cb..b9a2ed5298 100644 --- a/src/script/api/script_tilelist.cpp +++ b/src/script/api/script_tilelist.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. @@ -49,6 +47,32 @@ void ScriptTileList::RemoveTile(TileIndex tile) this->RemoveItem(tile); } +/** + * Helper to get list of tiles that will cover an industry's production or acceptance. + * @param i Industry in question + * @param radius Catchment radius to test + * @param bta BitmapTileArea to fill + */ +static void FillIndustryCatchment(const Industry *i, int radius, BitmapTileArea &bta) +{ + TILE_AREA_LOOP(cur_tile, i->location) { + if (!::IsTileType(cur_tile, MP_INDUSTRY) || ::GetIndustryIndex(cur_tile) != i->index) continue; + + 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; + for (int x = -radius; x <= radius; x++) { + if (tx + x < 0 || tx + x > (int)MapMaxX()) continue; + TileIndex tile = TileXY(tx + x, ty + y); + if (!IsValidTile(tile)) continue; + if (::IsTileType(tile, MP_INDUSTRY) && ::GetIndustryIndex(tile) == i->index) continue; + bta.SetTile(tile); + } + } + } +} + ScriptTileList_IndustryAccepting::ScriptTileList_IndustryAccepting(IndustryID industry_id, int radius) { if (!ScriptIndustry::IsValidIndustry(industry_id) || radius <= 0) return; @@ -66,12 +90,11 @@ ScriptTileList_IndustryAccepting::ScriptTileList_IndustryAccepting(IndustryID in if (!_settings_game.station.modified_catchment) radius = CA_UNMODIFIED; - TileArea ta(i->location.tile - ::TileDiffXY(radius, radius), i->location.w + radius * 2, i->location.h + radius * 2); - TILE_AREA_LOOP(cur_tile, ta) { - if (!::IsValidTile(cur_tile)) continue; - /* Exclude all tiles that belong to this industry */ - if (::IsTileType(cur_tile, MP_INDUSTRY) && ::GetIndustryIndex(cur_tile) == industry_id) continue; + BitmapTileArea bta(TileArea(i->location).Expand(radius)); + FillIndustryCatchment(i, radius, bta); + BitmapTileIterator it(bta); + for (TileIndex cur_tile = it; cur_tile != INVALID_TILE; cur_tile = ++it) { /* Only add the tile if it accepts the cargo (sometimes just 1 tile of an * industry triggers the acceptance). */ CargoArray acceptance = ::GetAcceptanceAroundTiles(cur_tile, 1, 1, radius); @@ -102,12 +125,11 @@ ScriptTileList_IndustryProducing::ScriptTileList_IndustryProducing(IndustryID in if (!_settings_game.station.modified_catchment) radius = CA_UNMODIFIED; - TileArea ta(i->location.tile - ::TileDiffXY(radius, radius), i->location.w + radius * 2, i->location.h + radius * 2); - TILE_AREA_LOOP(cur_tile, ta) { - if (!::IsValidTile(cur_tile)) continue; - /* Exclude all tiles that belong to this industry */ - if (::IsTileType(cur_tile, MP_INDUSTRY) && ::GetIndustryIndex(cur_tile) == industry_id) continue; + BitmapTileArea bta(TileArea(i->location).Expand(radius)); + FillIndustryCatchment(i, radius, bta); + BitmapTileIterator it(bta); + for (TileIndex cur_tile = it; cur_tile != INVALID_TILE; cur_tile = ++it) { this->AddTile(cur_tile); } } diff --git a/src/script/api/script_tilelist.hpp b/src/script/api/script_tilelist.hpp index 788432f783..38f08d62a8 100644 --- a/src/script/api/script_tilelist.hpp +++ b/src/script/api/script_tilelist.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/script/api/script_town.cpp b/src/script/api/script_town.cpp index 64f8e166ea..afe5614566 100644 --- a/src/script/api/script_town.cpp +++ b/src/script/api/script_town.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. @@ -35,7 +33,7 @@ /* static */ char *ScriptTown::GetName(TownID town_id) { - if (!IsValidTown(town_id)) return NULL; + if (!IsValidTown(town_id)) return nullptr; ::SetDParam(0, town_id); return GetString(STR_TOWN_NAME); @@ -45,8 +43,8 @@ { CCountedPtr counter(name); - const char *text = NULL; - if (name != NULL) { + const char *text = nullptr; + if (name != nullptr) { text = name->GetDecodedText(); EnforcePreconditionEncodedText(false, text); EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_TOWN_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG); @@ -60,9 +58,11 @@ { CCountedPtr counter(text); - EnforcePrecondition(false, text != NULL); - const char *encoded_text = text->GetEncodedText(); - EnforcePreconditionEncodedText(false, encoded_text); + const char *encoded_text = nullptr; + if (text != nullptr) { + encoded_text = text->GetEncodedText(); + EnforcePreconditionEncodedText(false, encoded_text); + } EnforcePrecondition(false, IsValidTown(town_id)); return ScriptObject::DoCommand(::Town::Get(town_id)->xy, town_id, 0, CMD_TOWN_SET_TEXT, encoded_text); @@ -257,7 +257,7 @@ if (ScriptObject::GetCompany() == OWNER_DEITY) return false; if (!IsValidTown(town_id)) return false; - return HasBit(::GetMaskOfTownActions(NULL, ScriptObject::GetCompany(), ::Town::Get(town_id)), town_action); + return HasBit(::GetMaskOfTownActions(nullptr, ScriptObject::GetCompany(), ::Town::Get(town_id)), town_action); } /* static */ bool ScriptTown::PerformTownAction(TownID town_id, TownAction town_action) @@ -293,8 +293,8 @@ layout = (RoadLayout) (byte)_settings_game.economy.town_layout; } - const char *text = NULL; - if (name != NULL) { + const char *text = nullptr; + if (name != nullptr) { text = name->GetDecodedText(); EnforcePreconditionEncodedText(false, text); EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_TOWN_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG); @@ -336,6 +336,33 @@ } } +/* static */ int ScriptTown::GetDetailedRating(TownID town_id, ScriptCompany::CompanyID company_id) +{ + if (!IsValidTown(town_id)) return TOWN_RATING_INVALID; + ScriptCompany::CompanyID company = ScriptCompany::ResolveCompanyID(company_id); + if (company == ScriptCompany::COMPANY_INVALID) return TOWN_RATING_INVALID; + + const Town *t = ::Town::Get(town_id); + return t->ratings[company]; +} + +/* static */ bool ScriptTown::ChangeRating(TownID town_id, ScriptCompany::CompanyID company_id, int delta) +{ + EnforcePrecondition(false, ScriptObject::GetCompany() == OWNER_DEITY); + EnforcePrecondition(false, IsValidTown(town_id)); + ScriptCompany::CompanyID company = ScriptCompany::ResolveCompanyID(company_id); + EnforcePrecondition(false, company != ScriptCompany::COMPANY_INVALID); + + const Town *t = ::Town::Get(town_id); + 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::DoCommand(0, town_id | (company_id << 16), p2, CMD_TOWN_RATING); +} + /* static */ int ScriptTown::GetAllowedNoise(TownID town_id) { if (!IsValidTown(town_id)) return -1; @@ -346,8 +373,7 @@ } int num = 0; - const Station *st; - FOR_ALL_STATIONS(st) { + for (const Station *st : Station::Iterate()) { if (st->town == t && (st->facilities & FACIL_AIRPORT) && st->airport.type != AT_OILRIG) num++; } return max(0, 2 - num); diff --git a/src/script/api/script_town.hpp b/src/script/api/script_town.hpp index 7fdf8a6b39..6ae7ee33f5 100644 --- a/src/script/api/script_town.hpp +++ b/src/script/api/script_town.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. @@ -148,7 +146,7 @@ public: /** * Rename a town. * @param town_id The town to rename - * @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. + * @param name The new name of the town. If null is passed, the town name will be reset to the default name. * @pre IsValidTown(town_id). * @return True if the action succeeded. * @api -ai @@ -158,7 +156,7 @@ public: /** * 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). + * @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. * @pre IsValidTown(town_id). * @return True if the action succeeded. * @api -ai @@ -402,7 +400,7 @@ public: * @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 NULL to use a random town name. + * @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. * @ai @pre ScriptSettings.GetValue("economy.found_town") != 0. * @game @pre no company mode in scope || size != TOWN_SIZE_LARGE. @@ -425,6 +423,30 @@ public: */ static TownRating GetRating(TownID town_id, ScriptCompany::CompanyID company_id); + /** + * Get the accurate rating of a company within a town. + * @param town_id The town to get the rating for. + * @param company_id The company to get the rating for. + * @pre IsValidTown(town_id). + * @pre ScriptCompany.ResolveCompanyID(company) != ScriptCompany::COMPANY_INVALID. + * @return The rating as a number between -1000 (worst) and 1000 (best). + * @api -ai + */ + static int GetDetailedRating(TownID town_id, ScriptCompany::CompanyID company_id); + + /** + * Change the rating of a company within a town. + * @param town_id The town to change the rating in. + * @param company_id The company to change the rating for. + * @param delta How much to change rating by (range -1000 to +1000). + * @return True if the rating was changed. + * @pre IsValidTown(town_id). + * @pre ScriptCompany.ResolveCompanyID(company) != ScriptCompany::COMPANY_INVALID. + * @pre no company mode in scope + * @api -ai + */ + static bool ChangeRating(TownID town_id, ScriptCompany::CompanyID company_id, int delta); + /** * Get the maximum level of noise that still can be added by airports * before the town start to refuse building a new airport. diff --git a/src/script/api/script_townlist.cpp b/src/script/api/script_townlist.cpp index a2e12febe1..b5af62b5f2 100644 --- a/src/script/api/script_townlist.cpp +++ b/src/script/api/script_townlist.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. @@ -17,8 +15,7 @@ ScriptTownList::ScriptTownList() { - Town *t; - FOR_ALL_TOWNS(t) { + for (const Town *t : Town::Iterate()) { this->AddItem(t->index); } } diff --git a/src/script/api/script_townlist.hpp b/src/script/api/script_townlist.hpp index 7baa09da1f..5b20eb2bd1 100644 --- a/src/script/api/script_townlist.hpp +++ b/src/script/api/script_townlist.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/script/api/script_tunnel.cpp b/src/script/api/script_tunnel.cpp index 7b891f28d0..c47c64e40e 100644 --- a/src/script/api/script_tunnel.cpp +++ b/src/script/api/script_tunnel.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. @@ -90,7 +88,7 @@ static void _DoCommandReturnBuildTunnel1(class ScriptInstance *instance) uint type = 0; if (vehicle_type == ScriptVehicle::VT_ROAD) { type |= (TRANSPORT_ROAD << 8); - type |= ::RoadTypeToRoadTypes((::RoadType)ScriptObject::GetRoadType()); + type |= ScriptRoad::GetCurrentRoadType(); } else { type |= (TRANSPORT_RAIL << 8); type |= ScriptRail::GetCurrentRailType(); @@ -102,7 +100,7 @@ static void _DoCommandReturnBuildTunnel1(class ScriptInstance *instance) } ScriptObject::SetCallbackVariable(0, start); - return ScriptObject::DoCommand(start, type, 0, CMD_BUILD_TUNNEL, NULL, &::_DoCommandReturnBuildTunnel1); + return ScriptObject::DoCommand(start, type, 0, CMD_BUILD_TUNNEL, nullptr, &::_DoCommandReturnBuildTunnel1); } /* static */ bool ScriptTunnel::_BuildTunnelRoad1() @@ -114,7 +112,7 @@ static void _DoCommandReturnBuildTunnel1(class ScriptInstance *instance) DiagDirection dir_1 = ::DiagdirBetweenTiles(end, start); DiagDirection dir_2 = ::ReverseDiagDir(dir_1); - return ScriptObject::DoCommand(start + ::TileOffsByDiagDir(dir_1), ::DiagDirToRoadBits(dir_2) | (ScriptObject::GetRoadType() << 4), 0, CMD_BUILD_ROAD, NULL, &::_DoCommandReturnBuildTunnel2); + return ScriptObject::DoCommand(start + ::TileOffsByDiagDir(dir_1), ::DiagDirToRoadBits(dir_2) | (ScriptObject::GetRoadType() << 4), 0, CMD_BUILD_ROAD, nullptr, &::_DoCommandReturnBuildTunnel2); } /* static */ bool ScriptTunnel::_BuildTunnelRoad2() diff --git a/src/script/api/script_tunnel.hpp b/src/script/api/script_tunnel.hpp index 74fdaabc55..b096dbcd06 100644 --- a/src/script/api/script_tunnel.hpp +++ b/src/script/api/script_tunnel.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/script/api/script_types.hpp b/src/script/api/script_types.hpp index bd9b7c5607..0d652a2d2d 100644 --- a/src/script/api/script_types.hpp +++ b/src/script/api/script_types.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/script/api/script_vehicle.cpp b/src/script/api/script_vehicle.cpp index ca841f7557..cd5cc5af72 100644 --- a/src/script/api/script_vehicle.cpp +++ b/src/script/api/script_vehicle.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. @@ -29,7 +27,7 @@ /* static */ bool ScriptVehicle::IsValidVehicle(VehicleID vehicle_id) { const Vehicle *v = ::Vehicle::GetIfValid(vehicle_id); - return v != NULL && (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() || ScriptObject::GetCompany() == OWNER_DEITY) && (v->IsPrimaryVehicle() || (v->type == VEH_TRAIN && ::Train::From(v)->IsFreeWagon())); } /* static */ ScriptCompany::CompanyID ScriptVehicle::GetOwner(VehicleID vehicle_id) @@ -46,8 +44,8 @@ int num = 1; const Train *v = ::Train::GetIfValid(vehicle_id); - if (v != NULL) { - while ((v = v->GetNextUnit()) != NULL) num++; + if (v != nullptr) { + while ((v = v->GetNextUnit()) != nullptr) num++; } return num; @@ -61,27 +59,50 @@ return v->IsGroundVehicle() ? v->GetGroundVehicleCache()->cached_total_length : -1; } -/* static */ VehicleID ScriptVehicle::BuildVehicle(TileIndex depot, EngineID engine_id) +/* static */ VehicleID ScriptVehicle::_BuildVehicleInternal(TileIndex depot, EngineID engine_id, CargoID cargo) { - EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); + EnforcePrecondition(VEHICLE_INVALID, ScriptObject::GetCompany() != OWNER_DEITY); EnforcePrecondition(VEHICLE_INVALID, ScriptEngine::IsBuildable(engine_id)); + EnforcePrecondition(VEHICLE_INVALID, cargo == CT_INVALID || ScriptCargo::IsValidCargo(cargo)); ::VehicleType type = ::Engine::Get(engine_id)->type; EnforcePreconditionCustomError(VEHICLE_INVALID, !ScriptGameSettings::IsDisabledVehicleType((ScriptVehicle::VehicleType)type), ScriptVehicle::ERR_VEHICLE_BUILD_DISABLED); - if (!ScriptObject::DoCommand(depot, engine_id, 0, ::GetCmdBuildVeh(type), NULL, &ScriptInstance::DoCommandReturnVehicleID)) return VEHICLE_INVALID; + if (!ScriptObject::DoCommand(depot, engine_id | (cargo << 24), 0, ::GetCmdBuildVeh(type), nullptr, &ScriptInstance::DoCommandReturnVehicleID)) return VEHICLE_INVALID; /* In case of test-mode, we return VehicleID 0 */ return 0; } +/* static */ VehicleID ScriptVehicle::BuildVehicle(TileIndex depot, EngineID engine_id) +{ + return _BuildVehicleInternal(depot, engine_id, CT_INVALID); +} + +/* static */ VehicleID ScriptVehicle::BuildVehicleWithRefit(TileIndex depot, EngineID engine_id, CargoID cargo) +{ + EnforcePrecondition(VEHICLE_INVALID, ScriptCargo::IsValidCargo(cargo)); + return _BuildVehicleInternal(depot, engine_id, cargo); +} + +/* static */ int ScriptVehicle::GetBuildWithRefitCapacity(TileIndex depot, EngineID engine_id, CargoID cargo) +{ + if (!ScriptEngine::IsBuildable(engine_id)) return -1; + if (!ScriptCargo::IsValidCargo(cargo)) return -1; + + ::VehicleType type = ::Engine::Get(engine_id)->type; + + CommandCost res = ::DoCommand(depot, engine_id | (cargo << 24), 0, DC_QUERY_COST, ::GetCmdBuildVeh(type)); + return res.Succeeded() ? _returned_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)); - if (!ScriptObject::DoCommand(depot, vehicle_id, share_orders, CMD_CLONE_VEHICLE, NULL, &ScriptInstance::DoCommandReturnVehicleID)) return VEHICLE_INVALID; + if (!ScriptObject::DoCommand(depot, vehicle_id, share_orders, CMD_CLONE_VEHICLE, nullptr, &ScriptInstance::DoCommandReturnVehicleID)) return VEHICLE_INVALID; /* In case of test-mode, we return VehicleID 0 */ return 0; @@ -97,13 +118,13 @@ const Train *v = ::Train::Get(source_vehicle_id); while (source_wagon-- > 0) v = v->GetNextUnit(); - const Train *w = NULL; + const Train *w = nullptr; if (dest_vehicle_id != -1) { w = ::Train::Get(dest_vehicle_id); while (dest_wagon-- > 0) w = w->GetNextUnit(); } - return ScriptObject::DoCommand(0, v->index | (move_attached_wagons ? 1 : 0) << 20, w == NULL ? ::INVALID_VEHICLE : w->index, CMD_MOVE_RAIL_VEHICLE); + return ScriptObject::DoCommand(0, v->index | (move_attached_wagons ? 1 : 0) << 20, w == nullptr ? ::INVALID_VEHICLE : w->index, CMD_MOVE_RAIL_VEHICLE); } /* static */ bool ScriptVehicle::MoveWagon(VehicleID source_vehicle_id, int source_wagon, int dest_vehicle_id, int dest_wagon) @@ -220,7 +241,7 @@ EnforcePrecondition(false, ScriptObject::GetCompany() != OWNER_DEITY); EnforcePrecondition(false, IsValidVehicle(vehicle_id)); - EnforcePrecondition(false, name != NULL); + EnforcePrecondition(false, name != nullptr); const char *text = name->GetDecodedText(); EnforcePreconditionEncodedText(false, text); EnforcePreconditionCustomError(false, ::Utf8StringLength(text) < MAX_LENGTH_VEHICLE_NAME_CHARS, ScriptError::ERR_PRECONDITION_STRING_TOO_LONG); @@ -270,7 +291,7 @@ /* static */ char *ScriptVehicle::GetName(VehicleID vehicle_id) { - if (!IsValidVehicle(vehicle_id)) return NULL; + if (!IsValidVehicle(vehicle_id)) return nullptr; ::SetDParam(0, vehicle_id); return GetString(STR_VEHICLE_NAME); @@ -378,7 +399,7 @@ if (!IsValidVehicle(vehicle_id)) return ScriptRoad::ROADTYPE_INVALID; if (GetVehicleType(vehicle_id) != VT_ROAD) return ScriptRoad::ROADTYPE_INVALID; - return (ScriptRoad::RoadType)(::RoadVehicle::Get(vehicle_id))->roadtype; + return (ScriptRoad::RoadType)(int)(::RoadVehicle::Get(vehicle_id))->roadtype; } /* static */ int32 ScriptVehicle::GetCapacity(VehicleID vehicle_id, CargoID cargo) @@ -387,7 +408,7 @@ if (!ScriptCargo::IsValidCargo(cargo)) return -1; uint32 amount = 0; - for (const Vehicle *v = ::Vehicle::Get(vehicle_id); v != NULL; v = v->Next()) { + for (const Vehicle *v = ::Vehicle::Get(vehicle_id); v != nullptr; v = v->Next()) { if (v->cargo_type == cargo) amount += v->cargo_cap; } @@ -400,7 +421,7 @@ if (!ScriptCargo::IsValidCargo(cargo)) return -1; uint32 amount = 0; - for (const Vehicle *v = ::Vehicle::Get(vehicle_id); v != NULL; v = v->Next()) { + for (const Vehicle *v = ::Vehicle::Get(vehicle_id); v != nullptr; v = v->Next()) { if (v->cargo_type == cargo) amount += v->cargo.StoredCount(); } @@ -432,7 +453,7 @@ if (!IsValidVehicle(vehicle_id)) return false; Vehicle *v = ::Vehicle::Get(vehicle_id); - return v->orders.list != NULL && v->orders.list->GetNumVehicles() > 1; + return v->orders.list != nullptr && v->orders.list->GetNumVehicles() > 1; } /* static */ int ScriptVehicle::GetReliability(VehicleID vehicle_id) @@ -449,9 +470,6 @@ const ::Vehicle *v = ::Vehicle::Get(vehicle_id); switch (v->type) { - case VEH_SHIP: - return _settings_game.pf.pathfinder_for_ships != VPF_NPF ? 129 : 0; - case VEH_AIRCRAFT: 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 f6b22c204d..4b8a4687ab 100644 --- a/src/script/api/script_vehicle.hpp +++ b/src/script/api/script_vehicle.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. @@ -115,7 +113,7 @@ public: * @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 != NULL && len(name) != 0. + * @pre name != nullptr && len(name) != 0. * @game @pre Valid ScriptCompanyMode active in scope. * @exception ScriptError::ERR_NAME_IS_NOT_UNIQUE * @return True if and only if the name was changed. @@ -320,6 +318,41 @@ public: */ static VehicleID BuildVehicle(TileIndex depot, EngineID engine_id); + /** + * Builds a vehicle with the given engine at the given depot and refits it to the given cargo. + * @param depot The depot where the vehicle will be build. + * @param engine_id The engine to use for this vehicle. + * @param cargo The cargo to refit to. + * @pre The tile at depot has a depot that can build the engine and + * is owned by you. + * @pre ScriptEngine::IsBuildable(engine_id). + * @pre ScriptCargo::IsValidCargo(cargo). + * @game @pre Valid ScriptCompanyMode active in scope. + * @exception ScriptVehicle::ERR_VEHICLE_TOO_MANY + * @exception ScriptVehicle::ERR_VEHICLE_BUILD_DISABLED + * @exception ScriptVehicle::ERR_VEHICLE_WRONG_DEPOT + * @return The VehicleID of the new vehicle, or an invalid VehicleID when + * it failed. Check the return value using IsValidVehicle. In test-mode + * 0 is returned if it was successful; any other value indicates failure. + * @note In Test Mode it means you can't assign orders yet to this vehicle, + * as the vehicle isn't really built yet. Build it for real first before + * assigning orders. + */ + static VehicleID BuildVehicleWithRefit(TileIndex depot, EngineID engine_id, CargoID cargo); + + /** + * Gets the capacity of a vehicle built at the given depot with the given engine and refitted to the given cargo. + * @param depot The depot where the vehicle will be build. + * @param engine_id The engine to use for this vehicle. + * @param cargo The cargo to refit to. + * @pre The tile at depot has a depot that can build the engine and + * is owned by you. + * @pre ScriptEngine::IsBuildable(engine_id). + * @pre ScriptCargo::IsValidCargo(cargo). + * @return The capacity the vehicle will have when refited. + */ + static int GetBuildWithRefitCapacity(TileIndex depot, EngineID engine_id, CargoID cargo); + /** * Clones a vehicle at the given depot, copying or cloning its orders. * @param depot The depot where the vehicle will be build. @@ -563,6 +596,11 @@ public: static uint GetMaximumOrderDistance(VehicleID vehicle_id); private: + /** + * Internal function used by BuildVehicle(WithRefit). + */ + static VehicleID _BuildVehicleInternal(TileIndex depot, EngineID engine_id, CargoID cargo); + /** * Internal function used by SellWagon(Chain). */ diff --git a/src/script/api/script_vehiclelist.cpp b/src/script/api/script_vehiclelist.cpp index 625f0f8c4f..58c03ff9a9 100644 --- a/src/script/api/script_vehiclelist.cpp +++ b/src/script/api/script_vehiclelist.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. @@ -16,14 +14,14 @@ #include "script_station.hpp" #include "../../depot_map.h" #include "../../vehicle_base.h" +#include "../../train.h" #include "../../safeguards.h" ScriptVehicleList::ScriptVehicleList() { - const Vehicle *v; - FOR_ALL_VEHICLES(v) { - if ((v->owner == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY) && v->IsPrimaryVehicle()) this->AddItem(v->index); + 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); } } @@ -31,8 +29,7 @@ ScriptVehicleList_Station::ScriptVehicleList_Station(StationID station_id) { if (!ScriptBaseStation::IsValidBaseStation(station_id)) return; - const Vehicle *v; - FOR_ALL_VEHICLES(v) { + for (const Vehicle *v : Vehicle::Iterate()) { if ((v->owner == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY) && v->IsPrimaryVehicle()) { const Order *order; @@ -82,8 +79,7 @@ ScriptVehicleList_Depot::ScriptVehicleList_Depot(TileIndex tile) return; } - const Vehicle *v; - FOR_ALL_VEHICLES(v) { + for (const Vehicle *v : Vehicle::Iterate()) { if ((v->owner == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY) && v->IsPrimaryVehicle() && v->type == type) { const Order *order; @@ -101,7 +97,7 @@ ScriptVehicleList_SharedOrders::ScriptVehicleList_SharedOrders(VehicleID vehicle { if (!ScriptVehicle::IsValidVehicle(vehicle_id)) return; - for (const Vehicle *v = Vehicle::Get(vehicle_id)->FirstShared(); v != NULL; v = v->NextShared()) { + for (const Vehicle *v = Vehicle::Get(vehicle_id)->FirstShared(); v != nullptr; v = v->NextShared()) { this->AddItem(v->index); } } @@ -110,8 +106,7 @@ ScriptVehicleList_Group::ScriptVehicleList_Group(GroupID group_id) { if (!ScriptGroup::IsValidGroup((ScriptGroup::GroupID)group_id)) return; - const Vehicle *v; - FOR_ALL_VEHICLES(v) { + for (const Vehicle *v : Vehicle::Iterate()) { if (v->owner == ScriptObject::GetCompany() && v->IsPrimaryVehicle()) { if (v->group_id == group_id) this->AddItem(v->index); } @@ -122,8 +117,7 @@ ScriptVehicleList_DefaultGroup::ScriptVehicleList_DefaultGroup(ScriptVehicle::Ve { if (vehicle_type < ScriptVehicle::VT_RAIL || vehicle_type > ScriptVehicle::VT_AIR) return; - const Vehicle *v; - FOR_ALL_VEHICLES(v) { + for (const Vehicle *v : Vehicle::Iterate()) { if (v->owner == ScriptObject::GetCompany() && v->IsPrimaryVehicle()) { if (v->type == (::VehicleType)vehicle_type && v->group_id == ScriptGroup::GROUP_DEFAULT) this->AddItem(v->index); } diff --git a/src/script/api/script_vehiclelist.hpp b/src/script/api/script_vehiclelist.hpp index 7df3a2bb01..0ce2d86a35 100644 --- a/src/script/api/script_vehiclelist.hpp +++ b/src/script/api/script_vehiclelist.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/script/api/script_viewport.cpp b/src/script/api/script_viewport.cpp index bed3ba9923..275ab33465 100644 --- a/src/script/api/script_viewport.cpp +++ b/src/script/api/script_viewport.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. diff --git a/src/script/api/script_viewport.hpp b/src/script/api/script_viewport.hpp index cae1a59300..81612031dc 100644 --- a/src/script/api/script_viewport.hpp +++ b/src/script/api/script_viewport.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/script/api/script_waypoint.cpp b/src/script/api/script_waypoint.cpp index 91733a38e8..8bc3695041 100644 --- a/src/script/api/script_waypoint.cpp +++ b/src/script/api/script_waypoint.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. @@ -20,7 +18,7 @@ /* static */ bool ScriptWaypoint::IsValidWaypoint(StationID waypoint_id) { const Waypoint *wp = ::Waypoint::GetIfValid(waypoint_id); - return wp != NULL && (wp->owner == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY || wp->owner == OWNER_NONE); + return wp != nullptr && (wp->owner == ScriptObject::GetCompany() || ScriptObject::GetCompany() == OWNER_DEITY || wp->owner == OWNER_NONE); } /* static */ StationID ScriptWaypoint::GetWaypointID(TileIndex tile) diff --git a/src/script/api/script_waypoint.hpp b/src/script/api/script_waypoint.hpp index 7a8b4c97b3..9dada43966 100644 --- a/src/script/api/script_waypoint.hpp +++ b/src/script/api/script_waypoint.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/script/api/script_waypointlist.cpp b/src/script/api/script_waypointlist.cpp index dd641a6848..1c0a804d1c 100644 --- a/src/script/api/script_waypointlist.cpp +++ b/src/script/api/script_waypointlist.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. @@ -19,8 +17,7 @@ ScriptWaypointList::ScriptWaypointList(ScriptWaypoint::WaypointType waypoint_type) { - const Waypoint *wp; - FOR_ALL_WAYPOINTS(wp) { + 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); } @@ -32,7 +29,7 @@ ScriptWaypointList_Vehicle::ScriptWaypointList_Vehicle(VehicleID vehicle_id) const Vehicle *v = ::Vehicle::Get(vehicle_id); - for (const Order *o = v->GetFirstOrder(); o != NULL; o = o->next) { + for (const Order *o = v->GetFirstOrder(); o != nullptr; o = o->next) { if (o->IsType(OT_GOTO_WAYPOINT)) this->AddItem(o->GetDestination()); } } diff --git a/src/script/api/script_waypointlist.hpp b/src/script/api/script_waypointlist.hpp index fde15c9537..0ee33eff68 100644 --- a/src/script/api/script_waypointlist.hpp +++ b/src/script/api/script_waypointlist.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/script/api/script_window.cpp b/src/script/api/script_window.cpp index 1252f0fc7e..f54b4fd601 100644 --- a/src/script/api/script_window.cpp +++ b/src/script/api/script_window.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. @@ -34,10 +32,10 @@ if (ScriptGame::IsMultiplayer()) return false; if (number == NUMBER_ALL) { - return (FindWindowByClass((::WindowClass)window) != NULL); + return (FindWindowByClass((::WindowClass)window) != nullptr); } - return FindWindowById((::WindowClass)window, number) != NULL; + return FindWindowById((::WindowClass)window, number) != nullptr; } /* static */ void ScriptWindow::Highlight(WindowClass window, uint32 number, uint8 widget, TextColour colour) @@ -56,6 +54,6 @@ } const NWidgetBase *wid = w->GetWidget(widget); - if (wid == NULL) return; + if (wid == nullptr) return; w->SetWidgetHighlight(widget, (::TextColour)colour); } diff --git a/src/script/api/script_window.hpp b/src/script/api/script_window.hpp index ad34ccd471..5b1d623df2 100644 --- a/src/script/api/script_window.hpp +++ b/src/script/api/script_window.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. @@ -54,6 +52,7 @@ #include "../../widgets/osk_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" @@ -784,6 +783,12 @@ public: */ WC_FRAMETIME_GRAPH = ::WC_FRAMETIME_GRAPH, + /** + * Screenshot window; %Window numbers: + * - 0 = #ScreenshotWidgets + */ + WC_SCREENSHOT = ::WC_SCREENSHOT, + WC_INVALID = ::WC_INVALID, ///< Invalid window. }; @@ -961,9 +966,11 @@ public: WID_RV_INFO_TAB = ::WID_RV_INFO_TAB, ///< Info tab. WID_RV_STOP_REPLACE = ::WID_RV_STOP_REPLACE, ///< Stop Replacing button. + /* Train/road only widgets */ + WID_RV_RAIL_ROAD_TYPE_DROPDOWN = ::WID_RV_RAIL_ROAD_TYPE_DROPDOWN, ///< Dropdown menu about the rail/roadtype. + /* Train only widgets. */ WID_RV_TRAIN_ENGINEWAGON_DROPDOWN = ::WID_RV_TRAIN_ENGINEWAGON_DROPDOWN, ///< Dropdown to select engines and/or wagons. - WID_RV_TRAIN_RAILTYPE_DROPDOWN = ::WID_RV_TRAIN_RAILTYPE_DROPDOWN, ///< Dropdown menu about the railtype. WID_RV_TRAIN_WAGONREMOVE_TOGGLE = ::WID_RV_TRAIN_WAGONREMOVE_TOGGLE, ///< Button to toggle removing wagons. }; @@ -1177,6 +1184,8 @@ public: WID_CI_RAIL_COUNT = ::WID_CI_RAIL_COUNT, ///< Count of rail. WID_CI_ROAD_DESC = ::WID_CI_ROAD_DESC, ///< Description of road. WID_CI_ROAD_COUNT = ::WID_CI_ROAD_COUNT, ///< Count of road. + WID_CI_TRAM_DESC = ::WID_CI_TRAM_DESC, ///< Description of tram. + WID_CI_TRAM_COUNT = ::WID_CI_TRAM_COUNT, ///< Count of tram. WID_CI_WATER_DESC = ::WID_CI_WATER_DESC, ///< Description of water. WID_CI_WATER_COUNT = ::WID_CI_WATER_COUNT, ///< Count of water. WID_CI_STATION_DESC = ::WID_CI_STATION_DESC, ///< Description of station. @@ -1312,6 +1321,8 @@ public: WID_FRW_TIMES_NAMES = ::WID_FRW_TIMES_NAMES, WID_FRW_TIMES_CURRENT = ::WID_FRW_TIMES_CURRENT, WID_FRW_TIMES_AVERAGE = ::WID_FRW_TIMES_AVERAGE, + WID_FRW_ALLOCSIZE = ::WID_FRW_ALLOCSIZE, + WID_FRW_SEL_MEMORY = ::WID_FRW_SEL_MEMORY, WID_FRW_SCROLLBAR = ::WID_FRW_SCROLLBAR, }; @@ -1519,6 +1530,8 @@ public: enum IndustryDirectoryWidgets { WID_ID_DROPDOWN_ORDER = ::WID_ID_DROPDOWN_ORDER, ///< Dropdown for the order of the sort. WID_ID_DROPDOWN_CRITERIA = ::WID_ID_DROPDOWN_CRITERIA, ///< Dropdown for the criteria of the sort. + WID_ID_FILTER_BY_ACC_CARGO = ::WID_ID_FILTER_BY_ACC_CARGO, ///< Accepted cargo filter dropdown list. + WID_ID_FILTER_BY_PROD_CARGO = ::WID_ID_FILTER_BY_PROD_CARGO, ///< Produced cargo filter dropdown list. WID_ID_INDUSTRY_LIST = ::WID_ID_INDUSTRY_LIST, ///< Industry list. WID_ID_SCROLLBAR = ::WID_ID_SCROLLBAR, ///< Scrollbar of the list. }; @@ -1605,6 +1618,7 @@ public: enum QueryStringWidgets { WID_QS_CAPTION = ::WID_QS_CAPTION, ///< Caption of the window. WID_QS_TEXT = ::WID_QS_TEXT, ///< Text of the query. + WID_QS_WARNING = ::WID_QS_WARNING, ///< Warning label about password security WID_QS_DEFAULT = ::WID_QS_DEFAULT, ///< Default button. WID_QS_CANCEL = ::WID_QS_CANCEL, ///< Cancel button. WID_QS_OK = ::WID_QS_OK, ///< OK button. @@ -1826,6 +1840,7 @@ public: WID_NCP_LABEL = ::WID_NCP_LABEL, ///< Label in front of the password field. WID_NCP_PASSWORD = ::WID_NCP_PASSWORD, ///< Input field for the password. WID_NCP_SAVE_AS_DEFAULT_PASSWORD = ::WID_NCP_SAVE_AS_DEFAULT_PASSWORD, ///< Toggle 'button' for saving the current password as default password. + WID_NCP_WARNING = ::WID_NCP_WARNING, ///< Warning text about password security WID_NCP_CANCEL = ::WID_NCP_CANCEL, ///< Close the window without changing anything. WID_NCP_OK = ::WID_NCP_OK, ///< Safe the password etc. }; @@ -1943,6 +1958,7 @@ public: WID_N_VEH_NAME = ::WID_N_VEH_NAME, ///< Name of the new vehicle. WID_N_VEH_SPR = ::WID_N_VEH_SPR, ///< Graphical display of the new vehicle. WID_N_VEH_INFO = ::WID_N_VEH_INFO, ///< Some technical data of the new vehicle. + WID_N_SHOW_GROUP = ::WID_N_SHOW_GROUP, ///< Show vehicle's group }; /** Widgets of the #MessageHistoryWindow class. */ @@ -2132,6 +2148,7 @@ public: /** Widgets of the #BuildRoadToolbarWindow class. */ enum RoadToolbarWidgets { /* Name starts with RO instead of R, because of collision with RailToolbarWidgets */ + WID_ROT_CAPTION = ::WID_ROT_CAPTION, ///< Caption of the window WID_ROT_ROAD_X = ::WID_ROT_ROAD_X, ///< Build road in x-direction. WID_ROT_ROAD_Y = ::WID_ROT_ROAD_Y, ///< Build road in y-direction. WID_ROT_AUTOROAD = ::WID_ROT_AUTOROAD, ///< Autorail. @@ -2143,6 +2160,7 @@ public: WID_ROT_BUILD_BRIDGE = ::WID_ROT_BUILD_BRIDGE, ///< Build bridge. WID_ROT_BUILD_TUNNEL = ::WID_ROT_BUILD_TUNNEL, ///< Build tunnel. WID_ROT_REMOVE = ::WID_ROT_REMOVE, ///< Remove road. + WID_ROT_CONVERT_ROAD = ::WID_ROT_CONVERT_ROAD, ///< Convert road. }; /** Widgets of the #BuildRoadDepotWindow class. */ @@ -2171,6 +2189,17 @@ public: WID_BROS_INFO = ::WID_BROS_INFO, ///< Station acceptance info. }; + /* automatically generated from ../../widgets/screenshot_widget.h */ + /** Widgets of the #ScreenshotWindow class. */ + enum ScreenshotWindowWidgets { + WID_SC_TAKE = ::WID_SC_TAKE, ///< Button for taking a normal screenshot + WID_SC_TAKE_ZOOMIN = ::WID_SC_TAKE_ZOOMIN, ///< Button for taking a zoomed in screenshot + WID_SC_TAKE_DEFAULTZOOM = ::WID_SC_TAKE_DEFAULTZOOM, ///< Button for taking a screenshot at normal zoom + WID_SC_TAKE_WORLD = ::WID_SC_TAKE_WORLD, ///< Button for taking a screenshot of the whole world + WID_SC_TAKE_HEIGHTMAP = ::WID_SC_TAKE_HEIGHTMAP, ///< Button for taking a heightmap "screenshot" + WID_SC_TAKE_MINIMAP = ::WID_SC_TAKE_MINIMAP, ///< Button for taking a minimap screenshot + }; + /* automatically generated from ../../widgets/settings_widget.h */ /** Widgets of the #GameOptionsWindow class. */ enum GameOptionsWidgets { @@ -2296,6 +2325,7 @@ public: WID_SV_ROADVEHS = ::WID_SV_ROADVEHS, ///< List of scheduled road vehs button. WID_SV_SHIPS = ::WID_SV_SHIPS, ///< List of scheduled ships button. WID_SV_PLANES = ::WID_SV_PLANES, ///< List of scheduled planes button. + WID_SV_CATCHMENT = ::WID_SV_CATCHMENT, ///< Toggle catchment area highlight. }; /** Widgets of the #CompanyStationsWindow class. */ @@ -2441,6 +2471,7 @@ public: WID_TN_BUILDING_TOOLS_START = ::WID_TN_BUILDING_TOOLS_START, ///< Helper for the offset of the building tools WID_TN_RAILS = ::WID_TN_RAILS, ///< Rail building menu. WID_TN_ROADS = ::WID_TN_ROADS, ///< Road building menu. + WID_TN_TRAMS = ::WID_TN_TRAMS, ///< Tram building menu. WID_TN_WATER = ::WID_TN_WATER, ///< Water building toolbar. WID_TN_AIR = ::WID_TN_AIR, ///< Airport building toolbar. WID_TN_LANDSCAPE = ::WID_TN_LANDSCAPE, ///< Landscaping toolbar. @@ -2471,11 +2502,11 @@ public: WID_TE_TOWN_GENERATE = ::WID_TE_TOWN_GENERATE, ///< Town building window. WID_TE_INDUSTRY = ::WID_TE_INDUSTRY, ///< Industry building window. WID_TE_ROADS = ::WID_TE_ROADS, ///< Road building menu. + WID_TE_TRAMS = ::WID_TE_TRAMS, ///< Tram building menu. WID_TE_WATER = ::WID_TE_WATER, ///< Water building toolbar. WID_TE_TREES = ::WID_TE_TREES, ///< Tree building toolbar. WID_TE_SIGNS = ::WID_TE_SIGNS, ///< Sign building. WID_TE_DATE_PANEL = ::WID_TE_DATE_PANEL, ///< Container for the date widgets. - /* The following three need to have the same actual widget number as the normal toolbar due to shared code. */ WID_TE_MUSIC_SOUND = ::WID_TE_MUSIC_SOUND, ///< Music/sound configuration menu. WID_TE_HELP = ::WID_TE_HELP, ///< Help menu. WID_TE_SWITCH_BAR = ::WID_TE_SWITCH_BAR, ///< Only available when toolbar has been split to switch between different subsets. @@ -2486,6 +2517,7 @@ public: enum TownDirectoryWidgets { WID_TD_SORT_ORDER = ::WID_TD_SORT_ORDER, ///< Direction of sort dropdown. WID_TD_SORT_CRITERIA = ::WID_TD_SORT_CRITERIA, ///< Criteria of sort dropdown. + WID_TD_FILTER = ::WID_TD_FILTER, ///< Filter of name. WID_TD_LIST = ::WID_TD_LIST, ///< List of towns. WID_TD_SCROLLBAR = ::WID_TD_SCROLLBAR, ///< Scrollbar for the town list. WID_TD_WORLD_POPULATION = ::WID_TD_WORLD_POPULATION, ///< The world's population. @@ -2494,6 +2526,7 @@ public: /** Widgets of the #TownAuthorityWindow class. */ enum TownAuthorityWidgets { WID_TA_CAPTION = ::WID_TA_CAPTION, ///< Caption of window. + WID_TA_ZONE_BUTTON = ::WID_TA_ZONE_BUTTON, ///< Turn on/off showing local authority zone. WID_TA_RATING_INFO = ::WID_TA_RATING_INFO, ///< Overview with ratings for each company. WID_TA_COMMAND_LIST = ::WID_TA_COMMAND_LIST, ///< List of commands for the player. WID_TA_SCROLLBAR = ::WID_TA_SCROLLBAR, ///< Scrollbar of the list of commands. @@ -2509,6 +2542,7 @@ public: WID_TV_CENTER_VIEW = ::WID_TV_CENTER_VIEW, ///< Center the main view on this town. WID_TV_SHOW_AUTHORITY = ::WID_TV_SHOW_AUTHORITY, ///< Show the town authority window. WID_TV_CHANGE_NAME = ::WID_TV_CHANGE_NAME, ///< Change the name of this town. + WID_TV_CATCHMENT = ::WID_TV_CATCHMENT, ///< Toggle catchment area highlight. WID_TV_EXPAND = ::WID_TV_EXPAND, ///< Expand this town (scenario editor only). WID_TV_DELETE = ::WID_TV_DELETE, ///< Delete this town (scenario editor only). }; diff --git a/src/script/api/squirrel_export.awk b/src/script/api/squirrel_export.awk index ef0a74c8db..29305b7896 100644 --- a/src/script/api/squirrel_export.awk +++ b/src/script/api/squirrel_export.awk @@ -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. # 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. @@ -34,7 +32,7 @@ function dump_class_templates(name) print " template <> inline const " name " *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (" name " *)instance; }" CR print " template <> inline const " name " &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(" name " *)instance; }" CR if (name == "ScriptEvent") { - print " template <> inline int Return<" name " *>(HSQUIRRELVM vm, " name " *res) { if (res == NULL) { sq_pushnull(vm); return 1; } Squirrel::CreateClassInstanceVM(vm, \"" realname "\", res, NULL, DefSQDestructorCallback<" name ">, true); return 1; }" CR + print " 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; }" CR } else if (name == "ScriptText") { print "" CR print " template <> inline Text *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) {" CR @@ -44,18 +42,15 @@ function dump_class_templates(name) print " if (sq_gettype(vm, index) == OT_STRING) {" CR print " return new RawText(GetParam(ForceType(), vm, index, ptr));" CR print " }" CR - print " return NULL;" CR + print " return nullptr;" CR print " }" CR } else { - print " template <> inline int Return<" name " *>(HSQUIRRELVM vm, " name " *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, \"" realname "\", res, NULL, DefSQDestructorCallback<" name ">, true); return 1; }" CR + print " 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; }" CR } } function dump_fileheader() { - # Break the Id tag, so SVN doesn't replace it - print "/* $I" "d$ */" CR - print "" CR print "/*" CR print " * This file is part of OpenTTD." CR print " * 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." CR diff --git a/src/script/api/squirrel_export.sh b/src/script/api/squirrel_export.sh index 14ff4e1477..96bd102f9b 100755 --- a/src/script/api/squirrel_export.sh +++ b/src/script/api/squirrel_export.sh @@ -1,7 +1,5 @@ #!/bin/bash -# $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. # 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. diff --git a/src/script/api/squirrel_export.vbs b/src/script/api/squirrel_export.vbs index a13869509a..2ebc77136a 100644 --- a/src/script/api/squirrel_export.vbs +++ b/src/script/api/squirrel_export.vbs @@ -1,7 +1,5 @@ Option Explicit -' $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. ' 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. @@ -62,7 +60,7 @@ Function DumpClassTemplates(name, file) file.WriteLine " template <> inline const " & name & " *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (" & name & " *)instance; }" file.WriteLine " template <> inline const " & name & " &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(" & name & " *)instance; }" If name = "ScriptEvent" Then - file.WriteLine " template <> inline int Return<" & name & " *>(HSQUIRRELVM vm, " & name & " *res) { if (res == NULL) { sq_pushnull(vm); return 1; } Squirrel::CreateClassInstanceVM(vm, " & Chr(34) & realname & Chr(34) & ", res, NULL, DefSQDestructorCallback<" & name & ">, true); return 1; }" + file.WriteLine " template <> inline int Return<" & name & " *>(HSQUIRRELVM vm, " & name & " *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } Squirrel::CreateClassInstanceVM(vm, " & Chr(34) & realname & Chr(34) & ", res, nullptr, DefSQDestructorCallback<" & name & ">, true); return 1; }" ElseIf name = "ScriptText" Then file.WriteLine "" file.WriteLine " template <> inline Text *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) {" @@ -72,19 +70,16 @@ Function DumpClassTemplates(name, file) file.WriteLine " if (sq_gettype(vm, index) == OT_STRING) {" file.WriteLine " return new RawText(GetParam(ForceType(), vm, index, ptr));" file.WriteLine " }" - file.WriteLine " return NULL;" + file.WriteLine " return nullptr;" file.WriteLine " }" Else - file.WriteLine " template <> inline int Return<" & name & " *>(HSQUIRRELVM vm, " & name & " *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, " & Chr(34) & realname & Chr(34) & ", res, NULL, DefSQDestructorCallback<" & name & ">, true); return 1; }" + file.WriteLine " template <> inline int Return<" & name & " *>(HSQUIRRELVM vm, " & name & " *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, " & Chr(34) & realname & Chr(34) & ", res, nullptr, DefSQDestructorCallback<" & name & ">, true); return 1; }" End If End Function Function DumpFileheader(api, file) Dim re Set re = New RegExp - ' Break the Id tag, so SVN doesn't replace it - file.WriteLine "/* $I" & "d$ */" - file.WriteLine "" file.WriteLine "/*" file.WriteLine " * This file is part of OpenTTD." file.WriteLine " * 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/script/api/template/template_accounting.hpp.sq b/src/script/api/template/template_accounting.hpp.sq index 298217a22f..06be408c94 100644 --- a/src/script/api/template/template_accounting.hpp.sq +++ b/src/script/api/template/template_accounting.hpp.sq @@ -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. @@ -17,5 +15,5 @@ namespace SQConvert { template <> inline ScriptAccounting &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptAccounting *)instance; } template <> inline const ScriptAccounting *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptAccounting *)instance; } template <> inline const ScriptAccounting &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptAccounting *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptAccounting *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Accounting", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptAccounting *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Accounting", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_admin.hpp.sq b/src/script/api/template/template_admin.hpp.sq index 2256d674b9..3fd8a2face 100644 --- a/src/script/api/template/template_admin.hpp.sq +++ b/src/script/api/template/template_admin.hpp.sq @@ -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. @@ -17,5 +15,5 @@ namespace SQConvert { template <> inline ScriptAdmin &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptAdmin *)instance; } template <> inline const ScriptAdmin *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptAdmin *)instance; } template <> inline const ScriptAdmin &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptAdmin *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptAdmin *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Admin", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptAdmin *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Admin", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_airport.hpp.sq b/src/script/api/template/template_airport.hpp.sq index 402eea076d..7f82808135 100644 --- a/src/script/api/template/template_airport.hpp.sq +++ b/src/script/api/template/template_airport.hpp.sq @@ -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. @@ -23,5 +21,5 @@ namespace SQConvert { template <> inline ScriptAirport &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptAirport *)instance; } template <> inline const ScriptAirport *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptAirport *)instance; } template <> inline const ScriptAirport &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptAirport *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptAirport *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Airport", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptAirport *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Airport", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_base.hpp.sq b/src/script/api/template/template_base.hpp.sq index 0ff19bcb89..b2ce115481 100644 --- a/src/script/api/template/template_base.hpp.sq +++ b/src/script/api/template/template_base.hpp.sq @@ -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. @@ -17,5 +15,5 @@ namespace SQConvert { template <> inline ScriptBase &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptBase *)instance; } template <> inline const ScriptBase *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptBase *)instance; } template <> inline const ScriptBase &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptBase *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptBase *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Base", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptBase *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Base", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_basestation.hpp.sq b/src/script/api/template/template_basestation.hpp.sq index c11a7745e4..297bb0c4a5 100644 --- a/src/script/api/template/template_basestation.hpp.sq +++ b/src/script/api/template/template_basestation.hpp.sq @@ -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. @@ -21,5 +19,5 @@ namespace SQConvert { template <> inline ScriptBaseStation &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptBaseStation *)instance; } template <> inline const ScriptBaseStation *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptBaseStation *)instance; } template <> inline const ScriptBaseStation &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptBaseStation *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptBaseStation *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "BaseStation", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptBaseStation *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "BaseStation", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_bridge.hpp.sq b/src/script/api/template/template_bridge.hpp.sq index f627155119..f3f9371d98 100644 --- a/src/script/api/template/template_bridge.hpp.sq +++ b/src/script/api/template/template_bridge.hpp.sq @@ -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. @@ -21,5 +19,5 @@ namespace SQConvert { template <> inline ScriptBridge &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptBridge *)instance; } template <> inline const ScriptBridge *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptBridge *)instance; } template <> inline const ScriptBridge &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptBridge *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptBridge *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Bridge", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptBridge *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Bridge", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_bridgelist.hpp.sq b/src/script/api/template/template_bridgelist.hpp.sq index 1f78a78742..d007a1aeec 100644 --- a/src/script/api/template/template_bridgelist.hpp.sq +++ b/src/script/api/template/template_bridgelist.hpp.sq @@ -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. @@ -17,7 +15,7 @@ namespace SQConvert { template <> inline ScriptBridgeList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptBridgeList *)instance; } template <> inline const ScriptBridgeList *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptBridgeList *)instance; } template <> inline const ScriptBridgeList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptBridgeList *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptBridgeList *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "BridgeList", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptBridgeList *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "BridgeList", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -26,5 +24,5 @@ namespace SQConvert { template <> inline ScriptBridgeList_Length &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptBridgeList_Length *)instance; } template <> inline const ScriptBridgeList_Length *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptBridgeList_Length *)instance; } template <> inline const ScriptBridgeList_Length &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptBridgeList_Length *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptBridgeList_Length *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "BridgeList_Length", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptBridgeList_Length *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "BridgeList_Length", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_cargo.hpp.sq b/src/script/api/template/template_cargo.hpp.sq index b57e5c05aa..5d46fdd373 100644 --- a/src/script/api/template/template_cargo.hpp.sq +++ b/src/script/api/template/template_cargo.hpp.sq @@ -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. @@ -27,5 +25,5 @@ namespace SQConvert { template <> inline ScriptCargo &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptCargo *)instance; } template <> inline const ScriptCargo *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptCargo *)instance; } template <> inline const ScriptCargo &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptCargo *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptCargo *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Cargo", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptCargo *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Cargo", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_cargolist.hpp.sq b/src/script/api/template/template_cargolist.hpp.sq index 5b39aa66d8..394d20f91d 100644 --- a/src/script/api/template/template_cargolist.hpp.sq +++ b/src/script/api/template/template_cargolist.hpp.sq @@ -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. @@ -17,7 +15,7 @@ namespace SQConvert { template <> inline ScriptCargoList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptCargoList *)instance; } template <> inline const ScriptCargoList *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptCargoList *)instance; } template <> inline const ScriptCargoList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptCargoList *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptCargoList *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "CargoList", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptCargoList *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "CargoList", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -26,7 +24,7 @@ namespace SQConvert { template <> inline ScriptCargoList_IndustryAccepting &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptCargoList_IndustryAccepting *)instance; } template <> inline const ScriptCargoList_IndustryAccepting *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptCargoList_IndustryAccepting *)instance; } template <> inline const ScriptCargoList_IndustryAccepting &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptCargoList_IndustryAccepting *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptCargoList_IndustryAccepting *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "CargoList_IndustryAccepting", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptCargoList_IndustryAccepting *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "CargoList_IndustryAccepting", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -35,7 +33,7 @@ namespace SQConvert { template <> inline ScriptCargoList_IndustryProducing &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptCargoList_IndustryProducing *)instance; } template <> inline const ScriptCargoList_IndustryProducing *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptCargoList_IndustryProducing *)instance; } template <> inline const ScriptCargoList_IndustryProducing &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptCargoList_IndustryProducing *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptCargoList_IndustryProducing *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "CargoList_IndustryProducing", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptCargoList_IndustryProducing *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "CargoList_IndustryProducing", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -44,5 +42,5 @@ namespace SQConvert { template <> inline ScriptCargoList_StationAccepting &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptCargoList_StationAccepting *)instance; } template <> inline const ScriptCargoList_StationAccepting *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptCargoList_StationAccepting *)instance; } template <> inline const ScriptCargoList_StationAccepting &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptCargoList_StationAccepting *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptCargoList_StationAccepting *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "CargoList_StationAccepting", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptCargoList_StationAccepting *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "CargoList_StationAccepting", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_cargomonitor.hpp.sq b/src/script/api/template/template_cargomonitor.hpp.sq index ce0a358ace..6d6965777f 100644 --- a/src/script/api/template/template_cargomonitor.hpp.sq +++ b/src/script/api/template/template_cargomonitor.hpp.sq @@ -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. @@ -17,5 +15,5 @@ namespace SQConvert { template <> inline ScriptCargoMonitor &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptCargoMonitor *)instance; } template <> inline const ScriptCargoMonitor *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptCargoMonitor *)instance; } template <> inline const ScriptCargoMonitor &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptCargoMonitor *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptCargoMonitor *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "CargoMonitor", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptCargoMonitor *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "CargoMonitor", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_client.hpp.sq b/src/script/api/template/template_client.hpp.sq index 13b9d68b6a..c37bd9a6ed 100644 --- a/src/script/api/template/template_client.hpp.sq +++ b/src/script/api/template/template_client.hpp.sq @@ -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. @@ -21,5 +19,5 @@ namespace SQConvert { template <> inline ScriptClient &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptClient *)instance; } template <> inline const ScriptClient *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptClient *)instance; } template <> inline const ScriptClient &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptClient *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptClient *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Client", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptClient *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Client", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_clientlist.hpp.sq b/src/script/api/template/template_clientlist.hpp.sq index 74c3f4525f..7021a59cd6 100644 --- a/src/script/api/template/template_clientlist.hpp.sq +++ b/src/script/api/template/template_clientlist.hpp.sq @@ -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. @@ -17,7 +15,7 @@ namespace SQConvert { template <> inline ScriptClientList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptClientList *)instance; } template <> inline const ScriptClientList *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptClientList *)instance; } template <> inline const ScriptClientList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptClientList *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptClientList *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "ClientList", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptClientList *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "ClientList", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -26,5 +24,5 @@ namespace SQConvert { template <> inline ScriptClientList_Company &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptClientList_Company *)instance; } template <> inline const ScriptClientList_Company *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptClientList_Company *)instance; } template <> inline const ScriptClientList_Company &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptClientList_Company *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptClientList_Company *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "ClientList_Company", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptClientList_Company *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "ClientList_Company", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_company.hpp.sq b/src/script/api/template/template_company.hpp.sq index 82c10381ab..97461448a9 100644 --- a/src/script/api/template/template_company.hpp.sq +++ b/src/script/api/template/template_company.hpp.sq @@ -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. @@ -31,5 +29,5 @@ namespace SQConvert { template <> inline ScriptCompany &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptCompany *)instance; } template <> inline const ScriptCompany *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptCompany *)instance; } template <> inline const ScriptCompany &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptCompany *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptCompany *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Company", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptCompany *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Company", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_companymode.hpp.sq b/src/script/api/template/template_companymode.hpp.sq index f99f1d42d5..aa3edd6b70 100644 --- a/src/script/api/template/template_companymode.hpp.sq +++ b/src/script/api/template/template_companymode.hpp.sq @@ -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. @@ -17,5 +15,5 @@ namespace SQConvert { template <> inline ScriptCompanyMode &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptCompanyMode *)instance; } template <> inline const ScriptCompanyMode *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptCompanyMode *)instance; } template <> inline const ScriptCompanyMode &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptCompanyMode *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptCompanyMode *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "CompanyMode", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptCompanyMode *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "CompanyMode", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_date.hpp.sq b/src/script/api/template/template_date.hpp.sq index cca4a258b1..747ead207e 100644 --- a/src/script/api/template/template_date.hpp.sq +++ b/src/script/api/template/template_date.hpp.sq @@ -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. @@ -21,5 +19,5 @@ namespace SQConvert { template <> inline ScriptDate &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptDate *)instance; } template <> inline const ScriptDate *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptDate *)instance; } template <> inline const ScriptDate &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptDate *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptDate *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Date", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptDate *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Date", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_depotlist.hpp.sq b/src/script/api/template/template_depotlist.hpp.sq index f5fcbcf544..9981f80ce7 100644 --- a/src/script/api/template/template_depotlist.hpp.sq +++ b/src/script/api/template/template_depotlist.hpp.sq @@ -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. @@ -17,5 +15,5 @@ namespace SQConvert { template <> inline ScriptDepotList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptDepotList *)instance; } template <> inline const ScriptDepotList *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptDepotList *)instance; } template <> inline const ScriptDepotList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptDepotList *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptDepotList *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "DepotList", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptDepotList *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "DepotList", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_engine.hpp.sq b/src/script/api/template/template_engine.hpp.sq index 3d652df9e8..4ae741eac2 100644 --- a/src/script/api/template/template_engine.hpp.sq +++ b/src/script/api/template/template_engine.hpp.sq @@ -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. @@ -17,5 +15,5 @@ namespace SQConvert { template <> inline ScriptEngine &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEngine *)instance; } template <> inline const ScriptEngine *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptEngine *)instance; } template <> inline const ScriptEngine &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEngine *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptEngine *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Engine", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptEngine *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Engine", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_enginelist.hpp.sq b/src/script/api/template/template_enginelist.hpp.sq index f17c244eb6..3e98f9c8a0 100644 --- a/src/script/api/template/template_enginelist.hpp.sq +++ b/src/script/api/template/template_enginelist.hpp.sq @@ -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. @@ -17,5 +15,5 @@ namespace SQConvert { template <> inline ScriptEngineList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEngineList *)instance; } template <> inline const ScriptEngineList *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptEngineList *)instance; } template <> inline const ScriptEngineList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEngineList *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptEngineList *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EngineList", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptEngineList *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EngineList", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_error.hpp.sq b/src/script/api/template/template_error.hpp.sq index 8e61f08103..99b37eafec 100644 --- a/src/script/api/template/template_error.hpp.sq +++ b/src/script/api/template/template_error.hpp.sq @@ -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. @@ -23,5 +21,5 @@ namespace SQConvert { template <> inline ScriptError &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptError *)instance; } template <> inline const ScriptError *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptError *)instance; } template <> inline const ScriptError &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptError *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptError *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Error", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptError *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Error", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_event.hpp.sq b/src/script/api/template/template_event.hpp.sq index c0a8afdc93..38ba818b40 100644 --- a/src/script/api/template/template_event.hpp.sq +++ b/src/script/api/template/template_event.hpp.sq @@ -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. @@ -21,7 +19,7 @@ namespace SQConvert { template <> inline ScriptEvent &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEvent *)instance; } template <> inline const ScriptEvent *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptEvent *)instance; } template <> inline const ScriptEvent &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEvent *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptEvent *res) { if (res == NULL) { sq_pushnull(vm); return 1; } Squirrel::CreateClassInstanceVM(vm, "Event", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptEvent *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } Squirrel::CreateClassInstanceVM(vm, "Event", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -30,5 +28,5 @@ namespace SQConvert { template <> inline ScriptEventController &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventController *)instance; } template <> inline const ScriptEventController *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptEventController *)instance; } template <> inline const ScriptEventController &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventController *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptEventController *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventController", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptEventController *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventController", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_event_types.hpp.sq b/src/script/api/template/template_event_types.hpp.sq index eb6d1f1b42..09cbe43f3f 100644 --- a/src/script/api/template/template_event_types.hpp.sq +++ b/src/script/api/template/template_event_types.hpp.sq @@ -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. @@ -21,7 +19,7 @@ namespace SQConvert { template <> inline ScriptEventVehicleCrashed &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventVehicleCrashed *)instance; } template <> inline const ScriptEventVehicleCrashed *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptEventVehicleCrashed *)instance; } template <> inline const ScriptEventVehicleCrashed &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventVehicleCrashed *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptEventVehicleCrashed *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventVehicleCrashed", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptEventVehicleCrashed *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventVehicleCrashed", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -30,7 +28,7 @@ namespace SQConvert { template <> inline ScriptEventSubsidyOffer &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventSubsidyOffer *)instance; } template <> inline const ScriptEventSubsidyOffer *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptEventSubsidyOffer *)instance; } template <> inline const ScriptEventSubsidyOffer &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventSubsidyOffer *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptEventSubsidyOffer *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventSubsidyOffer", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptEventSubsidyOffer *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventSubsidyOffer", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -39,7 +37,7 @@ namespace SQConvert { template <> inline ScriptEventSubsidyOfferExpired &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventSubsidyOfferExpired *)instance; } template <> inline const ScriptEventSubsidyOfferExpired *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptEventSubsidyOfferExpired *)instance; } template <> inline const ScriptEventSubsidyOfferExpired &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventSubsidyOfferExpired *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptEventSubsidyOfferExpired *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventSubsidyOfferExpired", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptEventSubsidyOfferExpired *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventSubsidyOfferExpired", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -48,7 +46,7 @@ namespace SQConvert { template <> inline ScriptEventSubsidyAwarded &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventSubsidyAwarded *)instance; } template <> inline const ScriptEventSubsidyAwarded *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptEventSubsidyAwarded *)instance; } template <> inline const ScriptEventSubsidyAwarded &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventSubsidyAwarded *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptEventSubsidyAwarded *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventSubsidyAwarded", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptEventSubsidyAwarded *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventSubsidyAwarded", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -57,7 +55,7 @@ namespace SQConvert { template <> inline ScriptEventSubsidyExpired &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventSubsidyExpired *)instance; } template <> inline const ScriptEventSubsidyExpired *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptEventSubsidyExpired *)instance; } template <> inline const ScriptEventSubsidyExpired &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventSubsidyExpired *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptEventSubsidyExpired *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventSubsidyExpired", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptEventSubsidyExpired *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventSubsidyExpired", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -66,7 +64,7 @@ namespace SQConvert { template <> inline ScriptEventEnginePreview &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventEnginePreview *)instance; } template <> inline const ScriptEventEnginePreview *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptEventEnginePreview *)instance; } template <> inline const ScriptEventEnginePreview &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventEnginePreview *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptEventEnginePreview *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventEnginePreview", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptEventEnginePreview *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventEnginePreview", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -75,7 +73,7 @@ namespace SQConvert { template <> inline ScriptEventCompanyNew &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventCompanyNew *)instance; } template <> inline const ScriptEventCompanyNew *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptEventCompanyNew *)instance; } template <> inline const ScriptEventCompanyNew &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventCompanyNew *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptEventCompanyNew *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventCompanyNew", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptEventCompanyNew *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventCompanyNew", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -84,7 +82,7 @@ namespace SQConvert { template <> inline ScriptEventCompanyInTrouble &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventCompanyInTrouble *)instance; } template <> inline const ScriptEventCompanyInTrouble *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptEventCompanyInTrouble *)instance; } template <> inline const ScriptEventCompanyInTrouble &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventCompanyInTrouble *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptEventCompanyInTrouble *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventCompanyInTrouble", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptEventCompanyInTrouble *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventCompanyInTrouble", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -93,7 +91,7 @@ namespace SQConvert { template <> inline ScriptEventCompanyAskMerger &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventCompanyAskMerger *)instance; } template <> inline const ScriptEventCompanyAskMerger *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptEventCompanyAskMerger *)instance; } template <> inline const ScriptEventCompanyAskMerger &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventCompanyAskMerger *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptEventCompanyAskMerger *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventCompanyAskMerger", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptEventCompanyAskMerger *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventCompanyAskMerger", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -102,7 +100,7 @@ namespace SQConvert { template <> inline ScriptEventCompanyMerger &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventCompanyMerger *)instance; } template <> inline const ScriptEventCompanyMerger *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptEventCompanyMerger *)instance; } template <> inline const ScriptEventCompanyMerger &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventCompanyMerger *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptEventCompanyMerger *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventCompanyMerger", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptEventCompanyMerger *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventCompanyMerger", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -111,7 +109,7 @@ namespace SQConvert { template <> inline ScriptEventCompanyBankrupt &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventCompanyBankrupt *)instance; } template <> inline const ScriptEventCompanyBankrupt *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptEventCompanyBankrupt *)instance; } template <> inline const ScriptEventCompanyBankrupt &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventCompanyBankrupt *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptEventCompanyBankrupt *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventCompanyBankrupt", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptEventCompanyBankrupt *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventCompanyBankrupt", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -120,7 +118,7 @@ namespace SQConvert { template <> inline ScriptEventVehicleLost &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventVehicleLost *)instance; } template <> inline const ScriptEventVehicleLost *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptEventVehicleLost *)instance; } template <> inline const ScriptEventVehicleLost &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventVehicleLost *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptEventVehicleLost *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventVehicleLost", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptEventVehicleLost *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventVehicleLost", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -129,7 +127,7 @@ namespace SQConvert { template <> inline ScriptEventVehicleWaitingInDepot &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventVehicleWaitingInDepot *)instance; } template <> inline const ScriptEventVehicleWaitingInDepot *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptEventVehicleWaitingInDepot *)instance; } template <> inline const ScriptEventVehicleWaitingInDepot &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventVehicleWaitingInDepot *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptEventVehicleWaitingInDepot *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventVehicleWaitingInDepot", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptEventVehicleWaitingInDepot *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventVehicleWaitingInDepot", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -138,7 +136,7 @@ namespace SQConvert { template <> inline ScriptEventVehicleUnprofitable &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventVehicleUnprofitable *)instance; } template <> inline const ScriptEventVehicleUnprofitable *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptEventVehicleUnprofitable *)instance; } template <> inline const ScriptEventVehicleUnprofitable &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventVehicleUnprofitable *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptEventVehicleUnprofitable *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventVehicleUnprofitable", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptEventVehicleUnprofitable *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventVehicleUnprofitable", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -147,7 +145,7 @@ namespace SQConvert { template <> inline ScriptEventIndustryOpen &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventIndustryOpen *)instance; } template <> inline const ScriptEventIndustryOpen *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptEventIndustryOpen *)instance; } template <> inline const ScriptEventIndustryOpen &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventIndustryOpen *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptEventIndustryOpen *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventIndustryOpen", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptEventIndustryOpen *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventIndustryOpen", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -156,7 +154,7 @@ namespace SQConvert { template <> inline ScriptEventIndustryClose &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventIndustryClose *)instance; } template <> inline const ScriptEventIndustryClose *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptEventIndustryClose *)instance; } template <> inline const ScriptEventIndustryClose &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventIndustryClose *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptEventIndustryClose *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventIndustryClose", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptEventIndustryClose *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventIndustryClose", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -165,7 +163,7 @@ namespace SQConvert { template <> inline ScriptEventEngineAvailable &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventEngineAvailable *)instance; } template <> inline const ScriptEventEngineAvailable *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptEventEngineAvailable *)instance; } template <> inline const ScriptEventEngineAvailable &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventEngineAvailable *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptEventEngineAvailable *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventEngineAvailable", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptEventEngineAvailable *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventEngineAvailable", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -174,7 +172,7 @@ namespace SQConvert { template <> inline ScriptEventStationFirstVehicle &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventStationFirstVehicle *)instance; } template <> inline const ScriptEventStationFirstVehicle *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptEventStationFirstVehicle *)instance; } template <> inline const ScriptEventStationFirstVehicle &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventStationFirstVehicle *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptEventStationFirstVehicle *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventStationFirstVehicle", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptEventStationFirstVehicle *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventStationFirstVehicle", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -183,7 +181,7 @@ namespace SQConvert { template <> inline ScriptEventDisasterZeppelinerCrashed &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventDisasterZeppelinerCrashed *)instance; } template <> inline const ScriptEventDisasterZeppelinerCrashed *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptEventDisasterZeppelinerCrashed *)instance; } template <> inline const ScriptEventDisasterZeppelinerCrashed &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventDisasterZeppelinerCrashed *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptEventDisasterZeppelinerCrashed *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventDisasterZeppelinerCrashed", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptEventDisasterZeppelinerCrashed *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventDisasterZeppelinerCrashed", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -192,7 +190,7 @@ namespace SQConvert { template <> inline ScriptEventDisasterZeppelinerCleared &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventDisasterZeppelinerCleared *)instance; } template <> inline const ScriptEventDisasterZeppelinerCleared *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptEventDisasterZeppelinerCleared *)instance; } template <> inline const ScriptEventDisasterZeppelinerCleared &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventDisasterZeppelinerCleared *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptEventDisasterZeppelinerCleared *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventDisasterZeppelinerCleared", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptEventDisasterZeppelinerCleared *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventDisasterZeppelinerCleared", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -201,7 +199,7 @@ namespace SQConvert { template <> inline ScriptEventTownFounded &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventTownFounded *)instance; } template <> inline const ScriptEventTownFounded *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptEventTownFounded *)instance; } template <> inline const ScriptEventTownFounded &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventTownFounded *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptEventTownFounded *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventTownFounded", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptEventTownFounded *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventTownFounded", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -210,7 +208,7 @@ namespace SQConvert { template <> inline ScriptEventAircraftDestTooFar &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventAircraftDestTooFar *)instance; } template <> inline const ScriptEventAircraftDestTooFar *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptEventAircraftDestTooFar *)instance; } template <> inline const ScriptEventAircraftDestTooFar &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventAircraftDestTooFar *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptEventAircraftDestTooFar *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventAircraftDestTooFar", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptEventAircraftDestTooFar *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventAircraftDestTooFar", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -219,7 +217,7 @@ namespace SQConvert { template <> inline ScriptEventAdminPort &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventAdminPort *)instance; } template <> inline const ScriptEventAdminPort *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptEventAdminPort *)instance; } template <> inline const ScriptEventAdminPort &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventAdminPort *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptEventAdminPort *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventAdminPort", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptEventAdminPort *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventAdminPort", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -228,7 +226,7 @@ namespace SQConvert { template <> inline ScriptEventWindowWidgetClick &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventWindowWidgetClick *)instance; } template <> inline const ScriptEventWindowWidgetClick *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptEventWindowWidgetClick *)instance; } template <> inline const ScriptEventWindowWidgetClick &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventWindowWidgetClick *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptEventWindowWidgetClick *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventWindowWidgetClick", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptEventWindowWidgetClick *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventWindowWidgetClick", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -237,7 +235,7 @@ namespace SQConvert { template <> inline ScriptEventGoalQuestionAnswer &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventGoalQuestionAnswer *)instance; } template <> inline const ScriptEventGoalQuestionAnswer *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptEventGoalQuestionAnswer *)instance; } template <> inline const ScriptEventGoalQuestionAnswer &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventGoalQuestionAnswer *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptEventGoalQuestionAnswer *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventGoalQuestionAnswer", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptEventGoalQuestionAnswer *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventGoalQuestionAnswer", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -246,7 +244,7 @@ namespace SQConvert { template <> inline ScriptEventCompanyTown &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventCompanyTown *)instance; } template <> inline const ScriptEventCompanyTown *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptEventCompanyTown *)instance; } template <> inline const ScriptEventCompanyTown &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventCompanyTown *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptEventCompanyTown *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventCompanyTown", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptEventCompanyTown *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventCompanyTown", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -255,7 +253,7 @@ namespace SQConvert { template <> inline ScriptEventExclusiveTransportRights &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventExclusiveTransportRights *)instance; } template <> inline const ScriptEventExclusiveTransportRights *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptEventExclusiveTransportRights *)instance; } template <> inline const ScriptEventExclusiveTransportRights &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventExclusiveTransportRights *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptEventExclusiveTransportRights *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventExclusiveTransportRights", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptEventExclusiveTransportRights *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventExclusiveTransportRights", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -264,5 +262,14 @@ namespace SQConvert { template <> inline ScriptEventRoadReconstruction &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventRoadReconstruction *)instance; } template <> inline const ScriptEventRoadReconstruction *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptEventRoadReconstruction *)instance; } template <> inline const ScriptEventRoadReconstruction &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventRoadReconstruction *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptEventRoadReconstruction *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventRoadReconstruction", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptEventRoadReconstruction *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventRoadReconstruction", res, nullptr, DefSQDestructorCallback, true); return 1; } +} // namespace SQConvert + +namespace SQConvert { + /* Allow ScriptEventVehicleAutoReplaced to be used as Squirrel parameter */ + template <> inline ScriptEventVehicleAutoReplaced *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptEventVehicleAutoReplaced *)instance; } + template <> inline ScriptEventVehicleAutoReplaced &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventVehicleAutoReplaced *)instance; } + template <> inline const ScriptEventVehicleAutoReplaced *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptEventVehicleAutoReplaced *)instance; } + template <> inline const ScriptEventVehicleAutoReplaced &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptEventVehicleAutoReplaced *)instance; } + template <> inline int Return(HSQUIRRELVM vm, ScriptEventVehicleAutoReplaced *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "EventVehicleAutoReplaced", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_execmode.hpp.sq b/src/script/api/template/template_execmode.hpp.sq index 4c8326bc17..7b93b2d1cc 100644 --- a/src/script/api/template/template_execmode.hpp.sq +++ b/src/script/api/template/template_execmode.hpp.sq @@ -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. @@ -17,5 +15,5 @@ namespace SQConvert { template <> inline ScriptExecMode &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptExecMode *)instance; } template <> inline const ScriptExecMode *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptExecMode *)instance; } template <> inline const ScriptExecMode &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptExecMode *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptExecMode *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "ExecMode", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptExecMode *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "ExecMode", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_game.hpp.sq b/src/script/api/template/template_game.hpp.sq index 495aeada41..a7f366f039 100644 --- a/src/script/api/template/template_game.hpp.sq +++ b/src/script/api/template/template_game.hpp.sq @@ -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. @@ -21,5 +19,5 @@ namespace SQConvert { template <> inline ScriptGame &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptGame *)instance; } template <> inline const ScriptGame *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptGame *)instance; } template <> inline const ScriptGame &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptGame *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptGame *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Game", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptGame *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Game", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_gamesettings.hpp.sq b/src/script/api/template/template_gamesettings.hpp.sq index 9c6e91746c..012d9240d0 100644 --- a/src/script/api/template/template_gamesettings.hpp.sq +++ b/src/script/api/template/template_gamesettings.hpp.sq @@ -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. @@ -17,5 +15,5 @@ namespace SQConvert { template <> inline ScriptGameSettings &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptGameSettings *)instance; } template <> inline const ScriptGameSettings *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptGameSettings *)instance; } template <> inline const ScriptGameSettings &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptGameSettings *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptGameSettings *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "GameSettings", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptGameSettings *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "GameSettings", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_goal.hpp.sq b/src/script/api/template/template_goal.hpp.sq index 6aa3014eea..984fe7fb6c 100644 --- a/src/script/api/template/template_goal.hpp.sq +++ b/src/script/api/template/template_goal.hpp.sq @@ -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. @@ -27,5 +25,5 @@ namespace SQConvert { template <> inline ScriptGoal &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptGoal *)instance; } template <> inline const ScriptGoal *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptGoal *)instance; } template <> inline const ScriptGoal &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptGoal *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptGoal *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Goal", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptGoal *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Goal", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_group.hpp.sq b/src/script/api/template/template_group.hpp.sq index ac4abe5a17..e598d550c0 100644 --- a/src/script/api/template/template_group.hpp.sq +++ b/src/script/api/template/template_group.hpp.sq @@ -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. @@ -21,5 +19,5 @@ namespace SQConvert { template <> inline ScriptGroup &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptGroup *)instance; } template <> inline const ScriptGroup *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptGroup *)instance; } template <> inline const ScriptGroup &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptGroup *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptGroup *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Group", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptGroup *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Group", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_grouplist.hpp.sq b/src/script/api/template/template_grouplist.hpp.sq index 858abcf015..5431adb83e 100644 --- a/src/script/api/template/template_grouplist.hpp.sq +++ b/src/script/api/template/template_grouplist.hpp.sq @@ -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. @@ -17,5 +15,5 @@ namespace SQConvert { template <> inline ScriptGroupList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptGroupList *)instance; } template <> inline const ScriptGroupList *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptGroupList *)instance; } template <> inline const ScriptGroupList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptGroupList *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptGroupList *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "GroupList", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptGroupList *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "GroupList", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_industry.hpp.sq b/src/script/api/template/template_industry.hpp.sq index e1e02263c6..711c3ab52d 100644 --- a/src/script/api/template/template_industry.hpp.sq +++ b/src/script/api/template/template_industry.hpp.sq @@ -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. @@ -21,5 +19,5 @@ namespace SQConvert { template <> inline ScriptIndustry &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptIndustry *)instance; } template <> inline const ScriptIndustry *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptIndustry *)instance; } template <> inline const ScriptIndustry &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptIndustry *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptIndustry *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Industry", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptIndustry *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Industry", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_industrylist.hpp.sq b/src/script/api/template/template_industrylist.hpp.sq index 0c0316346a..9c44a3e4cd 100644 --- a/src/script/api/template/template_industrylist.hpp.sq +++ b/src/script/api/template/template_industrylist.hpp.sq @@ -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. @@ -17,7 +15,7 @@ namespace SQConvert { template <> inline ScriptIndustryList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptIndustryList *)instance; } template <> inline const ScriptIndustryList *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptIndustryList *)instance; } template <> inline const ScriptIndustryList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptIndustryList *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptIndustryList *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "IndustryList", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptIndustryList *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "IndustryList", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -26,7 +24,7 @@ namespace SQConvert { template <> inline ScriptIndustryList_CargoAccepting &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptIndustryList_CargoAccepting *)instance; } template <> inline const ScriptIndustryList_CargoAccepting *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptIndustryList_CargoAccepting *)instance; } template <> inline const ScriptIndustryList_CargoAccepting &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptIndustryList_CargoAccepting *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptIndustryList_CargoAccepting *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "IndustryList_CargoAccepting", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptIndustryList_CargoAccepting *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "IndustryList_CargoAccepting", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -35,5 +33,5 @@ namespace SQConvert { template <> inline ScriptIndustryList_CargoProducing &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptIndustryList_CargoProducing *)instance; } template <> inline const ScriptIndustryList_CargoProducing *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptIndustryList_CargoProducing *)instance; } template <> inline const ScriptIndustryList_CargoProducing &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptIndustryList_CargoProducing *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptIndustryList_CargoProducing *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "IndustryList_CargoProducing", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptIndustryList_CargoProducing *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "IndustryList_CargoProducing", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_industrytype.hpp.sq b/src/script/api/template/template_industrytype.hpp.sq index 79495053ea..06c7c18bbe 100644 --- a/src/script/api/template/template_industrytype.hpp.sq +++ b/src/script/api/template/template_industrytype.hpp.sq @@ -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. @@ -21,5 +19,5 @@ namespace SQConvert { template <> inline ScriptIndustryType &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptIndustryType *)instance; } template <> inline const ScriptIndustryType *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptIndustryType *)instance; } template <> inline const ScriptIndustryType &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptIndustryType *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptIndustryType *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "IndustryType", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptIndustryType *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "IndustryType", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_industrytypelist.hpp.sq b/src/script/api/template/template_industrytypelist.hpp.sq index 044f9ccedf..71272b23ed 100644 --- a/src/script/api/template/template_industrytypelist.hpp.sq +++ b/src/script/api/template/template_industrytypelist.hpp.sq @@ -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. @@ -17,5 +15,5 @@ namespace SQConvert { template <> inline ScriptIndustryTypeList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptIndustryTypeList *)instance; } template <> inline const ScriptIndustryTypeList *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptIndustryTypeList *)instance; } template <> inline const ScriptIndustryTypeList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptIndustryTypeList *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptIndustryTypeList *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "IndustryTypeList", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptIndustryTypeList *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "IndustryTypeList", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_infrastructure.hpp.sq b/src/script/api/template/template_infrastructure.hpp.sq index 39460e1406..11b839ae25 100644 --- a/src/script/api/template/template_infrastructure.hpp.sq +++ b/src/script/api/template/template_infrastructure.hpp.sq @@ -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. @@ -21,5 +19,5 @@ namespace SQConvert { template <> inline ScriptInfrastructure &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptInfrastructure *)instance; } template <> inline const ScriptInfrastructure *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptInfrastructure *)instance; } template <> inline const ScriptInfrastructure &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptInfrastructure *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptInfrastructure *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Infrastructure", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptInfrastructure *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Infrastructure", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_list.hpp.sq b/src/script/api/template/template_list.hpp.sq index fa8d2b36dc..9ca4da9c10 100644 --- a/src/script/api/template/template_list.hpp.sq +++ b/src/script/api/template/template_list.hpp.sq @@ -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. @@ -21,5 +19,5 @@ namespace SQConvert { template <> inline ScriptList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptList *)instance; } template <> inline const ScriptList *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptList *)instance; } template <> inline const ScriptList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptList *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptList *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "List", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptList *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "List", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_log.hpp.sq b/src/script/api/template/template_log.hpp.sq index 91c0511d0c..2ebe7547de 100644 --- a/src/script/api/template/template_log.hpp.sq +++ b/src/script/api/template/template_log.hpp.sq @@ -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. @@ -17,5 +15,5 @@ namespace SQConvert { template <> inline ScriptLog &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptLog *)instance; } template <> inline const ScriptLog *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptLog *)instance; } template <> inline const ScriptLog &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptLog *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptLog *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Log", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptLog *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Log", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_map.hpp.sq b/src/script/api/template/template_map.hpp.sq index 4d34cc734b..3a15390277 100644 --- a/src/script/api/template/template_map.hpp.sq +++ b/src/script/api/template/template_map.hpp.sq @@ -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. @@ -17,5 +15,5 @@ namespace SQConvert { template <> inline ScriptMap &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptMap *)instance; } template <> inline const ScriptMap *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptMap *)instance; } template <> inline const ScriptMap &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptMap *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptMap *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Map", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptMap *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Map", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_marine.hpp.sq b/src/script/api/template/template_marine.hpp.sq index d2415b6994..115e88c263 100644 --- a/src/script/api/template/template_marine.hpp.sq +++ b/src/script/api/template/template_marine.hpp.sq @@ -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. @@ -23,5 +21,5 @@ namespace SQConvert { template <> inline ScriptMarine &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptMarine *)instance; } template <> inline const ScriptMarine *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptMarine *)instance; } template <> inline const ScriptMarine &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptMarine *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptMarine *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Marine", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptMarine *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Marine", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_news.hpp.sq b/src/script/api/template/template_news.hpp.sq index 445a055e10..443e04c858 100644 --- a/src/script/api/template/template_news.hpp.sq +++ b/src/script/api/template/template_news.hpp.sq @@ -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. @@ -23,5 +21,5 @@ namespace SQConvert { template <> inline ScriptNews &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptNews *)instance; } template <> inline const ScriptNews *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptNews *)instance; } template <> inline const ScriptNews &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptNews *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptNews *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "News", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptNews *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "News", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_order.hpp.sq b/src/script/api/template/template_order.hpp.sq index d11fafa14f..155baa3a75 100644 --- a/src/script/api/template/template_order.hpp.sq +++ b/src/script/api/template/template_order.hpp.sq @@ -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. @@ -31,5 +29,5 @@ namespace SQConvert { template <> inline ScriptOrder &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptOrder *)instance; } template <> inline const ScriptOrder *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptOrder *)instance; } template <> inline const ScriptOrder &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptOrder *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptOrder *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Order", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptOrder *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Order", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_rail.hpp.sq b/src/script/api/template/template_rail.hpp.sq index f92f96d587..f451175403 100644 --- a/src/script/api/template/template_rail.hpp.sq +++ b/src/script/api/template/template_rail.hpp.sq @@ -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. @@ -29,5 +27,5 @@ namespace SQConvert { template <> inline ScriptRail &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptRail *)instance; } template <> inline const ScriptRail *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptRail *)instance; } template <> inline const ScriptRail &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptRail *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptRail *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Rail", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptRail *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Rail", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_railtypelist.hpp.sq b/src/script/api/template/template_railtypelist.hpp.sq index 9a768e1d5c..09f63f8e37 100644 --- a/src/script/api/template/template_railtypelist.hpp.sq +++ b/src/script/api/template/template_railtypelist.hpp.sq @@ -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. @@ -17,5 +15,5 @@ namespace SQConvert { template <> inline ScriptRailTypeList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptRailTypeList *)instance; } template <> inline const ScriptRailTypeList *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptRailTypeList *)instance; } template <> inline const ScriptRailTypeList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptRailTypeList *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptRailTypeList *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "RailTypeList", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptRailTypeList *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "RailTypeList", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_road.hpp.sq b/src/script/api/template/template_road.hpp.sq index d50bda573d..f2f8c411df 100644 --- a/src/script/api/template/template_road.hpp.sq +++ b/src/script/api/template/template_road.hpp.sq @@ -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. @@ -17,6 +15,8 @@ namespace SQConvert { template <> inline int Return(HSQUIRRELVM vm, ScriptRoad::ErrorMessages res) { sq_pushinteger(vm, (int32)res); return 1; } template <> inline ScriptRoad::RoadType GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (ScriptRoad::RoadType)tmp; } template <> inline int Return(HSQUIRRELVM vm, ScriptRoad::RoadType res) { sq_pushinteger(vm, (int32)res); return 1; } + template <> inline ScriptRoad::RoadTramTypes GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (ScriptRoad::RoadTramTypes)tmp; } + template <> inline int Return(HSQUIRRELVM vm, ScriptRoad::RoadTramTypes res) { sq_pushinteger(vm, (int32)res); return 1; } template <> inline ScriptRoad::RoadVehicleType GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (ScriptRoad::RoadVehicleType)tmp; } template <> inline int Return(HSQUIRRELVM vm, ScriptRoad::RoadVehicleType res) { sq_pushinteger(vm, (int32)res); return 1; } template <> inline ScriptRoad::BuildType GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (ScriptRoad::BuildType)tmp; } @@ -27,5 +27,5 @@ namespace SQConvert { template <> inline ScriptRoad &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptRoad *)instance; } template <> inline const ScriptRoad *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptRoad *)instance; } template <> inline const ScriptRoad &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptRoad *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptRoad *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Road", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptRoad *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Road", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_roadtypelist.hpp.sq b/src/script/api/template/template_roadtypelist.hpp.sq new file mode 100644 index 0000000000..bd2c1931e4 --- /dev/null +++ b/src/script/api/template/template_roadtypelist.hpp.sq @@ -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 . + */ + +/* THIS FILE IS AUTO-GENERATED; PLEASE DO NOT ALTER MANUALLY */ + +#include "../script_roadtypelist.hpp" + +namespace SQConvert { + /* Allow ScriptRoadTypeList to be used as Squirrel parameter */ + template <> inline ScriptRoadTypeList *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptRoadTypeList *)instance; } + template <> inline ScriptRoadTypeList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptRoadTypeList *)instance; } + template <> inline const ScriptRoadTypeList *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptRoadTypeList *)instance; } + template <> inline const ScriptRoadTypeList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptRoadTypeList *)instance; } + template <> inline int Return(HSQUIRRELVM vm, ScriptRoadTypeList *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "RoadTypeList", res, nullptr, DefSQDestructorCallback, true); return 1; } +} // namespace SQConvert diff --git a/src/script/api/template/template_sign.hpp.sq b/src/script/api/template/template_sign.hpp.sq index db926fed3f..76e7759ebd 100644 --- a/src/script/api/template/template_sign.hpp.sq +++ b/src/script/api/template/template_sign.hpp.sq @@ -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. @@ -21,5 +19,5 @@ namespace SQConvert { template <> inline ScriptSign &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptSign *)instance; } template <> inline const ScriptSign *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptSign *)instance; } template <> inline const ScriptSign &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptSign *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptSign *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Sign", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptSign *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Sign", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_signlist.hpp.sq b/src/script/api/template/template_signlist.hpp.sq index e5bd67ae5f..e762202508 100644 --- a/src/script/api/template/template_signlist.hpp.sq +++ b/src/script/api/template/template_signlist.hpp.sq @@ -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. @@ -17,5 +15,5 @@ namespace SQConvert { template <> inline ScriptSignList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptSignList *)instance; } template <> inline const ScriptSignList *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptSignList *)instance; } template <> inline const ScriptSignList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptSignList *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptSignList *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "SignList", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptSignList *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "SignList", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_station.hpp.sq b/src/script/api/template/template_station.hpp.sq index 729ae68a6d..ba5af93c14 100644 --- a/src/script/api/template/template_station.hpp.sq +++ b/src/script/api/template/template_station.hpp.sq @@ -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. @@ -23,5 +21,5 @@ namespace SQConvert { template <> inline ScriptStation &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptStation *)instance; } template <> inline const ScriptStation *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptStation *)instance; } template <> inline const ScriptStation &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptStation *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptStation *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Station", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptStation *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Station", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_stationlist.hpp.sq b/src/script/api/template/template_stationlist.hpp.sq index 5f7bd28129..e6a1f0bbaf 100644 --- a/src/script/api/template/template_stationlist.hpp.sq +++ b/src/script/api/template/template_stationlist.hpp.sq @@ -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. @@ -17,7 +15,7 @@ namespace SQConvert { template <> inline ScriptStationList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptStationList *)instance; } template <> inline const ScriptStationList *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptStationList *)instance; } template <> inline const ScriptStationList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptStationList *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptStationList *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "StationList", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptStationList *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "StationList", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -32,7 +30,7 @@ namespace SQConvert { template <> inline ScriptStationList_Cargo &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptStationList_Cargo *)instance; } template <> inline const ScriptStationList_Cargo *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptStationList_Cargo *)instance; } template <> inline const ScriptStationList_Cargo &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptStationList_Cargo *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptStationList_Cargo *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "StationList_Cargo", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptStationList_Cargo *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "StationList_Cargo", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -41,7 +39,7 @@ namespace SQConvert { template <> inline ScriptStationList_CargoWaiting &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptStationList_CargoWaiting *)instance; } template <> inline const ScriptStationList_CargoWaiting *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptStationList_CargoWaiting *)instance; } template <> inline const ScriptStationList_CargoWaiting &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptStationList_CargoWaiting *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptStationList_CargoWaiting *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "StationList_CargoWaiting", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptStationList_CargoWaiting *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "StationList_CargoWaiting", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -50,7 +48,7 @@ namespace SQConvert { template <> inline ScriptStationList_CargoPlanned &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptStationList_CargoPlanned *)instance; } template <> inline const ScriptStationList_CargoPlanned *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptStationList_CargoPlanned *)instance; } template <> inline const ScriptStationList_CargoPlanned &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptStationList_CargoPlanned *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptStationList_CargoPlanned *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "StationList_CargoPlanned", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptStationList_CargoPlanned *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "StationList_CargoPlanned", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -59,7 +57,7 @@ namespace SQConvert { template <> inline ScriptStationList_CargoWaitingByFrom &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptStationList_CargoWaitingByFrom *)instance; } template <> inline const ScriptStationList_CargoWaitingByFrom *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptStationList_CargoWaitingByFrom *)instance; } template <> inline const ScriptStationList_CargoWaitingByFrom &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptStationList_CargoWaitingByFrom *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptStationList_CargoWaitingByFrom *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "StationList_CargoWaitingByFrom", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptStationList_CargoWaitingByFrom *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "StationList_CargoWaitingByFrom", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -68,7 +66,7 @@ namespace SQConvert { template <> inline ScriptStationList_CargoWaitingViaByFrom &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptStationList_CargoWaitingViaByFrom *)instance; } template <> inline const ScriptStationList_CargoWaitingViaByFrom *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptStationList_CargoWaitingViaByFrom *)instance; } template <> inline const ScriptStationList_CargoWaitingViaByFrom &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptStationList_CargoWaitingViaByFrom *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptStationList_CargoWaitingViaByFrom *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "StationList_CargoWaitingViaByFrom", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptStationList_CargoWaitingViaByFrom *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "StationList_CargoWaitingViaByFrom", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -77,7 +75,7 @@ namespace SQConvert { template <> inline ScriptStationList_CargoWaitingByVia &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptStationList_CargoWaitingByVia *)instance; } template <> inline const ScriptStationList_CargoWaitingByVia *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptStationList_CargoWaitingByVia *)instance; } template <> inline const ScriptStationList_CargoWaitingByVia &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptStationList_CargoWaitingByVia *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptStationList_CargoWaitingByVia *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "StationList_CargoWaitingByVia", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptStationList_CargoWaitingByVia *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "StationList_CargoWaitingByVia", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -86,7 +84,7 @@ namespace SQConvert { template <> inline ScriptStationList_CargoWaitingFromByVia &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptStationList_CargoWaitingFromByVia *)instance; } template <> inline const ScriptStationList_CargoWaitingFromByVia *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptStationList_CargoWaitingFromByVia *)instance; } template <> inline const ScriptStationList_CargoWaitingFromByVia &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptStationList_CargoWaitingFromByVia *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptStationList_CargoWaitingFromByVia *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "StationList_CargoWaitingFromByVia", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptStationList_CargoWaitingFromByVia *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "StationList_CargoWaitingFromByVia", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -95,7 +93,7 @@ namespace SQConvert { template <> inline ScriptStationList_CargoPlannedByFrom &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptStationList_CargoPlannedByFrom *)instance; } template <> inline const ScriptStationList_CargoPlannedByFrom *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptStationList_CargoPlannedByFrom *)instance; } template <> inline const ScriptStationList_CargoPlannedByFrom &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptStationList_CargoPlannedByFrom *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptStationList_CargoPlannedByFrom *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "StationList_CargoPlannedByFrom", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptStationList_CargoPlannedByFrom *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "StationList_CargoPlannedByFrom", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -104,7 +102,7 @@ namespace SQConvert { template <> inline ScriptStationList_CargoPlannedViaByFrom &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptStationList_CargoPlannedViaByFrom *)instance; } template <> inline const ScriptStationList_CargoPlannedViaByFrom *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptStationList_CargoPlannedViaByFrom *)instance; } template <> inline const ScriptStationList_CargoPlannedViaByFrom &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptStationList_CargoPlannedViaByFrom *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptStationList_CargoPlannedViaByFrom *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "StationList_CargoPlannedViaByFrom", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptStationList_CargoPlannedViaByFrom *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "StationList_CargoPlannedViaByFrom", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -113,7 +111,7 @@ namespace SQConvert { template <> inline ScriptStationList_CargoPlannedByVia &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptStationList_CargoPlannedByVia *)instance; } template <> inline const ScriptStationList_CargoPlannedByVia *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptStationList_CargoPlannedByVia *)instance; } template <> inline const ScriptStationList_CargoPlannedByVia &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptStationList_CargoPlannedByVia *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptStationList_CargoPlannedByVia *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "StationList_CargoPlannedByVia", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptStationList_CargoPlannedByVia *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "StationList_CargoPlannedByVia", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -122,7 +120,7 @@ namespace SQConvert { template <> inline ScriptStationList_CargoPlannedFromByVia &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptStationList_CargoPlannedFromByVia *)instance; } template <> inline const ScriptStationList_CargoPlannedFromByVia *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptStationList_CargoPlannedFromByVia *)instance; } template <> inline const ScriptStationList_CargoPlannedFromByVia &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptStationList_CargoPlannedFromByVia *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptStationList_CargoPlannedFromByVia *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "StationList_CargoPlannedFromByVia", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptStationList_CargoPlannedFromByVia *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "StationList_CargoPlannedFromByVia", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -131,5 +129,5 @@ namespace SQConvert { template <> inline ScriptStationList_Vehicle &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptStationList_Vehicle *)instance; } template <> inline const ScriptStationList_Vehicle *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptStationList_Vehicle *)instance; } template <> inline const ScriptStationList_Vehicle &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptStationList_Vehicle *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptStationList_Vehicle *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "StationList_Vehicle", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptStationList_Vehicle *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "StationList_Vehicle", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_story_page.hpp.sq b/src/script/api/template/template_story_page.hpp.sq index 4c322a3acf..106f9a6238 100644 --- a/src/script/api/template/template_story_page.hpp.sq +++ b/src/script/api/template/template_story_page.hpp.sq @@ -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. @@ -25,5 +23,5 @@ namespace SQConvert { template <> inline ScriptStoryPage &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptStoryPage *)instance; } template <> inline const ScriptStoryPage *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptStoryPage *)instance; } template <> inline const ScriptStoryPage &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptStoryPage *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptStoryPage *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "StoryPage", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptStoryPage *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "StoryPage", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_storypageelementlist.hpp.sq b/src/script/api/template/template_storypageelementlist.hpp.sq index 34d940f928..224f38c506 100644 --- a/src/script/api/template/template_storypageelementlist.hpp.sq +++ b/src/script/api/template/template_storypageelementlist.hpp.sq @@ -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. @@ -17,5 +15,5 @@ namespace SQConvert { template <> inline ScriptStoryPageElementList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptStoryPageElementList *)instance; } template <> inline const ScriptStoryPageElementList *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptStoryPageElementList *)instance; } template <> inline const ScriptStoryPageElementList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptStoryPageElementList *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptStoryPageElementList *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "StoryPageElementList", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptStoryPageElementList *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "StoryPageElementList", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_storypagelist.hpp.sq b/src/script/api/template/template_storypagelist.hpp.sq index 7325969fdc..6b799dd18f 100644 --- a/src/script/api/template/template_storypagelist.hpp.sq +++ b/src/script/api/template/template_storypagelist.hpp.sq @@ -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. @@ -17,5 +15,5 @@ namespace SQConvert { template <> inline ScriptStoryPageList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptStoryPageList *)instance; } template <> inline const ScriptStoryPageList *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptStoryPageList *)instance; } template <> inline const ScriptStoryPageList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptStoryPageList *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptStoryPageList *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "StoryPageList", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptStoryPageList *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "StoryPageList", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_subsidy.hpp.sq b/src/script/api/template/template_subsidy.hpp.sq index 61303a645e..78a35e8dea 100644 --- a/src/script/api/template/template_subsidy.hpp.sq +++ b/src/script/api/template/template_subsidy.hpp.sq @@ -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. @@ -21,5 +19,5 @@ namespace SQConvert { template <> inline ScriptSubsidy &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptSubsidy *)instance; } template <> inline const ScriptSubsidy *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptSubsidy *)instance; } template <> inline const ScriptSubsidy &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptSubsidy *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptSubsidy *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Subsidy", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptSubsidy *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Subsidy", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_subsidylist.hpp.sq b/src/script/api/template/template_subsidylist.hpp.sq index 4e6284f4e9..98f2e1fd09 100644 --- a/src/script/api/template/template_subsidylist.hpp.sq +++ b/src/script/api/template/template_subsidylist.hpp.sq @@ -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. @@ -17,5 +15,5 @@ namespace SQConvert { template <> inline ScriptSubsidyList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptSubsidyList *)instance; } template <> inline const ScriptSubsidyList *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptSubsidyList *)instance; } template <> inline const ScriptSubsidyList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptSubsidyList *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptSubsidyList *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "SubsidyList", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptSubsidyList *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "SubsidyList", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_testmode.hpp.sq b/src/script/api/template/template_testmode.hpp.sq index bacafa16e7..c779df57f5 100644 --- a/src/script/api/template/template_testmode.hpp.sq +++ b/src/script/api/template/template_testmode.hpp.sq @@ -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. @@ -17,5 +15,5 @@ namespace SQConvert { template <> inline ScriptTestMode &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptTestMode *)instance; } template <> inline const ScriptTestMode *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptTestMode *)instance; } template <> inline const ScriptTestMode &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptTestMode *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptTestMode *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "TestMode", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptTestMode *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "TestMode", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_text.hpp.sq b/src/script/api/template/template_text.hpp.sq index 7a44daf16f..b93fad8c5b 100644 --- a/src/script/api/template/template_text.hpp.sq +++ b/src/script/api/template/template_text.hpp.sq @@ -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. @@ -25,6 +23,6 @@ namespace SQConvert { if (sq_gettype(vm, index) == OT_STRING) { return new RawText(GetParam(ForceType(), vm, index, ptr)); } - return NULL; + return nullptr; } } // namespace SQConvert diff --git a/src/script/api/template/template_tile.hpp.sq b/src/script/api/template/template_tile.hpp.sq index e78aaa6ace..ac9365da7a 100644 --- a/src/script/api/template/template_tile.hpp.sq +++ b/src/script/api/template/template_tile.hpp.sq @@ -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. @@ -31,5 +29,5 @@ namespace SQConvert { template <> inline ScriptTile &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptTile *)instance; } template <> inline const ScriptTile *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptTile *)instance; } template <> inline const ScriptTile &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptTile *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptTile *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Tile", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptTile *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Tile", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_tilelist.hpp.sq b/src/script/api/template/template_tilelist.hpp.sq index e3d73a7c85..7f1ae696c1 100644 --- a/src/script/api/template/template_tilelist.hpp.sq +++ b/src/script/api/template/template_tilelist.hpp.sq @@ -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. @@ -17,7 +15,7 @@ namespace SQConvert { template <> inline ScriptTileList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptTileList *)instance; } template <> inline const ScriptTileList *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptTileList *)instance; } template <> inline const ScriptTileList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptTileList *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptTileList *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "TileList", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptTileList *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "TileList", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -26,7 +24,7 @@ namespace SQConvert { template <> inline ScriptTileList_IndustryAccepting &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptTileList_IndustryAccepting *)instance; } template <> inline const ScriptTileList_IndustryAccepting *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptTileList_IndustryAccepting *)instance; } template <> inline const ScriptTileList_IndustryAccepting &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptTileList_IndustryAccepting *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptTileList_IndustryAccepting *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "TileList_IndustryAccepting", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptTileList_IndustryAccepting *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "TileList_IndustryAccepting", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -35,7 +33,7 @@ namespace SQConvert { template <> inline ScriptTileList_IndustryProducing &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptTileList_IndustryProducing *)instance; } template <> inline const ScriptTileList_IndustryProducing *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptTileList_IndustryProducing *)instance; } template <> inline const ScriptTileList_IndustryProducing &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptTileList_IndustryProducing *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptTileList_IndustryProducing *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "TileList_IndustryProducing", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptTileList_IndustryProducing *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "TileList_IndustryProducing", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -44,5 +42,5 @@ namespace SQConvert { template <> inline ScriptTileList_StationType &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptTileList_StationType *)instance; } template <> inline const ScriptTileList_StationType *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptTileList_StationType *)instance; } template <> inline const ScriptTileList_StationType &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptTileList_StationType *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptTileList_StationType *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "TileList_StationType", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptTileList_StationType *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "TileList_StationType", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_town.hpp.sq b/src/script/api/template/template_town.hpp.sq index 0ec1c285d8..6134ecbe93 100644 --- a/src/script/api/template/template_town.hpp.sq +++ b/src/script/api/template/template_town.hpp.sq @@ -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. @@ -29,5 +27,5 @@ namespace SQConvert { template <> inline ScriptTown &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptTown *)instance; } template <> inline const ScriptTown *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptTown *)instance; } template <> inline const ScriptTown &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptTown *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptTown *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Town", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptTown *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Town", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_townlist.hpp.sq b/src/script/api/template/template_townlist.hpp.sq index 5bbd2e203a..ff97ef4471 100644 --- a/src/script/api/template/template_townlist.hpp.sq +++ b/src/script/api/template/template_townlist.hpp.sq @@ -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. @@ -17,7 +15,7 @@ namespace SQConvert { template <> inline ScriptTownList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptTownList *)instance; } template <> inline const ScriptTownList *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptTownList *)instance; } template <> inline const ScriptTownList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptTownList *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptTownList *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "TownList", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptTownList *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "TownList", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -26,5 +24,5 @@ namespace SQConvert { template <> inline ScriptTownEffectList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptTownEffectList *)instance; } template <> inline const ScriptTownEffectList *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptTownEffectList *)instance; } template <> inline const ScriptTownEffectList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptTownEffectList *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptTownEffectList *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "TownEffectList", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptTownEffectList *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "TownEffectList", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_tunnel.hpp.sq b/src/script/api/template/template_tunnel.hpp.sq index 2d7eed91e5..49b25b7ef0 100644 --- a/src/script/api/template/template_tunnel.hpp.sq +++ b/src/script/api/template/template_tunnel.hpp.sq @@ -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. @@ -21,5 +19,5 @@ namespace SQConvert { template <> inline ScriptTunnel &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptTunnel *)instance; } template <> inline const ScriptTunnel *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptTunnel *)instance; } template <> inline const ScriptTunnel &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptTunnel *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptTunnel *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Tunnel", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptTunnel *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Tunnel", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_vehicle.hpp.sq b/src/script/api/template/template_vehicle.hpp.sq index 999a9c5078..87713b8b40 100644 --- a/src/script/api/template/template_vehicle.hpp.sq +++ b/src/script/api/template/template_vehicle.hpp.sq @@ -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. @@ -25,5 +23,5 @@ namespace SQConvert { template <> inline ScriptVehicle &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptVehicle *)instance; } template <> inline const ScriptVehicle *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptVehicle *)instance; } template <> inline const ScriptVehicle &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptVehicle *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptVehicle *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Vehicle", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptVehicle *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Vehicle", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_vehiclelist.hpp.sq b/src/script/api/template/template_vehiclelist.hpp.sq index dd1d17682e..701116748d 100644 --- a/src/script/api/template/template_vehiclelist.hpp.sq +++ b/src/script/api/template/template_vehiclelist.hpp.sq @@ -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. @@ -17,7 +15,7 @@ namespace SQConvert { template <> inline ScriptVehicleList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptVehicleList *)instance; } template <> inline const ScriptVehicleList *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptVehicleList *)instance; } template <> inline const ScriptVehicleList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptVehicleList *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptVehicleList *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "VehicleList", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptVehicleList *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "VehicleList", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -26,7 +24,7 @@ namespace SQConvert { template <> inline ScriptVehicleList_Station &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptVehicleList_Station *)instance; } template <> inline const ScriptVehicleList_Station *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptVehicleList_Station *)instance; } template <> inline const ScriptVehicleList_Station &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptVehicleList_Station *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptVehicleList_Station *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "VehicleList_Station", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptVehicleList_Station *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "VehicleList_Station", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -35,7 +33,7 @@ namespace SQConvert { template <> inline ScriptVehicleList_Depot &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptVehicleList_Depot *)instance; } template <> inline const ScriptVehicleList_Depot *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptVehicleList_Depot *)instance; } template <> inline const ScriptVehicleList_Depot &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptVehicleList_Depot *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptVehicleList_Depot *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "VehicleList_Depot", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptVehicleList_Depot *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "VehicleList_Depot", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -44,7 +42,7 @@ namespace SQConvert { template <> inline ScriptVehicleList_SharedOrders &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptVehicleList_SharedOrders *)instance; } template <> inline const ScriptVehicleList_SharedOrders *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptVehicleList_SharedOrders *)instance; } template <> inline const ScriptVehicleList_SharedOrders &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptVehicleList_SharedOrders *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptVehicleList_SharedOrders *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "VehicleList_SharedOrders", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptVehicleList_SharedOrders *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "VehicleList_SharedOrders", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -53,7 +51,7 @@ namespace SQConvert { template <> inline ScriptVehicleList_Group &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptVehicleList_Group *)instance; } template <> inline const ScriptVehicleList_Group *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptVehicleList_Group *)instance; } template <> inline const ScriptVehicleList_Group &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptVehicleList_Group *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptVehicleList_Group *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "VehicleList_Group", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptVehicleList_Group *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "VehicleList_Group", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -62,5 +60,5 @@ namespace SQConvert { template <> inline ScriptVehicleList_DefaultGroup &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptVehicleList_DefaultGroup *)instance; } template <> inline const ScriptVehicleList_DefaultGroup *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptVehicleList_DefaultGroup *)instance; } template <> inline const ScriptVehicleList_DefaultGroup &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptVehicleList_DefaultGroup *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptVehicleList_DefaultGroup *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "VehicleList_DefaultGroup", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptVehicleList_DefaultGroup *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "VehicleList_DefaultGroup", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_viewport.hpp.sq b/src/script/api/template/template_viewport.hpp.sq index 8a187ae81d..845c824485 100644 --- a/src/script/api/template/template_viewport.hpp.sq +++ b/src/script/api/template/template_viewport.hpp.sq @@ -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. @@ -17,5 +15,5 @@ namespace SQConvert { template <> inline ScriptViewport &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptViewport *)instance; } template <> inline const ScriptViewport *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptViewport *)instance; } template <> inline const ScriptViewport &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptViewport *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptViewport *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Viewport", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptViewport *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Viewport", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_waypoint.hpp.sq b/src/script/api/template/template_waypoint.hpp.sq index 88cc495c98..179e62ae0c 100644 --- a/src/script/api/template/template_waypoint.hpp.sq +++ b/src/script/api/template/template_waypoint.hpp.sq @@ -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. @@ -23,5 +21,5 @@ namespace SQConvert { template <> inline ScriptWaypoint &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptWaypoint *)instance; } template <> inline const ScriptWaypoint *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptWaypoint *)instance; } template <> inline const ScriptWaypoint &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptWaypoint *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptWaypoint *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Waypoint", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptWaypoint *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Waypoint", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_waypointlist.hpp.sq b/src/script/api/template/template_waypointlist.hpp.sq index 2e23bba148..1de9eb40e9 100644 --- a/src/script/api/template/template_waypointlist.hpp.sq +++ b/src/script/api/template/template_waypointlist.hpp.sq @@ -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. @@ -17,7 +15,7 @@ namespace SQConvert { template <> inline ScriptWaypointList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptWaypointList *)instance; } template <> inline const ScriptWaypointList *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptWaypointList *)instance; } template <> inline const ScriptWaypointList &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptWaypointList *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptWaypointList *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "WaypointList", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptWaypointList *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "WaypointList", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert namespace SQConvert { @@ -26,5 +24,5 @@ namespace SQConvert { template <> inline ScriptWaypointList_Vehicle &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptWaypointList_Vehicle *)instance; } template <> inline const ScriptWaypointList_Vehicle *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptWaypointList_Vehicle *)instance; } template <> inline const ScriptWaypointList_Vehicle &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptWaypointList_Vehicle *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptWaypointList_Vehicle *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "WaypointList_Vehicle", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptWaypointList_Vehicle *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "WaypointList_Vehicle", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/api/template/template_window.hpp.sq b/src/script/api/template/template_window.hpp.sq index 3077215ec2..723c98a91b 100644 --- a/src/script/api/template/template_window.hpp.sq +++ b/src/script/api/template/template_window.hpp.sq @@ -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. @@ -195,6 +193,8 @@ namespace SQConvert { template <> inline int Return(HSQUIRRELVM vm, ScriptWindow::BuildRoadDepotWidgets res) { sq_pushinteger(vm, (int32)res); return 1; } template <> inline ScriptWindow::BuildRoadStationWidgets GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (ScriptWindow::BuildRoadStationWidgets)tmp; } template <> inline int Return(HSQUIRRELVM vm, ScriptWindow::BuildRoadStationWidgets res) { sq_pushinteger(vm, (int32)res); return 1; } + template <> inline ScriptWindow::ScreenshotWindowWidgets GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (ScriptWindow::ScreenshotWindowWidgets)tmp; } + template <> inline int Return(HSQUIRRELVM vm, ScriptWindow::ScreenshotWindowWidgets res) { sq_pushinteger(vm, (int32)res); return 1; } template <> inline ScriptWindow::GameOptionsWidgets GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (ScriptWindow::GameOptionsWidgets)tmp; } template <> inline int Return(HSQUIRRELVM vm, ScriptWindow::GameOptionsWidgets res) { sq_pushinteger(vm, (int32)res); return 1; } template <> inline ScriptWindow::GameSettingsWidgets GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQInteger tmp; sq_getinteger(vm, index, &tmp); return (ScriptWindow::GameSettingsWidgets)tmp; } @@ -259,5 +259,5 @@ namespace SQConvert { template <> inline ScriptWindow &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptWindow *)instance; } template <> inline const ScriptWindow *GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return (ScriptWindow *)instance; } template <> inline const ScriptWindow &GetParam(ForceType, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQUserPointer instance; sq_getinstanceup(vm, index, &instance, 0); return *(ScriptWindow *)instance; } - template <> inline int Return(HSQUIRRELVM vm, ScriptWindow *res) { if (res == NULL) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Window", res, NULL, DefSQDestructorCallback, true); return 1; } + template <> inline int Return(HSQUIRRELVM vm, ScriptWindow *res) { if (res == nullptr) { sq_pushnull(vm); return 1; } res->AddRef(); Squirrel::CreateClassInstanceVM(vm, "Window", res, nullptr, DefSQDestructorCallback, true); return 1; } } // namespace SQConvert diff --git a/src/script/script_config.cpp b/src/script/script_config.cpp index 3171e67d4f..e359afb1e9 100644 --- a/src/script/script_config.cpp +++ b/src/script/script_config.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. @@ -21,17 +19,17 @@ void ScriptConfig::Change(const char *name, int version, bool force_exact_match, bool is_random) { free(this->name); - this->name = (name == NULL) ? NULL : stredup(name); - this->info = (name == NULL) ? NULL : this->FindInfo(this->name, version, force_exact_match); - this->version = (info == NULL) ? -1 : info->GetVersion(); + this->name = (name == nullptr) ? nullptr : stredup(name); + this->info = (name == nullptr) ? nullptr : this->FindInfo(this->name, version, force_exact_match); + this->version = (info == nullptr) ? -1 : info->GetVersion(); this->is_random = is_random; - if (this->config_list != NULL) delete this->config_list; - this->config_list = (info == NULL) ? NULL : new ScriptConfigItemList(); - if (this->config_list != NULL) this->PushExtraConfigList(); + 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->ClearConfigList(); - if (_game_mode == GM_NORMAL && this->info != NULL) { + if (_game_mode == GM_NORMAL && this->info != nullptr) { /* If we're in an existing game and the Script is changed, set all settings * for the Script that have the random flag to a random value. */ for (ScriptConfigItemList::const_iterator it = this->info->GetConfigList()->begin(); it != this->info->GetConfigList()->end(); it++) { @@ -45,10 +43,10 @@ void ScriptConfig::Change(const char *name, int version, bool force_exact_match, ScriptConfig::ScriptConfig(const ScriptConfig *config) { - this->name = (config->name == NULL) ? NULL : stredup(config->name); + this->name = (config->name == nullptr) ? nullptr : stredup(config->name); this->info = config->info; this->version = config->version; - this->config_list = NULL; + this->config_list = nullptr; this->is_random = config->is_random; for (SettingValueList::const_iterator it = config->settings.begin(); it != config->settings.end(); it++) { @@ -61,7 +59,7 @@ ScriptConfig::~ScriptConfig() { free(this->name); this->ResetSettings(); - if (this->config_list != NULL) delete this->config_list; + if (this->config_list != nullptr) delete this->config_list; } ScriptInfo *ScriptConfig::GetInfo() const @@ -71,8 +69,8 @@ ScriptInfo *ScriptConfig::GetInfo() const const ScriptConfigItemList *ScriptConfig::GetConfigList() { - if (this->info != NULL) return this->info->GetConfigList(); - if (this->config_list == NULL) { + if (this->info != nullptr) return this->info->GetConfigList(); + if (this->config_list == nullptr) { this->config_list = new ScriptConfigItemList(); this->PushExtraConfigList(); } @@ -106,10 +104,10 @@ int ScriptConfig::GetSetting(const char *name) const void ScriptConfig::SetSetting(const char *name, int value) { /* You can only set Script specific settings if an Script is selected. */ - if (this->info == NULL) return; + if (this->info == nullptr) return; const ScriptConfigItem *config_item = this->info->GetConfigItem(name); - if (config_item == NULL) return; + if (config_item == nullptr) return; value = Clamp(value, config_item->min_value, config_item->max_value); @@ -140,7 +138,7 @@ void ScriptConfig::AddRandomDeviation() bool ScriptConfig::HasScript() const { - return this->info != NULL; + return this->info != nullptr; } bool ScriptConfig::IsRandom() const @@ -163,18 +161,18 @@ void ScriptConfig::StringToSettings(const char *value) char *value_copy = stredup(value); char *s = value_copy; - while (s != NULL) { + while (s != nullptr) { /* Analyze the string ('name=value,name=value\0') */ char *item_name = s; s = strchr(s, '='); - if (s == NULL) break; + if (s == nullptr) break; if (*s == '\0') break; *s = '\0'; s++; char *item_value = s; s = strchr(s, ','); - if (s != NULL) { + if (s != nullptr) { *s = '\0'; s++; } @@ -209,7 +207,7 @@ void ScriptConfig::SettingsToString(char *string, const char *last) const const char *ScriptConfig::GetTextfile(TextfileType type, CompanyID slot) const { - if (slot == INVALID_COMPANY || this->GetInfo() == NULL) return NULL; + if (slot == INVALID_COMPANY || this->GetInfo() == nullptr) return nullptr; return ::GetTextfile(type, (slot == OWNER_DEITY) ? GAME_DIR : AI_DIR, this->GetInfo()->GetMainScript()); } diff --git a/src/script/script_config.hpp b/src/script/script_config.hpp index dfc675473c..adadcd35c9 100644 --- a/src/script/script_config.hpp +++ b/src/script/script_config.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. @@ -61,10 +59,10 @@ protected: public: ScriptConfig() : - name(NULL), + name(nullptr), version(-1), - info(NULL), - config_list(NULL), + info(nullptr), + config_list(nullptr), is_random(false) {} @@ -178,7 +176,7 @@ public: * Search a textfile file next to this script. * @param type The type of the textfile to search for. * @param slot #CompanyID to check status of. - * @return The filename for the textfile, \c NULL otherwise. + * @return The filename for the textfile, \c nullptr otherwise. */ const char *GetTextfile(TextfileType type, CompanyID slot) const; diff --git a/src/script/script_fatalerror.hpp b/src/script/script_fatalerror.hpp index fc7e05402d..5d1a2c1250 100644 --- a/src/script/script_fatalerror.hpp +++ b/src/script/script_fatalerror.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/script/script_info.cpp b/src/script/script_info.cpp index b95c6e366d..53a8fb30ef 100644 --- a/src/script/script_info.cpp +++ b/src/script/script_info.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. @@ -25,9 +23,9 @@ ScriptInfo::~ScriptInfo() for (ScriptConfigItemList::iterator it = this->config_list.begin(); it != this->config_list.end(); it++) { free((*it).name); free((*it).description); - if (it->labels != NULL) { - for (LabelMapping::iterator it2 = (*it).labels->Begin(); it2 != (*it).labels->End(); it2++) { - free(it2->second); + if (it->labels != nullptr) { + for (auto &lbl_map : *(*it).labels) { + free(lbl_map.second); } delete it->labels; } @@ -85,7 +83,7 @@ bool ScriptInfo::CheckMethod(const char *name) const /* Get location information of the scanner */ info->main_script = stredup(info->scanner->GetMainScript()); const char *tar_name = info->scanner->GetTarFile(); - if (tar_name != NULL) info->tar_file = stredup(tar_name); + if (tar_name != nullptr) info->tar_file = stredup(tar_name); /* Cache the data the info file gives us. */ if (!info->engine->CallStringMethodStrdup(*info->SQ_instance, "GetAuthor", &info->author, MAX_GET_OPS)) return SQ_ERROR; @@ -111,7 +109,7 @@ bool ScriptInfo::CheckMethod(const char *name) const bool ScriptInfo::GetSettings() { - return this->engine->CallMethod(*this->SQ_instance, "GetSettings", NULL, MAX_GET_SETTING_OPS); + return this->engine->CallMethod(*this->SQ_instance, "GetSettings", nullptr, MAX_GET_SETTING_OPS); } SQInteger ScriptInfo::AddSetting(HSQUIRRELVM vm) @@ -138,8 +136,8 @@ SQInteger ScriptInfo::AddSetting(HSQUIRRELVM vm) /* Don't allow '=' and ',' in configure setting names, as we need those * 2 chars to nicely store the settings as a string. */ - while ((s = strchr(name, '=')) != NULL) *s = '_'; - while ((s = strchr(name, ',')) != NULL) *s = '_'; + while ((s = strchr(name, '=')) != nullptr) *s = '_'; + while ((s = strchr(name, ',')) != nullptr) *s = '_'; config.name = name; items |= 0x001; } else if (strcmp(key, "description") == 0) { @@ -233,18 +231,18 @@ SQInteger ScriptInfo::AddLabels(HSQUIRRELVM vm) if (SQ_FAILED(sq_getstring(vm, -2, &setting_name))) return SQ_ERROR; ValidateString(setting_name); - ScriptConfigItem *config = NULL; + ScriptConfigItem *config = nullptr; for (ScriptConfigItemList::iterator it = this->config_list.begin(); it != this->config_list.end(); it++) { if (strcmp((*it).name, setting_name) == 0) config = &(*it); } - if (config == NULL) { + if (config == nullptr) { char error[1024]; seprintf(error, lastof(error), "Trying to add labels for non-defined setting '%s'", setting_name); this->engine->ThrowError(error); return SQ_ERROR; } - if (config->labels != NULL) return SQ_ERROR; + if (config->labels != nullptr) return SQ_ERROR; config->labels = new LabelMapping; @@ -289,7 +287,7 @@ const ScriptConfigItem *ScriptInfo::GetConfigItem(const char *name) const for (ScriptConfigItemList::const_iterator it = this->config_list.begin(); it != this->config_list.end(); it++) { if (strcmp((*it).name, name) == 0) return &(*it); } - return NULL; + return nullptr; } int ScriptInfo::GetSettingDefaultValue(const char *name) const diff --git a/src/script/script_info.hpp b/src/script/script_info.hpp index ae341a7d82..5f90e9b23f 100644 --- a/src/script/script_info.hpp +++ b/src/script/script_info.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. @@ -32,19 +30,19 @@ static const int MAX_GET_SETTING_OPS = 100000; class ScriptInfo : public SimpleCountedObject { public: ScriptInfo() : - engine(NULL), - SQ_instance(NULL), - main_script(NULL), - tar_file(NULL), - author(NULL), - name(NULL), - short_name(NULL), - description(NULL), - date(NULL), - instance_name(NULL), + engine(nullptr), + SQ_instance(nullptr), + main_script(nullptr), + tar_file(nullptr), + author(nullptr), + name(nullptr), + short_name(nullptr), + description(nullptr), + date(nullptr), + instance_name(nullptr), version(0), - url(NULL), - scanner(NULL) + url(nullptr), + scanner(nullptr) {} ~ScriptInfo(); diff --git a/src/script/script_info_dummy.cpp b/src/script/script_info_dummy.cpp index 53860386c1..063c028cc3 100644 --- a/src/script/script_info_dummy.cpp +++ b/src/script/script_info_dummy.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. @@ -86,11 +84,11 @@ void Script_CreateDummy(HSQUIRRELVM vm, StringID string, const char *type) char *p = safe_error_message; do { newline = strchr(p, '\n'); - if (newline != NULL) *newline = '\0'; + if (newline != nullptr) *newline = '\0'; dp += seprintf(dp, lastof(dummy_script), " %sLog.Error(\"%s\");\n", type, p); p = newline + 1; - } while (newline != NULL); + } while (newline != nullptr); strecpy(dp, " }\n}\n", lastof(dummy_script)); diff --git a/src/script/script_instance.cpp b/src/script/script_instance.cpp index 5df06ad890..a38a315ffc 100644 --- a/src/script/script_instance.cpp +++ b/src/script/script_instance.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. @@ -34,8 +32,8 @@ ScriptStorage::~ScriptStorage() { /* Free our pointers */ - if (event_data != NULL) ScriptEventController::FreeEventPointer(); - if (log_data != NULL) ScriptLog::FreeLogPointer(); + if (event_data != nullptr) ScriptEventController::FreeEventPointer(); + if (log_data != nullptr) ScriptLog::FreeLogPointer(); } /** @@ -50,17 +48,17 @@ static void PrintFunc(bool error_msg, const SQChar *message) } ScriptInstance::ScriptInstance(const char *APIName) : - engine(NULL), - versionAPI(NULL), - controller(NULL), - storage(NULL), - instance(NULL), + engine(nullptr), + versionAPI(nullptr), + controller(nullptr), + storage(nullptr), + instance(nullptr), is_started(false), is_dead(false), is_save_data_on_stack(false), suspend(0), is_paused(false), - callback(NULL) + callback(nullptr) { this->storage = new ScriptStorage(); this->engine = new Squirrel(APIName); @@ -89,13 +87,17 @@ void ScriptInstance::Initialize(const char *main_script, const char *instance_na } /* Create the main-class */ - this->instance = MallocT(1); + this->instance = new SQObject(); if (!this->engine->CreateClassInstance(instance_name, this->controller, this->instance)) { + /* If CreateClassInstance has returned false instance has not been + * registered with squirrel, so avoid trying to Release it by clearing it now */ + delete this->instance; + this->instance = nullptr; this->Died(); return; } ScriptObject::SetAllowDoCommand(true); - } catch (Script_FatalError e) { + } catch (Script_FatalError &e) { this->is_dead = true; this->engine->ThrowError(e.GetErrorMessage()); this->engine->ResumeError(); @@ -135,11 +137,11 @@ ScriptInstance::~ScriptInstance() { ScriptObject::ActiveInstance active(this); - if (instance != NULL) this->engine->ReleaseObject(this->instance); - if (engine != NULL) delete this->engine; + if (instance != nullptr) this->engine->ReleaseObject(this->instance); + if (engine != nullptr) delete this->engine; delete this->storage; delete this->controller; - free(this->instance); + delete this->instance; } void ScriptInstance::Continue() @@ -153,10 +155,13 @@ void ScriptInstance::Died() DEBUG(script, 0, "The script died unexpectedly."); this->is_dead = true; - if (this->instance != NULL) this->engine->ReleaseObject(this->instance); + this->last_allocated_memory = this->GetAllocatedMemory(); // Update cache + + if (this->instance != nullptr) this->engine->ReleaseObject(this->instance); + delete this->instance; delete this->engine; - this->instance = NULL; - this->engine = NULL; + this->instance = nullptr; + this->engine = nullptr; } void ScriptInstance::GameLoop() @@ -179,14 +184,14 @@ void ScriptInstance::GameLoop() _current_company = ScriptObject::GetCompany(); /* If there is a callback to call, call that first */ - if (this->callback != NULL) { + if (this->callback != nullptr) { if (this->is_save_data_on_stack) { sq_poptop(this->engine->GetVM()); this->is_save_data_on_stack = false; } try { this->callback(this); - } catch (Script_Suspend e) { + } catch (Script_Suspend &e) { this->suspend = e.GetSuspendTime(); this->callback = e.GetSuspendCallback(); @@ -195,7 +200,7 @@ void ScriptInstance::GameLoop() } this->suspend = 0; - this->callback = NULL; + this->callback = nullptr; if (!this->is_started) { try { @@ -216,10 +221,10 @@ void ScriptInstance::GameLoop() ScriptObject::SetAllowDoCommand(true); /* Start the script by calling Start() */ if (!this->engine->CallMethod(*this->instance, "Start", _settings_game.script.script_max_opcode_till_suspend) || !this->engine->IsSuspended()) this->Died(); - } catch (Script_Suspend e) { + } catch (Script_Suspend &e) { this->suspend = e.GetSuspendTime(); this->callback = e.GetSuspendCallback(); - } catch (Script_FatalError e) { + } catch (Script_FatalError &e) { this->is_dead = true; this->engine->ThrowError(e.GetErrorMessage()); this->engine->ResumeError(); @@ -237,10 +242,10 @@ void ScriptInstance::GameLoop() /* Continue the VM */ try { if (!this->engine->Resume(_settings_game.script.script_max_opcode_till_suspend)) this->Died(); - } catch (Script_Suspend e) { + } catch (Script_Suspend &e) { this->suspend = e.GetSuspendTime(); this->callback = e.GetSuspendCallback(); - } catch (Script_FatalError e) { + } catch (Script_FatalError &e) { this->is_dead = true; this->engine->ThrowError(e.GetErrorMessage()); this->engine->ResumeError(); @@ -351,7 +356,7 @@ static const SaveLoad _script_byte[] = { case OT_INTEGER: { if (!test) { _script_sl_byte = SQSL_INT; - SlObject(NULL, _script_byte); + SlObject(nullptr, _script_byte); } SQInteger res; sq_getinteger(vm, index, &res); @@ -365,7 +370,7 @@ static const SaveLoad _script_byte[] = { case OT_STRING: { if (!test) { _script_sl_byte = SQSL_STRING; - SlObject(NULL, _script_byte); + SlObject(nullptr, _script_byte); } const SQChar *buf; sq_getstring(vm, index, &buf); @@ -376,7 +381,7 @@ static const SaveLoad _script_byte[] = { } if (!test) { _script_sl_byte = (byte)len; - SlObject(NULL, _script_byte); + SlObject(nullptr, _script_byte); SlArray(const_cast(buf), len, SLE_CHAR); } return true; @@ -385,7 +390,7 @@ static const SaveLoad _script_byte[] = { case OT_ARRAY: { if (!test) { _script_sl_byte = SQSL_ARRAY; - SlObject(NULL, _script_byte); + SlObject(nullptr, _script_byte); } sq_pushnull(vm); while (SQ_SUCCEEDED(sq_next(vm, index - 1))) { @@ -400,7 +405,7 @@ static const SaveLoad _script_byte[] = { sq_pop(vm, 1); if (!test) { _script_sl_byte = SQSL_ARRAY_TABLE_END; - SlObject(NULL, _script_byte); + SlObject(nullptr, _script_byte); } return true; } @@ -408,7 +413,7 @@ static const SaveLoad _script_byte[] = { case OT_TABLE: { if (!test) { _script_sl_byte = SQSL_TABLE; - SlObject(NULL, _script_byte); + SlObject(nullptr, _script_byte); } sq_pushnull(vm); while (SQ_SUCCEEDED(sq_next(vm, index - 1))) { @@ -423,7 +428,7 @@ static const SaveLoad _script_byte[] = { sq_pop(vm, 1); if (!test) { _script_sl_byte = SQSL_ARRAY_TABLE_END; - SlObject(NULL, _script_byte); + SlObject(nullptr, _script_byte); } return true; } @@ -431,13 +436,13 @@ static const SaveLoad _script_byte[] = { case OT_BOOL: { if (!test) { _script_sl_byte = SQSL_BOOL; - SlObject(NULL, _script_byte); + SlObject(nullptr, _script_byte); } SQBool res; sq_getbool(vm, index, &res); if (!test) { _script_sl_byte = res ? 1 : 0; - SlObject(NULL, _script_byte); + SlObject(nullptr, _script_byte); } return true; } @@ -445,7 +450,7 @@ static const SaveLoad _script_byte[] = { case OT_NULL: { if (!test) { _script_sl_byte = SQSL_NULL; - SlObject(NULL, _script_byte); + SlObject(nullptr, _script_byte); } return true; } @@ -459,7 +464,7 @@ static const SaveLoad _script_byte[] = { /* static */ void ScriptInstance::SaveEmpty() { _script_sl_byte = 0; - SlObject(NULL, _script_byte); + SlObject(nullptr, _script_byte); } void ScriptInstance::Save() @@ -467,7 +472,7 @@ void ScriptInstance::Save() ScriptObject::ActiveInstance active(this); /* Don't save data if the script didn't start yet or if it crashed. */ - if (this->engine == NULL || this->engine->HasScriptCrashed()) { + if (this->engine == nullptr || this->engine->HasScriptCrashed()) { SaveEmpty(); return; } @@ -475,7 +480,7 @@ void ScriptInstance::Save() HSQUIRRELVM vm = this->engine->GetVM(); if (this->is_save_data_on_stack) { _script_sl_byte = 1; - SlObject(NULL, _script_byte); + SlObject(nullptr, _script_byte); /* Save the data that was just loaded. */ SaveObject(vm, -1, SQUIRREL_MAX_DEPTH, false); } else if (!this->is_started) { @@ -494,7 +499,7 @@ void ScriptInstance::Save() this->engine->CrashOccurred(); return; } - } catch (Script_FatalError e) { + } catch (Script_FatalError &e) { /* If we don't mark the script as dead here cleaning up the squirrel * stack could throw Script_FatalError again. */ this->is_dead = true; @@ -518,7 +523,7 @@ void ScriptInstance::Save() sq_pushobject(vm, savedata); if (SaveObject(vm, -1, SQUIRREL_MAX_DEPTH, true)) { _script_sl_byte = 1; - SlObject(NULL, _script_byte); + SlObject(nullptr, _script_byte); SaveObject(vm, -1, SQUIRREL_MAX_DEPTH, false); this->is_save_data_on_stack = true; } else { @@ -528,7 +533,7 @@ void ScriptInstance::Save() } else { ScriptLog::Warning("Save function is not implemented"); _script_sl_byte = 0; - SlObject(NULL, _script_byte); + SlObject(nullptr, _script_byte); } } @@ -553,50 +558,50 @@ bool ScriptInstance::IsPaused() /* static */ bool ScriptInstance::LoadObjects(HSQUIRRELVM vm) { - SlObject(NULL, _script_byte); + SlObject(nullptr, _script_byte); switch (_script_sl_byte) { case SQSL_INT: { int value; SlArray(&value, 1, SLE_INT32); - if (vm != NULL) sq_pushinteger(vm, (SQInteger)value); + if (vm != nullptr) sq_pushinteger(vm, (SQInteger)value); return true; } case SQSL_STRING: { - SlObject(NULL, _script_byte); + SlObject(nullptr, _script_byte); static char buf[256]; SlArray(buf, _script_sl_byte, SLE_CHAR); - if (vm != NULL) sq_pushstring(vm, buf, -1); + if (vm != nullptr) sq_pushstring(vm, buf, -1); return true; } case SQSL_ARRAY: { - if (vm != NULL) sq_newarray(vm, 0); + if (vm != nullptr) sq_newarray(vm, 0); while (LoadObjects(vm)) { - if (vm != NULL) sq_arrayappend(vm, -2); + if (vm != nullptr) sq_arrayappend(vm, -2); /* The value is popped from the stack by squirrel. */ } return true; } case SQSL_TABLE: { - if (vm != NULL) sq_newtable(vm); + if (vm != nullptr) sq_newtable(vm); while (LoadObjects(vm)) { LoadObjects(vm); - if (vm != NULL) sq_rawset(vm, -3); + if (vm != nullptr) sq_rawset(vm, -3); /* The key (-2) and value (-1) are popped from the stack by squirrel. */ } return true; } case SQSL_BOOL: { - SlObject(NULL, _script_byte); - if (vm != NULL) sq_pushbool(vm, (SQBool)(_script_sl_byte != 0)); + SlObject(nullptr, _script_byte); + if (vm != nullptr) sq_pushbool(vm, (SQBool)(_script_sl_byte != 0)); return true; } case SQSL_NULL: { - if (vm != NULL) sq_pushnull(vm); + if (vm != nullptr) sq_pushnull(vm); return true; } @@ -610,24 +615,24 @@ bool ScriptInstance::IsPaused() /* static */ void ScriptInstance::LoadEmpty() { - SlObject(NULL, _script_byte); + SlObject(nullptr, _script_byte); /* Check if there was anything saved at all. */ if (_script_sl_byte == 0) return; - LoadObjects(NULL); + LoadObjects(nullptr); } void ScriptInstance::Load(int version) { ScriptObject::ActiveInstance active(this); - if (this->engine == NULL || version == -1) { + if (this->engine == nullptr || version == -1) { LoadEmpty(); return; } HSQUIRRELVM vm = this->engine->GetVM(); - SlObject(NULL, _script_byte); + SlObject(nullptr, _script_byte); /* Check if there was anything saved at all. */ if (_script_sl_byte == 0) return; @@ -678,10 +683,15 @@ SQInteger ScriptInstance::GetOpsTillSuspend() return this->engine->GetOpsTillSuspend(); } -void ScriptInstance::DoCommandCallback(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) +bool ScriptInstance::DoCommandCallback(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) { ScriptObject::ActiveInstance active(this); + if (!ScriptObject::CheckLastCommand(tile, p1, p2, cmd)) { + DEBUG(script, 1, "DoCommandCallback terminating a script, last command does not match expected command"); + return false; + } + ScriptObject::SetLastCommandRes(result.Succeeded()); if (result.Failed()) { @@ -690,6 +700,10 @@ void ScriptInstance::DoCommandCallback(const CommandCost &result, TileIndex tile ScriptObject::IncreaseDoCommandCosts(result.GetCost()); ScriptObject::SetLastCost(result.GetCost()); } + + ScriptObject::SetLastCommand(INVALID_TILE, 0, 0, CMD_END); + + return true; } void ScriptInstance::InsertEvent(class ScriptEvent *event) @@ -698,3 +712,9 @@ void ScriptInstance::InsertEvent(class ScriptEvent *event) ScriptEventController::InsertEvent(event); } + +size_t ScriptInstance::GetAllocatedMemory() const +{ + if (this->engine == nullptr) return this->last_allocated_memory; + return this->engine->GetAllocatedMemory(); +} diff --git a/src/script/script_instance.hpp b/src/script/script_instance.hpp index e6f3c64b22..e5024c80bc 100644 --- a/src/script/script_instance.hpp +++ b/src/script/script_instance.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. @@ -52,7 +50,7 @@ public: * Find a library. * @param library The library name to find. * @param version The version the library should have. - * @return The library if found, NULL otherwise. + * @return The library if found, nullptr otherwise. */ virtual class ScriptInfo *FindLibrary(const char *library, int version) = 0; @@ -182,8 +180,10 @@ public: * @param tile The tile on which the command was executed. * @param p1 p1 as given to DoCommandPInternal. * @param p2 p2 as given to DoCommandPInternal. + * @param cmd cmd as given to DoCommandPInternal. + * @return true if we handled result. */ - void DoCommandCallback(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2); + bool DoCommandCallback(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd); /** * Insert an event for this script. @@ -198,6 +198,8 @@ public: */ bool IsSleeping() { return this->suspend != 0; } + size_t GetAllocatedMemory() const; + protected: class Squirrel *engine; ///< A wrapper around the squirrel vm. const char *versionAPI; ///< Current API used by this script. @@ -241,6 +243,7 @@ private: int suspend; ///< The amount of ticks to suspend this script before it's allowed to continue. bool is_paused; ///< Is the script paused? (a paused script will not be executed until unpaused) Script_SuspendCallbackProc *callback; ///< Callback that should be called in the next tick the script runs. + size_t last_allocated_memory; ///< Last known allocated memory value (for display for crashed scripts) /** * Call the script Load function if it exists and data was loaded diff --git a/src/script/script_scanner.cpp b/src/script/script_scanner.cpp index fe6d41cf92..e33f233f7b 100644 --- a/src/script/script_scanner.cpp +++ b/src/script/script_scanner.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. @@ -17,12 +15,11 @@ #include "../script/squirrel.hpp" #include "script_scanner.hpp" #include "script_info.hpp" +#include "script_fatalerror.hpp" -#if defined(ENABLE_NETWORK) #include "../network/network_content.h" #include "../3rdparty/md5/md5.h" #include "../tar_type.h" -#endif /* ENABLE_NETWORK */ #include "../safeguards.h" @@ -30,19 +27,19 @@ bool ScriptScanner::AddFile(const char *filename, size_t basepath_length, const { free(this->main_script); this->main_script = stredup(filename); - if (this->main_script == NULL) return false; + if (this->main_script == nullptr) return false; free(this->tar_file); - if (tar_filename != NULL) { + if (tar_filename != nullptr) { this->tar_file = stredup(tar_filename); - if (this->tar_file == NULL) return false; + if (this->tar_file == nullptr) return false; } else { - this->tar_file = NULL; + this->tar_file = nullptr; } const char *end = this->main_script + strlen(this->main_script) + 1; char *p = strrchr(this->main_script, PATHSEPCHAR); - if (p == NULL) { + if (p == nullptr) { p = this->main_script; } else { /* Skip over the path separator character. We don't need that. */ @@ -54,15 +51,19 @@ bool ScriptScanner::AddFile(const char *filename, size_t basepath_length, const if (!FioCheckFileExists(filename, this->subdir) || !FioCheckFileExists(this->main_script, this->subdir)) return false; this->ResetEngine(); - this->engine->LoadScript(filename); - + try { + this->engine->LoadScript(filename); + } catch (Script_FatalError &e) { + DEBUG(script, 0, "Fatal error '%s' when trying to load the script '%s'.", e.GetErrorMessage(), filename); + return false; + } return true; } ScriptScanner::ScriptScanner() : - engine(NULL), - main_script(NULL), - tar_file(NULL) + engine(nullptr), + main_script(nullptr), + tar_file(nullptr) { } @@ -180,8 +181,6 @@ char *ScriptScanner::GetConsoleList(char *p, const char *last, bool newest_only) return p; } -#if defined(ENABLE_NETWORK) - /** Helper for creating a MD5sum of all files within of a script. */ struct ScriptFileChecksumCreator : FileScanner { byte md5sum[16]; ///< The final md5sum. @@ -207,7 +206,7 @@ struct ScriptFileChecksumCreator : FileScanner { /* Open the file ... */ FILE *f = FioFOpenFile(filename, "rb", this->dir, &size); - if (f == NULL) return false; + if (f == nullptr) return false; /* ... calculate md5sum... */ while ((len = fread(buffer, 1, (size > sizeof(buffer)) ? sizeof(buffer) : size, f)) != 0 && size != 0) { @@ -245,7 +244,7 @@ static bool IsSameScript(const ContentInfo *ci, bool md5sum, ScriptInfo *info, S ScriptFileChecksumCreator checksum(dir); const char *tar_filename = info->GetTarFile(); TarList::iterator iter; - if (tar_filename != NULL && (iter = _tar_list[dir].find(tar_filename)) != _tar_list[dir].end()) { + if (tar_filename != nullptr && (iter = _tar_list[dir].find(tar_filename)) != _tar_list[dir].end()) { /* The main script is in a tar file, so find all files that * are in the same tar and add them to the MD5 checksumming. */ TarFileList::iterator tar; @@ -255,7 +254,7 @@ static bool IsSameScript(const ContentInfo *ci, bool md5sum, ScriptInfo *info, S /* Check the extension. */ const char *ext = strrchr(tar->first.c_str(), '.'); - if (ext == NULL || strcasecmp(ext, ".nut") != 0) continue; + if (ext == nullptr || strcasecmp(ext, ".nut") != 0) continue; checksum.AddFile(tar->first.c_str(), 0, tar_filename); } @@ -285,7 +284,5 @@ const char *ScriptScanner::FindMainScript(const ContentInfo *ci, bool md5sum) for (ScriptInfoList::iterator it = this->info_list.begin(); it != this->info_list.end(); it++) { if (IsSameScript(ci, md5sum, (*it).second, this->GetDirectory())) return (*it).second->GetMainScript(); } - return NULL; + return nullptr; } - -#endif /* ENABLE_NETWORK */ diff --git a/src/script/script_scanner.hpp b/src/script/script_scanner.hpp index 50dad02ad2..eb65a197e4 100644 --- a/src/script/script_scanner.hpp +++ b/src/script/script_scanner.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. @@ -73,11 +71,11 @@ public: * Find a script of a #ContentInfo * @param ci The information to compare to. * @param md5sum Whether to check the MD5 checksum. - * @return A filename of a file of the content, else \c NULL. + * @return A filename of a file of the content, else \c nullptr. */ const char *FindMainScript(const ContentInfo *ci, bool md5sum); - /* virtual */ bool AddFile(const char *filename, size_t basepath_length, const char *tar_filename); + bool AddFile(const char *filename, size_t basepath_length, const char *tar_filename) override; /** * Rescan the script dir. diff --git a/src/script/script_storage.hpp b/src/script/script_storage.hpp index 8fe1e17323..2f5520cffa 100644 --- a/src/script/script_storage.hpp +++ b/src/script/script_storage.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. @@ -46,6 +44,11 @@ private: 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. + uint32 last_p1; ///< The last p1 passed to a command. + uint32 last_p2; ///< The last p2 passed to a command. + uint32 last_cmd; ///< The last cmd passed to a command. + VehicleID new_vehicle_id; ///< The ID of the new Vehicle. SignID new_sign_id; ///< The ID of the new Sign. GroupID new_group_id; ///< The ID of the new Group. @@ -63,8 +66,8 @@ private: public: ScriptStorage() : - mode (NULL), - mode_instance (NULL), + mode (nullptr), + mode_instance (nullptr), root_company (INVALID_OWNER), company (INVALID_OWNER), delay (1), @@ -73,6 +76,10 @@ public: last_cost (0), last_error (STR_NULL), last_command_res (true), + last_tile (INVALID_TILE), + last_p1 (0), + last_p2 (0), + last_cmd (CMD_END), new_vehicle_id (0), new_sign_id (0), new_group_id (0), @@ -82,8 +89,8 @@ public: /* calback_value (can't be set) */ road_type (INVALID_ROADTYPE), rail_type (INVALID_RAILTYPE), - event_data (NULL), - log_data (NULL) + event_data (nullptr), + log_data (nullptr) { } ~ScriptStorage(); diff --git a/src/script/script_suspend.hpp b/src/script/script_suspend.hpp index 9f8a1513c9..c8a4501f30 100644 --- a/src/script/script_suspend.hpp +++ b/src/script/script_suspend.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/script/squirrel.cpp b/src/script/squirrel.cpp index 23163f6b34..2bd2c9c744 100644 --- a/src/script/squirrel.cpp +++ b/src/script/squirrel.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. @@ -10,17 +8,128 @@ /** @file squirrel.cpp the implementation of the Squirrel class. It handles all Squirrel-stuff and gives a nice API back to work with. */ #include +#include #include "../stdafx.h" #include "../debug.h" #include "squirrel_std.hpp" #include "../fileio_func.h" #include "../string_func.h" +#include "script_fatalerror.hpp" +#include "../settings_type.h" #include #include <../squirrel/sqpcheader.h> #include <../squirrel/sqvm.h> +#include "../core/alloc_func.hpp" #include "../safeguards.h" +/* + * If changing the call paths into the scripting engine, define this symbol to enable full debugging of allocations. + * This lets you track whether the allocator context is being switched correctly in all call paths. +#define SCRIPT_DEBUG_ALLOCATIONS +*/ + +struct ScriptAllocator { + size_t allocated_size; ///< Sum of allocated data size + size_t allocation_limit; ///< Maximum this allocator may use before allocations fail + + static const size_t SAFE_LIMIT = 0x8000000; ///< 128 MiB, a safe choice for almost any situation + +#ifdef SCRIPT_DEBUG_ALLOCATIONS + std::map allocations; +#endif + + void CheckLimit() const + { + if (this->allocated_size > this->allocation_limit) throw Script_FatalError("Maximum memory allocation exceeded"); + } + + void *Malloc(SQUnsignedInteger size) + { + void *p = MallocT(size); + this->allocated_size += size; + +#ifdef SCRIPT_DEBUG_ALLOCATIONS + assert(p != nullptr); + assert(this->allocations.find(p) == this->allocations.end()); + this->allocations[p] = size; +#endif + + return p; + } + + void *Realloc(void *p, SQUnsignedInteger oldsize, SQUnsignedInteger size) + { + if (p == nullptr) { + return this->Malloc(size); + } + if (size == 0) { + this->Free(p, oldsize); + return nullptr; + } + +#ifdef SCRIPT_DEBUG_ALLOCATIONS + assert(this->allocations[p] == oldsize); + this->allocations.erase(p); +#endif + + void *new_p = ReallocT(static_cast(p), size); + + this->allocated_size -= oldsize; + this->allocated_size += size; + +#ifdef SCRIPT_DEBUG_ALLOCATIONS + assert(new_p != nullptr); + assert(this->allocations.find(p) == this->allocations.end()); + this->allocations[new_p] = size; +#endif + + return new_p; + } + + void Free(void *p, SQUnsignedInteger size) + { + if (p == nullptr) return; + free(p); + this->allocated_size -= size; + +#ifdef SCRIPT_DEBUG_ALLOCATIONS + assert(this->allocations.at(p) == size); + this->allocations.erase(p); +#endif + } + + ScriptAllocator() + { + this->allocated_size = 0; + this->allocation_limit = static_cast(_settings_game.script.script_max_memory_megabytes) << 20; + if (this->allocation_limit == 0) this->allocation_limit = SAFE_LIMIT; // in case the setting is somehow zero + } + + ~ScriptAllocator() + { +#ifdef SCRIPT_DEBUG_ALLOCATIONS + assert(this->allocations.size() == 0); +#endif + } +}; + +ScriptAllocator *_squirrel_allocator = nullptr; + +/* See 3rdparty/squirrel/squirrel/sqmem.cpp for the default allocator implementation, which this overrides */ +#ifndef SQUIRREL_DEFAULT_ALLOCATOR +void *sq_vm_malloc(SQUnsignedInteger size) { return _squirrel_allocator->Malloc(size); } +void *sq_vm_realloc(void *p, SQUnsignedInteger oldsize, SQUnsignedInteger size) { return _squirrel_allocator->Realloc(p, oldsize, size); } +void sq_vm_free(void *p, SQUnsignedInteger size) { _squirrel_allocator->Free(p, size); } +#endif + +size_t Squirrel::GetAllocatedMemory() const noexcept +{ + assert(this->allocator != nullptr); + return this->allocator->allocated_size; +} + + void Squirrel::CompileError(HSQUIRRELVM vm, const SQChar *desc, const SQChar *source, SQInteger line, SQInteger column) { SQChar buf[1024]; @@ -31,7 +140,7 @@ void Squirrel::CompileError(HSQUIRRELVM vm, const SQChar *desc, const SQChar *so Squirrel *engine = (Squirrel *)sq_getforeignptr(vm); engine->crashed = true; SQPrintFunc *func = engine->print_func; - if (func == NULL) { + if (func == nullptr) { DEBUG(misc, 0, "[Squirrel] Compile error: %s", buf); } else { (*func)(true, buf); @@ -49,7 +158,7 @@ void Squirrel::ErrorPrintFunc(HSQUIRRELVM vm, const SQChar *s, ...) /* Check if we have a custom print function */ SQPrintFunc *func = ((Squirrel *)sq_getforeignptr(vm))->print_func; - if (func == NULL) { + if (func == nullptr) { fprintf(stderr, "%s", buf); } else { (*func)(true, buf); @@ -67,7 +176,7 @@ void Squirrel::RunError(HSQUIRRELVM vm, const SQChar *error) seprintf(buf, lastof(buf), "Your script made an error: %s\n", error); Squirrel *engine = (Squirrel *)sq_getforeignptr(vm); SQPrintFunc *func = engine->print_func; - if (func == NULL) { + if (func == nullptr) { fprintf(stderr, "%s", buf); } else { (*func)(true, buf); @@ -106,7 +215,7 @@ void Squirrel::PrintFunc(HSQUIRRELVM vm, const SQChar *s, ...) /* Check if we have a custom print function */ SQPrintFunc *func = ((Squirrel *)sq_getforeignptr(vm))->print_func; - if (func == NULL) { + if (func == nullptr) { printf("%s", buf); } else { (*func)(false, buf); @@ -115,6 +224,8 @@ void Squirrel::PrintFunc(HSQUIRRELVM vm, const SQChar *s, ...) void Squirrel::AddMethod(const char *method_name, SQFUNCTION proc, uint nparam, const char *params, void *userdata, int size) { + ScriptAllocatorScope alloc_scope(this); + sq_pushstring(this->vm, method_name, -1); if (size != 0) { @@ -130,6 +241,8 @@ void Squirrel::AddMethod(const char *method_name, SQFUNCTION proc, uint nparam, void Squirrel::AddConst(const char *var_name, int value) { + ScriptAllocatorScope alloc_scope(this); + sq_pushstring(this->vm, var_name, -1); sq_pushinteger(this->vm, value); sq_newslot(this->vm, -3, SQTrue); @@ -137,6 +250,8 @@ void Squirrel::AddConst(const char *var_name, int value) void Squirrel::AddConst(const char *var_name, bool value) { + ScriptAllocatorScope alloc_scope(this); + sq_pushstring(this->vm, var_name, -1); sq_pushbool(this->vm, value); sq_newslot(this->vm, -3, SQTrue); @@ -144,6 +259,8 @@ void Squirrel::AddConst(const char *var_name, bool value) void Squirrel::AddClassBegin(const char *class_name) { + ScriptAllocatorScope alloc_scope(this); + sq_pushroottable(this->vm); sq_pushstring(this->vm, class_name, -1); sq_newclass(this->vm, SQFalse); @@ -151,6 +268,8 @@ void Squirrel::AddClassBegin(const char *class_name) void Squirrel::AddClassBegin(const char *class_name, const char *parent_class) { + ScriptAllocatorScope alloc_scope(this); + sq_pushroottable(this->vm); sq_pushstring(this->vm, class_name, -1); sq_pushstring(this->vm, parent_class, -1); @@ -164,6 +283,8 @@ void Squirrel::AddClassBegin(const char *class_name, const char *parent_class) void Squirrel::AddClassEnd() { + ScriptAllocatorScope alloc_scope(this); + sq_newslot(vm, -3, SQFalse); sq_pop(vm, 1); } @@ -171,6 +292,8 @@ void Squirrel::AddClassEnd() bool Squirrel::MethodExists(HSQOBJECT instance, const char *method_name) { assert(!this->crashed); + ScriptAllocatorScope alloc_scope(this); + int top = sq_gettop(this->vm); /* Go to the instance-root */ sq_pushobject(this->vm, instance); @@ -187,6 +310,8 @@ bool Squirrel::MethodExists(HSQOBJECT instance, const char *method_name) bool Squirrel::Resume(int suspend) { assert(!this->crashed); + ScriptAllocatorScope alloc_scope(this); + /* Did we use more operations than we should have in the * previous tick? If so, subtract that from the current run. */ if (this->overdrawn_ops > 0 && suspend > 0) { @@ -200,23 +325,29 @@ bool Squirrel::Resume(int suspend) this->crashed = !sq_resumecatch(this->vm, suspend); this->overdrawn_ops = -this->vm->_ops_till_suspend; + this->allocator->CheckLimit(); return this->vm->_suspended != 0; } void Squirrel::ResumeError() { assert(!this->crashed); + ScriptAllocatorScope alloc_scope(this); sq_resumeerror(this->vm); } void Squirrel::CollectGarbage() { + ScriptAllocatorScope alloc_scope(this); sq_collectgarbage(this->vm); } bool Squirrel::CallMethod(HSQOBJECT instance, const char *method_name, HSQOBJECT *ret, int suspend) { assert(!this->crashed); + ScriptAllocatorScope alloc_scope(this); + this->allocator->CheckLimit(); + /* Store the stack-location for the return value. We need to * restore this after saving or the stack will be corrupted * if we're in the middle of a DoCommand. */ @@ -234,8 +365,8 @@ bool Squirrel::CallMethod(HSQOBJECT instance, const char *method_name, HSQOBJECT } /* Call the method */ sq_pushobject(this->vm, instance); - if (SQ_FAILED(sq_call(this->vm, 1, ret == NULL ? SQFalse : SQTrue, SQTrue, suspend))) return false; - if (ret != NULL) sq_getstackobj(vm, -1, ret); + if (SQ_FAILED(sq_call(this->vm, 1, ret == nullptr ? SQFalse : SQTrue, SQTrue, suspend))) return false; + if (ret != nullptr) sq_getstackobj(vm, -1, ret); /* Reset the top, but don't do so for the script main function, as we need * a correct stack when resuming. */ if (suspend == -1 || !this->IsSuspended()) sq_settop(this->vm, top); @@ -305,7 +436,7 @@ bool Squirrel::CallBoolMethod(HSQOBJECT instance, const char *method_name, bool return false; } - if (instance != NULL) { + if (instance != nullptr) { /* Find our instance */ sq_getstackobj(vm, -1, instance); /* Add a reference to it, so it survives for ever */ @@ -316,28 +447,31 @@ bool Squirrel::CallBoolMethod(HSQOBJECT instance, const char *method_name, bool /* Store it in the class */ sq_setinstanceup(vm, -1, real_instance); - if (release_hook != NULL) sq_setreleasehook(vm, -1, release_hook); + if (release_hook != nullptr) sq_setreleasehook(vm, -1, release_hook); - if (instance != NULL) sq_settop(vm, oldtop); + if (instance != nullptr) sq_settop(vm, oldtop); return true; } bool Squirrel::CreateClassInstance(const char *class_name, void *real_instance, HSQOBJECT *instance) { - return Squirrel::CreateClassInstanceVM(this->vm, class_name, real_instance, instance, NULL); + ScriptAllocatorScope alloc_scope(this); + return Squirrel::CreateClassInstanceVM(this->vm, class_name, real_instance, instance, nullptr); } Squirrel::Squirrel(const char *APIName) : - APIName(APIName) + APIName(APIName), allocator(new ScriptAllocator()) { this->Initialize(); } void Squirrel::Initialize() { - this->global_pointer = NULL; - this->print_func = NULL; + ScriptAllocatorScope alloc_scope(this); + + this->global_pointer = nullptr; + this->print_func = nullptr; this->crashed = false; this->overdrawn_ops = 0; this->vm = sq_open(1024); @@ -432,19 +566,21 @@ static SQInteger _io_file_read(SQUserPointer file, SQUserPointer buf, SQInteger SQRESULT Squirrel::LoadFile(HSQUIRRELVM vm, const char *filename, SQBool printerror) { + ScriptAllocatorScope alloc_scope(this); + FILE *file; size_t size; if (strncmp(this->GetAPIName(), "AI", 2) == 0) { file = FioFOpenFile(filename, "rb", AI_DIR, &size); - if (file == NULL) file = FioFOpenFile(filename, "rb", AI_LIBRARY_DIR, &size); + if (file == nullptr) file = FioFOpenFile(filename, "rb", AI_LIBRARY_DIR, &size); } else if (strncmp(this->GetAPIName(), "GS", 2) == 0) { file = FioFOpenFile(filename, "rb", GAME_DIR, &size); - if (file == NULL) file = FioFOpenFile(filename, "rb", GAME_LIBRARY_DIR, &size); + if (file == nullptr) file = FioFOpenFile(filename, "rb", GAME_LIBRARY_DIR, &size); } else { NOT_REACHED(); } - if (file == NULL) { + if (file == nullptr) { return sq_throwerror(vm, "cannot open the file"); } unsigned short bom = 0; @@ -517,6 +653,8 @@ SQRESULT Squirrel::LoadFile(HSQUIRRELVM vm, const char *filename, SQBool printer bool Squirrel::LoadScript(HSQUIRRELVM vm, const char *script, bool in_root) { + ScriptAllocatorScope alloc_scope(this); + /* Make sure we are always in the root-table */ if (in_root) sq_pushroottable(vm); @@ -549,6 +687,8 @@ Squirrel::~Squirrel() void Squirrel::Uninitialize() { + ScriptAllocatorScope alloc_scope(this); + /* Clean up the stuff */ sq_pop(this->vm, 1); sq_close(this->vm); @@ -562,6 +702,8 @@ void Squirrel::Reset() void Squirrel::InsertResult(bool result) { + ScriptAllocatorScope alloc_scope(this); + sq_pushbool(this->vm, result); if (this->IsSuspended()) { // Called before resuming a suspended script? vm->GetAt(vm->_stackbase + vm->_suspended_target) = vm->GetUp(-1); @@ -571,6 +713,8 @@ void Squirrel::InsertResult(bool result) void Squirrel::InsertResult(int result) { + ScriptAllocatorScope alloc_scope(this); + sq_pushinteger(this->vm, result); if (this->IsSuspended()) { // Called before resuming a suspended script? vm->GetAt(vm->_stackbase + vm->_suspended_target) = vm->GetUp(-1); @@ -600,6 +744,7 @@ void Squirrel::CrashOccurred() bool Squirrel::CanSuspend() { + ScriptAllocatorScope alloc_scope(this); return sq_can_suspend(this->vm); } diff --git a/src/script/squirrel.hpp b/src/script/squirrel.hpp index 9e1d113a80..cfe54b36ec 100644 --- a/src/script/squirrel.hpp +++ b/src/script/squirrel.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,16 +18,21 @@ enum ScriptType { ST_GS, ///< The script is for Game scripts. }; +struct ScriptAllocator; + class Squirrel { + friend class ScriptAllocatorScope; + private: typedef void (SQPrintFunc)(bool error_msg, const SQChar *message); HSQUIRRELVM vm; ///< The VirtualMachine instance for squirrel void *global_pointer; ///< Can be set by who ever initializes Squirrel - SQPrintFunc *print_func; ///< Points to either NULL, or a custom print handler + SQPrintFunc *print_func; ///< Points to either nullptr, or a custom print handler bool crashed; ///< True if the squirrel script made an error. int overdrawn_ops; ///< The amount of operations we have overdrawn. const char *APIName; ///< Name of the API used for this squirrel. + std::unique_ptr allocator; ///< Allocator object used by this script. /** * The internal RunError handler. It looks up the real error and calls RunError with it. @@ -93,7 +96,7 @@ public: * Adds a function to the stack. Depending on the current state this means * either a method or a global function. */ - void AddMethod(const char *method_name, SQFUNCTION proc, uint nparam = 0, const char *params = NULL, void *userdata = NULL, int size = 0); + void AddMethod(const char *method_name, SQFUNCTION proc, uint nparam = 0, const char *params = nullptr, void *userdata = nullptr, int size = 0); /** * Adds a const to the stack. Depending on the current state this means @@ -155,7 +158,7 @@ public: * @return False if the script crashed or returned a wrong type. */ bool CallMethod(HSQOBJECT instance, const char *method_name, HSQOBJECT *ret, int suspend); - bool CallMethod(HSQOBJECT instance, const char *method_name, int suspend) { return this->CallMethod(instance, method_name, NULL, suspend); } + bool CallMethod(HSQOBJECT instance, const char *method_name, int suspend) { return this->CallMethod(instance, method_name, nullptr, suspend); } bool CallStringMethodStrdup(HSQOBJECT instance, const char *method_name, const char **res, int suspend); bool CallIntegerMethod(HSQOBJECT instance, const char *method_name, int *res, int suspend); bool CallBoolMethod(HSQOBJECT instance, const char *method_name, bool *res, int suspend); @@ -272,6 +275,31 @@ public: * Completely reset the engine; start from scratch. */ void Reset(); + + /** + * Get number of bytes allocated by this VM. + */ + size_t GetAllocatedMemory() const noexcept; +}; + + +extern ScriptAllocator *_squirrel_allocator; + +class ScriptAllocatorScope { + ScriptAllocator *old_allocator; + +public: + ScriptAllocatorScope(const Squirrel *engine) + { + this->old_allocator = _squirrel_allocator; + /* This may get called with a nullptr engine, in case of a crashed script */ + _squirrel_allocator = engine != nullptr ? engine->allocator.get() : nullptr; + } + + ~ScriptAllocatorScope() + { + _squirrel_allocator = this->old_allocator; + } }; #endif /* SQUIRREL_HPP */ diff --git a/src/script/squirrel_class.hpp b/src/script/squirrel_class.hpp index ce63e3b034..b600839d4d 100644 --- a/src/script/squirrel_class.hpp +++ b/src/script/squirrel_class.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. @@ -35,7 +33,7 @@ public: void DefSQMethod(Squirrel *engine, Func function_proc, const char *function_name) { using namespace SQConvert; - engine->AddMethod(function_name, DefSQNonStaticCallback, 0, NULL, &function_proc, sizeof(function_proc)); + engine->AddMethod(function_name, DefSQNonStaticCallback, 0, nullptr, &function_proc, sizeof(function_proc)); } /** @@ -45,7 +43,7 @@ public: void DefSQAdvancedMethod(Squirrel *engine, Func function_proc, const char *function_name) { using namespace SQConvert; - engine->AddMethod(function_name, DefSQAdvancedNonStaticCallback, 0, NULL, &function_proc, sizeof(function_proc)); + engine->AddMethod(function_name, DefSQAdvancedNonStaticCallback, 0, nullptr, &function_proc, sizeof(function_proc)); } /** @@ -68,7 +66,7 @@ public: void DefSQStaticMethod(Squirrel *engine, Func function_proc, const char *function_name) { using namespace SQConvert; - engine->AddMethod(function_name, DefSQStaticCallback, 0, NULL, &function_proc, sizeof(function_proc)); + engine->AddMethod(function_name, DefSQStaticCallback, 0, nullptr, &function_proc, sizeof(function_proc)); } /** @@ -78,7 +76,7 @@ public: void DefSQAdvancedStaticMethod(Squirrel *engine, Func function_proc, const char *function_name) { using namespace SQConvert; - engine->AddMethod(function_name, DefSQAdvancedStaticCallback, 0, NULL, &function_proc, sizeof(function_proc)); + engine->AddMethod(function_name, DefSQAdvancedStaticCallback, 0, nullptr, &function_proc, sizeof(function_proc)); } /** @@ -120,7 +118,7 @@ public: void AddSQAdvancedConstructor(Squirrel *engine) { using namespace SQConvert; - engine->AddMethod("constructor", DefSQAdvancedConstructorCallback, 0, NULL); + engine->AddMethod("constructor", DefSQAdvancedConstructorCallback, 0, nullptr); } void PostRegister(Squirrel *engine) diff --git a/src/script/squirrel_helper.hpp b/src/script/squirrel_helper.hpp index 22d738d4f7..3c6bed6c2c 100644 --- a/src/script/squirrel_helper.hpp +++ b/src/script/squirrel_helper.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. @@ -29,10 +27,10 @@ namespace SQConvert { * comes out of scope. Useful to make sure you can use stredup(), * without leaking memory. */ - struct SQAutoFreePointers : SmallVector { + struct SQAutoFreePointers : std::vector { ~SQAutoFreePointers() { - for (uint i = 0; i < this->items; i++) free(this->data[i]); + for (void * p : *this) free(p); } }; @@ -88,8 +86,8 @@ namespace SQConvert { 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, bool res) { sq_pushbool (vm, res); return 1; } - template <> inline int Return (HSQUIRRELVM vm, char *res) { if (res == NULL) sq_pushnull(vm); else { sq_pushstring(vm, res, -1); free(res); } return 1; } - template <> inline int Return(HSQUIRRELVM vm, const char *res) { if (res == NULL) sq_pushnull(vm); else { sq_pushstring(vm, res, -1); } 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; } @@ -117,7 +115,7 @@ namespace SQConvert { sq_getstring(vm, -1, &tmp); char *tmp_str = stredup(tmp); sq_poptop(vm); - *ptr->Append() = (void *)tmp_str; + ptr->push_back((void *)tmp_str); str_validate(tmp_str, tmp_str + strlen(tmp_str)); return tmp_str; } @@ -132,12 +130,12 @@ namespace SQConvert { sq_pushobject(vm, obj); sq_pushnull(vm); - SmallVector data; + std::vector data; while (SQ_SUCCEEDED(sq_next(vm, -2))) { SQInteger tmp; if (SQ_SUCCEEDED(sq_getinteger(vm, -1, &tmp))) { - *data.Append() = (int32)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"); @@ -147,11 +145,11 @@ namespace SQConvert { } sq_pop(vm, 2); - Array *arr = (Array*)MallocT(sizeof(Array) + sizeof(int32) * data.Length()); - arr->size = data.Length(); - memcpy(arr->array, data.Begin(), sizeof(int32) * data.Length()); + Array *arr = (Array*)MallocT(sizeof(Array) + sizeof(int32) * data.size()); + arr->size = data.size(); + memcpy(arr->array, data.data(), sizeof(int32) * data.size()); - *ptr->Append() = arr; + ptr->push_back(arr); return arr; } @@ -739,8 +737,8 @@ namespace SQConvert { { /* Find the amount of params we got */ int nparam = sq_gettop(vm); - SQUserPointer ptr = NULL; - SQUserPointer real_instance = NULL; + SQUserPointer ptr = nullptr; + SQUserPointer real_instance = nullptr; HSQOBJECT instance; /* Get the 'SQ' instance of this class */ @@ -759,14 +757,14 @@ namespace SQConvert { sq_getinstanceup(vm, 1, &real_instance, 0); /* Get the real function pointer */ sq_getuserdata(vm, nparam, &ptr, 0); - if (real_instance == NULL) return sq_throwerror(vm, "couldn't detect real instance of class for non-static call"); + if (real_instance == nullptr) return sq_throwerror(vm, "couldn't detect real instance of class for non-static call"); /* Remove the userdata from the stack */ sq_pop(vm, 1); try { /* Delegate it to a template that can handle this specific function */ return HelperT::SQCall((Tcls *)real_instance, *(Tmethod *)ptr, vm); - } catch (SQInteger e) { + } catch (SQInteger &e) { return e; } } @@ -781,8 +779,8 @@ namespace SQConvert { { /* Find the amount of params we got */ int nparam = sq_gettop(vm); - SQUserPointer ptr = NULL; - SQUserPointer real_instance = NULL; + SQUserPointer ptr = nullptr; + SQUserPointer real_instance = nullptr; HSQOBJECT instance; /* Get the 'SQ' instance of this class */ @@ -801,7 +799,7 @@ namespace SQConvert { sq_getinstanceup(vm, 1, &real_instance, 0); /* Get the real function pointer */ sq_getuserdata(vm, nparam, &ptr, 0); - if (real_instance == NULL) return sq_throwerror(vm, "couldn't detect real instance of class for non-static call"); + if (real_instance == nullptr) return sq_throwerror(vm, "couldn't detect real instance of class for non-static call"); /* Remove the userdata from the stack */ sq_pop(vm, 1); @@ -819,15 +817,15 @@ namespace SQConvert { { /* Find the amount of params we got */ int nparam = sq_gettop(vm); - SQUserPointer ptr = NULL; + SQUserPointer ptr = nullptr; /* Get the real function pointer */ sq_getuserdata(vm, nparam, &ptr, 0); try { /* Delegate it to a template that can handle this specific function */ - return HelperT::SQCall((Tcls *)NULL, *(Tmethod *)ptr, vm); - } catch (SQInteger e) { + return HelperT::SQCall((Tcls *)nullptr, *(Tmethod *)ptr, vm); + } catch (SQInteger &e) { return e; } } @@ -843,7 +841,7 @@ namespace SQConvert { { /* Find the amount of params we got */ int nparam = sq_gettop(vm); - SQUserPointer ptr = NULL; + SQUserPointer ptr = nullptr; /* Get the real function pointer */ sq_getuserdata(vm, nparam, &ptr, 0); @@ -862,7 +860,7 @@ namespace SQConvert { static SQInteger DefSQDestructorCallback(SQUserPointer p, SQInteger size) { /* Remove the real instance too */ - if (p != NULL) ((Tcls *)p)->Release(); + if (p != nullptr) ((Tcls *)p)->Release(); return 0; } @@ -876,12 +874,12 @@ namespace SQConvert { { try { /* Create the real instance */ - Tcls *instance = HelperT::SQConstruct((Tcls *)NULL, (Tmethod)NULL, vm); + Tcls *instance = HelperT::SQConstruct((Tcls *)nullptr, (Tmethod)nullptr, vm); sq_setinstanceup(vm, -Tnparam, instance); sq_setreleasehook(vm, -Tnparam, DefSQDestructorCallback); instance->AddRef(); return 0; - } catch (SQInteger e) { + } catch (SQInteger &e) { return e; } } @@ -903,7 +901,7 @@ namespace SQConvert { sq_setreleasehook(vm, -nparam, DefSQDestructorCallback); instance->AddRef(); return 0; - } catch (SQInteger e) { + } catch (SQInteger &e) { return e; } } diff --git a/src/script/squirrel_helper_type.hpp b/src/script/squirrel_helper_type.hpp index 946a59547a..c20655ca19 100644 --- a/src/script/squirrel_helper_type.hpp +++ b/src/script/squirrel_helper_type.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. @@ -14,7 +12,7 @@ /** Definition of a simple array. */ struct Array { - int32 size; ///< The size of the array. + size_t size; ///< The size of the array. int32 array[]; ///< The data of the array. }; diff --git a/src/script/squirrel_std.cpp b/src/script/squirrel_std.cpp index 96f087a2a7..9a01dc5d60 100644 --- a/src/script/squirrel_std.cpp +++ b/src/script/squirrel_std.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. @@ -51,7 +49,7 @@ SQInteger SquirrelStd::require(HSQUIRRELVM vm) /* Get the script-name of the current file, so we can work relative from it */ SQStackInfos si; sq_stackinfos(vm, 1, &si); - if (si.source == NULL) { + if (si.source == nullptr) { DEBUG(misc, 0, "[squirrel] Couldn't detect the script-name of the 'require'-caller; this should never happen!"); return SQ_ERROR; } @@ -60,7 +58,7 @@ SQInteger SquirrelStd::require(HSQUIRRELVM vm) strecpy(path, si.source, lastof(path)); /* Keep the dir, remove the rest */ SQChar *s = strrchr(path, PATHSEPCHAR); - if (s != NULL) { + if (s != nullptr) { /* Keep the PATHSEPCHAR there, remove the rest */ s++; *s = '\0'; diff --git a/src/script/squirrel_std.hpp b/src/script/squirrel_std.hpp index b1c7b30132..5e977045f8 100644 --- a/src/script/squirrel_std.hpp +++ b/src/script/squirrel_std.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/settings.cpp b/src/settings.cpp index dc11a37635..b1ec16e8ca 100644 --- a/src/settings.cpp +++ b/src/settings.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. @@ -24,6 +22,7 @@ */ #include "stdafx.h" +#include #include "currency.h" #include "screenshot.h" #include "network/network.h" @@ -39,7 +38,7 @@ #include "sound_func.h" #include "company_func.h" #include "rev.h" -#ifdef WITH_FREETYPE +#if defined(WITH_FREETYPE) || defined(_WIN32) #include "fontcache.h" #endif #include "textbuf_gui.h" @@ -70,6 +69,10 @@ #include "void_map.h" #include "station_base.h" +#if defined(WITH_FREETYPE) || defined(_WIN32) +#define HAS_TRUETYPE_FONT +#endif + #include "table/strings.h" #include "table/settings.h" @@ -86,7 +89,7 @@ static ErrorList _settings_error_list; ///< Errors while loading minimal setting typedef void SettingDescProc(IniFile *ini, const SettingDesc *desc, const char *grpname, void *object); -typedef void SettingDescProcList(IniFile *ini, const char *grpname, StringList *list); +typedef void SettingDescProcList(IniFile *ini, const char *grpname, StringList &list); static bool IsSignedVarMemType(VarType vt); @@ -98,7 +101,7 @@ static const char * const _list_group_names[] = { "newgrf", "servers", "server_bind_addresses", - NULL + nullptr }; /** @@ -116,7 +119,7 @@ static size_t LookupOneOfMany(const char *many, const char *one, size_t onelen = if (onelen == 0) onelen = strlen(one); /* check if it's an integer */ - if (*one >= '0' && *one <= '9') return strtoul(one, NULL, 0); + if (*one >= '0' && *one <= '9') return strtoul(one, nullptr, 0); idx = 0; for (;;) { @@ -169,7 +172,8 @@ static size_t LookupManyOfMany(const char *many, const char *str) * @param maxitems the maximum number of elements the integerlist-array has * @return returns the number of items found, or -1 on an error */ -static int ParseIntList(const char *p, int *items, int maxitems) +template +static int ParseIntList(const char *p, T *items, int maxitems) { int n = 0; // number of items read so far bool comma = false; // do we accept comma? @@ -189,9 +193,9 @@ static int ParseIntList(const char *p, int *items, int maxitems) default: { if (n == maxitems) return -1; // we don't accept that many numbers char *end; - long v = strtol(p, &end, 0); + unsigned long v = strtoul(p, &end, 0); if (p == end) return -1; // invalid character (not a number) - if (sizeof(int) < sizeof(long)) v = ClampToI32(v); + if (sizeof(T) < sizeof(v)) v = Clamp(v, std::numeric_limits::min(), std::numeric_limits::max()); items[n++] = v; p = end; // first non-number comma = true; // we accept comma now @@ -217,10 +221,10 @@ static int ParseIntList(const char *p, int *items, int maxitems) */ static bool LoadIntList(const char *str, void *array, int nelems, VarType type) { - int items[64]; + unsigned long items[64]; int i, nitems; - if (str == NULL) { + if (str == nullptr) { memset(items, 0, sizeof(items)); nitems = nelems; } else { @@ -266,7 +270,7 @@ static void MakeIntList(char *buf, const char *last, const void *array, int nele const byte *p = (const byte *)array; for (i = 0; i != nelems; i++) { - switch (type) { + switch (GetVarMemType(type)) { case SLE_VAR_BL: case SLE_VAR_I8: v = *(const int8 *)p; p += 1; break; case SLE_VAR_U8: v = *(const uint8 *)p; p += 1; break; @@ -276,7 +280,13 @@ static void MakeIntList(char *buf, const char *last, const void *array, int nele case SLE_VAR_U32: v = *(const uint32 *)p; p += 4; break; default: NOT_REACHED(); } - buf += seprintf(buf, last, (i == 0) ? "%d" : ",%d", v); + if (IsSignedVarMemType(type)) { + buf += seprintf(buf, last, (i == 0) ? "%d" : ",%d", v); + } else if (type & SLF_HEX) { + buf += seprintf(buf, last, (i == 0) ? "0x%X" : ",0x%X", v); + } else { + buf += seprintf(buf, last, (i == 0) ? "%u" : ",%u", v); + } } } @@ -350,7 +360,7 @@ static void MakeManyOfMany(char *buf, const char *last, const char *many, uint32 */ static const void *StringToVal(const SettingDescBase *desc, const char *orig_str) { - const char *str = orig_str == NULL ? "" : orig_str; + const char *str = orig_str == nullptr ? "" : orig_str; switch (desc->cmd) { case SDT_NUMX: { @@ -375,7 +385,7 @@ static const void *StringToVal(const SettingDescBase *desc, const char *orig_str size_t r = LookupOneOfMany(desc->many, str); /* if the first attempt of conversion from string to the appropriate value fails, * look if we have defined a converter from old value to new value. */ - if (r == (size_t)-1 && desc->proc_cnvt != NULL) r = desc->proc_cnvt(str); + if (r == (size_t)-1 && desc->proc_cnvt != nullptr) r = desc->proc_cnvt(str); if (r != (size_t)-1) return (void*)r; // and here goes converted value ErrorMessageData msg(STR_CONFIG_ERROR, STR_CONFIG_ERROR_INVALID_VALUE); @@ -411,7 +421,7 @@ static const void *StringToVal(const SettingDescBase *desc, const char *orig_str default: break; } - return NULL; + return nullptr; } /** @@ -450,13 +460,30 @@ static void Write_ValidateSetting(void *ptr, const SettingDesc *sd, int32 val) case SLE_VAR_U16: case SLE_VAR_I32: { /* Override the minimum value. No value below sdb->min, except special value 0 */ - if (!(sdb->flags & SGF_0ISDISABLED) || val != 0) val = Clamp(val, sdb->min, sdb->max); + if (!(sdb->flags & SGF_0ISDISABLED) || val != 0) { + if (!(sdb->flags & SGF_MULTISTRING)) { + /* Clamp value-type setting to its valid range */ + val = Clamp(val, sdb->min, sdb->max); + } else if (val < sdb->min || val > (int32)sdb->max) { + /* Reset invalid discrete setting (where different values change gameplay) to its default value */ + val = (int32)(size_t)sdb->def; + } + } break; } case SLE_VAR_U32: { /* Override the minimum value. No value below sdb->min, except special value 0 */ - uint min = ((sdb->flags & SGF_0ISDISABLED) && (uint)val <= (uint)sdb->min) ? 0 : sdb->min; - WriteValue(ptr, SLE_VAR_U32, (int64)ClampU(val, min, sdb->max)); + uint32 uval = (uint32)val; + if (!(sdb->flags & SGF_0ISDISABLED) || uval != 0) { + if (!(sdb->flags & SGF_MULTISTRING)) { + /* Clamp value-type setting to its valid range */ + uval = ClampU(uval, sdb->min, sdb->max); + } else if (uval < (uint)sdb->min || uval > sdb->max) { + /* Reset invalid discrete setting to its default value */ + uval = (uint32)(size_t)sdb->def; + } + } + WriteValue(ptr, SLE_VAR_U32, (int64)uval); return; } case SLE_VAR_I64: @@ -493,7 +520,7 @@ static void IniLoadSettings(IniFile *ini, const SettingDesc *sd, const char *grp /* For settings.xx.yy load the settings from [xx] yy = ? */ s = strchr(sdb->name, '.'); - if (s != NULL) { + if (s != nullptr) { group = ini->GetGroup(sdb->name, s - sdb->name); s++; } else { @@ -502,19 +529,19 @@ static void IniLoadSettings(IniFile *ini, const SettingDesc *sd, const char *grp } item = group->GetItem(s, false); - if (item == NULL && group != group_def) { + if (item == nullptr && group != group_def) { /* For settings.xx.yy load the settings from [settingss] yy = ? in case the previous * did not exist (e.g. loading old config files with a [settings] section */ item = group_def->GetItem(s, false); } - if (item == NULL) { + if (item == nullptr) { /* For settings.xx.zz.yy load the settings from [zz] yy = ? in case the previous * did not exist (e.g. loading old config files with a [yapf] section */ const char *sc = strchr(s, '.'); - if (sc != NULL) item = ini->GetGroup(s, sc - s)->GetItem(sc + 1, false); + if (sc != nullptr) item = ini->GetGroup(s, sc - s)->GetItem(sc + 1, false); } - p = (item == NULL) ? sdb->def : StringToVal(sdb, item->value); + p = (item == nullptr) ? sdb->def : StringToVal(sdb, item->value); ptr = GetVariableAddress(object, sld); switch (sdb->cmd) { @@ -529,16 +556,16 @@ static void IniLoadSettings(IniFile *ini, const SettingDesc *sd, const char *grp switch (GetVarMemType(sld->conv)) { case SLE_VAR_STRB: case SLE_VAR_STRBQ: - if (p != NULL) strecpy((char*)ptr, (const char*)p, (char*)ptr + sld->length - 1); + if (p != nullptr) strecpy((char*)ptr, (const char*)p, (char*)ptr + sld->length - 1); break; case SLE_VAR_STR: case SLE_VAR_STRQ: free(*(char**)ptr); - *(char**)ptr = p == NULL ? NULL : stredup((const char*)p); + *(char**)ptr = p == nullptr ? nullptr : stredup((const char*)p); break; - case SLE_VAR_CHAR: if (p != NULL) *(char *)ptr = *(const char *)p; break; + case SLE_VAR_CHAR: if (p != nullptr) *(char *)ptr = *(const char *)p; break; default: NOT_REACHED(); } @@ -552,7 +579,7 @@ static void IniLoadSettings(IniFile *ini, const SettingDesc *sd, const char *grp /* Use default */ LoadIntList((const char*)sdb->def, ptr, sld->length, GetVarMemType(sld->conv)); - } else if (sd->desc.proc_cnvt != NULL) { + } else if (sd->desc.proc_cnvt != nullptr) { sd->desc.proc_cnvt((const char*)p); } break; @@ -576,7 +603,7 @@ static void IniLoadSettings(IniFile *ini, const SettingDesc *sd, const char *grp */ static void IniSaveSettings(IniFile *ini, const SettingDesc *sd, const char *grpname, void *object) { - IniGroup *group_def = NULL, *group; + IniGroup *group_def = nullptr, *group; IniItem *item; char buf[512]; const char *s; @@ -593,11 +620,11 @@ static void IniSaveSettings(IniFile *ini, const SettingDesc *sd, const char *grp /* XXX - wtf is this?? (group override?) */ s = strchr(sdb->name, '.'); - if (s != NULL) { + if (s != nullptr) { group = ini->GetGroup(sdb->name, s - sdb->name); s++; } else { - if (group_def == NULL) group_def = ini->GetGroup(grpname); + if (group_def == nullptr) group_def = ini->GetGroup(grpname); s = sdb->name; group = group_def; } @@ -605,7 +632,7 @@ static void IniSaveSettings(IniFile *ini, const SettingDesc *sd, const char *grp item = group->GetItem(s, true); ptr = GetVariableAddress(object, sld); - if (item->value != NULL) { + if (item->value != nullptr) { /* check if the value is the same as the old value */ const void *p = StringToVal(sdb, item->value); @@ -618,7 +645,7 @@ static void IniSaveSettings(IniFile *ini, const SettingDesc *sd, const char *grp case SDT_MANYOFMANY: switch (GetVarMemType(sld->conv)) { case SLE_VAR_BL: - if (*(bool*)ptr == (p != NULL)) continue; + if (*(bool*)ptr == (p != nullptr)) continue; break; case SLE_VAR_I8: @@ -654,7 +681,7 @@ static void IniSaveSettings(IniFile *ini, const SettingDesc *sd, const char *grp switch (sdb->cmd) { case SDT_BOOLX: strecpy(buf, (i != 0) ? "true" : "false", lastof(buf)); break; - case SDT_NUMX: seprintf(buf, lastof(buf), IsSignedVarMemType(sld->conv) ? "%d" : "%u", i); break; + case SDT_NUMX: seprintf(buf, lastof(buf), IsSignedVarMemType(sld->conv) ? "%d" : (sld->conv & SLF_HEX) ? "%X" : "%u", i); break; case SDT_ONEOFMANY: MakeOneOfMany(buf, lastof(buf), sdb->many, i); break; case SDT_MANYOFMANY: MakeManyOfMany(buf, lastof(buf), sdb->many, i); break; default: NOT_REACHED(); @@ -669,7 +696,7 @@ static void IniSaveSettings(IniFile *ini, const SettingDesc *sd, const char *grp case SLE_VAR_STR: strecpy(buf, *(char**)ptr, lastof(buf)); break; case SLE_VAR_STRQ: - if (*(char**)ptr == NULL) { + if (*(char**)ptr == nullptr) { buf[0] = '\0'; } else { seprintf(buf, lastof(buf), "\"%s\"", *(char**)ptr); @@ -682,7 +709,7 @@ static void IniSaveSettings(IniFile *ini, const SettingDesc *sd, const char *grp break; case SDT_INTLIST: - MakeIntList(buf, lastof(buf), ptr, sld->length, GetVarMemType(sld->conv)); + MakeIntList(buf, lastof(buf), ptr, sld->length, sld->conv); break; default: NOT_REACHED(); @@ -696,44 +723,44 @@ static void IniSaveSettings(IniFile *ini, const SettingDesc *sd, const char *grp /** * Loads all items from a 'grpname' section into a list - * The list parameter can be a NULL pointer, in this case nothing will be + * The list parameter can be a nullptr pointer, in this case nothing will be * saved and a callback function should be defined that will take over the * list-handling and store the data itself somewhere. * @param ini IniFile handle to the ini file with the source data * @param grpname character string identifying the section-header of the ini file that will be parsed * @param list new list with entries of the given section */ -static void IniLoadSettingList(IniFile *ini, const char *grpname, StringList *list) +static void IniLoadSettingList(IniFile *ini, const char *grpname, StringList &list) { IniGroup *group = ini->GetGroup(grpname); - if (group == NULL || list == NULL) return; + if (group == nullptr) return; - list->Clear(); + list.clear(); - for (const IniItem *item = group->item; item != NULL; item = item->next) { - if (item->name != NULL) *list->Append() = stredup(item->name); + for (const IniItem *item = group->item; item != nullptr; item = item->next) { + if (item->name != nullptr) list.emplace_back(item->name); } } /** * Saves all items from a list into the 'grpname' section - * The list parameter can be a NULL pointer, in this case a callback function + * The list parameter can be a nullptr pointer, in this case a callback function * should be defined that will provide the source data to be saved. * @param ini IniFile handle to the ini file where the destination data is saved * @param grpname character string identifying the section-header of the ini file * @param list pointer to an string(pointer) array that will be used as the * source to be saved into the relevant ini section */ -static void IniSaveSettingList(IniFile *ini, const char *grpname, StringList *list) +static void IniSaveSettingList(IniFile *ini, const char *grpname, StringList &list) { IniGroup *group = ini->GetGroup(grpname); - if (group == NULL || list == NULL) return; + if (group == nullptr) return; group->Clear(); - for (char **iter = list->Begin(); iter != list->End(); iter++) { - group->GetItem(*iter, true)->SetValue(""); + for (const auto &iter : list) { + group->GetItem(iter.c_str(), true)->SetValue(""); } } @@ -790,7 +817,7 @@ SettingType SettingDesc::GetType() const /** Reposition the main toolbar as the setting changed. */ static bool v_PositionMainToolbar(int32 p1) { - if (_game_mode != GM_MENU) PositionMainToolbar(NULL); + if (_game_mode != GM_MENU) PositionMainToolbar(nullptr); return true; } @@ -798,9 +825,9 @@ static bool v_PositionMainToolbar(int32 p1) static bool v_PositionStatusbar(int32 p1) { if (_game_mode != GM_MENU) { - PositionStatusbar(NULL); - PositionNewsMessage(NULL); - PositionNetworkChatWindow(NULL); + PositionStatusbar(nullptr); + PositionNewsMessage(nullptr); + PositionNetworkChatWindow(nullptr); } return true; } @@ -871,8 +898,7 @@ static bool DeleteSelectStationWindow(int32 p1) static bool UpdateConsists(int32 p1) { - Train *t; - FOR_ALL_TRAINS(t) { + for (Train *t : Train::Iterate()) { /* Update the consist of all trains so the maximum speed is set correctly. */ if (t->IsFrontEngine() || t->IsFreeWagon()) t->ConsistChanged(CCF_TRACK); } @@ -907,8 +933,7 @@ static bool CheckInterval(int32 p1) if (update_vehicles) { const Company *c = Company::Get(_current_company); - Vehicle *v; - FOR_ALL_VEHICLES(v) { + for (Vehicle *v : Vehicle::Iterate()) { if (v->owner == _current_company && v->IsPrimaryVehicle() && !v->ServiceIntervalIsCustom()) { v->SetServiceInterval(CompanyServiceInterval(c, v->type)); v->SetServiceIntervalIsPercent(p1 != 0); @@ -938,8 +963,7 @@ static bool UpdateInterval(VehicleType type, int32 p1) if (interval != p1) return false; if (update_vehicles) { - Vehicle *v; - FOR_ALL_VEHICLES(v) { + for (Vehicle *v : Vehicle::Iterate()) { if (v->owner == _current_company && v->type == type && v->IsPrimaryVehicle() && !v->ServiceIntervalIsCustom()) { v->SetServiceInterval(p1); } @@ -973,8 +997,7 @@ static bool UpdateIntervalAircraft(int32 p1) static bool TrainAccelerationModelChanged(int32 p1) { - Train *t; - FOR_ALL_TRAINS(t) { + for (Train *t : Train::Iterate()) { if (t->IsFrontEngine()) { t->tcache.cached_max_curve_speed = t->GetCurveSpeedLimit(); t->UpdateAcceleration(); @@ -996,8 +1019,7 @@ static bool TrainAccelerationModelChanged(int32 p1) */ static bool TrainSlopeSteepnessChanged(int32 p1) { - Train *t; - FOR_ALL_TRAINS(t) { + for (Train *t : Train::Iterate()) { if (t->IsFrontEngine()) t->CargoChanged(); } @@ -1012,8 +1034,7 @@ static bool TrainSlopeSteepnessChanged(int32 p1) static bool RoadVehAccelerationModelChanged(int32 p1) { if (_settings_game.vehicle.roadveh_acceleration_model != AM_ORIGINAL) { - RoadVehicle *rv; - FOR_ALL_ROADVEHICLES(rv) { + for (RoadVehicle *rv : RoadVehicle::Iterate()) { if (rv->IsFrontEngine()) { rv->CargoChanged(); } @@ -1035,8 +1056,7 @@ static bool RoadVehAccelerationModelChanged(int32 p1) */ static bool RoadVehSlopeSteepnessChanged(int32 p1) { - RoadVehicle *rv; - FOR_ALL_ROADVEHICLES(rv) { + for (RoadVehicle *rv : RoadVehicle::Iterate()) { if (rv->IsFrontEngine()) rv->CargoChanged(); } @@ -1218,16 +1238,14 @@ static bool CheckFreeformEdges(int32 p1) { if (_game_mode == GM_MENU) return true; if (p1 != 0) { - Ship *s; - FOR_ALL_SHIPS(s) { + for (Ship *s : Ship::Iterate()) { /* Check if there is a ship on the northern border. */ if (TileX(s->tile) == 0 || TileY(s->tile) == 0) { ShowErrorMessage(STR_CONFIG_SETTING_EDGES_NOT_EMPTY, INVALID_STRING_ID, WL_ERROR); return false; } } - BaseStation *st; - FOR_ALL_BASE_STATIONS(st) { + for (const BaseStation *st : BaseStation::Iterate()) { /* Check if there is a non-deleted buoy on the northern border. */ if (st->IsInUse() && (TileX(st->xy) == 0 || TileY(st->xy) == 0)) { ShowErrorMessage(STR_CONFIG_SETTING_EDGES_NOT_EMPTY, INVALID_STRING_ID, WL_ERROR); @@ -1314,7 +1332,8 @@ static bool ChangeMaxHeightLevel(int32 p1) static bool StationCatchmentChanged(int32 p1) { - Station::RecomputeIndustriesNearForAll(); + Station::RecomputeCatchmentForAll(); + MarkWholeScreenDirty(); return true; } @@ -1327,16 +1346,12 @@ static bool MaxVehiclesChanged(int32 p1) static bool InvalidateShipPathCache(int32 p1) { - Ship *s; - FOR_ALL_SHIPS(s) { + for (Ship *s : Ship::Iterate()) { s->path.clear(); } return true; } - -#ifdef ENABLE_NETWORK - static bool UpdateClientName(int32 p1) { NetworkUpdateClientName(); @@ -1368,9 +1383,6 @@ static bool UpdateClientConfigValues(int32 p1) return true; } -#endif /* ENABLE_NETWORK */ - - /* End - Callback Functions */ /** @@ -1417,14 +1429,14 @@ static void AILoadConfig(IniFile *ini, const char *grpname) /* Clean any configured AI */ for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) { - AIConfig::GetConfig(c, AIConfig::SSS_FORCE_NEWGAME)->Change(NULL); + AIConfig::GetConfig(c, AIConfig::SSS_FORCE_NEWGAME)->Change(nullptr); } /* If no group exists, return */ - if (group == NULL) return; + if (group == nullptr) return; CompanyID c = COMPANY_FIRST; - for (item = group->item; c < MAX_COMPANIES && item != NULL; c++, item = item->next) { + for (item = group->item; c < MAX_COMPANIES && item != nullptr; c++, item = item->next) { AIConfig *config = AIConfig::GetConfig(c, AIConfig::SSS_FORCE_NEWGAME); config->Change(item->name); @@ -1434,7 +1446,7 @@ static void AILoadConfig(IniFile *ini, const char *grpname) continue; } } - if (item->value != NULL) config->StringToSettings(item->value); + if (item->value != nullptr) config->StringToSettings(item->value); } } @@ -1444,13 +1456,13 @@ static void GameLoadConfig(IniFile *ini, const char *grpname) IniItem *item; /* Clean any configured GameScript */ - GameConfig::GetConfig(GameConfig::SSS_FORCE_NEWGAME)->Change(NULL); + GameConfig::GetConfig(GameConfig::SSS_FORCE_NEWGAME)->Change(nullptr); /* If no group exists, return */ - if (group == NULL) return; + if (group == nullptr) return; item = group->item; - if (item == NULL) return; + if (item == nullptr) return; GameConfig *config = GameConfig::GetConfig(AIConfig::SSS_FORCE_NEWGAME); @@ -1461,7 +1473,7 @@ static void GameLoadConfig(IniFile *ini, const char *grpname) return; } } - if (item->value != NULL) config->StringToSettings(item->value); + if (item->value != nullptr) config->StringToSettings(item->value); } /** @@ -1508,13 +1520,13 @@ static GRFConfig *GRFLoadConfig(IniFile *ini, const char *grpname, bool is_stati { IniGroup *group = ini->GetGroup(grpname); IniItem *item; - GRFConfig *first = NULL; + GRFConfig *first = nullptr; GRFConfig **curr = &first; - if (group == NULL) return NULL; + if (group == nullptr) return nullptr; - for (item = group->item; item != NULL; item = item->next) { - GRFConfig *c = NULL; + for (item = group->item; item != nullptr; item = item->next) { + GRFConfig *c = nullptr; uint8 grfid_buf[4], md5sum[16]; char *filename = item->name; @@ -1531,18 +1543,18 @@ static GRFConfig *GRFLoadConfig(IniFile *ini, const char *grpname, bool is_stati uint32 grfid = grfid_buf[0] | (grfid_buf[1] << 8) | (grfid_buf[2] << 16) | (grfid_buf[3] << 24); if (has_md5sum) { const GRFConfig *s = FindGRFConfig(grfid, FGCM_EXACT, md5sum); - if (s != NULL) c = new GRFConfig(*s); + if (s != nullptr) c = new GRFConfig(*s); } - if (c == NULL && !FioCheckFileExists(filename, NEWGRF_DIR)) { + if (c == nullptr && !FioCheckFileExists(filename, NEWGRF_DIR)) { const GRFConfig *s = FindGRFConfig(grfid, FGCM_NEWEST_VALID); - if (s != NULL) c = new GRFConfig(*s); + if (s != nullptr) c = new GRFConfig(*s); } } - if (c == NULL) c = new GRFConfig(filename); + if (c == nullptr) c = new GRFConfig(filename); /* Parse parameters */ if (!StrEmpty(item->value)) { - int count = ParseIntList(item->value, (int*)c->param, lengthof(c->param)); + int count = ParseIntList(item->value, c->param, lengthof(c->param)); if (count < 0) { SetDParamStr(0, filename); ShowErrorMessage(STR_CONFIG_ERROR, STR_CONFIG_ERROR_ARRAY, WL_CRITICAL); @@ -1573,7 +1585,7 @@ static GRFConfig *GRFLoadConfig(IniFile *ini, const char *grpname, bool is_stati /* Check for duplicate GRFID (will also check for duplicate filenames) */ bool duplicate = false; - for (const GRFConfig *gc = first; gc != NULL; gc = gc->next) { + for (const GRFConfig *gc = first; gc != nullptr; gc = gc->next) { if (gc->ident.grfid == c->ident.grfid) { SetDParamStr(0, c->filename); SetDParamStr(1, gc->filename); @@ -1602,7 +1614,7 @@ static void AISaveConfig(IniFile *ini, const char *grpname) { IniGroup *group = ini->GetGroup(grpname); - if (group == NULL) return; + if (group == nullptr) return; group->Clear(); for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) { @@ -1626,7 +1638,7 @@ static void GameSaveConfig(IniFile *ini, const char *grpname) { IniGroup *group = ini->GetGroup(grpname); - if (group == NULL) return; + if (group == nullptr) return; group->Clear(); GameConfig *config = GameConfig::GetConfig(AIConfig::SSS_FORCE_NEWGAME); @@ -1672,7 +1684,7 @@ static void GRFSaveConfig(IniFile *ini, const char *grpname, const GRFConfig *li IniGroup *group = ini->GetGroup(grpname); const GRFConfig *c; - for (c = list; c != NULL; c = c->next) { + for (c = list; c != nullptr; c = c->next) { /* Hex grfid (4 bytes in nibbles), "|", hex md5sum (16 bytes in nibbles), "|", file system path. */ char key[4 * 2 + 1 + 16 * 2 + 1 + MAX_PATH]; char params[512]; @@ -1689,9 +1701,9 @@ static void GRFSaveConfig(IniFile *ini, const char *grpname, const GRFConfig *li static void HandleSettingDescs(IniFile *ini, SettingDescProc *proc, SettingDescProcList *proc_list, bool basic_settings = true, bool other_settings = true) { if (basic_settings) { - proc(ini, (const SettingDesc*)_misc_settings, "misc", NULL); + proc(ini, (const SettingDesc*)_misc_settings, "misc", nullptr); #if defined(_WIN32) && !defined(DEDICATED) - proc(ini, (const SettingDesc*)_win32_settings, "win32", NULL); + proc(ini, (const SettingDesc*)_win32_settings, "win32", nullptr); #endif /* _WIN32 */ } @@ -1700,11 +1712,9 @@ static void HandleSettingDescs(IniFile *ini, SettingDescProc *proc, SettingDescP proc(ini, _currency_settings,"currency", &_custom_currency); proc(ini, _company_settings, "company", &_settings_client.company); -#ifdef ENABLE_NETWORK - proc_list(ini, "server_bind_addresses", &_network_bind_list); - proc_list(ini, "servers", &_network_host_list); - proc_list(ini, "bans", &_network_ban_list); -#endif /* ENABLE_NETWORK */ + proc_list(ini, "server_bind_addresses", _network_bind_list); + proc_list(ini, "servers", _network_host_list); + proc_list(ini, "bans", _network_ban_list); } } @@ -1739,10 +1749,10 @@ void LoadFromConfig(bool minimal) ValidateSettings(); - /* Display sheduled errors */ + /* Display scheduled errors */ extern void ScheduleErrorMessage(ErrorList &datas); ScheduleErrorMessage(_settings_error_list); - if (FindWindowById(WC_ERRMSG, 0) == NULL) ShowFirstError(); + if (FindWindowById(WC_ERRMSG, 0) == nullptr) ShowFirstError(); } delete ini; @@ -1770,21 +1780,20 @@ void SaveToConfig() /** * Get the list of known NewGrf presets. - * @param[in,out] list Pointer to list for storing the preset names. + * @returns List of preset names. */ -void GetGRFPresetList(GRFPresetList *list) +StringList GetGRFPresetList() { - list->Clear(); + StringList list; - IniFile *ini = IniLoadConfig(); - IniGroup *group; - for (group = ini->group; group != NULL; group = group->next) { + std::unique_ptr ini(IniLoadConfig()); + for (IniGroup *group = ini->group; group != nullptr; group = group->next) { if (strncmp(group->name, "preset-", 7) == 0) { - *list->Append() = stredup(group->name + 7); + list.emplace_back(group->name + 7); } } - delete ini; + return list; } /** @@ -1842,7 +1851,7 @@ void DeleteGRFPresetFromConfig(const char *config_name) const SettingDesc *GetSettingDescription(uint index) { - if (index >= lengthof(_settings)) return NULL; + if (index >= lengthof(_settings)) return nullptr; return &_settings[index]; } @@ -1861,7 +1870,7 @@ CommandCost CmdChangeSetting(TileIndex tile, DoCommandFlag flags, uint32 p1, uin { const SettingDesc *sd = GetSettingDescription(p1); - if (sd == NULL) return CMD_ERROR; + if (sd == nullptr) return CMD_ERROR; if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) return CMD_ERROR; if (!sd->IsEditable(true)) return CMD_ERROR; @@ -1877,7 +1886,7 @@ CommandCost CmdChangeSetting(TileIndex tile, DoCommandFlag flags, uint32 p1, uin if (oldval == newval) return CommandCost(); - if (sd->desc.proc != NULL && !sd->desc.proc(newval)) { + if (sd->desc.proc != nullptr && !sd->desc.proc(newval)) { WriteValue(var, sd->save.conv, (int64)oldval); return CommandCost(); } @@ -1920,7 +1929,7 @@ CommandCost CmdChangeCompanySetting(TileIndex tile, DoCommandFlag flags, uint32 if (oldval == newval) return CommandCost(); - if (sd->desc.proc != NULL && !sd->desc.proc(newval)) { + if (sd->desc.proc != nullptr && !sd->desc.proc(newval)) { WriteValue(var, sd->save.conv, (int64)oldval); return CommandCost(); } @@ -1953,7 +1962,7 @@ bool SetSettingValue(uint index, int32 value, bool force_newgame) void *var2 = GetVariableAddress(&_settings_newgame, &sd->save); Write_ValidateSetting(var2, sd, value); } - if (sd->desc.proc != NULL) sd->desc.proc((int32)ReadValue(var, sd->save.conv)); + if (sd->desc.proc != nullptr) sd->desc.proc((int32)ReadValue(var, sd->save.conv)); SetWindowClassesDirty(WC_GAME_OPTIONS); @@ -1987,7 +1996,7 @@ void SetCompanySetting(uint index, int32 value) } else { void *var = GetVariableAddress(&_settings_client.company, &sd->save); Write_ValidateSetting(var, sd, value); - if (sd->desc.proc != NULL) sd->desc.proc((int32)ReadValue(var, sd->save.conv)); + if (sd->desc.proc != nullptr) sd->desc.proc((int32)ReadValue(var, sd->save.conv)); } } @@ -2004,7 +2013,6 @@ void SetDefaultCompanySettings(CompanyID cid) } } -#if defined(ENABLE_NETWORK) /** * Sync all company settings in a multiplayer game. */ @@ -2017,10 +2025,9 @@ void SyncCompanySettings() const void *new_var = GetVariableAddress(&_settings_client.company, &sd->save); uint32 old_value = (uint32)ReadValue(old_var, sd->save.conv); uint32 new_value = (uint32)ReadValue(new_var, sd->save.conv); - if (old_value != new_value) NetworkSendCommand(0, i, new_value, CMD_CHANGE_COMPANY_SETTING, NULL, NULL, _local_company); + if (old_value != new_value) NetworkSendCommand(0, i, new_value, CMD_CHANGE_COMPANY_SETTING, nullptr, nullptr, _local_company); } } -#endif /* ENABLE_NETWORK */ /** * Get the index in the _company_settings array of a setting @@ -2031,7 +2038,7 @@ uint GetCompanySettingIndex(const char *name) { uint i; const SettingDesc *sd = GetSettingFromName(name, &i); - assert(sd != NULL && (sd->desc.flags & SGF_PER_COMPANY) != 0); + assert(sd != nullptr && (sd->desc.flags & SGF_PER_COMPANY) != 0); return i; } @@ -2050,12 +2057,12 @@ bool SetSettingValue(uint index, const char *value, bool force_newgame) if (GetVarMemType(sd->save.conv) == SLE_VAR_STRQ) { char **var = (char**)GetVariableAddress((_game_mode == GM_MENU || force_newgame) ? &_settings_newgame : &_settings_game, &sd->save); free(*var); - *var = strcmp(value, "(null)") == 0 ? NULL : stredup(value); + *var = strcmp(value, "(null)") == 0 ? nullptr : stredup(value); } else { - char *var = (char*)GetVariableAddress(NULL, &sd->save); + char *var = (char*)GetVariableAddress(nullptr, &sd->save); strecpy(var, value, &var[sd->save.length - 1]); } - if (sd->desc.proc != NULL) sd->desc.proc(0); + if (sd->desc.proc != nullptr) sd->desc.proc(0); return true; } @@ -2065,7 +2072,7 @@ bool SetSettingValue(uint index, const char *value, bool force_newgame) * @param name Name of the setting to return a setting description of * @param i Pointer to an integer that will contain the index of the setting after the call, if it is successful. * @return Pointer to the setting description of setting \a name if it can be found, - * \c NULL indicates failure to obtain the description + * \c nullptr indicates failure to obtain the description */ const SettingDesc *GetSettingFromName(const char *name, uint *i) { @@ -2081,7 +2088,7 @@ const SettingDesc *GetSettingFromName(const char *name, uint *i) for (*i = 0, sd = _settings; sd->save.cmd != SL_END; sd++, (*i)++) { if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) continue; const char *short_name = strchr(sd->desc.name, '.'); - if (short_name != NULL) { + if (short_name != nullptr) { short_name++; if (strcmp(short_name, name) == 0) return sd; } @@ -2094,7 +2101,7 @@ const SettingDesc *GetSettingFromName(const char *name, uint *i) if (strcmp(sd->desc.name, name) == 0) return sd; } - return NULL; + return nullptr; } /* Those 2 functions need to be here, else we have to make some stuff non-static @@ -2104,7 +2111,7 @@ void IConsoleSetSetting(const char *name, const char *value, bool force_newgame) uint index; const SettingDesc *sd = GetSettingFromName(name, &index); - if (sd == NULL) { + if (sd == nullptr) { IConsolePrintF(CC_WARNING, "'%s' is an unknown setting.", name); return; } @@ -2137,7 +2144,7 @@ void IConsoleSetSetting(const char *name, int value) { uint index; const SettingDesc *sd = GetSettingFromName(name, &index); - assert(sd != NULL); + assert(sd != nullptr); SetSettingValue(index, value); } @@ -2153,7 +2160,7 @@ void IConsoleGetSetting(const char *name, bool force_newgame) const SettingDesc *sd = GetSettingFromName(name, &index); const void *ptr; - if (sd == NULL) { + if (sd == nullptr) { IConsolePrintF(CC_WARNING, "'%s' is an unknown setting.", name); return; } @@ -2177,7 +2184,7 @@ void IConsoleGetSetting(const char *name, bool force_newgame) /** * List all settings and their value to the console * - * @param prefilter If not \c NULL, only list settings with names that begin with \a prefilter prefix + * @param prefilter If not \c nullptr, only list settings with names that begin with \a prefilter prefix */ void IConsoleListSettings(const char *prefilter) { @@ -2185,7 +2192,7 @@ void IConsoleListSettings(const char *prefilter) for (const SettingDesc *sd = _settings; sd->save.cmd != SL_END; sd++) { if (!SlIsObjectCurrentlyValid(sd->save.version_from, sd->save.version_to)) continue; - if (prefilter != NULL && strstr(sd->desc.name, prefilter) == NULL) continue; + if (prefilter != nullptr && strstr(sd->desc.name, prefilter) == nullptr) continue; char value[80]; const void *ptr = GetVariableAddress(&GetGameSettings(), &sd->save); @@ -2205,7 +2212,7 @@ void IConsoleListSettings(const char *prefilter) /** * Save and load handler for settings * @param osd SettingDesc struct containing all information - * @param object can be either NULL in which case we load global variables or + * @param object can be either nullptr in which case we load global variables or * a pointer to a struct which is getting saved */ static void LoadSettings(const SettingDesc *osd, void *object) @@ -2222,7 +2229,7 @@ static void LoadSettings(const SettingDesc *osd, void *object) /** * Save and load handler for settings * @param sd SettingDesc struct containing all information - * @param object can be either NULL in which case we load global variables or + * @param object can be either nullptr in which case we load global variables or * a pointer to a struct which is getting saved */ static void SaveSettings(const SettingDesc *sd, void *object) @@ -2270,21 +2277,9 @@ static void Save_PATS() SaveSettings(_settings, &_settings_game); } -void CheckConfig() -{ - /* - * Increase old default values for pf_maxdepth and pf_maxlength - * to support big networks. - */ - if (_settings_newgame.pf.opf.pf_maxdepth == 16 && _settings_newgame.pf.opf.pf_maxlength == 512) { - _settings_newgame.pf.opf.pf_maxdepth = 48; - _settings_newgame.pf.opf.pf_maxlength = 4096; - } -} - extern const ChunkHandler _setting_chunk_handlers[] = { - { 'OPTS', NULL, Load_OPTS, NULL, NULL, CH_RIFF}, - { 'PATS', Save_PATS, Load_PATS, NULL, Check_PATS, CH_RIFF | CH_LAST}, + { 'OPTS', nullptr, Load_OPTS, nullptr, nullptr, CH_RIFF}, + { 'PATS', Save_PATS, Load_PATS, nullptr, Check_PATS, CH_RIFF | CH_LAST}, }; static bool IsSignedVarMemType(VarType vt) diff --git a/src/settings_func.h b/src/settings_func.h index 3b3387b5fd..4a55821cf6 100644 --- a/src/settings_func.h +++ b/src/settings_func.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. @@ -14,6 +12,7 @@ #include "core/smallvec_type.hpp" #include "company_type.h" +#include "string_type.h" struct IniFile; @@ -24,16 +23,11 @@ void IConsoleListSettings(const char *prefilter); void LoadFromConfig(bool minimal = false); void SaveToConfig(); -void CheckConfig(); void IniLoadWindowSettings(IniFile *ini, const char *grpname, void *desc); void IniSaveWindowSettings(IniFile *ini, const char *grpname, void *desc); -/* Functions to load and save NewGRF settings to a separate - * configuration file, used for presets. */ -typedef AutoFreeSmallVector GRFPresetList; - -void GetGRFPresetList(GRFPresetList *list); +StringList GetGRFPresetList(); struct GRFConfig *LoadGRFPresetFromConfig(const char *config_name); void SaveGRFPresetToConfig(const char *config_name, struct GRFConfig *config); void DeleteGRFPresetFromConfig(const char *config_name); @@ -41,10 +35,6 @@ void DeleteGRFPresetFromConfig(const char *config_name); uint GetCompanySettingIndex(const char *name); void SetDefaultCompanySettings(CompanyID cid); -#if defined(ENABLE_NETWORK) void SyncCompanySettings(); -#else /* ENABLE_NETWORK */ -static inline void SyncCompanySettings() {} -#endif /* ENABLE_NETWORK */ #endif /* SETTINGS_FUNC_H */ diff --git a/src/settings_gui.cpp b/src/settings_gui.cpp index d60ed67739..713847b9ce 100644 --- a/src/settings_gui.cpp +++ b/src/settings_gui.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. @@ -38,6 +36,7 @@ #include "querystring_gui.h" #include "fontcache.h" #include "settings_func.h" +#include "zoom_func.h" #include @@ -79,7 +78,7 @@ static const StringID _font_zoom_dropdown[] = { }; int _nb_orig_names = SPECSTR_TOWNNAME_LAST - SPECSTR_TOWNNAME_START + 1; ///< Number of original town names. -static StringID *_grf_names = NULL; ///< Pointer to town names defined by NewGRFs. +static StringID *_grf_names = nullptr; ///< Pointer to town names defined by NewGRFs. static int _nb_grf_names = 0; ///< Number of town names defined by NewGRFs. static Dimension _circle_size; ///< Dimension of the circle +/- icon. This is here as not all users are within the class of the settings window. @@ -110,17 +109,14 @@ static inline StringID TownName(int town_name) /** * Get index of the current screen resolution. - * @return Index of the current screen resolution if it is a known resolution, #_num_resolutions otherwise. + * @return Index of the current screen resolution if it is a known resolution, _resolutions.size() otherwise. */ -static int GetCurRes() +static uint GetCurRes() { - int i; + uint i; - for (i = 0; i != _num_resolutions; i++) { - if ((int)_resolutions[i].width == _screen.width && - (int)_resolutions[i].height == _screen.height) { - break; - } + for (i = 0; i != _resolutions.size(); i++) { + if (_resolutions[i] == Dimension(_screen.width, _screen.height)) break; } return i; } @@ -130,20 +126,20 @@ static void ShowCustCurrency(); static void ReconstructUserInterface(); template -static DropDownList *BuildSetDropDownList(int *selected_index, bool allow_selection) +static DropDownList BuildSetDropDownList(int *selected_index, bool allow_selection) { int n = T::GetNumSets(); *selected_index = T::GetIndexOfUsedSet(); - DropDownList *list = new DropDownList(); + DropDownList list; for (int i = 0; i < n; i++) { - *list->Append() = new DropDownListCharStringItem(T::GetSet(i)->name, i, !allow_selection && (*selected_index != i)); + list.emplace_back(new DropDownListCharStringItem(T::GetSet(i)->name, i, !allow_selection && (*selected_index != i))); } return list; } -DropDownList *BuildMusicSetDropDownList(int *selected_index) +DropDownList BuildMusicSetDropDownList(int *selected_index) { return BuildSetDropDownList(selected_index, true); } @@ -160,7 +156,7 @@ struct BaseSetTextfileWindow : public TextfileWindow { this->LoadTextfile(textfile, BASESET_DIR); } - /* virtual */ void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { if (widget == WID_TF_CAPTION) { SetDParam(0, content_type); @@ -207,14 +203,13 @@ struct GameOptionsWindow : Window { * Build the dropdown list for a specific widget. * @param widget Widget to build list for * @param selected_index Currently selected item - * @return the built dropdown list, or NULL if the widget has no dropdown menu. + * @return the built dropdown list, or nullptr if the widget has no dropdown menu. */ - DropDownList *BuildDropDownList(int widget, int *selected_index) const + DropDownList BuildDropDownList(int widget, int *selected_index) const { - DropDownList *list = NULL; + DropDownList list; switch (widget) { case WID_GO_CURRENCY_DROPDOWN: { // Setup currencies dropdown - list = new DropDownList(); *selected_index = this->opt->locale.currency; StringID *items = BuildCurrencyDropdown(); uint64 disabled = _game_mode == GM_MENU ? 0LL : ~GetMaskOfAllowedCurrencies(); @@ -222,18 +217,17 @@ struct GameOptionsWindow : Window { /* Add non-custom currencies; sorted naturally */ for (uint i = 0; i < CURRENCY_END; items++, i++) { if (i == CURRENCY_CUSTOM) continue; - *list->Append() = new DropDownListStringItem(*items, i, HasBit(disabled, i)); + list.emplace_back(new DropDownListStringItem(*items, i, HasBit(disabled, i))); } - QSortT(list->Begin(), list->Length(), DropDownListStringItem::NatSortFunc); + std::sort(list.begin(), list.end(), DropDownListStringItem::NatSortFunc); /* Append custom currency at the end */ - *list->Append() = new DropDownListItem(-1, false); // separator line - *list->Append() = new DropDownListStringItem(STR_GAME_OPTIONS_CURRENCY_CUSTOM, CURRENCY_CUSTOM, HasBit(disabled, CURRENCY_CUSTOM)); + list.emplace_back(new DropDownListItem(-1, false)); // separator line + list.emplace_back(new DropDownListStringItem(STR_GAME_OPTIONS_CURRENCY_CUSTOM, CURRENCY_CUSTOM, HasBit(disabled, CURRENCY_CUSTOM))); break; } case WID_GO_ROADSIDE_DROPDOWN: { // Setup road-side dropdown - list = new DropDownList(); *selected_index = this->opt->vehicle.road_side; const StringID *items = _driveside_dropdown; uint disabled = 0; @@ -246,13 +240,12 @@ struct GameOptionsWindow : Window { } for (uint i = 0; *items != INVALID_STRING_ID; items++, i++) { - *list->Append() = new DropDownListStringItem(*items, i, HasBit(disabled, i)); + list.emplace_back(new DropDownListStringItem(*items, i, HasBit(disabled, i))); } break; } case WID_GO_TOWNNAME_DROPDOWN: { // Setup townname dropdown - list = new DropDownList(); *selected_index = this->opt->game_creation.town_name; int enabled_item = (_game_mode == GM_MENU || Town::GetNumItems() == 0) ? -1 : *selected_index; @@ -260,52 +253,49 @@ struct GameOptionsWindow : Window { /* Add and sort newgrf townnames generators */ for (int i = 0; i < _nb_grf_names; i++) { int result = _nb_orig_names + i; - *list->Append() = new DropDownListStringItem(_grf_names[i], result, enabled_item != result && enabled_item >= 0); + list.emplace_back(new DropDownListStringItem(_grf_names[i], result, enabled_item != result && enabled_item >= 0)); } - QSortT(list->Begin(), list->Length(), DropDownListStringItem::NatSortFunc); + std::sort(list.begin(), list.end(), DropDownListStringItem::NatSortFunc); - int newgrf_size = list->Length(); + size_t newgrf_size = list.size(); /* Insert newgrf_names at the top of the list */ if (newgrf_size > 0) { - *list->Append() = new DropDownListItem(-1, false); // separator line + list.emplace_back(new DropDownListItem(-1, false)); // separator line newgrf_size++; } /* Add and sort original townnames generators */ for (int i = 0; i < _nb_orig_names; i++) { - *list->Append() = new DropDownListStringItem(STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH + i, i, enabled_item != i && enabled_item >= 0); + list.emplace_back(new DropDownListStringItem(STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH + i, i, enabled_item != i && enabled_item >= 0)); } - QSortT(list->Begin() + newgrf_size, list->Length() - newgrf_size, DropDownListStringItem::NatSortFunc); + std::sort(list.begin() + newgrf_size, list.end(), DropDownListStringItem::NatSortFunc); break; } case WID_GO_AUTOSAVE_DROPDOWN: { // Setup autosave dropdown - list = new DropDownList(); *selected_index = _settings_client.gui.autosave; const StringID *items = _autosave_dropdown; for (uint i = 0; *items != INVALID_STRING_ID; items++, i++) { - *list->Append() = new DropDownListStringItem(*items, i, false); + list.emplace_back(new DropDownListStringItem(*items, i, false)); } break; } case WID_GO_LANG_DROPDOWN: { // Setup interface language dropdown - list = new DropDownList(); - for (uint i = 0; i < _languages.Length(); i++) { + for (uint i = 0; i < _languages.size(); i++) { if (&_languages[i] == _current_language) *selected_index = i; - *list->Append() = new DropDownListStringItem(SPECSTR_LANGUAGE_START + i, i, false); + list.emplace_back(new DropDownListStringItem(SPECSTR_LANGUAGE_START + i, i, false)); } - QSortT(list->Begin(), list->Length(), DropDownListStringItem::NatSortFunc); + std::sort(list.begin(), list.end(), DropDownListStringItem::NatSortFunc); break; } case WID_GO_RESOLUTION_DROPDOWN: // Setup resolution dropdown - if (_num_resolutions == 0) break; + if (_resolutions.empty()) break; - list = new DropDownList(); *selected_index = GetCurRes(); - for (int i = 0; i < _num_resolutions; i++) { - *list->Append() = new DropDownListStringItem(SPECSTR_RESOLUTION_START + i, i, false); + for (uint i = 0; i < _resolutions.size(); i++) { + list.emplace_back(new DropDownListStringItem(SPECSTR_RESOLUTION_START + i, i, false)); } break; @@ -323,21 +313,19 @@ struct GameOptionsWindow : Window { break; case WID_GO_GUI_ZOOM_DROPDOWN: { - list = new DropDownList(); *selected_index = ZOOM_LVL_OUT_4X - _gui_zoom; const StringID *items = _gui_zoom_dropdown; for (int i = 0; *items != INVALID_STRING_ID; items++, i++) { - *list->Append() = new DropDownListStringItem(*items, i, _settings_client.gui.zoom_min > ZOOM_LVL_OUT_4X - i); + list.emplace_back(new DropDownListStringItem(*items, i, _settings_client.gui.zoom_min > ZOOM_LVL_OUT_4X - i)); } break; } case WID_GO_FONT_ZOOM_DROPDOWN: { - list = new DropDownList(); *selected_index = ZOOM_LVL_OUT_4X - _font_zoom; const StringID *items = _font_zoom_dropdown; for (int i = 0; *items != INVALID_STRING_ID; items++, i++) { - *list->Append() = new DropDownListStringItem(*items, i, false); + list.emplace_back(new DropDownListStringItem(*items, i, false)); } break; } @@ -353,15 +341,12 @@ struct GameOptionsWindow : Window { case WID_GO_BASE_MUSIC_DROPDOWN: list = BuildMusicSetDropDownList(selected_index); break; - - default: - return NULL; } return list; } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { switch (widget) { case WID_GO_CURRENCY_DROPDOWN: SetDParam(0, _currency_specs[this->opt->locale.currency].name); break; @@ -369,7 +354,7 @@ struct GameOptionsWindow : Window { case WID_GO_TOWNNAME_DROPDOWN: SetDParam(0, TownName(this->opt->game_creation.town_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_RESOLUTION_DROPDOWN: SetDParam(0, GetCurRes() == _num_resolutions ? STR_GAME_OPTIONS_RESOLUTION_OTHER : SPECSTR_RESOLUTION_START + GetCurRes()); break; + case WID_GO_RESOLUTION_DROPDOWN: SetDParam(0, GetCurRes() == _resolutions.size() ? STR_GAME_OPTIONS_RESOLUTION_OTHER : SPECSTR_RESOLUTION_START + GetCurRes()); break; case WID_GO_BUTTON_SIZE_DROPDOWN:SetDParam(0, _settings_client.gui.min_button); break; case WID_GO_TEXT_SIZE_DROPDOWN: SetDParam(0, _freetype.medium.size); break; case WID_GO_GUI_ZOOM_DROPDOWN: SetDParam(0, _gui_zoom_dropdown[ZOOM_LVL_OUT_4X - _gui_zoom]); break; @@ -382,7 +367,7 @@ struct GameOptionsWindow : Window { } } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { switch (widget) { case WID_GO_BASE_GRF_DESCRIPTION: @@ -402,7 +387,7 @@ struct GameOptionsWindow : Window { } } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_GO_BASE_GRF_DESCRIPTION: @@ -453,38 +438,37 @@ struct GameOptionsWindow : Window { default: { int selected; - DropDownList *list = this->BuildDropDownList(widget, &selected); - if (list != NULL) { + DropDownList list = this->BuildDropDownList(widget, &selected); + if (!list.empty()) { /* Find the biggest item for the default size. */ - for (const DropDownListItem * const *it = list->Begin(); it != list->End(); it++) { + for (const auto &ddli : list) { Dimension string_dim; - int width = (*it)->Width(); + int width = ddli->Width(); string_dim.width = width + padding.width; - string_dim.height = (*it)->Height(width) + padding.height; + string_dim.height = ddli->Height(width) + padding.height; *size = maxdim(*size, string_dim); } - delete list; } } } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { if (widget >= WID_GO_BASE_GRF_TEXTFILE && widget < WID_GO_BASE_GRF_TEXTFILE + TFT_END) { - if (BaseGraphics::GetUsedSet() == NULL) return; + if (BaseGraphics::GetUsedSet() == nullptr) return; ShowBaseSetTextfileWindow((TextfileType)(widget - WID_GO_BASE_GRF_TEXTFILE), BaseGraphics::GetUsedSet(), STR_CONTENT_TYPE_BASE_GRAPHICS); return; } if (widget >= WID_GO_BASE_SFX_TEXTFILE && widget < WID_GO_BASE_SFX_TEXTFILE + TFT_END) { - if (BaseSounds::GetUsedSet() == NULL) return; + if (BaseSounds::GetUsedSet() == nullptr) return; ShowBaseSetTextfileWindow((TextfileType)(widget - WID_GO_BASE_SFX_TEXTFILE), BaseSounds::GetUsedSet(), STR_CONTENT_TYPE_BASE_SOUNDS); return; } if (widget >= WID_GO_BASE_MUSIC_TEXTFILE && widget < WID_GO_BASE_MUSIC_TEXTFILE + TFT_END) { - if (BaseMusic::GetUsedSet() == NULL) return; + if (BaseMusic::GetUsedSet() == nullptr) return; ShowBaseSetTextfileWindow((TextfileType)(widget - WID_GO_BASE_MUSIC_TEXTFILE), BaseMusic::GetUsedSet(), STR_CONTENT_TYPE_BASE_MUSIC); return; @@ -549,9 +533,9 @@ struct GameOptionsWindow : Window { default: { int selected; - DropDownList *list = this->BuildDropDownList(widget, &selected); - if (list != NULL) { - ShowDropDownList(this, list, selected, widget); + DropDownList list = this->BuildDropDownList(widget, &selected); + if (!list.empty()) { + ShowDropDownList(this, std::move(list), selected, widget); } else { if (widget == WID_GO_RESOLUTION_DROPDOWN) ShowErrorMessage(STR_ERROR_RESOLUTION_LIST_FAILED, INVALID_STRING_ID, WL_ERROR); } @@ -580,7 +564,7 @@ struct GameOptionsWindow : Window { } } - virtual void OnDropdownSelect(int widget, int index) + void OnDropdownSelect(int widget, int index) override { switch (widget) { case WID_GO_CURRENCY_DROPDOWN: // Currency @@ -592,7 +576,7 @@ struct GameOptionsWindow : Window { case WID_GO_ROADSIDE_DROPDOWN: // Road side if (this->opt->vehicle.road_side != index) { // only change if setting changed uint i; - if (GetSettingFromName("vehicle.road_side", &i) == NULL) NOT_REACHED(); + if (GetSettingFromName("vehicle.road_side", &i) == nullptr) NOT_REACHED(); SetSettingValue(i, index); MarkWholeScreenDirty(); } @@ -614,14 +598,15 @@ struct GameOptionsWindow : Window { ReadLanguagePack(&_languages[index]); DeleteWindowByClass(WC_QUERY_STRING); CheckForMissingGlyphs(); + ClearAllCachedNames(); UpdateAllVirtCoords(); ReInitAllWindows(); break; case WID_GO_RESOLUTION_DROPDOWN: // Change resolution - if (index < _num_resolutions && ChangeResInGame(_resolutions[index].width, _resolutions[index].height)) { - ReconstructUserInterface(); + if ((uint)index < _resolutions.size() && ChangeResInGame(_resolutions[index].width, _resolutions[index].height)) { this->SetDirty(); + ReconstructUserInterface(); } break; @@ -644,6 +629,7 @@ struct GameOptionsWindow : Window { _gui_zoom = (ZoomLevel)(ZOOM_LVL_OUT_4X - index); UpdateCursorSize(); UpdateAllVirtCoords(); + FixTitleGameZoom(); ReInitAllWindows(); break; @@ -675,7 +661,7 @@ struct GameOptionsWindow : Window { * @param data Information about the changed data. @see GameOptionsInvalidationData * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; this->SetWidgetLoweredState(WID_GO_WINDOWS_TITLEBARS, _settings_client.gui.windows_titlebars); @@ -691,9 +677,9 @@ struct GameOptionsWindow : Window { this->GetWidget(WID_GO_BASE_GRF_STATUS)->SetDataTip(missing_files ? STR_EMPTY : STR_GAME_OPTIONS_BASE_GRF_STATUS, STR_NULL); for (TextfileType tft = TFT_BEGIN; tft < TFT_END; tft++) { - this->SetWidgetDisabledState(WID_GO_BASE_GRF_TEXTFILE + tft, BaseGraphics::GetUsedSet() == NULL || BaseGraphics::GetUsedSet()->GetTextfile(tft) == NULL); - this->SetWidgetDisabledState(WID_GO_BASE_SFX_TEXTFILE + tft, BaseSounds::GetUsedSet() == NULL || BaseSounds::GetUsedSet()->GetTextfile(tft) == NULL); - this->SetWidgetDisabledState(WID_GO_BASE_MUSIC_TEXTFILE + tft, BaseMusic::GetUsedSet() == NULL || BaseMusic::GetUsedSet()->GetTextfile(tft) == NULL); + this->SetWidgetDisabledState(WID_GO_BASE_GRF_TEXTFILE + tft, BaseGraphics::GetUsedSet() == nullptr || BaseGraphics::GetUsedSet()->GetTextfile(tft) == nullptr); + this->SetWidgetDisabledState(WID_GO_BASE_SFX_TEXTFILE + tft, BaseSounds::GetUsedSet() == nullptr || BaseSounds::GetUsedSet()->GetTextfile(tft) == nullptr); + this->SetWidgetDisabledState(WID_GO_BASE_MUSIC_TEXTFILE + tft, BaseMusic::GetUsedSet() == nullptr || BaseMusic::GetUsedSet()->GetTextfile(tft) == nullptr); } missing_files = BaseMusic::GetUsedSet()->GetNumInvalid() == 0; @@ -1001,14 +987,14 @@ bool BaseSettingEntry::IsVisible(const BaseSettingEntry *item) const * Find setting entry at row \a row_num * @param row_num Index of entry to return * @param cur_row Current row number - * @return The requested setting entry or \c NULL if it not found (folded or filtered) + * @return The requested setting entry or \c nullptr if it not found (folded or filtered) */ BaseSettingEntry *BaseSettingEntry::FindEntry(uint row_num, uint *cur_row) { - if (this->IsFiltered()) return NULL; + if (this->IsFiltered()) return nullptr; if (row_num == *cur_row) return this; (*cur_row)++; - return NULL; + return nullptr; } /** @@ -1083,7 +1069,7 @@ uint BaseSettingEntry::Draw(GameSettings *settings_ptr, int left, int right, int SettingEntry::SettingEntry(const char *name) { this->name = name; - this->setting = NULL; + this->setting = nullptr; this->index = 0; } @@ -1095,7 +1081,7 @@ void SettingEntry::Init(byte level) { BaseSettingEntry::Init(level); this->setting = GetSettingFromName(this->name, &this->index); - assert(this->setting != NULL); + assert(this->setting != nullptr); } /** @@ -1374,14 +1360,14 @@ uint SettingsContainer::Length() const * Find the setting entry at row number \a row_num * @param row_num Index of entry to return * @param cur_row Variable used for keeping track of the current row number. Should point to memory initialized to \c 0 when first called. - * @return The requested setting entry or \c NULL if it does not exist + * @return The requested setting entry or \c nullptr if it does not exist */ BaseSettingEntry *SettingsContainer::FindEntry(uint row_num, uint *cur_row) { - BaseSettingEntry *pe = NULL; + BaseSettingEntry *pe = nullptr; for (EntryVector::iterator it = this->entries.begin(); it != this->entries.end(); ++it) { pe = (*it)->FindEntry(row_num, cur_row); - if (pe != NULL) { + if (pe != nullptr) { break; } } @@ -1537,14 +1523,14 @@ uint SettingsPage::Length() const * Find setting entry at row \a row_num * @param row_num Index of entry to return * @param cur_row Current row number - * @return The requested setting entry or \c NULL if it not found (folded or filtered) + * @return The requested setting entry or \c nullptr if it not found (folded or filtered) */ BaseSettingEntry *SettingsPage::FindEntry(uint row_num, uint *cur_row) { - if (this->IsFiltered()) return NULL; + if (this->IsFiltered()) return nullptr; if (row_num == *cur_row) return this; (*cur_row)++; - if (this->folded) return NULL; + if (this->folded) return nullptr; return SettingsContainer::FindEntry(row_num, cur_row); } @@ -1600,9 +1586,9 @@ void SettingsPage::DrawSetting(GameSettings *settings_ptr, int left, int right, /** Construct settings tree */ static SettingsContainer &GetSettingsTree() { - static SettingsContainer *main = NULL; + static SettingsContainer *main = nullptr; - if (main == NULL) + if (main == nullptr) { /* Build up the dynamic settings-array only once per OpenTTD session */ main = new SettingsContainer(); @@ -1695,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.expenses_layout")); + interface->Add(new SettingEntry("gui.show_newgrf_name")); } SettingsPage *advisors = main->Add(new SettingsPage(STR_CONFIG_SETTING_ADVISORS)); @@ -1827,6 +1814,7 @@ static SettingsContainer &GetSettingsTree() genworld->Add(new SettingEntry("economy.town_layout")); genworld->Add(new SettingEntry("difficulty.industry_density")); genworld->Add(new SettingEntry("gui.pause_on_newgame")); + genworld->Add(new SettingEntry("game_creation.ending_year")); } SettingsPage *environment = main->Add(new SettingsPage(STR_CONFIG_SETTING_ENVIRONMENT)); @@ -1847,6 +1835,7 @@ static SettingsContainer &GetSettingsTree() towns->Add(new SettingEntry("economy.allow_town_roads")); towns->Add(new SettingEntry("economy.allow_town_level_crossings")); towns->Add(new SettingEntry("economy.found_town")); + towns->Add(new SettingEntry("economy.town_cargogen_mode")); } SettingsPage *industries = environment->Add(new SettingsPage(STR_CONFIG_SETTING_ENVIRONMENT_INDUSTRIES)); @@ -1856,6 +1845,7 @@ static SettingsContainer &GetSettingsTree() industries->Add(new SettingEntry("economy.multiple_industry_per_town")); industries->Add(new SettingEntry("game_creation.oil_refinery_limit")); industries->Add(new SettingEntry("economy.smooth_economy")); + industries->Add(new SettingEntry("station.serve_neutral_industries")); } SettingsPage *cdist = environment->Add(new SettingsPage(STR_CONFIG_SETTING_ENVIRONMENT_CARGODIST)); @@ -1882,6 +1872,7 @@ static SettingsContainer &GetSettingsTree() { npc->Add(new SettingEntry("script.settings_profile")); npc->Add(new SettingEntry("script.script_max_opcode_till_suspend")); + npc->Add(new SettingEntry("script.script_max_memory_megabytes")); npc->Add(new SettingEntry("difficulty.competitor_speed")); npc->Add(new SettingEntry("ai.ai_in_multiplayer")); npc->Add(new SettingEntry("ai.ai_disable_veh_train")); @@ -1892,6 +1883,7 @@ static SettingsContainer &GetSettingsTree() ai->Add(new SettingEntry("economy.give_money")); ai->Add(new SettingEntry("economy.allow_shares")); + ai->Add(new SettingEntry("economy.min_years_for_shares")); } main->Init(); @@ -1925,10 +1917,10 @@ struct GameSettingsWindow : Window { static GameSettings *settings_ptr; ///< Pointer to the game settings being displayed and modified. - SettingEntry *valuewindow_entry; ///< If non-NULL, pointer to setting for which a value-entering window has been opened. - SettingEntry *clicked_entry; ///< If non-NULL, pointer to a clicked numeric setting (with a depressed left or right button). - SettingEntry *last_clicked; ///< If non-NULL, pointer to the last clicked setting. - SettingEntry *valuedropdown_entry; ///< If non-NULL, pointer to the value for which a dropdown window is currently opened. + SettingEntry *valuewindow_entry; ///< If non-nullptr, pointer to setting for which a value-entering window has been opened. + SettingEntry *clicked_entry; ///< If non-nullptr, pointer to a clicked numeric setting (with a depressed left or right button). + SettingEntry *last_clicked; ///< If non-nullptr, pointer to the last clicked setting. + SettingEntry *valuedropdown_entry; ///< If non-nullptr, pointer to the value for which a dropdown window is currently opened. bool closing_dropdown; ///< True, if the dropdown list is currently closing. SettingFilter filter; ///< Filter for the list. @@ -1952,10 +1944,10 @@ struct GameSettingsWindow : Window { _circle_size = maxdim(GetSpriteSize(SPR_CIRCLE_FOLDED), GetSpriteSize(SPR_CIRCLE_UNFOLDED)); GetSettingsTree().FoldAll(); // Close all sub-pages - this->valuewindow_entry = NULL; // No setting entry for which a entry window is opened - this->clicked_entry = NULL; // No numeric setting buttons are depressed - this->last_clicked = NULL; - this->valuedropdown_entry = NULL; + this->valuewindow_entry = nullptr; // No setting entry for which a entry window is opened + this->clicked_entry = nullptr; // No numeric setting buttons are depressed + this->last_clicked = nullptr; + this->valuedropdown_entry = nullptr; this->closing_dropdown = false; this->manually_changed_folding = false; @@ -1975,7 +1967,7 @@ struct GameSettingsWindow : Window { SaveToConfig(); // save all settins immediately on Android, because users tend to kill the app instead of pressing 'Quit' button } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_GS_OPTIONSPANEL: @@ -2010,13 +2002,13 @@ struct GameSettingsWindow : Window { } } - virtual void OnPaint() + void OnPaint() override { if (this->closing_dropdown) { this->closing_dropdown = false; - assert(this->valuedropdown_entry != NULL); + assert(this->valuedropdown_entry != nullptr); this->valuedropdown_entry->SetButtons(0); - this->valuedropdown_entry = NULL; + this->valuedropdown_entry = nullptr; } /* Reserve the correct number of lines for the 'some search results are hidden' notice in the central settings display panel. */ @@ -2051,7 +2043,7 @@ struct GameSettingsWindow : Window { } } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { switch (widget) { case WID_GS_RESTRICT_DROPDOWN: @@ -2069,34 +2061,31 @@ struct GameSettingsWindow : Window { } } - DropDownList *BuildDropDownList(int widget) const + DropDownList BuildDropDownList(int widget) const { - DropDownList *list = NULL; + DropDownList list; switch (widget) { case WID_GS_RESTRICT_DROPDOWN: - list = new DropDownList(); - for (int mode = 0; mode != RM_END; mode++) { /* If we are in adv. settings screen for the new game's settings, * we don't want to allow comparing with new game's settings. */ bool disabled = mode == RM_CHANGED_AGAINST_NEW && settings_ptr == &_settings_newgame; - *list->Append() = new DropDownListStringItem(_game_settings_restrict_dropdown[mode], mode, disabled); + list.emplace_back(new DropDownListStringItem(_game_settings_restrict_dropdown[mode], mode, disabled)); } break; case WID_GS_TYPE_DROPDOWN: - list = new DropDownList(); - *list->Append() = new DropDownListStringItem(STR_CONFIG_SETTING_TYPE_DROPDOWN_ALL, ST_ALL, false); - *list->Append() = new DropDownListStringItem(_game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_INGAME, ST_GAME, false); - *list->Append() = new DropDownListStringItem(_game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_INGAME, ST_COMPANY, false); - *list->Append() = new DropDownListStringItem(STR_CONFIG_SETTING_TYPE_DROPDOWN_CLIENT, ST_CLIENT, false); + list.emplace_back(new DropDownListStringItem(STR_CONFIG_SETTING_TYPE_DROPDOWN_ALL, ST_ALL, false)); + list.emplace_back(new DropDownListStringItem(_game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_GAME_INGAME, ST_GAME, false)); + list.emplace_back(new DropDownListStringItem(_game_mode == GM_MENU ? STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_MENU : STR_CONFIG_SETTING_TYPE_DROPDOWN_COMPANY_INGAME, ST_COMPANY, false)); + list.emplace_back(new DropDownListStringItem(STR_CONFIG_SETTING_TYPE_DROPDOWN_CLIENT, ST_CLIENT, false)); break; } return list; } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { switch (widget) { case WID_GS_OPTIONSPANEL: { @@ -2109,7 +2098,7 @@ struct GameSettingsWindow : Window { } case WID_GS_HELP_TEXT: - if (this->last_clicked != NULL) { + if (this->last_clicked != nullptr) { const SettingDesc *sd = this->last_clicked->setting; int y = r.top; @@ -2138,7 +2127,7 @@ struct GameSettingsWindow : Window { /** * Set the entry that should have its help text displayed, and mark the window dirty so it gets repainted. - * @param pe Setting to display help text of, use \c NULL to stop displaying help of the currently displayed setting. + * @param pe Setting to display help text of, use \c nullptr to stop displaying help of the currently displayed setting. */ void SetDisplayedHelpText(SettingEntry *pe) { @@ -2146,7 +2135,7 @@ struct GameSettingsWindow : Window { this->last_clicked = pe; } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_GS_EXPAND_ALL: @@ -2162,17 +2151,17 @@ struct GameSettingsWindow : Window { break; case WID_GS_RESTRICT_DROPDOWN: { - DropDownList *list = this->BuildDropDownList(widget); - if (list != NULL) { - ShowDropDownList(this, list, this->filter.mode, widget); + DropDownList list = this->BuildDropDownList(widget); + if (!list.empty()) { + ShowDropDownList(this, std::move(list), this->filter.mode, widget); } break; } case WID_GS_TYPE_DROPDOWN: { - DropDownList *list = this->BuildDropDownList(widget); - if (list != NULL) { - ShowDropDownList(this, list, this->filter.type, widget); + DropDownList list = this->BuildDropDownList(widget); + if (!list.empty()) { + ShowDropDownList(this, std::move(list), this->filter.type, widget); } break; } @@ -2187,14 +2176,14 @@ struct GameSettingsWindow : Window { uint cur_row = 0; BaseSettingEntry *clicked_entry = GetSettingsTree().FindEntry(btn, &cur_row); - if (clicked_entry == NULL) return; // Clicked below the last setting of the page + 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 if (x < 0) return; // Clicked left of the entry SettingsPage *clicked_page = dynamic_cast(clicked_entry); - if (clicked_page != NULL) { - this->SetDisplayedHelpText(NULL); + if (clicked_page != nullptr) { + this->SetDisplayedHelpText(nullptr); clicked_page->folded = !clicked_page->folded; // Flip 'folded'-ness of the sub-page this->manually_changed_folding = true; @@ -2204,7 +2193,7 @@ struct GameSettingsWindow : Window { } SettingEntry *pe = dynamic_cast(clicked_entry); - assert(pe != NULL); + assert(pe != nullptr); const SettingDesc *sd = pe->setting; /* return if action is only active in network, or only settable by server */ @@ -2226,9 +2215,9 @@ struct GameSettingsWindow : Window { HideDropDownMenu(this); this->closing_dropdown = false; this->valuedropdown_entry->SetButtons(0); - this->valuedropdown_entry = NULL; + this->valuedropdown_entry = nullptr; } else { - if (this->valuedropdown_entry != NULL) this->valuedropdown_entry->SetButtons(0); + if (this->valuedropdown_entry != nullptr) this->valuedropdown_entry->SetButtons(0); this->closing_dropdown = false; const NWidgetBase *wid = this->GetWidget(WID_GS_OPTIONSPANEL); @@ -2245,12 +2234,12 @@ struct GameSettingsWindow : Window { this->valuedropdown_entry = pe; this->valuedropdown_entry->SetButtons(SEF_LEFT_DEPRESSED); - DropDownList *list = new DropDownList(); + DropDownList list; for (int i = sdb->min; i <= (int)sdb->max; i++) { - *list->Append() = new DropDownListStringItem(sdb->str_val + i - sdb->min, i, false); + list.emplace_back(new DropDownListStringItem(sdb->str_val + i - sdb->min, i, false)); } - ShowDropDownListAt(this, list, value, -1, wi_rect, COLOUR_ORANGE, true); + ShowDropDownListAt(this, std::move(list), value, -1, wi_rect, COLOUR_ORANGE, true); } } this->SetDirty(); @@ -2293,7 +2282,7 @@ struct GameSettingsWindow : Window { /* Set up scroller timeout for numeric values */ if (value != oldvalue) { - if (this->clicked_entry != NULL) { // Release previous buttons if any + if (this->clicked_entry != nullptr) { // Release previous buttons if any this->clicked_entry->SetButtons(0); } this->clicked_entry = pe; @@ -2329,21 +2318,21 @@ struct GameSettingsWindow : Window { } } - virtual void OnTimeout() + void OnTimeout() override { - if (this->clicked_entry != NULL) { // On timeout, release any depressed buttons + if (this->clicked_entry != nullptr) { // On timeout, release any depressed buttons this->clicked_entry->SetButtons(0); - this->clicked_entry = NULL; + this->clicked_entry = nullptr; this->SetDirty(); } } - virtual void OnQueryTextFinished(char *str) + void OnQueryTextFinished(char *str) override { /* The user pressed cancel */ - if (str == NULL) return; + if (str == nullptr) return; - assert(this->valuewindow_entry != NULL); + assert(this->valuewindow_entry != nullptr); const SettingDesc *sd = this->valuewindow_entry->setting; int32 value; @@ -2364,7 +2353,7 @@ struct GameSettingsWindow : Window { this->SetDirty(); } - virtual void OnDropdownSelect(int widget, int index) + void OnDropdownSelect(int widget, int index) override { switch (widget) { case WID_GS_RESTRICT_DROPDOWN: @@ -2392,7 +2381,7 @@ struct GameSettingsWindow : Window { default: if (widget < 0) { /* Deal with drop down boxes on the panel. */ - assert(this->valuedropdown_entry != NULL); + assert(this->valuedropdown_entry != nullptr); const SettingDesc *sd = this->valuedropdown_entry->setting; assert(sd->desc.flags & SGF_MULTISTRING); @@ -2408,7 +2397,7 @@ struct GameSettingsWindow : Window { } } - virtual void OnDropdownClose(Point pt, int widget, int index, bool instant_close) + void OnDropdownClose(Point pt, int widget, int index, bool instant_close) override { if (widget >= 0) { /* Normally the default implementation of OnDropdownClose() takes care of @@ -2421,13 +2410,13 @@ struct GameSettingsWindow : Window { * 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->valuedropdown_entry != NULL); + assert(this->valuedropdown_entry != nullptr); this->closing_dropdown = true; this->SetDirty(); } } - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; @@ -2446,8 +2435,8 @@ struct GameSettingsWindow : Window { } this->vscroll->SetCount(GetSettingsTree().Length() + this->warn_lines); - if (this->last_clicked != NULL && !GetSettingsTree().IsVisible(this->last_clicked)) { - this->SetDisplayedHelpText(NULL); + if (this->last_clicked != nullptr && !GetSettingsTree().IsVisible(this->last_clicked)) { + this->SetDisplayedHelpText(nullptr); } bool all_folded = true; @@ -2457,7 +2446,7 @@ struct GameSettingsWindow : Window { this->SetWidgetDisabledState(WID_GS_COLLAPSE_ALL, all_folded); } - virtual void OnEditboxChanged(int wid) + void OnEditboxChanged(int wid) override { if (wid == WID_GS_FILTER) { this->filter.string.SetFilterTerm(this->filter_editbox.text.buf); @@ -2470,13 +2459,13 @@ struct GameSettingsWindow : Window { } } - virtual void OnResize() + void OnResize() override { this->vscroll->SetCapacityFromWidget(this, WID_GS_OPTIONSPANEL, SETTINGTREE_TOP_OFFSET + SETTINGTREE_BOTTOM_OFFSET); } }; -GameSettings *GameSettingsWindow::settings_ptr = NULL; +GameSettings *GameSettingsWindow::settings_ptr = nullptr; static const NWidgetPart _nested_settings_selection_widgets[] = { NWidget(NWID_HORIZONTAL), @@ -2614,7 +2603,7 @@ struct CustomCurrencyWindow : Window { this->SetWidgetDisabledState(WID_CC_YEAR_UP, _custom_currency.to_euro == MAX_YEAR); } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { switch (widget) { case WID_CC_RATE: SetDParam(0, 1); SetDParam(1, 1); break; @@ -2632,7 +2621,7 @@ struct CustomCurrencyWindow : Window { } } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { /* Set the appropriate width for the edit 'buttons' */ @@ -2651,7 +2640,7 @@ struct CustomCurrencyWindow : Window { } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { int line = 0; int len = 0; @@ -2733,9 +2722,9 @@ struct CustomCurrencyWindow : Window { this->SetDirty(); } - virtual void OnQueryTextFinished(char *str) + void OnQueryTextFinished(char *str) override { - if (str == NULL) return; + if (str == nullptr) return; switch (this->query_widget) { case WID_CC_RATE: @@ -2765,7 +2754,7 @@ struct CustomCurrencyWindow : Window { SetButtonState(); } - virtual void OnTimeout() + void OnTimeout() override { this->SetDirty(); } @@ -2812,7 +2801,7 @@ static const NWidgetPart _nested_cust_currency_widgets[] = { }; static WindowDesc _cust_currency_desc( - WDP_CENTER, NULL, 0, 0, + WDP_CENTER, nullptr, 0, 0, WC_CUSTOM_CURRENCY, WC_NONE, 0, _nested_cust_currency_widgets, lengthof(_nested_cust_currency_widgets) diff --git a/src/settings_gui.h b/src/settings_gui.h index 8cc507ddd1..2699d8aa8c 100644 --- a/src/settings_gui.h +++ b/src/settings_gui.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. @@ -22,7 +20,7 @@ void DrawArrowButtons(int x, int y, Colours button_colour, byte state, bool clic void DrawDropDownButton(int x, int y, Colours button_colour, bool state, bool clickable); void DrawBoolButton(int x, int y, bool state, bool clickable); -DropDownList *BuildMusicSetDropDownList(int *selected_index); +DropDownList BuildMusicSetDropDownList(int *selected_index); /* Actually implemented in music_gui.cpp */ void ChangeMusicSet(int index); diff --git a/src/settings_internal.h b/src/settings_internal.h index 028e977e48..3d9764dc6f 100644 --- a/src/settings_internal.h +++ b/src/settings_internal.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. @@ -20,7 +18,7 @@ * @see VarTypes * @see SettingDescBase */ -enum SettingDescTypeLong { +enum SettingDescType : byte { /* 4 bytes allocated a maximum of 16 types for GenericType */ SDT_BEGIN = 0, SDT_NUMX = 0, ///< any number-type @@ -32,10 +30,9 @@ enum SettingDescTypeLong { SDT_END, /* 10 more possible primitives */ }; -typedef SimpleTinyEnumT SettingDescType; -enum SettingGuiFlagLong { +enum SettingGuiFlag : uint16 { /* 1 byte allocated for a maximum of 8 flags * Flags directing saving/loading of a variable */ SGF_NONE = 0, @@ -49,8 +46,7 @@ enum SettingGuiFlagLong { SGF_SCENEDIT_TOO = 1 << 7, ///< this setting can be changed in the scenario editor (only makes sense when SGF_NEWGAME_ONLY is set) SGF_PER_COMPANY = 1 << 8, ///< this setting can be different for each company (saved in company struct) }; -DECLARE_ENUM_AS_BIT_SET(SettingGuiFlagLong) -typedef SimpleTinyEnumT SettingGuiFlag; +DECLARE_ENUM_AS_BIT_SET(SettingGuiFlag) /** * A SettingCategory defines a grouping of the settings. diff --git a/src/settings_type.h b/src/settings_type.h index 5756c6e4e9..b85844dd19 100644 --- a/src/settings_type.h +++ b/src/settings_type.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. @@ -114,8 +112,8 @@ struct GUISettings { uint8 statusbar_pos; ///< position of statusbar, 0=left, 1=center, 2=right uint8 window_snap_radius; ///< windows snap at each other if closer than this uint8 window_soft_limit; ///< soft limit of maximum number of non-stickied non-vital windows (0 = no limit) - ZoomLevelByte zoom_min; ///< minimum zoom out level - ZoomLevelByte zoom_max; ///< maximum zoom out level + ZoomLevel zoom_min; ///< minimum zoom out level + ZoomLevel zoom_max; ///< maximum zoom out level bool disable_unsuitable_building; ///< disable infrastructure building when no suitable vehicles are available byte autosave; ///< how often should we do autosaves? byte save_to_network; ///< backup all savegames to network @@ -155,6 +153,7 @@ struct GUISettings { uint8 graph_line_thickness; ///< the thickness of the lines in the various graph guis 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 uint16 console_backlog_timeout; ///< the minimum amount of time items should be in the console backlog before they will be removed in ~3 seconds granularity. uint16 console_backlog_length; ///< the minimum amount of items in the console backlog before items will be removed. @@ -162,11 +161,9 @@ struct GUISettings { uint8 station_gui_group_order; ///< the order of grouping cargo entries in the station gui uint8 station_gui_sort_by; ///< sort cargo entries in the station gui by station name or amount uint8 station_gui_sort_order; ///< the sort order of entries in the station gui - ascending or descending -#ifdef ENABLE_NETWORK uint16 network_chat_box_width_pct; ///< width of the chat box in percent uint8 network_chat_box_height; ///< height of the chat box in lines uint16 network_chat_timeout; ///< timeout of chat messages in seconds -#endif 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 @@ -192,7 +189,7 @@ struct SoundSettings { bool news_ticker; ///< Play a ticker sound when a news item is published. bool news_full; ///< Play sound effects associated to certain news types. bool new_year; ///< Play sound on new year, summarising the performance during the last year. - bool confirm; ///< Play sound effect on succesful constructions or other actions. + bool confirm; ///< Play sound effect on successful constructions or other actions. bool click_beep; ///< Beep on a random selection of buttons. bool disaster; ///< Play disaster and accident sounds. bool vehicle; ///< Play vehicle sound effects. @@ -245,7 +242,6 @@ struct NewsSettings { /** All settings related to the network. */ struct NetworkSettings { -#ifdef ENABLE_NETWORK uint16 sync_freq; ///< how often do we check whether we are still in-sync uint8 frame_freq; ///< how often do we send commands to the clients uint16 commands_per_frame; ///< how many commands may be sent each frame_freq frames? @@ -285,14 +281,13 @@ struct NetworkSettings { char last_host[NETWORK_HOSTNAME_LENGTH]; ///< IP address of the last joined server uint16 last_port; ///< port of the last joined server bool no_http_content_downloads; ///< do not do content downloads over HTTP -#else /* ENABLE_NETWORK */ -#endif }; /** Settings related to the creation of games. */ struct GameCreationSettings { uint32 generation_seed; ///< noise seed for world generation Year starting_year; ///< starting date + Year ending_year; ///< scoring end date uint8 map_x; ///< X size of map uint8 map_y; ///< Y size of map byte land_generator; ///< the landscape generator @@ -352,12 +347,7 @@ struct AISettings { struct ScriptSettings { uint8 settings_profile; ///< difficulty profile to set initial settings of scripts, esp. random AIs uint32 script_max_opcode_till_suspend; ///< max opcode calls till scripts will suspend -}; - -/** Settings related to the old pathfinder. */ -struct OPFSettings { - uint16 pf_maxlength; ///< maximum length when searching for a train route for new pathfinder - byte pf_maxdepth; ///< maximum recursion depth when searching for a train route for new pathfinder + uint32 script_max_memory_megabytes; ///< limit on memory a single script instance may have allocated }; /** Settings related to the new pathfinder. */ @@ -426,6 +416,8 @@ struct YAPFSettings { uint32 rail_longer_platform_per_tile_penalty; ///< penalty for longer station platform than train (per tile) uint32 rail_shorter_platform_penalty; ///< penalty for shorter station platform than train uint32 rail_shorter_platform_per_tile_penalty; ///< penalty for shorter station platform than train (per tile) + uint32 ship_curve45_penalty; ///< penalty for 45-deg curve for ships + uint32 ship_curve90_penalty; ///< penalty for 90-deg curve for ships }; /** Settings related to all pathfinders. */ @@ -446,7 +438,6 @@ struct PathfinderSettings { byte wait_for_pbs_path; ///< how long to wait for a path reservation. byte path_backoff_interval; ///< ticks between checks for a free path. - OPFSettings opf; ///< pathfinder settings for the old pathfinder NPFSettings npf; ///< pathfinder settings for the new pathfinder YAPFSettings yapf; ///< pathfinder settings for the yet another pathfinder }; @@ -489,6 +480,7 @@ struct EconomySettings { bool bribe; ///< enable bribing the local authority bool smooth_economy; ///< smooth economy bool allow_shares; ///< allow the buying/selling of shares + uint8 min_years_for_shares; ///< minimum age of a company for it to trade shares uint8 feeder_payment_share; ///< percentage of leg payment to virtually pay in feeder systems byte dist_local_authority; ///< distance for town local authority, default 20 bool exclusive_rights; ///< allow buying exclusive rights @@ -500,9 +492,10 @@ struct EconomySettings { uint8 town_growth_rate; ///< town growth rate uint8 larger_towns; ///< the number of cities to build. These start off larger and grow twice as fast uint8 initial_city_size; ///< multiplier for the initial size of the cities compared to towns - TownLayoutByte town_layout; ///< select town layout, @see TownLayout + TownLayout town_layout; ///< select town layout, @see TownLayout + TownCargoGenMode town_cargogen_mode; ///< algorithm for generating cargo from houses, @see TownCargoGenMode bool allow_town_roads; ///< towns are allowed to build roads (always allowed when generating world / in SE) - TownFoundingByte found_town; ///< town founding, @see TownFounding + TownFounding found_town; ///< town founding. bool station_noise_level; ///< build new airports when the town noise level is still within accepted limits uint16 town_noise_population[3]; ///< population to base decision on noise evaluation (@see town_council_tolerance) bool allow_town_level_crossings; ///< towns are allowed to build level crossings @@ -510,16 +503,16 @@ struct EconomySettings { }; struct LinkGraphSettings { - uint16 recalc_time; ///< time (in days) for recalculating each link graph component. - uint16 recalc_interval; ///< time (in days) between subsequent checks for link graphs to be calculated. - DistributionTypeByte distribution_pax; ///< distribution type for passengers - DistributionTypeByte distribution_mail; ///< distribution type for mail - DistributionTypeByte distribution_armoured; ///< distribution type for armoured cargo class - DistributionTypeByte distribution_default; ///< distribution type for all other goods - uint8 accuracy; ///< accuracy when calculating things on the link graph. low accuracy => low running time - uint8 demand_size; ///< influence of supply ("station size") on the demand function - uint8 demand_distance; ///< influence of distance between stations on the demand function - uint8 short_path_saturation; ///< percentage up to which short paths are saturated before saturating most capacious paths + uint16 recalc_time; ///< time (in days) for recalculating each link graph component. + uint16 recalc_interval; ///< time (in days) between subsequent checks for link graphs to be calculated. + DistributionType distribution_pax; ///< distribution type for passengers + DistributionType distribution_mail; ///< distribution type for mail + DistributionType distribution_armoured; ///< distribution type for armoured cargo class + DistributionType distribution_default; ///< distribution type for all other goods + uint8 accuracy; ///< accuracy when calculating things on the link graph. low accuracy => low running time + uint8 demand_size; ///< influence of supply ("station size") on the demand function + uint8 demand_distance; ///< influence of distance between stations on the demand function + uint8 short_path_saturation; ///< percentage up to which short paths are saturated before saturating most capacious paths inline DistributionType GetDistributionType(CargoID cargo) const { if (IsCargoInClass(cargo, CC_PASSENGERS)) return this->distribution_pax; @@ -532,6 +525,7 @@ struct LinkGraphSettings { /** Settings related to stations. */ struct StationSettings { bool modified_catchment; ///< different-size catchment areas + bool serve_neutral_industries; ///< company stations can serve industries with attached neutral stations bool adjacent_stations; ///< allow stations to be built directly adjacent to other stations bool distant_join_stations; ///< allow to join non-adjacent stations bool never_expire_airports; ///< never expire airports diff --git a/src/settingsgen/settingsgen.cpp b/src/settingsgen/settingsgen.cpp index 298539417e..9f272dabbe 100644 --- a/src/settingsgen/settingsgen.cpp +++ b/src/settingsgen/settingsgen.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. @@ -23,13 +21,6 @@ #include #endif -#ifdef __MORPHOS__ -#ifdef stderr -#undef stderr -#endif -#define stderr stdout -#endif /* __MORPHOS__ */ - #include "../safeguards.h" /** @@ -48,7 +39,7 @@ void NORETURN CDECL error(const char *s, ...) exit(1); } -static const int OUTPUT_BLOCK_SIZE = 16000; ///< Block size of the buffer in #OutputBuffer. +static const size_t OUTPUT_BLOCK_SIZE = 16000; ///< Block size of the buffer in #OutputBuffer. /** Output buffer for a block of data. */ class OutputBuffer { @@ -65,10 +56,9 @@ public: * @param length Length of the text in bytes. * @return Number of bytes actually stored. */ - int Add(const char *text, int length) + size_t Add(const char *text, size_t length) { - int store_size = min(length, OUTPUT_BLOCK_SIZE - this->size); - assert(store_size >= 0); + size_t store_size = min(length, OUTPUT_BLOCK_SIZE - this->size); assert(store_size <= OUTPUT_BLOCK_SIZE); MemCpyT(this->data + this->size, text, store_size); this->size += store_size; @@ -81,7 +71,7 @@ public: */ void Write(FILE *out_fp) const { - if (fwrite(this->data, 1, this->size, out_fp) != (size_t)this->size) { + if (fwrite(this->data, 1, this->size, out_fp) != this->size) { fprintf(stderr, "Error: Cannot write output\n"); } } @@ -95,7 +85,7 @@ public: return this->size < OUTPUT_BLOCK_SIZE; } - int size; ///< Number of bytes stored in \a data. + size_t size; ///< Number of bytes stored in \a data. char data[OUTPUT_BLOCK_SIZE]; ///< Stored data. }; @@ -110,7 +100,7 @@ public: /** Clear the temporary storage. */ void Clear() { - this->output_buffer.Clear(); + this->output_buffer.clear(); } /** @@ -118,19 +108,20 @@ public: * @param text Text to store. * @param length Length of the text in bytes, \c 0 means 'length of the string'. */ - void Add(const char *text, int length = 0) + void Add(const char *text, size_t length = 0) { if (length == 0) length = strlen(text); if (length > 0 && this->BufferHasRoom()) { - int stored_size = this->output_buffer[this->output_buffer.Length() - 1].Add(text, length); + size_t stored_size = this->output_buffer[this->output_buffer.size() - 1].Add(text, length); length -= stored_size; text += stored_size; } while (length > 0) { - OutputBuffer *block = this->output_buffer.Append(); - block->Clear(); // Initialize the new block. - int stored_size = block->Add(text, length); + /*C++17: OutputBuffer &block =*/ this->output_buffer.emplace_back(); + OutputBuffer &block = this->output_buffer.back(); + block.Clear(); // Initialize the new block. + size_t stored_size = block.Add(text, length); length -= stored_size; text += stored_size; } @@ -142,8 +133,8 @@ public: */ void Write(FILE *out_fp) const { - for (const OutputBuffer *out_data = this->output_buffer.Begin(); out_data != this->output_buffer.End(); out_data++) { - out_data->Write(out_fp); + for (const OutputBuffer &out_data : output_buffer) { + out_data.Write(out_fp); } } @@ -154,11 +145,11 @@ private: */ bool BufferHasRoom() const { - uint num_blocks = this->output_buffer.Length(); + size_t num_blocks = this->output_buffer.size(); return num_blocks > 0 && this->output_buffer[num_blocks - 1].HasRoom(); } - typedef SmallVector OutputBufferVector; ///< Vector type for output buffers. + typedef std::vector OutputBufferVector; ///< Vector type for output buffers. OutputBufferVector output_buffer; ///< Vector of blocks containing the stored output. }; @@ -167,10 +158,10 @@ private: struct SettingsIniFile : IniLoadFile { /** * Construct a new ini loader. - * @param list_group_names A \c NULL terminated list with group names that should be loaded as lists instead of variables. @see IGT_LIST - * @param seq_group_names A \c NULL terminated list with group names that should be loaded as lists of names. @see IGT_SEQUENCE + * @param list_group_names A \c nullptr terminated list with group names that should be loaded as lists instead of variables. @see IGT_LIST + * @param seq_group_names A \c nullptr terminated list with group names that should be loaded as lists of names. @see IGT_SEQUENCE */ - SettingsIniFile(const char * const *list_group_names = NULL, const char * const *seq_group_names = NULL) : + SettingsIniFile(const char * const *list_group_names = nullptr, const char * const *seq_group_names = nullptr) : IniLoadFile(list_group_names, seq_group_names) { } @@ -180,7 +171,7 @@ struct SettingsIniFile : IniLoadFile { /* Open the text file in binary mode to prevent end-of-line translations * done by ftell() and friends, as defined by K&R. */ FILE *in = fopen(filename, "rb"); - if (in == NULL) return NULL; + if (in == nullptr) return nullptr; fseek(in, 0L, SEEK_END); *size = ftell(in); @@ -209,9 +200,9 @@ static const char *DEFAULTS_GROUP_NAME = "defaults"; ///< Name of the group c */ static IniLoadFile *LoadIniFile(const char *filename) { - static const char * const seq_groups[] = {PREAMBLE_GROUP_NAME, POSTAMBLE_GROUP_NAME, NULL}; + static const char * const seq_groups[] = {PREAMBLE_GROUP_NAME, POSTAMBLE_GROUP_NAME, nullptr}; - IniLoadFile *ini = new SettingsIniFile(NULL, seq_groups); + IniLoadFile *ini = new SettingsIniFile(nullptr, seq_groups); ini->LoadFromDisk(filename, NO_DIRECTORY); return ini; } @@ -224,8 +215,8 @@ static IniLoadFile *LoadIniFile(const char *filename) static void DumpGroup(IniLoadFile *ifile, const char * const group_name) { IniGroup *grp = ifile->GetGroup(group_name, 0, false); - if (grp != NULL && grp->type == IGT_SEQUENCE) { - for (IniItem *item = grp->item; item != NULL; item = item->next) { + if (grp != nullptr && grp->type == IGT_SEQUENCE) { + for (IniItem *item = grp->item; item != nullptr; item = item->next) { if (item->name) { _stored_output.Add(item->name); _stored_output.Add("\n", 1); @@ -238,14 +229,14 @@ static void DumpGroup(IniLoadFile *ifile, const char * const group_name) * Find the value of a template variable. * @param name Name of the item to find. * @param grp Group currently being expanded (searched first). - * @param defaults Fallback group to search, \c NULL skips the search. - * @return Text of the item if found, else \c NULL. + * @param defaults Fallback group to search, \c nullptr skips the search. + * @return Text of the item if found, else \c nullptr. */ static const char *FindItemValue(const char *name, IniGroup *grp, IniGroup *defaults) { IniItem *item = grp->GetItem(name, false); - if (item == NULL && defaults != NULL) item = defaults->GetItem(name, false); - if (item == NULL || item->value == NULL) return NULL; + if (item == nullptr && defaults != nullptr) item = defaults->GetItem(name, false); + if (item == nullptr || item->value == nullptr) return nullptr; return item->value; } @@ -256,30 +247,30 @@ static const char *FindItemValue(const char *name, IniGroup *grp, IniGroup *defa static void DumpSections(IniLoadFile *ifile) { static const int MAX_VAR_LENGTH = 64; - static const char * const special_group_names[] = {PREAMBLE_GROUP_NAME, POSTAMBLE_GROUP_NAME, DEFAULTS_GROUP_NAME, TEMPLATES_GROUP_NAME, NULL}; + static const char * const special_group_names[] = {PREAMBLE_GROUP_NAME, POSTAMBLE_GROUP_NAME, DEFAULTS_GROUP_NAME, TEMPLATES_GROUP_NAME, nullptr}; IniGroup *default_grp = ifile->GetGroup(DEFAULTS_GROUP_NAME, 0, false); IniGroup *templates_grp = ifile->GetGroup(TEMPLATES_GROUP_NAME, 0, false); - if (templates_grp == NULL) return; + if (templates_grp == nullptr) return; /* Output every group, using its name as template name. */ - for (IniGroup *grp = ifile->group; grp != NULL; grp = grp->next) { + for (IniGroup *grp = ifile->group; grp != nullptr; grp = grp->next) { const char * const *sgn; - for (sgn = special_group_names; *sgn != NULL; sgn++) if (strcmp(grp->name, *sgn) == 0) break; - if (*sgn != NULL) continue; + for (sgn = special_group_names; *sgn != nullptr; sgn++) if (strcmp(grp->name, *sgn) == 0) break; + if (*sgn != nullptr) continue; IniItem *template_item = templates_grp->GetItem(grp->name, false); // Find template value. - if (template_item == NULL || template_item->value == NULL) { + if (template_item == nullptr || template_item->value == nullptr) { fprintf(stderr, "settingsgen: Warning: Cannot find template %s\n", grp->name); continue; } /* Prefix with #if/#ifdef/#ifndef */ - static const char * const pp_lines[] = {"if", "ifdef", "ifndef", NULL}; + static const char * const pp_lines[] = {"if", "ifdef", "ifndef", nullptr}; int count = 0; - for (const char * const *name = pp_lines; *name != NULL; name++) { + for (const char * const *name = pp_lines; *name != nullptr; name++) { const char *condition = FindItemValue(*name, grp, default_grp); - if (condition != NULL) { + if (condition != nullptr) { _stored_output.Add("#", 1); _stored_output.Add(*name); _stored_output.Add(" ", 1); @@ -318,7 +309,7 @@ static void DumpSections(IniLoadFile *ifile) if (i > 0) { /* Find the text to output. */ const char *valitem = FindItemValue(variable, grp, default_grp); - if (valitem != NULL) _stored_output.Add(valitem); + if (valitem != nullptr) _stored_output.Add(valitem); } else { _stored_output.Add("$", 1); } @@ -338,10 +329,10 @@ static void DumpSections(IniLoadFile *ifile) */ static void CopyFile(const char *fname, FILE *out_fp) { - if (fname == NULL) return; + if (fname == nullptr) return; FILE *in_fp = fopen(fname, "r"); - if (in_fp == NULL) { + if (in_fp == nullptr) { fprintf(stderr, "settingsgen: Warning: Cannot open file %s for copying\n", fname); return; } @@ -368,10 +359,10 @@ static void CopyFile(const char *fname, FILE *out_fp) static bool CompareFiles(const char *n1, const char *n2) { FILE *f2 = fopen(n2, "rb"); - if (f2 == NULL) return false; + if (f2 == nullptr) return false; FILE *f1 = fopen(n1, "rb"); - if (f1 == NULL) { + if (f1 == nullptr) { fclose(f2); error("can't open %s", n1); } @@ -399,7 +390,7 @@ static bool CompareFiles(const char *n1, const char *n2) static const OptionData _opts[] = { GETOPT_NOVAL( 'v', "--version"), GETOPT_NOVAL( 'h', "--help"), - GETOPT_GENERAL('h', '?', NULL, ODF_NO_VALUE), + GETOPT_GENERAL('h', '?', nullptr, ODF_NO_VALUE), GETOPT_VALUE( 'o', "--output"), GETOPT_VALUE( 'b', "--before"), GETOPT_VALUE( 'a', "--after"), @@ -442,9 +433,9 @@ static void ProcessIniFile(const char *fname) */ int CDECL main(int argc, char *argv[]) { - const char *output_file = NULL; - const char *before_file = NULL; - const char *after_file = NULL; + const char *output_file = nullptr; + const char *before_file = nullptr; + const char *after_file = nullptr; GetOptData mgo(argc - 1, argv + 1, _opts); for (;;) { @@ -490,7 +481,7 @@ int CDECL main(int argc, char *argv[]) for (int i = 0; i < mgo.numleft; i++) ProcessIniFile(mgo.argv[i]); /* Write output. */ - if (output_file == NULL) { + if (output_file == nullptr) { CopyFile(before_file, stdout); _stored_output.Write(stdout); CopyFile(after_file, stdout); @@ -498,7 +489,7 @@ int CDECL main(int argc, char *argv[]) static const char * const tmp_output = "tmp2.xxx"; FILE *fp = fopen(tmp_output, "w"); - if (fp == NULL) { + if (fp == nullptr) { fprintf(stderr, "settingsgen: Warning: Cannot open file %s\n", tmp_output); return 1; } diff --git a/src/ship.h b/src/ship.h index 60d4466d68..f3e56c39fe 100644 --- a/src/ship.h +++ b/src/ship.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. @@ -20,17 +18,17 @@ void GetShipSpriteSize(EngineID engine, uint &width, uint &height, int &xoffs, int &yoffs, EngineImageType image_type); WaterClass GetEffectiveWaterClass(TileIndex tile); -typedef std::deque ShipPathCache; +typedef std::deque ShipPathCache; /** * All ships have this type. */ struct Ship FINAL : public SpecializedVehicle { - TrackBitsByte state; ///< The "track" the ship is following. - ShipPathCache path; ///< Cached path. - DirectionByte rotation; ///< Visible direction. - int16 rotation_x_pos; ///< NOSAVE: X Position before rotation. - int16 rotation_y_pos; ///< NOSAVE: Y Position before rotation. + TrackBits state; ///< The "track" the ship is following. + ShipPathCache path; ///< Cached path. + Direction rotation; ///< Visible direction. + int16 rotation_x_pos; ///< NOSAVE: X Position before rotation. + int16 rotation_y_pos; ///< NOSAVE: Y Position before rotation. /** We don't want GCC to zero our struct! It already is zeroed and has an index! */ Ship() : SpecializedVehicleBase() {} @@ -57,12 +55,6 @@ struct Ship FINAL : public SpecializedVehicle { void SetDestTile(TileIndex tile); }; -static const uint SHIP_MAX_ORDER_DISTANCE = 130; - -/** - * Iterate over all ships. - * @param var The variable used for iteration. - */ -#define FOR_ALL_SHIPS(var) FOR_ALL_VEHICLES_OF_TYPE(Ship, var) +bool IsShipDestinationTile(TileIndex tile, StationID station); #endif /* SHIP_H */ diff --git a/src/ship_cmd.cpp b/src/ship_cmd.cpp index 786375689b..1758454add 100644 --- a/src/ship_cmd.cpp +++ b/src/ship_cmd.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. @@ -29,12 +27,13 @@ #include "sound_func.h" #include "ai/ai.hpp" #include "game/game.hpp" -#include "pathfinder/opf/opf_ship.h" #include "engine_base.h" #include "company_base.h" #include "tunnelbridge_map.h" #include "zoom_func.h" #include "framerate_type.h" +#include "industry.h" +#include "industry_map.h" #include "table/strings.h" @@ -145,8 +144,7 @@ void Ship::GetImage(Direction direction, EngineImageType image_type, VehicleSpri static const Depot *FindClosestShipDepot(const Vehicle *v, uint max_distance) { /* Find the closest depot */ - const Depot *depot; - const Depot *best_depot = NULL; + const Depot *best_depot = nullptr; /* If we don't have a maximum distance, i.e. distance = 0, * we want to find any depot so the best distance of no * depot must be more than any correct distance. On the @@ -154,7 +152,7 @@ static const Depot *FindClosestShipDepot(const Vehicle *v, uint max_distance) * further away than max_distance can safely be ignored. */ uint best_dist = max_distance == 0 ? UINT_MAX : max_distance + 1; - FOR_ALL_DEPOTS(depot) { + for (const Depot *depot : Depot::Iterate()) { TileIndex tile = depot->xy; if (IsShipDepotTile(tile) && IsTileOwner(tile, v->owner)) { uint dist = DistanceManhattan(tile, v->tile); @@ -178,7 +176,6 @@ static void CheckIfShipNeedsService(Vehicle *v) uint max_distance; switch (_settings_game.pf.pathfinder_for_ships) { - case VPF_OPF: max_distance = 12; break; case VPF_NPF: max_distance = _settings_game.pf.npf.maximum_go_to_depot_penalty / NPF_TILE_LENGTH; break; case VPF_YAPF: max_distance = _settings_game.pf.yapf.maximum_go_to_depot_penalty / YAPF_TILE_LENGTH; break; default: NOT_REACHED(); @@ -186,7 +183,7 @@ static void CheckIfShipNeedsService(Vehicle *v) const Depot *depot = FindClosestShipDepot(v, max_distance); - if (depot == NULL) { + if (depot == nullptr) { if (v->current_order.IsType(OT_GOTO_DEPOT)) { v->current_order.MakeDummy(); SetWindowWidgetDirty(WC_VEHICLE_VIEW, v->index, WID_VV_START_STOP); @@ -291,8 +288,8 @@ TileIndex Ship::GetOrderStationLocation(StationID station) if (station == this->last_station_visited) this->last_station_visited = INVALID_STATION; const Station *st = Station::Get(station); - if (st->dock_tile != INVALID_TILE) { - return TILE_ADD(st->dock_tile, ToTileIndexDiff(GetDockOffset(st->dock_tile))); + if (CanVehicleUseStation(this, st)) { + return st->xy; } else { this->IncrementRealOrderIndex(); return 0; @@ -335,7 +332,7 @@ void Ship::UpdateDeltaXY() */ static Vehicle *EnsureNoVisibleShipProc(Vehicle *v, void *data) { - return v->type == VEH_SHIP && (v->vehstatus & VS_HIDDEN) == 0 ? v : NULL; + return v->type == VEH_SHIP && (v->vehstatus & VS_HIDDEN) == 0 ? v : nullptr; } static bool CheckShipLeaveDepot(Ship *v) @@ -354,7 +351,7 @@ static bool CheckShipLeaveDepot(Ship *v) /* Don't leave depot if another vehicle is already entering/leaving */ /* This helps avoid CPU load if many ships are set to start at the same time */ - if (HasVehicleOnPos(v->tile, NULL, &EnsureNoVisibleShipProc)) return true; + if (HasVehicleOnPos(v->tile, nullptr, &EnsureNoVisibleShipProc)) return true; TileIndex tile = v->tile; Axis axis = GetShipDepotAxis(tile); @@ -369,9 +366,7 @@ static bool CheckShipLeaveDepot(Ship *v) if (north_tracks && south_tracks) { /* Ask pathfinder for best direction */ bool reverse = false; - bool path_found; switch (_settings_game.pf.pathfinder_for_ships) { - case VPF_OPF: reverse = OPFShipChooseTrack(v, north_neighbour, north_dir, north_tracks, path_found) == INVALID_TRACK; break; // OPF always allows reversing case VPF_NPF: reverse = NPFShipCheckReverse(v); break; case VPF_YAPF: reverse = YapfShipCheckReverse(v); break; default: NOT_REACHED(); @@ -470,18 +465,11 @@ static Track ChooseShipTrack(Ship *v, TileIndex tile, DiagDirection enterdir, Tr bool path_found = true; Track track; - if (v->dest_tile == 0 || DistanceManhattan(tile, v->dest_tile) > SHIP_MAX_ORDER_DISTANCE + 5) { - /* No destination or destination too far, don't invoke pathfinder. */ + if (v->dest_tile == 0) { + /* No destination, don't invoke pathfinder. */ track = TrackBitsToTrack(v->state); if (!IsDiagonalTrack(track)) track = TrackToOppositeTrack(track); - if (!HasBit(tracks, track)) { - /* Can't continue in same direction so pick first available track. */ - if (_settings_game.pf.forbid_90_deg) { - tracks &= ~TrackCrossesTracks(TrackdirToTrack(v->GetVehicleTrackdir())); - if (tracks == TRACK_BIT_NONE) return INVALID_TRACK; - } - track = FindFirstTrack(tracks); - } + if (!HasBit(tracks, track)) track = FindFirstTrack(tracks); path_found = false; } else { /* Attempt to follow cached path. */ @@ -499,7 +487,6 @@ static Track ChooseShipTrack(Ship *v, TileIndex tile, DiagDirection enterdir, Tr } switch (_settings_game.pf.pathfinder_for_ships) { - case VPF_OPF: track = OPFShipChooseTrack(v, tile, enterdir, tracks, path_found); break; case VPF_NPF: track = NPFShipChooseTrack(v, path_found); break; case VPF_YAPF: track = YapfShipChooseTrack(v, tile, enterdir, tracks, path_found, v->path); break; default: NOT_REACHED(); @@ -514,16 +501,12 @@ static Track ChooseShipTrack(Ship *v, TileIndex tile, DiagDirection enterdir, Tr * Get the available water tracks on a tile for a ship entering a tile. * @param tile The tile about to enter. * @param dir The entry direction. - * @param trackdir The trackdir the ship has on the old tile. * @return The available trackbits on the next tile. */ -static inline TrackBits GetAvailShipTracks(TileIndex tile, DiagDirection dir, Trackdir trackdir) +static inline TrackBits GetAvailShipTracks(TileIndex tile, DiagDirection dir) { TrackBits tracks = GetTileShipTrackStatus(tile) & DiagdirReachesTracks(dir); - /* Do not remove 90 degree turns for OPF, as it isn't able to find paths taking it into account. */ - if (_settings_game.pf.forbid_90_deg && _settings_game.pf.pathfinder_for_ships != VPF_OPF) tracks &= ~TrackCrossesTracks(TrackdirToTrack(trackdir)); - return tracks; } @@ -612,6 +595,28 @@ static bool ShipMoveUpDownOnLock(Ship *v) return true; } +/** + * Test if a tile is a docking tile for the given station. + * @param tile Docking tile to test. + * @param station Destination station. + * @return true iff docking tile is next to station. + */ +bool IsShipDestinationTile(TileIndex tile, StationID station) +{ + assert(IsDockingTile(tile)); + /* Check each tile adjacent to docking tile. */ + for (DiagDirection d = DIAGDIR_BEGIN; d != DIAGDIR_END; d++) { + TileIndex t = tile + TileOffsByDiagDir(d); + if (!IsValidTile(t)) continue; + if (IsDockTile(t) && GetStationIndex(t) == station && IsValidDockingDirectionForDock(t, d)) return true; + if (IsTileType(t, MP_INDUSTRY)) { + const Industry *i = Industry::GetByTile(t); + if (i->neutral_station != nullptr && i->neutral_station->index == station) return true; + } + } + return false; +} + static void ShipController(Ship *v) { uint32 r; @@ -680,26 +685,24 @@ static void ShipController(Ship *v) UpdateVehicleTimetable(v, true); v->IncrementRealOrderIndex(); v->current_order.MakeDummy(); - } else { - /* Non-buoy orders really need to reach the tile */ - if (v->dest_tile == gp.new_tile) { - if (v->current_order.IsType(OT_GOTO_DEPOT)) { - if ((gp.x & 0xF) == 8 && (gp.y & 0xF) == 8) { - VehicleEnterDepot(v); - return; - } - } else if (v->current_order.IsType(OT_GOTO_STATION)) { - v->last_station_visited = v->current_order.GetDestination(); - - /* Process station in the orderlist. */ - Station *st = Station::Get(v->current_order.GetDestination()); - if (st->facilities & FACIL_DOCK) { // ugly, ugly workaround for problem with ships able to drop off cargo at wrong stations - ShipArrivesAt(v, st); - v->BeginLoading(); - } else { // leave stations without docks right aways - v->current_order.MakeLeaveStation(); - v->IncrementRealOrderIndex(); - } + } else if (v->current_order.IsType(OT_GOTO_DEPOT) && + v->dest_tile == gp.new_tile) { + /* Depot orders really need to reach the tile */ + if ((gp.x & 0xF) == 8 && (gp.y & 0xF) == 8) { + VehicleEnterDepot(v); + return; + } + } else if (v->current_order.IsType(OT_GOTO_STATION) && IsDockingTile(gp.new_tile)) { + /* Process station in the orderlist. */ + Station *st = Station::Get(v->current_order.GetDestination()); + if (st->docking_station.Contains(gp.new_tile) && IsShipDestinationTile(gp.new_tile, st->index)) { + v->last_station_visited = st->index; + if (st->facilities & FACIL_DOCK) { // ugly, ugly workaround for problem with ships able to drop off cargo at wrong stations + ShipArrivesAt(v, st); + v->BeginLoading(); + } else { // leave stations without docks right away + v->current_order.MakeLeaveStation(); + v->IncrementRealOrderIndex(); } } } @@ -711,7 +714,7 @@ static void ShipController(Ship *v) DiagDirection diagdir = DiagdirBetweenTiles(gp.old_tile, gp.new_tile); assert(diagdir != INVALID_DIAGDIR); - tracks = GetAvailShipTracks(gp.new_tile, diagdir, v->GetVehicleTrackdir()); + tracks = GetAvailShipTracks(gp.new_tile, diagdir); if (tracks == TRACK_BIT_NONE) goto reverse_direction; /* Choose a direction, and continue if we find one */ @@ -767,7 +770,7 @@ static void ShipController(Ship *v) return; } - /* Ship is back on the bridge head, we need to comsume its path + /* Ship is back on the bridge head, we need to consume its path * cache entry here as we didn't have to choose a ship track. */ if (!v->path.empty()) v->path.pop_front(); } @@ -884,10 +887,10 @@ bool Ship::FindClosestDepot(TileIndex *location, DestinationID *destination, boo { const Depot *depot = FindClosestShipDepot(this, 0); - if (depot == NULL) return false; + if (depot == nullptr) return false; - if (location != NULL) *location = depot->xy; - if (destination != NULL) *destination = depot->index; + if (location != nullptr) *location = depot->xy; + if (destination != nullptr) *destination = depot->index; return true; } diff --git a/src/ship_gui.cpp b/src/ship_gui.cpp index c6bf342d97..aff7077f07 100644 --- a/src/ship_gui.cpp +++ b/src/ship_gui.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. diff --git a/src/signal.cpp b/src/signal.cpp index b37e15074a..068ca6193b 100644 --- a/src/signal.cpp +++ b/src/signal.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. @@ -192,7 +190,7 @@ static SmallSet _globset("_globset"); ///< set of /** Check whether there is a train on rail, not in a depot */ static Vehicle *TrainOnTileEnum(Vehicle *v, void *) { - if (v->type != VEH_TRAIN || Train::From(v)->track == TRACK_BIT_DEPOT) return NULL; + if (v->type != VEH_TRAIN || Train::From(v)->track == TRACK_BIT_DEPOT) return nullptr; return v; } @@ -283,13 +281,13 @@ static SigFlags ExploreSegment(Owner owner) if (IsRailDepot(tile)) { if (enterdir == INVALID_DIAGDIR) { // from 'inside' - train just entered or left the depot - if (!(flags & SF_TRAIN) && HasVehicleOnPos(tile, NULL, &TrainOnTileEnum)) flags |= SF_TRAIN; + if (!(flags & SF_TRAIN) && HasVehicleOnPos(tile, nullptr, &TrainOnTileEnum)) flags |= SF_TRAIN; exitdir = GetRailDepotDirection(tile); tile += TileOffsByDiagDir(exitdir); enterdir = ReverseDiagDir(exitdir); break; } else if (enterdir == GetRailDepotDirection(tile)) { // entered a depot - if (!(flags & SF_TRAIN) && HasVehicleOnPos(tile, NULL, &TrainOnTileEnum)) flags |= SF_TRAIN; + if (!(flags & SF_TRAIN) && HasVehicleOnPos(tile, nullptr, &TrainOnTileEnum)) flags |= SF_TRAIN; continue; } else { continue; @@ -306,7 +304,7 @@ static SigFlags ExploreSegment(Owner owner) if (!(flags & SF_TRAIN) && EnsureNoTrainOnTrackBits(tile, tracks).Failed()) flags |= SF_TRAIN; } else { if (tracks_masked == TRACK_BIT_NONE) continue; // no incidating track - if (!(flags & SF_TRAIN) && HasVehicleOnPos(tile, NULL, &TrainOnTileEnum)) flags |= SF_TRAIN; + if (!(flags & SF_TRAIN) && HasVehicleOnPos(tile, nullptr, &TrainOnTileEnum)) flags |= SF_TRAIN; } if (HasSignals(tile)) { // there is exactly one track - not zero, because there is exit from this tile @@ -358,7 +356,7 @@ static SigFlags ExploreSegment(Owner owner) if (DiagDirToAxis(enterdir) != GetRailStationAxis(tile)) continue; // different axis if (IsStationTileBlocked(tile)) continue; // 'eye-candy' station tile - if (!(flags & SF_TRAIN) && HasVehicleOnPos(tile, NULL, &TrainOnTileEnum)) flags |= SF_TRAIN; + if (!(flags & SF_TRAIN) && HasVehicleOnPos(tile, nullptr, &TrainOnTileEnum)) flags |= SF_TRAIN; tile += TileOffsByDiagDir(exitdir); break; @@ -367,7 +365,7 @@ static SigFlags ExploreSegment(Owner owner) if (GetTileOwner(tile) != owner) continue; if (DiagDirToAxis(enterdir) == GetCrossingRoadAxis(tile)) continue; // different axis - if (!(flags & SF_TRAIN) && HasVehicleOnPos(tile, NULL, &TrainOnTileEnum)) flags |= SF_TRAIN; + if (!(flags & SF_TRAIN) && HasVehicleOnPos(tile, nullptr, &TrainOnTileEnum)) flags |= SF_TRAIN; tile += TileOffsByDiagDir(exitdir); break; @@ -377,13 +375,13 @@ static SigFlags ExploreSegment(Owner owner) DiagDirection dir = GetTunnelBridgeDirection(tile); if (enterdir == INVALID_DIAGDIR) { // incoming from the wormhole - if (!(flags & SF_TRAIN) && HasVehicleOnPos(tile, NULL, &TrainOnTileEnum)) flags |= SF_TRAIN; + if (!(flags & SF_TRAIN) && HasVehicleOnPos(tile, nullptr, &TrainOnTileEnum)) flags |= SF_TRAIN; enterdir = dir; exitdir = ReverseDiagDir(dir); tile += TileOffsByDiagDir(exitdir); // just skip to next tile } else { // NOT incoming from the wormhole! if (ReverseDiagDir(enterdir) != dir) continue; - if (!(flags & SF_TRAIN) && HasVehicleOnPos(tile, NULL, &TrainOnTileEnum)) flags |= SF_TRAIN; + if (!(flags & SF_TRAIN) && HasVehicleOnPos(tile, nullptr, &TrainOnTileEnum)) flags |= SF_TRAIN; tile = GetOtherTunnelBridgeEnd(tile); // just skip to exit tile enterdir = INVALID_DIAGDIR; exitdir = INVALID_DIAGDIR; diff --git a/src/signal_func.h b/src/signal_func.h index 4597a039b0..621eeedc50 100644 --- a/src/signal_func.h +++ b/src/signal_func.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/signal_type.h b/src/signal_type.h index c7d06072a7..5af2a2c94a 100644 --- a/src/signal_type.h +++ b/src/signal_type.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/signs.cpp b/src/signs.cpp index 2a23a43c9c..f477ab7641 100644 --- a/src/signs.cpp +++ b/src/signs.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. @@ -15,6 +13,7 @@ #include "signs_func.h" #include "strings_func.h" #include "core/pool_func.hpp" +#include "viewport_kdtree.h" #include "table/strings.h" @@ -48,16 +47,19 @@ Sign::~Sign() void Sign::UpdateVirtCoord() { Point pt = RemapCoords(this->x, this->y, this->z); + + if (this->sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeSign(this->index)); + SetDParam(0, this->index); this->sign.UpdatePosition(pt.x, pt.y - 6 * ZOOM_LVL_BASE, STR_WHITE_SIGN); + + _viewport_sign_kdtree.Insert(ViewportSignKdtreeItem::MakeSign(this->index)); } /** Update the coordinates of all signs */ void UpdateAllSignVirtCoords() { - Sign *si; - - FOR_ALL_SIGNS(si) { + for (Sign *si : Sign::Iterate()) { si->UpdateVirtCoord(); } } diff --git a/src/signs_base.h b/src/signs_base.h index 3e7b4c4651..6cc7dc6d80 100644 --- a/src/signs_base.h +++ b/src/signs_base.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. @@ -21,12 +19,12 @@ typedef Pool SignPool; extern SignPool _sign_pool; struct Sign : SignPool::PoolItem<&_sign_pool> { - char *name; - ViewportSign sign; - int32 x; - int32 y; - int32 z; - OwnerByte owner; // placed by this company. Anyone can delete them though. OWNER_NONE for gray signs from old games. + char *name; + TrackedViewportSign sign; + int32 x; + int32 y; + int32 z; + Owner owner; // placed by this company. Anyone can delete them though. OWNER_NONE for gray signs from old games. Sign(Owner owner = INVALID_OWNER); ~Sign(); @@ -34,7 +32,4 @@ struct Sign : SignPool::PoolItem<&_sign_pool> { void UpdateVirtCoord(); }; -#define FOR_ALL_SIGNS_FROM(var, start) FOR_ALL_ITEMS_FROM(Sign, sign_index, var, start) -#define FOR_ALL_SIGNS(var) FOR_ALL_SIGNS_FROM(var, 0) - #endif /* SIGNS_BASE_H */ diff --git a/src/signs_cmd.cpp b/src/signs_cmd.cpp index 4badd36050..d2caa4a235 100644 --- a/src/signs_cmd.cpp +++ b/src/signs_cmd.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. @@ -16,6 +14,7 @@ #include "signs_func.h" #include "command_func.h" #include "tilehighlight_func.h" +#include "viewport_kdtree.h" #include "window_func.h" #include "string_func.h" @@ -79,7 +78,7 @@ CommandCost CmdPlaceSign(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 CommandCost CmdRenameSign(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { Sign *si = Sign::GetIfValid(p1); - if (si == NULL) return CMD_ERROR; + if (si == nullptr) return CMD_ERROR; if (si->owner == OWNER_DEITY && _current_company != OWNER_DEITY && _game_mode != GM_EDITOR) return CMD_ERROR; /* Rename the signs when empty, otherwise remove it */ @@ -99,6 +98,7 @@ CommandCost CmdRenameSign(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 } else { // Delete sign if (flags & DC_EXEC) { si->sign.MarkDirty(); + if (si->sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeSign(si->index)); delete si; InvalidateWindowData(WC_SIGN_LIST, 0, 0); @@ -114,8 +114,9 @@ CommandCost CmdRenameSign(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 * @param tile unused * @param p1 unused * @param p2 unused + * @param cmd unused */ -void CcPlaceSign(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) +void CcPlaceSign(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) { if (result.Failed()) return; diff --git a/src/signs_func.h b/src/signs_func.h index 4cc89d947c..55e831fdca 100644 --- a/src/signs_func.h +++ b/src/signs_func.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/signs_gui.cpp b/src/signs_gui.cpp index 7d64c33589..96848026fd 100644 --- a/src/signs_gui.cpp +++ b/src/signs_gui.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. @@ -46,7 +44,7 @@ struct SignList { StringFilter string_filter; ///< The match string to be used when the GUIList is (re)-sorted. static bool match_case; ///< Should case sensitive matching be used? - static char default_name[64]; ///< Default sign name, used if Sign::name is NULL. + static char default_name[64]; ///< Default sign name, used if Sign::name is nullptr. /** * Creates a SignList with filtering disabled by default. @@ -61,33 +59,32 @@ struct SignList { DEBUG(misc, 3, "Building sign list"); - this->signs.Clear(); + this->signs.clear(); - const Sign *si; - FOR_ALL_SIGNS(si) *this->signs.Append() = si; + for (const Sign *si : Sign::Iterate()) this->signs.push_back(si); this->signs.SetFilterState(true); this->FilterSignList(); - this->signs.Compact(); + this->signs.shrink_to_fit(); this->signs.RebuildDone(); } /** Sort signs by their name */ - static int CDECL SignNameSorter(const Sign * const *a, const Sign * const *b) + static bool SignNameSorter(const Sign * const &a, const Sign * const &b) { /* Signs are very very rarely using the default text, but there can also be * a lot of them. Therefore a worthwhile performance gain can be made by * directly comparing Sign::name instead of going through the string * system for each comparison. */ - const char *a_name = (*a)->name; - const char *b_name = (*b)->name; + const char *a_name = a->name; + const char *b_name = b->name; - if (a_name == NULL) a_name = SignList::default_name; - if (b_name == NULL) b_name = SignList::default_name; + if (a_name == nullptr) a_name = SignList::default_name; + if (b_name == nullptr) b_name = SignList::default_name; int r = strnatcmp(a_name, b_name); // Sort by name (natural sorting). - return r != 0 ? r : ((*a)->index - (*b)->index); + return r != 0 ? r < 0 : (a->index < b->index); } void SortSignsList() @@ -101,7 +98,7 @@ struct SignList { /* Same performance benefit as above for sorting. */ const char *a_name = (*a)->name; - if (a_name == NULL) a_name = SignList::default_name; + if (a_name == nullptr) a_name = SignList::default_name; filter.ResetState(); filter.AddLine(a_name); @@ -167,9 +164,9 @@ struct SignListWindow : Window, SignList { this->BuildSortSignList(); } - virtual void OnInit() + void OnInit() override { - /* Default sign name, used if Sign::name is NULL. */ + /* Default sign name, used if Sign::name is nullptr. */ GetString(SignList::default_name, STR_DEFAULT_SIGN_NAME, lastof(SignList::default_name)); this->signs.ForceResort(); this->SortSignsList(); @@ -191,13 +188,13 @@ struct SignListWindow : Window, SignList { this->InvalidateData(); } - virtual void OnPaint() + void OnPaint() override { if (!this->IsShaded() && this->signs.NeedRebuild()) this->BuildSortSignList(); this->DrawWidgets(); } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { switch (widget) { case WID_SIL_LIST: { @@ -229,12 +226,12 @@ struct SignListWindow : Window, SignList { } } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { if (widget == WID_SIL_CAPTION) SetDParam(0, this->vscroll->GetCount()); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_SIL_LIST: { @@ -247,7 +244,7 @@ struct SignListWindow : Window, SignList { } case WID_SIL_FILTER_ENTER_BTN: - if (this->signs.Length() >= 1) { + if (this->signs.size() >= 1) { const Sign *si = this->signs[0]; ScrollMainWindowToTile(TileVirtXY(si->x, si->y)); } @@ -261,12 +258,12 @@ struct SignListWindow : Window, SignList { } } - virtual void OnResize() + void OnResize() override { this->vscroll->SetCapacityFromWidget(this, WID_SIL_LIST, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM); } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_SIL_LIST: { @@ -288,7 +285,7 @@ struct SignListWindow : Window, SignList { } } - virtual EventState OnHotkey(int hotkey) + EventState OnHotkey(int hotkey) override { switch (hotkey) { case SLHK_FOCUS_FILTER_BOX: @@ -303,7 +300,7 @@ struct SignListWindow : Window, SignList { return ES_HANDLED; } - virtual void OnEditboxChanged(int widget) + void OnEditboxChanged(int widget) override { if (widget == WID_SIL_FILTER_TEXT) this->SetFilterString(this->filter_editbox.text.buf); } @@ -312,13 +309,13 @@ struct SignListWindow : Window, SignList { { if (this->signs.NeedRebuild()) { this->BuildSignsList(); - this->vscroll->SetCount(this->signs.Length()); + this->vscroll->SetCount((uint)this->signs.size()); this->SetWidgetDirty(WID_SIL_CAPTION); } this->SortSignsList(); } - virtual void OnHundredthTick() + void OnHundredthTick() override { this->BuildSortSignList(); this->SetDirty(); @@ -329,7 +326,7 @@ struct SignListWindow : Window, SignList { * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { /* When there is a filter string, we always need to rebuild the list even if * the amount of signs in total is unchanged, as the subset of signs that is @@ -354,7 +351,7 @@ static EventState SignListGlobalHotkeys(int hotkey) { if (_game_mode == GM_MENU) return ES_NOT_HANDLED; Window *w = ShowSignList(); - if (w == NULL) return ES_NOT_HANDLED; + if (w == nullptr) return ES_NOT_HANDLED; return w->OnHotkey(hotkey); } @@ -404,7 +401,7 @@ static WindowDesc _sign_list_desc( /** * Open the sign list window * - * @return newly opened sign list window, or NULL if the window could not be opened. + * @return newly opened sign list window, or nullptr if the window could not be opened. */ Window *ShowSignList() { @@ -420,7 +417,7 @@ Window *ShowSignList() static bool RenameSign(SignID index, const char *text) { bool remove = StrEmpty(text); - DoCommandP(0, index, 0, CMD_RENAME_SIGN | (StrEmpty(text) ? CMD_MSG(STR_ERROR_CAN_T_DELETE_SIGN) : CMD_MSG(STR_ERROR_CAN_T_CHANGE_SIGN_NAME)), NULL, text); + DoCommandP(0, index, 0, CMD_RENAME_SIGN | (StrEmpty(text) ? CMD_MSG(STR_ERROR_CAN_T_DELETE_SIGN) : CMD_MSG(STR_ERROR_CAN_T_CHANGE_SIGN_NAME)), nullptr, text); return remove; } @@ -444,7 +441,7 @@ struct SignWindow : Window, SignList { void UpdateSignEditWindow(const Sign *si) { /* Display an empty string when the sign hasn't been edited yet */ - if (si->name != NULL) { + if (si->name != nullptr) { SetDParam(0, si->index); this->name_editbox.text.Assign(STR_SIGN_NAME); } else { @@ -473,7 +470,7 @@ struct SignWindow : Window, SignList { /* Search through the list for the current sign, excluding * - the first sign if we want the previous sign or * - the last sign if we want the next sign */ - uint end = this->signs.Length() - (next ? 1 : 0); + size_t end = this->signs.size() - (next ? 1 : 0); for (uint i = next ? 0 : 1; i < end; i++) { if (this->cur_sign == this->signs[i]->index) { /* We've found the current sign, so return the sign before/after it */ @@ -481,10 +478,10 @@ struct SignWindow : Window, SignList { } } /* If we haven't found the current sign by now, return the last/first sign */ - return this->signs[next ? 0 : this->signs.Length() - 1]; + return next ? this->signs.front() : this->signs.back(); } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { switch (widget) { case WID_QES_CAPTION: @@ -493,7 +490,7 @@ struct SignWindow : Window, SignList { } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_QES_PREVIOUS: @@ -561,7 +558,7 @@ static WindowDesc _query_sign_edit_desc( void HandleClickOnSign(const Sign *si) { if (_ctrl_pressed && (si->owner == _local_company || (si->owner == OWNER_DEITY && _game_mode == GM_EDITOR))) { - RenameSign(si->index, NULL); + RenameSign(si->index, nullptr); return; } ShowRenameSignWindow(si); @@ -587,5 +584,5 @@ void DeleteRenameSignWindow(SignID sign) { SignWindow *w = dynamic_cast(FindWindowById(WC_QUERY_STRING, WN_QUERY_STRING_SIGN)); - if (w != NULL && w->cur_sign == sign) delete w; + if (w != nullptr && w->cur_sign == sign) delete w; } diff --git a/src/signs_type.h b/src/signs_type.h index a539c66899..fd73af8fad 100644 --- a/src/signs_type.h +++ b/src/signs_type.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/slope_func.h b/src/slope_func.h index 4aff6b9d31..47a89bfcf9 100644 --- a/src/slope_func.h +++ b/src/slope_func.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/slope_type.h b/src/slope_type.h index 395b1f0fbc..a2c51bd19e 100644 --- a/src/slope_type.h +++ b/src/slope_type.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/smallmap_gui.cpp b/src/smallmap_gui.cpp index c4f0fa7d6d..7ba687908a 100644 --- a/src/smallmap_gui.cpp +++ b/src/smallmap_gui.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. @@ -42,13 +40,6 @@ static uint8 _linkstat_colours_in_legenda[] = {0, 1, 3, 5, 7}; static const int NUM_NO_COMPANY_ENTRIES = 4; ///< Number of entries in the owner legend that are not companies. -static const uint8 PC_ROUGH_LAND = 0x52; ///< Dark green palette colour for rough land. -static const uint8 PC_GRASS_LAND = 0x54; ///< Dark green palette colour for grass land. -static const uint8 PC_BARE_LAND = 0x37; ///< Brown palette colour for bare land. -static const uint8 PC_FIELDS = 0x25; ///< Light brown palette colour for fields. -static const uint8 PC_TREES = 0x57; ///< Green palette colour for trees. -static const uint8 PC_WATER = 0xCA; ///< Dark blue palette colour for water. - /** Macro for ordinary entry of LegendAndColour */ #define MK(a, b) {a, b, INVALID_INDUSTRYTYPE, 0, INVALID_COMPANY, true, false, false} @@ -180,8 +171,7 @@ void BuildIndustriesLegend() uint j = 0; /* Add each name */ - for (uint i = 0; i < NUM_INDUSTRYTYPES; i++) { - IndustryType ind = _sorted_industry_types[i]; + for (IndustryType ind : _sorted_industry_types) { const IndustrySpec *indsp = GetIndustrySpec(ind); if (indsp->enabled) { _legend_from_industries[j].legend = indsp->name; @@ -212,7 +202,7 @@ void BuildLinkStatsLegend() memset(_legend_linkstats, 0, sizeof(_legend_linkstats)); uint i = 0; - for (; i < _sorted_cargo_specs_size; ++i) { + for (; i < _sorted_cargo_specs.size(); ++i) { const CargoSpec *cs = _sorted_cargo_specs[i]; _legend_linkstats[i].legend = cs->name; @@ -275,9 +265,9 @@ struct SmallMapColourScheme { /** Available colour schemes for height maps. */ static SmallMapColourScheme _heightmap_schemes[] = { - {NULL, _green_map_heights, lengthof(_green_map_heights), MKCOLOUR_XXXX(0x54)}, ///< Green colour scheme. - {NULL, _dark_green_map_heights, lengthof(_dark_green_map_heights), MKCOLOUR_XXXX(0x62)}, ///< Dark green colour scheme. - {NULL, _violet_map_heights, lengthof(_violet_map_heights), MKCOLOUR_XXXX(0x82)}, ///< Violet colour scheme. + {nullptr, _green_map_heights, lengthof(_green_map_heights), MKCOLOUR_XXXX(0x54)}, ///< Green colour scheme. + {nullptr, _dark_green_map_heights, lengthof(_dark_green_map_heights), MKCOLOUR_XXXX(0x62)}, ///< Dark green colour scheme. + {nullptr, _violet_map_heights, lengthof(_violet_map_heights), MKCOLOUR_XXXX(0x81)}, ///< Violet colour scheme. }; /** @@ -286,7 +276,7 @@ static SmallMapColourScheme _heightmap_schemes[] = { void BuildLandLegend() { /* The smallmap window has never been initialized, so no need to change the legend. */ - if (_heightmap_schemes[0].height_colours == NULL) return; + if (_heightmap_schemes[0].height_colours == nullptr) return; /* * The general idea of this function is to fill the legend with an appropriate evenly spaced @@ -339,8 +329,7 @@ void BuildOwnerLegend() _legend_land_owners[1].colour = _heightmap_schemes[_settings_client.gui.smallmap_land_colour].default_colour; int i = NUM_NO_COMPANY_ENTRIES; - const Company *c; - FOR_ALL_COMPANIES(c) { + for (const Company *c : Company::Iterate()) { _legend_land_owners[i].colour = _colour_gradient[c->colour][5]; _legend_land_owners[i].company = c->index; _legend_land_owners[i].show_on_map = true; @@ -464,28 +453,51 @@ static inline uint32 GetSmallMapIndustriesPixels(TileIndex tile, TileType t) */ static inline uint32 GetSmallMapRoutesPixels(TileIndex tile, TileType t) { - if (t == MP_STATION) { - switch (GetStationType(tile)) { - case STATION_RAIL: return MKCOLOUR_XXXX(PC_VERY_DARK_BROWN); - case STATION_AIRPORT: return MKCOLOUR_XXXX(PC_RED); - case STATION_TRUCK: return MKCOLOUR_XXXX(PC_ORANGE); - case STATION_BUS: return MKCOLOUR_XXXX(PC_YELLOW); - case STATION_DOCK: return MKCOLOUR_XXXX(PC_LIGHT_BLUE); - default: return MKCOLOUR_FFFF; + switch (t) { + case MP_STATION: + switch (GetStationType(tile)) { + case STATION_RAIL: return MKCOLOUR_XXXX(PC_VERY_DARK_BROWN); + case STATION_AIRPORT: return MKCOLOUR_XXXX(PC_RED); + case STATION_TRUCK: return MKCOLOUR_XXXX(PC_ORANGE); + case STATION_BUS: return MKCOLOUR_XXXX(PC_YELLOW); + case STATION_DOCK: return MKCOLOUR_XXXX(PC_LIGHT_BLUE); + default: return MKCOLOUR_FFFF; + } + + case MP_RAILWAY: { + AndOr andor = { + MKCOLOUR_0XX0(GetRailTypeInfo(GetRailType(tile))->map_colour), + _smallmap_contours_andor[t].mand + }; + + const SmallMapColourScheme *cs = &_heightmap_schemes[_settings_client.gui.smallmap_land_colour]; + return ApplyMask(cs->default_colour, &andor); } - } else if (t == MP_RAILWAY) { - AndOr andor = { - MKCOLOUR_0XX0(GetRailTypeInfo(GetRailType(tile))->map_colour), - _smallmap_contours_andor[t].mand - }; - const SmallMapColourScheme *cs = &_heightmap_schemes[_settings_client.gui.smallmap_land_colour]; - return ApplyMask(cs->default_colour, &andor); + case MP_ROAD: { + const RoadTypeInfo *rti = nullptr; + if (GetRoadTypeRoad(tile) != INVALID_ROADTYPE) { + rti = GetRoadTypeInfo(GetRoadTypeRoad(tile)); + } else { + rti = GetRoadTypeInfo(GetRoadTypeTram(tile)); + } + if (rti != nullptr) { + AndOr andor = { + MKCOLOUR_0XX0(rti->map_colour), + _smallmap_contours_andor[t].mand + }; + + const SmallMapColourScheme *cs = &_heightmap_schemes[_settings_client.gui.smallmap_land_colour]; + return ApplyMask(cs->default_colour, &andor); + } + FALLTHROUGH; + } + + default: + /* Ground colour */ + const SmallMapColourScheme *cs = &_heightmap_schemes[_settings_client.gui.smallmap_land_colour]; + return ApplyMask(cs->default_colour, &_smallmap_contours_andor[t]); } - - /* Ground colour */ - const SmallMapColourScheme *cs = &_heightmap_schemes[_settings_client.gui.smallmap_land_colour]; - return ApplyMask(cs->default_colour, &_smallmap_contours_andor[t]); } /** @@ -570,7 +582,7 @@ static inline uint32 GetSmallMapOwnerPixels(TileIndex tile, TileType t) return MKCOLOUR_XXXX(_legend_land_owners[_company_to_list_pos[o]].colour); } -/** Vehicle colours in #SMT_VEHICLES mode. Indexed by #VehicleTypeByte. */ +/** Vehicle colours in #SMT_VEHICLES mode. Indexed by #VehicleType. */ static const byte _vehicle_type_colours[6] = { PC_RED, PC_YELLOW, PC_LIGHT_BLUE, PC_WHITE, PC_BLACK, PC_RED }; @@ -860,8 +872,7 @@ void SmallMapWindow::DrawSmallMapColumn(void *dst, uint xc, uint yc, int pitch, */ void SmallMapWindow::DrawVehicles(const DrawPixelInfo *dpi, Blitter *blitter) const { - const Vehicle *v; - FOR_ALL_VEHICLES(v) { + for (const Vehicle *v : Vehicle::Iterate()) { if (v->type == VEH_EFFECT) continue; if (v->vehstatus & (VS_HIDDEN | VS_UNCLICKABLE)) continue; @@ -899,8 +910,7 @@ void SmallMapWindow::DrawVehicles(const DrawPixelInfo *dpi, Blitter *blitter) co */ void SmallMapWindow::DrawTowns(const DrawPixelInfo *dpi) const { - const Town *t; - FOR_ALL_TOWNS(t) { + for (const Town *t : Town::Iterate()) { /* Remap the town coordinate */ Point pt = this->RemapTile(TileX(t->xy), TileY(t->xy)); int x = pt.x - this->subscroll - (t->cache.sign.width_small >> 1); @@ -1079,7 +1089,7 @@ SmallMapWindow::SmallMapWindow(WindowDesc *desc, int window_number) : this->SetupWidgetData(); - this->SetZoomLevel(ZLC_INITIALIZE, NULL); + this->SetZoomLevel(ZLC_INITIALIZE, nullptr); this->SmallMapCenterOnCurrentPos(); this->SetOverlayCargoMask(); } @@ -1490,7 +1500,7 @@ int SmallMapWindow::GetPositionOnLegend(Point pt) case WID_SM_ENABLE_ALL: case WID_SM_DISABLE_ALL: { - LegendAndColour *tbl = NULL; + LegendAndColour *tbl = nullptr; switch (this->map_type) { case SMT_INDUSTRY: tbl = _legend_from_industries; @@ -1706,10 +1716,10 @@ class NWidgetSmallmapDisplay : public NWidgetContainer { public: NWidgetSmallmapDisplay() : NWidgetContainer(NWID_VERTICAL) { - this->smallmap_window = NULL; + this->smallmap_window = nullptr; } - virtual void SetupSmallestSize(Window *w, bool init_array) + void SetupSmallestSize(Window *w, bool init_array) override { NWidgetBase *display = this->head; NWidgetBase *bar = display->next; @@ -1718,9 +1728,8 @@ public: bar->SetupSmallestSize(w, init_array); this->smallmap_window = dynamic_cast(w); - - assert(this->smallmap_window != NULL); - this->smallest_x = max(display->smallest_x, max(bar->smallest_x, WD_FRAMERECT_LEFT + smallmap_window->column_width)); + assert(this->smallmap_window != nullptr); + this->smallest_x = max(display->smallest_x, bar->smallest_x + smallmap_window->GetMinLegendWidth()); this->smallest_y = display->smallest_y + max(bar->smallest_y, smallmap_window->GetLegendHeight(smallmap_window->min_number_of_columns)); this->fill_x = max(display->fill_x, bar->fill_x); this->fill_y = (display->fill_y == 0 && bar->fill_y == 0) ? 0 : min(display->fill_y, bar->fill_y); @@ -1728,7 +1737,7 @@ public: this->resize_y = min(display->resize_y, bar->resize_y); } - virtual void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl) + void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl) override { this->pos_x = x; this->pos_y = y; @@ -1752,19 +1761,19 @@ public: bar->AssignSizePosition(ST_RESIZE, x, y + display_height, given_width, bar_height, rtl); } - virtual NWidgetCore *GetWidgetFromPos(int x, int y) + NWidgetCore *GetWidgetFromPos(int x, int y) override { - if (!IsInsideBS(x, this->pos_x, this->current_x) || !IsInsideBS(y, this->pos_y, this->current_y)) return NULL; - for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) { + if (!IsInsideBS(x, this->pos_x, this->current_x) || !IsInsideBS(y, this->pos_y, this->current_y)) return nullptr; + for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { NWidgetCore *widget = child_wid->GetWidgetFromPos(x, y); - if (widget != NULL) return widget; + if (widget != nullptr) return widget; } - return NULL; + return nullptr; } - virtual void Draw(const Window *w) + void Draw(const Window *w) override { - for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) child_wid->Draw(w); + for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) child_wid->Draw(w); } }; @@ -1893,7 +1902,7 @@ bool ScrollMainWindowTo(int x, int y, int z, bool instant) if (res) return res; SmallMapWindow *w = dynamic_cast(FindWindowById(WC_SMALLMAP, 0)); - if (w != NULL) w->SmallMapCenterOnCurrentPos(); + if (w != nullptr) w->SmallMapCenterOnCurrentPos(); return res; } diff --git a/src/smallmap_gui.h b/src/smallmap_gui.h index 5ff916dccd..f6c6f98705 100644 --- a/src/smallmap_gui.h +++ b/src/smallmap_gui.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. @@ -182,19 +180,17 @@ public: return WD_FRAMERECT_LEFT + this->min_number_of_columns * this->column_width; } - virtual void SetStringParameters(int widget) const; - virtual void OnInit(); - virtual void OnPaint(); - virtual void DrawWidget(const Rect &r, int widget) const; - virtual void OnClick(Point pt, int widget, int click_count); - virtual void OnInvalidateData(int data = 0, bool gui_scope = true); - virtual bool OnRightClick(Point pt, int widget); - virtual void OnMouseWheel(int wheel); - virtual void OnRealtimeTick(uint delta_ms); - virtual void OnScroll(Point delta); - virtual void OnMouseOver(Point pt, int widget); - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize); - + void SetStringParameters(int widget) const override; + void OnInit() override; + void OnPaint() override; + void DrawWidget(const Rect &r, int widget) const override; + void OnClick(Point pt, int widget, int click_count) override; + void OnInvalidateData(int data = 0, bool gui_scope = true) override; + bool OnRightClick(Point pt, int widget) override; + void OnMouseWheel(int wheel) override; + void OnRealtimeTick(uint delta_ms) override; + void OnScroll(Point delta) override; + void OnMouseOver(Point pt, int widget) override; }; #endif /* SMALLMAP_GUI_H */ diff --git a/src/sortlist_type.h b/src/sortlist_type.h index 1a30c3b1a8..a8730d96d9 100644 --- a/src/sortlist_type.h +++ b/src/sortlist_type.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. @@ -14,7 +12,6 @@ #include "core/enum_type.hpp" #include "core/bitmath_func.hpp" -#include "core/sort_func.hpp" #include "core/smallvec_type.hpp" #include "date_type.h" @@ -47,10 +44,10 @@ struct Filtering { * @tparam F Type of data fed as additional value to the filter function. @see FilterFunction */ template -class GUIList : public SmallVector { +class GUIList : public std::vector { public: - typedef int CDECL SortFunction(const T*, const T*); ///< Signature of sort function. - typedef bool CDECL FilterFunction(const T*, F); ///< Signature of filter function. + typedef bool SortFunction(const T&, const T&); ///< Signature of sort function. + typedef bool CDECL FilterFunction(const T*, F); ///< Signature of filter function. protected: SortFunction * const *sort_func_list; ///< the sort criteria functions @@ -67,7 +64,7 @@ protected: */ bool IsSortable() const { - return (this->data != NULL && this->items >= 2); + return std::vector::size() >= 2; } /** @@ -81,8 +78,8 @@ protected: public: GUIList() : - sort_func_list(NULL), - filter_func_list(NULL), + sort_func_list(nullptr), + filter_func_list(nullptr), flags(VL_FIRST_SORT), sort_type(0), filter_type(0), @@ -240,7 +237,7 @@ public: { this->flags ^= VL_DESC; - if (this->IsSortable()) MemReverseT(this->data, this->items); + if (this->IsSortable()) MemReverseT(std::vector::data(), std::vector::size()); } /** @@ -270,11 +267,11 @@ public: if (this->flags & VL_FIRST_SORT) { CLRBITS(this->flags, VL_FIRST_SORT); - QSortT(this->data, this->items, compare, desc); + std::sort(std::vector::begin(), std::vector::end(), [&](const T &a, const T &b) { return desc ? compare(b, a) : compare(a, b); }); return true; } - GSortT(this->data, this->items, compare, desc); + std::sort(std::vector::begin(), std::vector::end(), [&](const T &a, const T &b) { return desc ? compare(b, a) : compare(a, b); }); return true; } @@ -296,7 +293,7 @@ public: */ bool Sort() { - assert(this->sort_func_list != NULL); + assert(this->sort_func_list != nullptr); return this->Sort(this->sort_func_list[this->sort_type]); } @@ -337,13 +334,12 @@ public: if (!(this->flags & VL_FILTER)) return false; bool changed = false; - for (uint iter = 0; iter < this->items;) { - T *item = &this->data[iter]; - if (!decide(item, filter_data)) { - this->Erase(item); + for (auto it = std::vector::begin(); it != std::vector::end(); /* Nothing */) { + if (!decide(&*it, filter_data)) { + it = std::vector::erase(it); changed = true; } else { - iter++; + it++; } } @@ -368,7 +364,7 @@ public: */ bool Filter(F filter_data) { - if (this->filter_func_list == NULL) return false; + if (this->filter_func_list == nullptr) return false; return this->Filter(this->filter_func_list[this->filter_type], filter_data); } diff --git a/src/sound.cpp b/src/sound.cpp index 79dd988bfa..d96adfe29f 100644 --- a/src/sound.cpp +++ b/src/sound.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. @@ -30,7 +28,7 @@ static void OpenBankFile(const char *filename) memset(_original_sounds, 0, sizeof(_original_sounds)); /* If there is no sound file (nosound set), don't load anything */ - if (filename == NULL) return; + if (filename == nullptr) return; FioOpenFile(SOUND_SLOT, filename, BASESET_DIR); size_t pos = FioGetPos(); @@ -110,7 +108,7 @@ static void OpenBankFile(const char *filename) static bool SetBankSource(MixerChannel *mc, const SoundEntry *sound) { - assert(sound != NULL); + assert(sound != nullptr); /* Check for valid sound size. */ if (sound->file_size == 0 || sound->file_size > ((size_t)-1) - 2) return false; @@ -162,7 +160,7 @@ static void StartSound(SoundID sound_id, float pan, uint volume) if (volume == 0) return; SoundEntry *sound = GetSound(sound_id); - if (sound == NULL) return; + if (sound == nullptr) return; /* NewGRF sound that wasn't loaded yet? */ if (sound->rate == 0 && sound->file_slot != 0) { @@ -177,7 +175,7 @@ static void StartSound(SoundID sound_id, float pan, uint volume) if (sound->rate == 0) return; MixerChannel *mc = MxAllocateChannel(); - if (mc == NULL) return; + if (mc == nullptr) return; if (!SetBankSource(mc, sound)) return; @@ -244,7 +242,7 @@ static void SndPlayScreenCoordFx(SoundID sound, int left, int right, int top, in FOR_ALL_WINDOWS_FROM_BACK(w) { const ViewPort *vp = w->viewport; - if (vp != NULL && + if (vp != nullptr && left < vp->virtual_left + vp->virtual_width && right > vp->virtual_left && top < vp->virtual_top + vp->virtual_height && bottom > vp->virtual_top) { int screen_x = (left + right) / 2 - vp->virtual_left; @@ -304,14 +302,14 @@ template template /* static */ bool BaseMedia::DetermineBestSet() { - if (BaseMedia::used_set != NULL) return true; + if (BaseMedia::used_set != nullptr) return true; - const Tbase_set *best = NULL; - for (const Tbase_set *c = BaseMedia::available_sets; c != NULL; c = c->next) { + const Tbase_set *best = nullptr; + for (const Tbase_set *c = BaseMedia::available_sets; c != nullptr; c = c->next) { /* Skip unusable sets */ if (c->GetNumMissing() != 0) continue; - if (best == NULL || + if (best == nullptr || (best->fallback && !c->fallback) || best->valid_files < c->valid_files || (best->valid_files == c->valid_files && @@ -321,6 +319,6 @@ template } BaseMedia::used_set = best; - return BaseMedia::used_set != NULL; + return BaseMedia::used_set != nullptr; } diff --git a/src/sound/allegro_s.cpp b/src/sound/allegro_s.cpp index 88a723ff85..f7fa5df08b 100644 --- a/src/sound/allegro_s.cpp +++ b/src/sound/allegro_s.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. @@ -22,18 +20,18 @@ static FSoundDriver_Allegro iFSoundDriver_Allegro; /** The stream we are writing too */ -static AUDIOSTREAM *_stream = NULL; +static AUDIOSTREAM *_stream = nullptr; /** The number of samples in the buffer */ static int _buffer_size; void SoundDriver_Allegro::MainLoop() { /* We haven't opened a stream yet */ - if (_stream == NULL) return; + if (_stream == nullptr) return; void *data = get_audio_stream_buffer(_stream); /* We don't have to fill the stream yet */ - if (data == NULL) return; + if (data == nullptr) return; /* Mix the samples */ MxMixSamples(data, _buffer_size); @@ -54,14 +52,14 @@ extern int _allegro_instance_count; const char *SoundDriver_Allegro::Start(const char * const *parm) { - if (_allegro_instance_count == 0 && install_allegro(SYSTEM_AUTODETECT, &errno, NULL)) { + if (_allegro_instance_count == 0 && install_allegro(SYSTEM_AUTODETECT, &errno, nullptr)) { DEBUG(driver, 0, "allegro: install_allegro failed '%s'", allegro_error); return "Failed to set up Allegro"; } _allegro_instance_count++; /* Initialise the sound */ - if (install_sound(DIGI_AUTODETECT, MIDI_AUTODETECT, NULL) != 0) { + if (install_sound(DIGI_AUTODETECT, MIDI_AUTODETECT, nullptr) != 0) { DEBUG(driver, 0, "allegro: install_sound failed '%s'", allegro_error); return "Failed to set up Allegro sound"; } @@ -76,14 +74,14 @@ const char *SoundDriver_Allegro::Start(const char * const *parm) _buffer_size = GetDriverParamInt(parm, "samples", 1024) * hz / 11025; _stream = play_audio_stream(_buffer_size, 16, true, hz, 255, 128); MxInitialize(hz); - return NULL; + return nullptr; } void SoundDriver_Allegro::Stop() { - if (_stream != NULL) { + if (_stream != nullptr) { stop_audio_stream(_stream); - _stream = NULL; + _stream = nullptr; } remove_sound(); diff --git a/src/sound/allegro_s.h b/src/sound/allegro_s.h index e0a247f7b3..307d10fca4 100644 --- a/src/sound/allegro_s.h +++ b/src/sound/allegro_s.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. @@ -7,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 allegro_s.h Base fo playing sound via Allegro. */ +/** @file allegro_s.h Base for playing sound via Allegro. */ #ifndef SOUND_ALLEGRO_H #define SOUND_ALLEGRO_H @@ -17,12 +15,12 @@ /** Implementation of the allegro sound driver. */ class SoundDriver_Allegro : public SoundDriver { public: - /* virtual */ const char *Start(const char * const *param); + const char *Start(const char * const *param); - /* virtual */ void Stop(); + void Stop(); - /* virtual */ void MainLoop(); - /* virtual */ const char *GetName() const { return "allegro"; } + void MainLoop(); + const char *GetName() const { return "allegro"; } }; /** Factory for the allegro sound driver. */ diff --git a/src/sound/cocoa_s.cpp b/src/sound/cocoa_s.cpp index 8133bf62f6..10fae12a60 100644 --- a/src/sound/cocoa_s.cpp +++ b/src/sound/cocoa_s.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. @@ -80,9 +78,9 @@ const char *SoundDriver_Cocoa::Start(const char * const *parm) desc.componentFlags = 0; desc.componentFlagsMask = 0; - AudioComponent comp = AudioComponentFindNext (NULL, &desc); - if (comp == NULL) { - return "cocoa_s: Failed to start CoreAudio: AudioComponentFindNext returned NULL"; + AudioComponent comp = AudioComponentFindNext (nullptr, &desc); + if (comp == nullptr) { + return "cocoa_s: Failed to start CoreAudio: AudioComponentFindNext returned nullptr"; } /* Open & initialize the default output audio unit */ @@ -101,9 +99,9 @@ const char *SoundDriver_Cocoa::Start(const char * const *parm) desc.componentFlags = 0; desc.componentFlagsMask = 0; - Component comp = FindNextComponent (NULL, &desc); - if (comp == NULL) { - return "cocoa_s: Failed to start CoreAudio: FindNextComponent returned NULL"; + Component comp = FindNextComponent (nullptr, &desc); + if (comp == nullptr) { + return "cocoa_s: Failed to start CoreAudio: FindNextComponent returned nullptr"; } /* Open & initialize the default output audio unit */ @@ -126,7 +124,7 @@ const char *SoundDriver_Cocoa::Start(const char * const *parm) /* Set the audio callback */ callback.inputProc = audioCallback; - callback.inputProcRefCon = NULL; + callback.inputProcRefCon = nullptr; if (AudioUnitSetProperty(_outputAudioUnit, kAudioUnitProperty_SetRenderCallback, kAudioUnitScope_Input, 0, &callback, sizeof(callback)) != noErr) { return "cocoa_s: Failed to start CoreAudio: AudioUnitSetProperty (kAudioUnitProperty_SetRenderCallback)"; } @@ -137,7 +135,7 @@ const char *SoundDriver_Cocoa::Start(const char * const *parm) } /* We're running! */ - return NULL; + return nullptr; } diff --git a/src/sound/cocoa_s.h b/src/sound/cocoa_s.h index 7010914258..43646504d7 100644 --- a/src/sound/cocoa_s.h +++ b/src/sound/cocoa_s.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. @@ -16,16 +14,16 @@ class SoundDriver_Cocoa : public SoundDriver { public: - /* virtual */ const char *Start(const char * const *param); + const char *Start(const char * const *param) override; - /* virtual */ void Stop(); - /* virtual */ const char *GetName() const { return "cocoa"; } + void Stop() override; + const char *GetName() const override { return "cocoa"; } }; class FSoundDriver_Cocoa : public DriverFactoryBase { public: FSoundDriver_Cocoa() : DriverFactoryBase(Driver::DT_SOUND, 10, "cocoa", "Cocoa Sound Driver") {} - /* virtual */ Driver *CreateInstance() const { return new SoundDriver_Cocoa(); } + Driver *CreateInstance() const override { return new SoundDriver_Cocoa(); } }; #endif /* SOUND_COCOA_H */ diff --git a/src/sound/null_s.cpp b/src/sound/null_s.cpp index 3dc95c46ff..738c213403 100644 --- a/src/sound/null_s.cpp +++ b/src/sound/null_s.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. diff --git a/src/sound/null_s.h b/src/sound/null_s.h index b2acd90937..5b883dde1e 100644 --- a/src/sound/null_s.h +++ b/src/sound/null_s.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. @@ -17,17 +15,17 @@ /** Implementation of the null sound driver. */ class SoundDriver_Null : public SoundDriver { public: - /* virtual */ const char *Start(const char * const *param) { return NULL; } + const char *Start(const char * const *param) override { return nullptr; } - /* virtual */ void Stop() { } - /* virtual */ const char *GetName() const { return "null"; } + void Stop() override { } + const char *GetName() const override { return "null"; } }; /** Factory for the null sound driver. */ class FSoundDriver_Null : public DriverFactoryBase { public: FSoundDriver_Null() : DriverFactoryBase(Driver::DT_SOUND, 1, "null", "Null Sound Driver") {} - /* virtual */ Driver *CreateInstance() const { return new SoundDriver_Null(); } + Driver *CreateInstance() const override { return new SoundDriver_Null(); } }; #endif /* SOUND_NULL_H */ diff --git a/src/sound/sdl2_s.cpp b/src/sound/sdl2_s.cpp new file mode 100644 index 0000000000..0b4e6c086d --- /dev/null +++ b/src/sound/sdl2_s.cpp @@ -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 sdl2_s.cpp Playing sound via SDL2. */ + +#ifdef WITH_SDL2 + +#include "../stdafx.h" + +#include "../mixer.h" +#include "sdl_s.h" +#include + +#include "../safeguards.h" + +/** Factory for the SDL sound driver. */ +static FSoundDriver_SDL iFSoundDriver_SDL; + +/** + * Callback that fills the sound buffer. + * @param userdata Ignored. + * @param stream The stream to put data into. + * @param len The length of the stream in bytes. + */ +static void CDECL fill_sound_buffer(void *userdata, Uint8 *stream, int len) +{ + MxMixSamples(stream, len / 4); +} + +const char *SoundDriver_SDL::Start(const char * const *parm) +{ + SDL_AudioSpec spec; + SDL_AudioSpec spec_actual; + + /* Only initialise SDL if the video driver hasn't done it already */ + int ret_code = 0; + if (SDL_WasInit(SDL_INIT_EVERYTHING) == 0) { + ret_code = SDL_Init(SDL_INIT_AUDIO); + } else if (SDL_WasInit(SDL_INIT_AUDIO) == 0) { + ret_code = SDL_InitSubSystem(SDL_INIT_AUDIO); + } + if (ret_code == -1) return SDL_GetError(); + + spec.freq = GetDriverParamInt(parm, "hz", 44100); + spec.format = AUDIO_S16SYS; + spec.channels = 2; + spec.samples = GetDriverParamInt(parm, "samples", 1024); + spec.callback = fill_sound_buffer; + SDL_AudioDeviceID dev = SDL_OpenAudioDevice(nullptr, 0, &spec, &spec_actual, SDL_AUDIO_ALLOW_FREQUENCY_CHANGE); + MxInitialize(spec_actual.freq); + SDL_PauseAudioDevice(dev, 0); + return nullptr; +} + +void SoundDriver_SDL::Stop() +{ + SDL_CloseAudio(); + SDL_QuitSubSystem(SDL_INIT_AUDIO); + if (SDL_WasInit(SDL_INIT_EVERYTHING) == 0) { + SDL_Quit(); // If there's nothing left, quit SDL + } +} + +#endif /* WITH_SDL2 */ diff --git a/src/sound/sdl_s.cpp b/src/sound/sdl_s.cpp index e4c89b0f20..df3a342d70 100644 --- a/src/sound/sdl_s.cpp +++ b/src/sound/sdl_s.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. @@ -61,7 +59,7 @@ const char *SoundDriver_SDL::Start(const char * const *parm) MxInitialize(spec.freq); SDL_OpenAudio(&spec, &spec); SDL_PauseAudio(0); - return NULL; + return nullptr; } void SoundDriver_SDL::Stop() diff --git a/src/sound/sdl_s.h b/src/sound/sdl_s.h index 544ce2070d..4f746107c7 100644 --- a/src/sound/sdl_s.h +++ b/src/sound/sdl_s.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. @@ -7,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 sdl_s.h Base fo playing sound via SDL. */ +/** @file sdl_s.h Base for playing sound via SDL. */ #ifndef SOUND_SDL_H #define SOUND_SDL_H @@ -17,17 +15,17 @@ /** Implementation of the SDL sound driver. */ class SoundDriver_SDL : public SoundDriver { public: - /* virtual */ const char *Start(const char * const *param); + const char *Start(const char * const *param) override; - /* virtual */ void Stop(); - /* virtual */ const char *GetName() const { return "sdl"; } + void Stop() override; + const char *GetName() const override { return "sdl"; } }; /** Factory for the SDL sound driver. */ class FSoundDriver_SDL : public DriverFactoryBase { public: FSoundDriver_SDL() : DriverFactoryBase(Driver::DT_SOUND, 5, "sdl", "SDL Sound Driver") {} - /* virtual */ Driver *CreateInstance() const { return new SoundDriver_SDL(); } + Driver *CreateInstance() const override { return new SoundDriver_SDL(); } }; #endif /* SOUND_SDL_H */ diff --git a/src/sound/sound_driver.hpp b/src/sound/sound_driver.hpp index 0df69b8b45..f1a0519f83 100644 --- a/src/sound/sound_driver.hpp +++ b/src/sound/sound_driver.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/sound/win32_s.cpp b/src/sound/win32_s.cpp index c9c1a8afdc..f45a619b53 100644 --- a/src/sound/win32_s.cpp +++ b/src/sound/win32_s.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. @@ -20,6 +18,7 @@ #include #include #include "../os/windows/win32.h" +#include "../thread.h" #include "../safeguards.h" @@ -42,19 +41,19 @@ static void PrepareHeader(WAVEHDR *hdr) static DWORD WINAPI SoundThread(LPVOID arg) { - SetWin32ThreadName(-1, "ottd:win-sound"); + SetCurrentThreadName("ottd:win-sound"); do { for (WAVEHDR *hdr = _wave_hdr; hdr != endof(_wave_hdr); hdr++) { if ((hdr->dwFlags & WHDR_INQUEUE) != 0) continue; MxMixSamples(hdr->lpData, hdr->dwBufferLength / 4); if (waveOutWrite(_waveout, hdr, sizeof(WAVEHDR)) != MMSYSERR_NOERROR) { - MessageBox(NULL, _T("Sounds are disabled until restart."), _T("waveOutWrite failed"), MB_ICONINFORMATION); + MessageBox(nullptr, _T("Sounds are disabled until restart."), _T("waveOutWrite failed"), MB_ICONINFORMATION); return 0; } } WaitForSingleObject(_event, INFINITE); - } while (_waveout != NULL); + } while (_waveout != nullptr); return 0; } @@ -74,7 +73,7 @@ const char *SoundDriver_Win32::Start(const char * const *parm) _bufsize = min(_bufsize, UINT16_MAX); try { - if (NULL == (_event = CreateEvent(NULL, FALSE, FALSE, NULL))) throw "Failed to create event"; + if (nullptr == (_event = CreateEvent(nullptr, FALSE, FALSE, nullptr))) throw "Failed to create event"; if (waveOutOpen(&_waveout, WAVE_MAPPER, &wfex, (DWORD_PTR)_event, 0, CALLBACK_EVENT) != MMSYSERR_NOERROR) throw "waveOutOpen failed"; @@ -83,13 +82,13 @@ const char *SoundDriver_Win32::Start(const char * const *parm) PrepareHeader(&_wave_hdr[0]); PrepareHeader(&_wave_hdr[1]); - if (NULL == (_thread = CreateThread(NULL, 8192, SoundThread, 0, 0, &_threadId))) throw "Failed to create thread"; + if (nullptr == (_thread = CreateThread(nullptr, 8192, SoundThread, 0, 0, &_threadId))) throw "Failed to create thread"; } catch (const char *error) { this->Stop(); return error; } - return NULL; + return nullptr; } void SoundDriver_Win32::Stop() @@ -97,7 +96,7 @@ void SoundDriver_Win32::Stop() HWAVEOUT waveout = _waveout; /* Stop the sound thread. */ - _waveout = NULL; + _waveout = nullptr; SetEvent(_event); WaitForSingleObject(_thread, INFINITE); diff --git a/src/sound/win32_s.h b/src/sound/win32_s.h index c6c8e8d149..be48a055c5 100644 --- a/src/sound/win32_s.h +++ b/src/sound/win32_s.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. @@ -17,17 +15,17 @@ /** Implementation of the sound driver for Windows. */ class SoundDriver_Win32 : public SoundDriver { public: - /* virtual */ const char *Start(const char * const *param); + const char *Start(const char * const *param) override; - /* virtual */ void Stop(); - /* virtual */ const char *GetName() const { return "win32"; } + void Stop() override; + const char *GetName() const override { return "win32"; } }; /** 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") {} - /* virtual */ Driver *CreateInstance() const { return new SoundDriver_Win32(); } + Driver *CreateInstance() const override { return new SoundDriver_Win32(); } }; #endif /* SOUND_WIN32_H */ diff --git a/src/sound/xaudio2_s.cpp b/src/sound/xaudio2_s.cpp index 60311ced20..8b9afbd1b1 100644 --- a/src/sound/xaudio2_s.cpp +++ b/src/sound/xaudio2_s.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. @@ -125,7 +123,7 @@ static StreamingVoiceContext* _voice_context = nullptr; * Initialises the XAudio2 driver. * * @param parm Driver parameters. -* @return An error message if unsuccessful, or NULL otherwise. +* @return An error message if unsuccessful, or nullptr otherwise. * */ const char *SoundDriver_XAudio2::Start(const char * const *parm) @@ -140,7 +138,7 @@ const char *SoundDriver_XAudio2::Start(const char * const *parm) _xaudio_dll_handle = LoadLibraryA(XAUDIO2_DLL_A); - if (_xaudio_dll_handle == NULL) + if (_xaudio_dll_handle == nullptr) { CoUninitialize(); @@ -150,7 +148,7 @@ const char *SoundDriver_XAudio2::Start(const char * const *parm) API_XAudio2Create xAudio2Create = (API_XAudio2Create) GetProcAddress(_xaudio_dll_handle, "XAudio2Create"); - if (xAudio2Create == NULL) + if (xAudio2Create == nullptr) { FreeLibrary(_xaudio_dll_handle); CoUninitialize(); @@ -248,7 +246,7 @@ const char *SoundDriver_XAudio2::Start(const char * const *parm) return "Failed to submit the first audio buffer"; } - return NULL; + return nullptr; } /** diff --git a/src/sound/xaudio2_s.h b/src/sound/xaudio2_s.h index 2385f49ee2..70b4d80cc9 100644 --- a/src/sound/xaudio2_s.h +++ b/src/sound/xaudio2_s.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. @@ -17,17 +15,17 @@ /** Implementation of the XAudio2 sound driver. */ class SoundDriver_XAudio2 : public SoundDriver { public: - /* virtual */ const char *Start(const char * const *param); + const char *Start(const char * const *param) override; - /* virtual */ void Stop(); - /* virtual */ const char *GetName() const { return "xaudio2"; } + void Stop() override; + const char *GetName() const override { return "xaudio2"; } }; /** Factory for the XAudio2 sound driver. */ class FSoundDriver_XAudio2 : public DriverFactoryBase { public: FSoundDriver_XAudio2() : DriverFactoryBase(Driver::DT_SOUND, 10, "xaudio2", "XAudio2 Sound Driver") {} - /* virtual */ Driver *CreateInstance() const { return new SoundDriver_XAudio2(); } + Driver *CreateInstance() const override { return new SoundDriver_XAudio2(); } }; #endif /* SOUND_XAUDIO2_H */ diff --git a/src/sound_func.h b/src/sound_func.h index 7117bb6466..b378dbdfe2 100644 --- a/src/sound_func.h +++ b/src/sound_func.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/sound_type.h b/src/sound_type.h index 76fe25139e..0fb0b0a731 100644 --- a/src/sound_type.h +++ b/src/sound_type.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/sprite.cpp b/src/sprite.cpp index 22210712a9..a6ff4c9224 100644 --- a/src/sprite.cpp +++ b/src/sprite.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. @@ -75,7 +73,7 @@ void DrawCommonTileSeq(const TileInfo *ti, const DrawTileSprites *dts, Transpare SetBit(image, PALETTE_MODIFIER_TRANSPARENT); pal = PALETTE_TO_TRANSPARENT; } - DrawGroundSprite(image, pal, NULL, offs_x, offs_y); + DrawGroundSprite(image, pal, nullptr, offs_x, offs_y); } } } diff --git a/src/sprite.h b/src/sprite.h index 16da834c75..44814c09b9 100644 --- a/src/sprite.h +++ b/src/sprite.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/spritecache.cpp b/src/spritecache.cpp index 2f9e243d46..8543039910 100644 --- a/src/spritecache.cpp +++ b/src/spritecache.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. @@ -29,22 +27,20 @@ /* Default of 4MB spritecache */ uint _sprite_cache_size = 4; -typedef SimpleTinyEnumT SpriteTypeByte; - struct SpriteCache { void *ptr; size_t file_pos; uint32 id; uint16 file_slot; int16 lru; - SpriteTypeByte 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. + 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 container_ver; ///< Container version of the GRF the sprite is from. }; static uint _spritecache_items = 0; -static SpriteCache *_spritecache = NULL; +static SpriteCache *_spritecache = nullptr; static inline SpriteCache *GetSpriteCache(uint index) @@ -149,6 +145,17 @@ uint GetOriginFileSlot(SpriteID sprite) return GetSpriteCache(sprite)->file_slot; } +/** + * Get the GRF-local sprite id of a given sprite. + * @param sprite The sprite to look at. + * @return The GRF-local sprite id. + */ +uint32 GetSpriteLocalID(SpriteID sprite) +{ + if (!SpriteExists(sprite)) return 0; + return GetSpriteCache(sprite)->id; +} + /** * Count the sprites which originate from a specific file slot in a range of SpriteIDs. * @param file_slot FIOS file slot. @@ -428,7 +435,7 @@ static void *ReadSprite(const SpriteCache *sc, SpriteID id, SpriteType sprite_ty } if (sprite_avail == 0) { - if (sprite_type == ST_MAPGEN) return NULL; + if (sprite_type == ST_MAPGEN) return nullptr; if (id == SPR_IMG_QUERY) usererror("Okay... something went horribly wrong. I couldn't load the fallback sprite. What should I do?"); return (void*)GetRawSprite(SPR_IMG_QUERY, ST_NORMAL, allocator); } @@ -539,7 +546,7 @@ bool LoadNextSprite(int load_index, byte file_slot, uint file_sprite_id, byte co byte grf_type = FioReadByte(); SpriteType type; - void *data = NULL; + void *data = nullptr; 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. */ @@ -599,7 +606,7 @@ void DupSprite(SpriteID old_spr, SpriteID new_spr) scnew->file_slot = scold->file_slot; scnew->file_pos = scold->file_pos; - scnew->ptr = NULL; + scnew->ptr = nullptr; scnew->id = scold->id; scnew->type = scold->type; scnew->warned = false; @@ -647,7 +654,7 @@ void IncreaseSpriteLRU() for (i = 0; i != _spritecache_items; i++) { SpriteCache *sc = GetSpriteCache(i); - if (sc->ptr != NULL) { + if (sc->ptr != nullptr) { if (sc->lru >= 0) { sc->lru = -1; } else if (sc->lru != -32768) { @@ -719,7 +726,7 @@ static void DeleteEntryFromSpriteCache(uint item) MemBlock *s = (MemBlock*)GetSpriteCache(item)->ptr - 1; assert(!(s->size & S_FREE_MASK)); s->size |= S_FREE_MASK; - GetSpriteCache(item)->ptr = NULL; + GetSpriteCache(item)->ptr = nullptr; /* And coalesce adjacent free blocks */ for (s = _spritecache_ptr; s->size != 0; s = NextBlock(s)) { @@ -741,7 +748,7 @@ static void DeleteEntryFromSpriteCache() cur_lru = 0xffff; for (SpriteID i = 0; i != _spritecache_items; i++) { SpriteCache *sc = GetSpriteCache(i); - if (sc->type != ST_RECOLOUR && sc->ptr != NULL && sc->lru < cur_lru) { + if (sc->type != ST_RECOLOUR && sc->ptr != nullptr && sc->lru < cur_lru) { cur_lru = sc->lru; best = i; } @@ -811,7 +818,7 @@ static void *HandleInvalidSpriteRequest(SpriteID sprite, SpriteType requested, S SpriteType available = sc->type; if (requested == ST_FONT && available == ST_NORMAL) { - if (sc->ptr == NULL) sc->type = ST_FONT; + if (sc->ptr == nullptr) sc->type = ST_FONT; return GetRawSprite(sprite, sc->type, allocator); } @@ -841,7 +848,7 @@ static void *HandleInvalidSpriteRequest(SpriteID sprite, SpriteType requested, S * If the sprite is not available or of wrong type, a fallback sprite is returned. * @param sprite Sprite to read. * @param type Expected sprite type. - * @param allocator Allocator function to use. Set to NULL to use the usual sprite cache. + * @param allocator Allocator function to use. Set to nullptr to use the usual sprite cache. * @return Sprite raw data */ void *GetRawSprite(SpriteID sprite, SpriteType type, AllocatorProc *allocator) @@ -860,14 +867,14 @@ void *GetRawSprite(SpriteID sprite, SpriteType type, AllocatorProc *allocator) if (sc->type != type) return HandleInvalidSpriteRequest(sprite, type, sc, allocator); - if (allocator == NULL) { + if (allocator == nullptr) { /* Load sprite into/from spritecache */ /* Update LRU */ sc->lru = ++_sprite_lru_counter; /* Load the sprite, if it is not loaded, yet */ - if (sc->ptr == NULL) sc->ptr = ReadSprite(sc, sprite, type, AllocSprite); + if (sc->ptr == nullptr) sc->ptr = ReadSprite(sc, sprite, type, AllocSprite); return sc->ptr; } else { @@ -886,7 +893,7 @@ static void GfxInitSpriteCache() /* Remember 'target_size' from the previous allocation attempt, so we do not try to reach the target_size multiple times in case of failure. */ static uint last_alloc_attempt = 0; - if (_spritecache_ptr == NULL || (_allocated_sprite_cache_size != target_size && target_size != last_alloc_attempt)) { + if (_spritecache_ptr == nullptr || (_allocated_sprite_cache_size != target_size && target_size != last_alloc_attempt)) { delete[] reinterpret_cast(_spritecache_ptr); last_alloc_attempt = target_size; @@ -897,10 +904,10 @@ static void GfxInitSpriteCache() /* 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 = NULL; + _spritecache_ptr = nullptr; } - if (_spritecache_ptr != NULL) { + if (_spritecache_ptr != nullptr) { /* Allocation succeeded, but we wanted less. */ delete[] reinterpret_cast(_spritecache_ptr); _spritecache_ptr = reinterpret_cast(new byte[_allocated_sprite_cache_size]); @@ -910,7 +917,7 @@ static void GfxInitSpriteCache() /* Try again to allocate half. */ _allocated_sprite_cache_size >>= 1; } - } while (_spritecache_ptr == NULL); + } while (_spritecache_ptr == nullptr); if (_allocated_sprite_cache_size != target_size) { DEBUG(misc, 0, "Not enough memory to allocate %d MiB of spritecache. Spritecache was reduced to %d MiB.", target_size / 1024 / 1024, _allocated_sprite_cache_size / 1024 / 1024); @@ -935,7 +942,7 @@ void GfxInitSpriteMem() /* Reset the spritecache 'pool' */ free(_spritecache); _spritecache_items = 0; - _spritecache = NULL; + _spritecache = nullptr; _compact_cache_counter = 0; } @@ -949,7 +956,7 @@ void GfxClearSpriteCache() /* Clear sprite ptr for all cached items */ for (uint i = 0; i != _spritecache_items; i++) { SpriteCache *sc = GetSpriteCache(i); - if (sc->type != ST_RECOLOUR && sc->ptr != NULL) DeleteEntryFromSpriteCache(i); + if (sc->type != ST_RECOLOUR && sc->ptr != nullptr) DeleteEntryFromSpriteCache(i); } } diff --git a/src/spritecache.h b/src/spritecache.h index 8013105183..1b738a8658 100644 --- a/src/spritecache.h +++ b/src/spritecache.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. @@ -27,11 +25,12 @@ extern uint _sprite_cache_size; typedef void *AllocatorProc(size_t size); -void *GetRawSprite(SpriteID sprite, SpriteType type, AllocatorProc *allocator = NULL); +void *GetRawSprite(SpriteID sprite, SpriteType type, AllocatorProc *allocator = nullptr); bool SpriteExists(SpriteID sprite); SpriteType GetSpriteType(SpriteID sprite); uint GetOriginFileSlot(SpriteID sprite); +uint32 GetSpriteLocalID(SpriteID sprite); uint GetSpriteCountForSlot(uint file_slot, SpriteID begin, SpriteID end); uint GetMaxSpriteID(); diff --git a/src/spriteloader/grf.cpp b/src/spriteloader/grf.cpp index b21e70b1db..058193c34c 100644 --- a/src/spriteloader/grf.cpp +++ b/src/spriteloader/grf.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. @@ -69,8 +67,8 @@ static bool WarnCorruptSprite(uint8 file_slot, size_t file_pos, int line) */ bool DecodeSingleSprite(SpriteLoader::Sprite *sprite, uint8 file_slot, size_t file_pos, SpriteType sprite_type, int64 num, byte type, ZoomLevel zoom_lvl, byte colour_fmt, byte container_format) { - AutoFreePtr dest_orig(MallocT(num)); - byte *dest = dest_orig; + std::unique_ptr dest_orig(new byte[num]); + byte *dest = dest_orig.get(); const int64 dest_size = num; /* Read the file, which has some kind of compression */ @@ -89,7 +87,7 @@ bool DecodeSingleSprite(SpriteLoader::Sprite *sprite, uint8 file_slot, size_t fi } else { /* Copy bytes from earlier in the sprite */ const uint data_offset = ((code & 7) << 8) | FioReadByte(); - if (dest - data_offset < dest_orig) return WarnCorruptSprite(file_slot, file_pos, __LINE__); + if (dest - data_offset < dest_orig.get()) return WarnCorruptSprite(file_slot, file_pos, __LINE__); int size = -(code >> 3); num -= size; if (num < 0) return WarnCorruptSprite(file_slot, file_pos, __LINE__); @@ -123,10 +121,10 @@ bool DecodeSingleSprite(SpriteLoader::Sprite *sprite, uint8 file_slot, size_t fi } /* Go to that row */ - dest = dest_orig + offset; + dest = dest_orig.get() + offset; do { - if (dest + (container_format >= 2 && sprite->width > 256 ? 4 : 2) > dest_orig + dest_size) { + if (dest + (container_format >= 2 && sprite->width > 256 ? 4 : 2) > dest_orig.get() + dest_size) { return WarnCorruptSprite(file_slot, file_pos, __LINE__); } @@ -152,7 +150,7 @@ bool DecodeSingleSprite(SpriteLoader::Sprite *sprite, uint8 file_slot, size_t fi data = &sprite->data[y * sprite->width + skip]; - if (skip + length > sprite->width || dest + length * bpp > dest_orig + dest_size) { + if (skip + length > sprite->width || dest + length * bpp > dest_orig.get() + dest_size) { return WarnCorruptSprite(file_slot, file_pos, __LINE__); } @@ -188,7 +186,7 @@ bool DecodeSingleSprite(SpriteLoader::Sprite *sprite, uint8 file_slot, size_t fi warning_level = 6; } - dest = dest_orig; + dest = dest_orig.get(); for (int i = 0; i < sprite->width * sprite->height; i++) { byte *pixel = &dest[i * bpp]; diff --git a/src/spriteloader/grf.hpp b/src/spriteloader/grf.hpp index 4081a9f337..20d60edf51 100644 --- a/src/spriteloader/grf.hpp +++ b/src/spriteloader/grf.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/spriteloader/spriteloader.hpp b/src/spriteloader/spriteloader.hpp index 060e72d16b..0122631716 100644 --- a/src/spriteloader/spriteloader.hpp +++ b/src/spriteloader/spriteloader.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/station.cpp b/src/station.cpp index f86286f3d9..61c53bc562 100644 --- a/src/station.cpp +++ b/src/station.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. @@ -14,6 +12,7 @@ #include "company_base.h" #include "roadveh.h" #include "viewport_func.h" +#include "viewport_kdtree.h" #include "date_func.h" #include "command_func.h" #include "news_func.h" @@ -21,8 +20,10 @@ #include "vehiclelist.h" #include "core/pool_func.hpp" #include "station_base.h" +#include "station_kdtree.h" #include "roadstop_base.h" #include "industry.h" +#include "town.h" #include "core/random_func.hpp" #include "linkgraph/linkgraph.h" #include "linkgraph/linkgraphschedule.h" @@ -35,6 +36,19 @@ StationPool _station_pool("Station"); INSTANTIATE_POOL_METHODS(Station) + +StationKdtree _station_kdtree(Kdtree_StationXYFunc); + +void RebuildStationKdtree() +{ + std::vector stids; + for (const Station *st : Station::Iterate()) { + stids.push_back(st->index); + } + _station_kdtree.Build(stids.begin(), stids.end()); +} + + BaseStation::~BaseStation() { free(this->name); @@ -54,7 +68,7 @@ Station::Station(TileIndex tile) : SpecializedStation(tile), bus_station(INVALID_TILE, 0, 0), truck_station(INVALID_TILE, 0, 0), - dock_tile(INVALID_TILE), + ship_station(INVALID_TILE, 0, 0), indtype(IT_INVALID), time_since_load(255), time_since_unload(255), @@ -83,15 +97,14 @@ Station::~Station() this->loading_vehicles.front()->LeaveStation(); } - Aircraft *a; - FOR_ALL_AIRCRAFT(a) { + for (Aircraft *a : Aircraft::Iterate()) { if (!a->IsNormalAircraft()) continue; if (a->targetairport == this->index) a->targetairport = INVALID_STATION; } for (CargoID c = 0; c < NUM_CARGO; ++c) { LinkGraph *lg = LinkGraph::GetIfValid(this->goods[c].link_graph); - if (lg == NULL) continue; + if (lg == nullptr) continue; for (NodeID node = 0; node < lg->Size(); ++node) { Station *st = Station::Get((*lg)[node].Station()); @@ -108,8 +121,7 @@ Station::~Station() } } - Vehicle *v; - FOR_ALL_VEHICLES(v) { + for (Vehicle *v : Vehicle::Iterate()) { /* Forget about this station if this station is removed */ if (v->last_station_visited == this->index) { v->last_station_visited = INVALID_STATION; @@ -119,6 +131,9 @@ Station::~Station() } } + /* Remove station from industries and towns that reference it. */ + this->RemoveFromAllNearbyLists(); + /* Clear the persistent storage. */ delete this->airport.psa; @@ -142,6 +157,9 @@ Station::~Station() } CargoPacket::InvalidateAllFrom(this->index); + + _station_kdtree.Remove(this->index); + if (this->sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeStation(this->index)); } @@ -164,9 +182,9 @@ RoadStop *Station::GetPrimaryRoadStop(const RoadVehicle *v) const { RoadStop *rs = this->GetPrimaryRoadStop(v->IsBus() ? ROADSTOP_BUS : ROADSTOP_TRUCK); - for (; rs != NULL; rs = rs->next) { + for (; rs != nullptr; rs = rs->next) { /* The vehicle cannot go to this roadstop (different roadtype) */ - if ((GetRoadTypes(rs->xy) & v->compatible_roadtypes) == ROADTYPES_NONE) continue; + if (!HasTileAnyRoadType(rs->xy, v->compatible_roadtypes)) continue; /* The vehicle is articulated and can therefore not go to a standard road stop. */ if (IsStandardRoadStopTile(rs->xy) && v->HasArticulatedPart()) continue; @@ -184,7 +202,7 @@ RoadStop *Station::GetPrimaryRoadStop(const RoadVehicle *v) const void Station::AddFacility(StationFacility new_facility_bit, TileIndex facil_xy) { if (this->facilities == FACIL_NONE) { - this->xy = facil_xy; + this->MoveSign(facil_xy); this->random_bits = Random(); } this->facilities |= new_facility_bit; @@ -261,6 +279,39 @@ void Station::MarkTilesDirty(bool cargo_change) const return length; } +/** + * Get the catchment size of an individual station tile. + * @param tile Station tile to get catchment size of. + * @param st Associated station of station tile. + * @pre IsTileType(tile, MP_STATION) + * @return The catchment size of the station tile. + */ +static uint GetTileCatchmentRadius(TileIndex tile, const Station *st) +{ + assert(IsTileType(tile, MP_STATION)); + + if (_settings_game.station.modified_catchment) { + switch (GetStationType(tile)) { + case STATION_RAIL: return CA_TRAIN; + case STATION_OILRIG: return CA_UNMODIFIED; + case STATION_AIRPORT: return st->airport.GetSpec()->catchment; + case STATION_TRUCK: return CA_TRUCK; + case STATION_BUS: return CA_BUS; + case STATION_DOCK: return CA_DOCK; + + default: NOT_REACHED(); + case STATION_BUOY: + case STATION_WAYPOINT: return CA_NONE; + } + } else { + switch (GetStationType(tile)) { + default: return CA_UNMODIFIED; + case STATION_BUOY: + case STATION_WAYPOINT: return CA_NONE; + } + } +} + /** * Determines the catchment radius of the station * @return The radius @@ -270,13 +321,13 @@ uint Station::GetCatchmentRadius() const uint ret = CA_NONE; if (_settings_game.station.modified_catchment) { - if (this->bus_stops != NULL) ret = max(ret, CA_BUS); - if (this->truck_stops != NULL) ret = max(ret, CA_TRUCK); + if (this->bus_stops != nullptr) ret = max(ret, CA_BUS); + if (this->truck_stops != nullptr) ret = max(ret, CA_TRUCK); if (this->train_station.tile != INVALID_TILE) ret = max(ret, CA_TRAIN); - if (this->dock_tile != INVALID_TILE) ret = max(ret, CA_DOCK); + if (this->ship_station.tile != INVALID_TILE) ret = max(ret, CA_DOCK); if (this->airport.tile != INVALID_TILE) ret = max(ret, this->airport.GetSpec()->catchment); } else { - if (this->bus_stops != NULL || this->truck_stops != NULL || this->train_station.tile != INVALID_TILE || this->dock_tile != INVALID_TILE || this->airport.tile != INVALID_TILE) { + if (this->bus_stops != nullptr || this->truck_stops != nullptr || this->train_station.tile != INVALID_TILE || this->ship_station.tile != INVALID_TILE || this->airport.tile != INVALID_TILE) { ret = CA_UNMODIFIED; } } @@ -305,79 +356,126 @@ Rect Station::GetCatchmentRect() const return ret; } -/** Rect and pointer to IndustryVector */ -struct RectAndIndustryVector { - Rect rect; ///< The rectangle to search the industries in. - IndustryVector *industries_near; ///< The nearby industries. -}; - /** - * Callback function for Station::RecomputeIndustriesNear() - * Tests whether tile is an industry and possibly adds - * the industry to station's industries_near list. - * @param ind_tile tile to check - * @param user_data pointer to RectAndIndustryVector - * @return always false, we want to search all tiles + * Add nearby industry to station's industries_near list if it accepts cargo. + * @param ind Industry + * @param st Station */ -static bool FindIndustryToDeliver(TileIndex ind_tile, void *user_data) +static void AddIndustryToDeliver(Industry *ind, Station *st) { - /* Only process industry tiles */ - if (!IsTileType(ind_tile, MP_INDUSTRY)) return false; - - RectAndIndustryVector *riv = (RectAndIndustryVector *)user_data; - Industry *ind = Industry::GetByTile(ind_tile); - /* Don't check further if this industry is already in the list */ - if (riv->industries_near->Contains(ind)) return false; - - /* Only process tiles in the station acceptance rectangle */ - int x = TileX(ind_tile); - int y = TileY(ind_tile); - if (x < riv->rect.left || x > riv->rect.right || y < riv->rect.top || y > riv->rect.bottom) return false; + if (st->industries_near.find(ind) != st->industries_near.end()) return; /* Include only industries that can accept cargo */ uint cargo_index; for (cargo_index = 0; cargo_index < lengthof(ind->accepts_cargo); cargo_index++) { if (ind->accepts_cargo[cargo_index] != CT_INVALID) break; } - if (cargo_index >= lengthof(ind->accepts_cargo)) return false; + if (cargo_index >= lengthof(ind->accepts_cargo)) return; - *riv->industries_near->Append() = ind; + st->industries_near.insert(ind); +} +/** + * Remove this station from the nearby stations lists of all towns and industries. + */ +void Station::RemoveFromAllNearbyLists() +{ + for (Town *t : Town::Iterate()) { t->stations_near.erase(this); } + for (Industry *i : Industry::Iterate()) { i->stations_near.erase(this); } +} + +/** + * Test if the given town ID is covered by our catchment area. + * This is used when removing a house tile to determine if it was the last house tile + * within our catchment. + * @param t TownID to test. + * @return true if at least one house tile of TownID is covered. + */ +bool Station::CatchmentCoversTown(TownID t) const +{ + BitmapTileIterator it(this->catchment_tiles); + for (TileIndex tile = it; tile != INVALID_TILE; tile = ++it) { + if (IsTileType(tile, MP_HOUSE) && GetTownIndex(tile) == t) return true; + } return false; } /** - * Recomputes Station::industries_near, list of industries possibly - * accepting cargo in station's catchment radius + * Recompute tiles covered in our catchment area. + * This will additionally recompute nearby towns and industries. */ -void Station::RecomputeIndustriesNear() +void Station::RecomputeCatchment() { - this->industries_near.Clear(); - if (this->rect.IsEmpty()) return; + this->industries_near.clear(); + this->RemoveFromAllNearbyLists(); - RectAndIndustryVector riv = { - this->GetCatchmentRect(), - &this->industries_near - }; + if (this->rect.IsEmpty()) { + this->catchment_tiles.Reset(); + return; + } - /* Compute maximum extent of acceptance rectangle wrt. station sign */ - TileIndex start_tile = this->xy; - uint max_radius = max( - max(DistanceManhattan(start_tile, TileXY(riv.rect.left, riv.rect.top)), DistanceManhattan(start_tile, TileXY(riv.rect.left, riv.rect.bottom))), - max(DistanceManhattan(start_tile, TileXY(riv.rect.right, riv.rect.top)), DistanceManhattan(start_tile, TileXY(riv.rect.right, riv.rect.bottom))) - ); + if (!_settings_game.station.serve_neutral_industries && this->industry != nullptr) { + /* Station is associated with an industry, so we only need to deliver to that industry. */ + this->catchment_tiles.Initialize(this->industry->location); + TILE_AREA_LOOP(tile, this->industry->location) { + if (IsTileType(tile, MP_INDUSTRY) && GetIndustryIndex(tile) == this->industry->index) { + this->catchment_tiles.SetTile(tile); + } + } + /* The industry's stations_near may have been computed before its neutral station was built so clear and re-add here. */ + for (Station *st : this->industry->stations_near) { + st->industries_near.erase(this->industry); + } + this->industry->stations_near.clear(); + this->industry->stations_near.insert(this); + this->industries_near.insert(this->industry); + return; + } - CircularTileSearch(&start_tile, 2 * max_radius + 1, &FindIndustryToDeliver, &riv); + this->catchment_tiles.Initialize(GetCatchmentRect()); + + /* Loop finding all station tiles */ + TileArea ta(TileXY(this->rect.left, this->rect.top), TileXY(this->rect.right, this->rect.bottom)); + TILE_AREA_LOOP(tile, ta) { + if (!IsTileType(tile, MP_STATION) || GetStationIndex(tile) != this->index) continue; + + uint r = GetTileCatchmentRadius(tile, this); + if (r == CA_NONE) continue; + + /* This tile sub-loop doesn't need to test any tiles, they are simply added to the catchment set. */ + TileArea ta2 = TileArea(tile, 1, 1).Expand(r); + TILE_AREA_LOOP(tile2, ta2) this->catchment_tiles.SetTile(tile2); + } + + /* Search catchment tiles for towns and industries */ + BitmapTileIterator it(this->catchment_tiles); + for (TileIndex tile = it; tile != INVALID_TILE; tile = ++it) { + if (IsTileType(tile, MP_HOUSE)) { + Town *t = Town::GetByTile(tile); + t->stations_near.insert(this); + } + if (IsTileType(tile, MP_INDUSTRY)) { + Industry *i = Industry::GetByTile(tile); + + /* Ignore industry if it has a neutral station. It already can't be this station. */ + if (!_settings_game.station.serve_neutral_industries && i->neutral_station != nullptr) continue; + + i->stations_near.insert(this); + + /* Add if we can deliver to this industry as well */ + AddIndustryToDeliver(i, this); + } + } } /** - * Recomputes Station::industries_near for all stations + * Recomputes catchment of all stations. + * This will additionally recompute nearby stations for all towns and industries. */ -/* static */ void Station::RecomputeIndustriesNearForAll() +/* static */ void Station::RecomputeCatchmentForAll() { - Station *st; - FOR_ALL_STATIONS(st) st->RecomputeIndustriesNear(); + for (Station *st : Station::Iterate()) { st->RecomputeCatchment(); } } /************************************************************************/ @@ -556,8 +654,7 @@ Money AirportMaintenanceCost(Owner owner) { Money total_cost = 0; - const Station *st; - FOR_ALL_STATIONS(st) { + for (const Station *st : Station::Iterate()) { if (st->owner == owner && (st->facilities & FACIL_AIRPORT)) { total_cost += _price[PR_INFRASTRUCTURE_AIRPORT] * st->airport.GetSpec()->maintenance_cost; } @@ -565,3 +662,8 @@ Money AirportMaintenanceCost(Owner owner) /* 3 bits fraction for the maintenance cost factor. */ return total_cost >> 3; } + +bool StationCompare::operator() (const Station *lhs, const Station *rhs) const +{ + return lhs->index < rhs->index; +} diff --git a/src/station_base.h b/src/station_base.h index 7b349a39e7..d6ef468082 100644 --- a/src/station_base.h +++ b/src/station_base.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. @@ -19,7 +17,9 @@ #include "industry_type.h" #include "linkgraph/linkgraph_type.h" #include "newgrf_storage.h" +#include "bitmap_type.h" #include +#include typedef Pool StationPool; extern StationPool _station_pool; @@ -316,7 +316,7 @@ struct Airport : public TileArea { uint64 flags; ///< stores which blocks on the airport are taken. was 16 bit earlier on, then 32 byte type; ///< Type of this airport, @see AirportTypes byte layout; ///< Airport layout number. - DirectionByte rotation; ///< How this airport is rotated. + Direction rotation; ///< How this airport is rotated. PersistentStorage *psa; ///< Persistent storage for NewGRF airports. @@ -448,7 +448,11 @@ private: } }; -typedef SmallVector IndustryVector; +struct IndustryCompare { + bool operator() (const Industry *lhs, const Industry *rhs) const; +}; + +typedef std::set IndustryList; /** Station data structure */ struct Station FINAL : SpecializedStation { @@ -465,12 +469,15 @@ public: RoadStop *truck_stops; ///< All the truck stops TileArea truck_station; ///< Tile area the truck 'station' part covers - Airport airport; ///< Tile area the airport covers - TileIndex dock_tile; ///< The location of the dock + Airport airport; ///< Tile area the airport covers + TileArea ship_station; ///< Tile area the ship 'station' part covers + TileArea docking_station; ///< Tile area the docking tiles cover IndustryType indtype; ///< Industry type to get the name from - StationHadVehicleOfTypeByte had_vehicle_of_type; + BitmapTileArea catchment_tiles; ///< NOSAVE: Set of individual tiles covered by catchment area + + StationHadVehicleOfType had_vehicle_of_type; byte time_since_load; byte time_since_unload; @@ -480,7 +487,8 @@ public: GoodsEntry goods[NUM_CARGO]; ///< Goods at this station CargoTypes always_accepted; ///< Bitmask of always accepted cargo types (by houses, HQs, industry tiles when industry doesn't accept cargo) - IndustryVector industries_near; ///< Cached list of industries near the station that can accept cargo, @see DeliverGoodsToIndustry() + IndustryList industries_near; ///< Cached list of industries near the station that can accept cargo, @see DeliverGoodsToIndustry() + Industry *industry; ///< NOSAVE: Associated industry for neutral stations. (Rebuilt on load from Industry->st) Station(TileIndex tile = INVALID_TILE); ~Station(); @@ -489,19 +497,28 @@ public: void MarkTilesDirty(bool cargo_change) const; - void UpdateVirtCoord(); + void UpdateVirtCoord() override; + + void MoveSign(TileIndex new_xy) override; void AfterStationTileSetChange(bool adding, StationType type); - /* virtual */ uint GetPlatformLength(TileIndex tile, DiagDirection dir) const; - /* virtual */ uint GetPlatformLength(TileIndex tile) const; - void RecomputeIndustriesNear(); - static void RecomputeIndustriesNearForAll(); + uint GetPlatformLength(TileIndex tile, DiagDirection dir) const override; + uint GetPlatformLength(TileIndex tile) const override; + void RecomputeCatchment(); + static void RecomputeCatchmentForAll(); uint GetCatchmentRadius() const; Rect GetCatchmentRect() const; + bool CatchmentCoversTown(TownID t) const; + void RemoveFromAllNearbyLists(); - /* virtual */ inline bool TileBelongsToRailStation(TileIndex tile) const + inline bool TileIsInCatchment(TileIndex tile) const + { + return this->catchment_tiles.HasTile(tile); + } + + inline bool TileBelongsToRailStation(TileIndex tile) const override { return IsRailStationTile(tile) && GetStationIndex(tile) == this->index; } @@ -511,13 +528,11 @@ public: return IsAirportTile(tile) && GetStationIndex(tile) == this->index; } - /* virtual */ uint32 GetNewGRFVariable(const ResolverObject &object, byte variable, byte parameter, bool *available) const; + uint32 GetNewGRFVariable(const ResolverObject &object, byte variable, byte parameter, bool *available) const override; - /* virtual */ void GetTileArea(TileArea *ta, StationType type) const; + void GetTileArea(TileArea *ta, StationType type) const override; }; -#define FOR_ALL_STATIONS(var) FOR_ALL_BASE_STATIONS_OF_TYPE(Station, var) - /** Iterator to iterate over all tiles belonging to an airport. */ class AirportTileIterator : public OrthogonalTileIterator { private: @@ -548,4 +563,6 @@ public: } }; +void RebuildStationKdtree(); + #endif /* STATION_BASE_H */ diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index e6864d70db..385072b956 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.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. @@ -14,6 +12,7 @@ #include "bridge_map.h" #include "cmd_helper.h" #include "viewport_func.h" +#include "viewport_kdtree.h" #include "command_func.h" #include "town.h" #include "news_func.h" @@ -37,8 +36,10 @@ #include "animated_tile_func.h" #include "elrail_func.h" #include "station_base.h" +#include "station_kdtree.h" #include "roadstop_base.h" #include "newgrf_railtype.h" +#include "newgrf_roadtype.h" #include "waypoint_base.h" #include "waypoint_func.h" #include "pbs.h" @@ -53,6 +54,7 @@ #include "linkgraph/linkgraph_base.h" #include "linkgraph/refresh.h" #include "widgets/station_widget.h" +#include "tunnelbridge_map.h" #include "table/strings.h" @@ -99,9 +101,7 @@ bool IsHangar(TileIndex t) template CommandCost GetStationAround(TileArea ta, StationID closest_station, CompanyID company, T **st) { - ta.tile -= TileDiffXY(1, 1); - ta.w += 2; - ta.h += 2; + ta.Expand(1); /* check around to see if there are any stations there owned by the company */ TILE_AREA_LOOP(tile_cur, ta) { @@ -115,7 +115,7 @@ CommandCost GetStationAround(TileArea ta, StationID closest_station, CompanyID c } } } - *st = (closest_station == INVALID_STATION) ? NULL : T::Get(closest_station); + *st = (closest_station == INVALID_STATION) ? nullptr : T::Get(closest_station); return CommandCost(); } @@ -251,8 +251,7 @@ static StringID GenerateStationName(Station *st, TileIndex tile, StationNaming n bool indtypes[NUM_INDUSTRYTYPES]; memset(indtypes, 0, sizeof(indtypes)); - const Station *s; - FOR_ALL_STATIONS(s) { + for (const Station *s : Station::Iterate()) { if (s != st && s->town == t) { if (s->indtype != IT_INVALID) { indtypes[s->indtype] = true; @@ -354,24 +353,26 @@ static StringID GenerateStationName(Station *st, TileIndex tile, StationNaming n /** * Find the closest deleted station of the current company * @param tile the tile to search from. - * @return the closest station or NULL if too far. + * @return the closest station or nullptr if too far. */ static Station *GetClosestDeletedStation(TileIndex tile) { uint threshold = 8; - Station *best_station = NULL; - Station *st; - FOR_ALL_STATIONS(st) { + Station *best_station = nullptr; + ForAllStationsRadius(tile, threshold, [&](Station *st) { if (!st->IsInUse() && st->owner == _current_company) { uint cur_dist = DistanceManhattan(tile, st->xy); if (cur_dist < threshold) { threshold = cur_dist; best_station = st; + } else if (cur_dist == threshold && best_station != nullptr) { + /* In case of a tie, lowest station ID wins */ + if (st->index < best_station->index) best_station = st; } } - } + }); return best_station; } @@ -398,7 +399,7 @@ void Station::GetTileArea(TileArea *ta, StationType type) const case STATION_DOCK: case STATION_OILRIG: - ta->tile = this->dock_tile; + *ta = this->docking_station; break; default: NOT_REACHED(); @@ -418,23 +419,56 @@ void Station::UpdateVirtCoord() pt.y -= 32 * ZOOM_LVL_BASE; if ((this->facilities & FACIL_AIRPORT) && this->airport.type == AT_OILRIG) pt.y -= 16 * ZOOM_LVL_BASE; + if (this->sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeStation(this->index)); + SetDParam(0, this->index); SetDParam(1, this->facilities); this->sign.UpdatePosition(pt.x, pt.y, STR_VIEWPORT_STATION); + _viewport_sign_kdtree.Insert(ViewportSignKdtreeItem::MakeStation(this->index)); + SetWindowDirty(WC_STATION_VIEW, this->index); } +/** + * Move the station main coordinate somewhere else. + * @param new_xy new tile location of the sign + */ +void Station::MoveSign(TileIndex new_xy) +{ + if (this->xy == new_xy) return; + + _station_kdtree.Remove(this->index); + + this->BaseStation::MoveSign(new_xy); + + _station_kdtree.Insert(this->index); +} + /** Update the virtual coords needed to draw the station sign for all stations. */ void UpdateAllStationVirtCoords() { - BaseStation *st; - - FOR_ALL_BASE_STATIONS(st) { + for (BaseStation *st : BaseStation::Iterate()) { st->UpdateVirtCoord(); } } +void BaseStation::FillCachedName() const +{ + char buf[MAX_LENGTH_STATION_NAME_CHARS * MAX_CHAR_LENGTH]; + int64 args_array[] = { this->index }; + StringParameters tmp_params(args_array); + char *end = GetStringWithArgs(buf, Waypoint::IsExpected(this) ? STR_WAYPOINT_NAME : STR_STATION_NAME, &tmp_params, lastof(buf)); + this->cached_name.assign(buf, end); +} + +void ClearAllStationCachedNames() +{ + for (BaseStation *st : BaseStation::Iterate()) { + st->cached_name.clear(); + } +} + /** * Get a mask of the cargo types that the station accepts. * @param st Station to query @@ -474,38 +508,23 @@ static void ShowRejectOrAcceptNews(const Station *st, uint num_items, CargoID *c CargoArray GetProductionAroundTiles(TileIndex tile, int w, int h, int rad) { CargoArray produced; - - int x = TileX(tile); - int y = TileY(tile); - - /* expand the region by rad tiles on each side - * while making sure that we remain inside the board. */ - int x2 = min(x + w + rad, MapSizeX()); - int x1 = max(x - rad, 0); - - int y2 = min(y + h + rad, MapSizeY()); - int y1 = max(y - rad, 0); - - assert(x1 < x2); - assert(y1 < y2); - assert(w > 0); - assert(h > 0); - - TileArea ta(TileXY(x1, y1), TileXY(x2 - 1, y2 - 1)); + std::set industries; + TileArea ta = TileArea(tile, w, h).Expand(rad); /* Loop over all tiles to get the produced cargo of * everything except industries */ - TILE_AREA_LOOP(tile, ta) AddProducedCargo(tile, produced); + TILE_AREA_LOOP(tile, ta) { + if (IsTileType(tile, MP_INDUSTRY)) industries.insert(GetIndustryIndex(tile)); + AddProducedCargo(tile, produced); + } - /* Loop over the industries. They produce cargo for - * anything that is within 'rad' from their bounding - * box. As such if you have e.g. a oil well the tile - * area loop might not hit an industry tile while - * the industry would produce cargo for the station. + /* Loop over the seen industries. They produce cargo for + * anything that is within 'rad' of any one of their tiles. */ - const Industry *i; - FOR_ALL_INDUSTRIES(i) { - if (!ta.Intersects(i->location)) continue; + for (IndustryID industry : industries) { + const Industry *i = Industry::Get(industry); + /* Skip industry with neutral station */ + if (i->neutral_station != nullptr && !_settings_game.station.serve_neutral_industries) continue; for (uint j = 0; j < lengthof(i->produced_cargo); j++) { CargoID cargo = i->produced_cargo[j]; @@ -522,33 +541,39 @@ CargoArray GetProductionAroundTiles(TileIndex tile, int w, int h, int rad) * @param w X extent of area * @param h Y extent of area * @param rad Search radius in addition to given area - * @param always_accepted bitmask of cargo accepted by houses and headquarters; can be NULL + * @param always_accepted bitmask of cargo accepted by houses and headquarters; can be nullptr + * @param ind Industry associated with neutral station (e.g. oil rig) or nullptr */ CargoArray GetAcceptanceAroundTiles(TileIndex tile, int w, int h, int rad, CargoTypes *always_accepted) { CargoArray acceptance; - if (always_accepted != NULL) *always_accepted = 0; + if (always_accepted != nullptr) *always_accepted = 0; - int x = TileX(tile); - int y = TileY(tile); + TileArea ta = TileArea(tile, w, h).Expand(rad); - /* expand the region by rad tiles on each side - * while making sure that we remain inside the board. */ - int x2 = min(x + w + rad, MapSizeX()); - int y2 = min(y + h + rad, MapSizeY()); - int x1 = max(x - rad, 0); - int y1 = max(y - rad, 0); + TILE_AREA_LOOP(tile, ta) { + /* Ignore industry if it has a neutral station. */ + if (!_settings_game.station.serve_neutral_industries && IsTileType(tile, MP_INDUSTRY) && Industry::GetByTile(tile)->neutral_station != nullptr) continue; - assert(x1 < x2); - assert(y1 < y2); - assert(w > 0); - assert(h > 0); + AddAcceptedCargo(tile, acceptance, always_accepted); + } - for (int yc = y1; yc != y2; yc++) { - for (int xc = x1; xc != x2; xc++) { - TileIndex tile = TileXY(xc, yc); - AddAcceptedCargo(tile, acceptance, always_accepted); - } + return acceptance; +} + +/** + * Get the acceptance of cargoes around the station in. + * @param st Station to get acceptance of. + * @param always_accepted bitmask of cargo accepted by houses and headquarters; can be nullptr + */ +static CargoArray GetAcceptanceAroundStation(const Station *st, CargoTypes *always_accepted) +{ + CargoArray acceptance; + if (always_accepted != nullptr) *always_accepted = 0; + + BitmapTileIterator it(st->catchment_tiles); + for (TileIndex tile = it; tile != INVALID_TILE; tile = ++it) { + AddAcceptedCargo(tile, acceptance, always_accepted); } return acceptance; @@ -567,13 +592,7 @@ void UpdateStationAcceptance(Station *st, bool show_msg) /* And retrieve the acceptance. */ CargoArray acceptance; if (!st->rect.IsEmpty()) { - acceptance = GetAcceptanceAroundTiles( - TileXY(st->rect.left, st->rect.top), - st->rect.right - st->rect.left + 1, - st->rect.bottom - st->rect.top + 1, - st->GetCatchmentRadius(), - &st->always_accepted - ); + acceptance = GetAcceptanceAroundStation(st, &st->always_accepted); } /* Adjust in case our station only accepts fewer kinds of goods */ @@ -648,8 +667,8 @@ static void UpdateStationSignCoord(BaseStation *st) if (r->IsEmpty()) return; // no tiles belong to this station /* clamp sign coord to be inside the station rect */ - st->xy = TileXY(ClampU(TileX(st->xy), r->left, r->right), ClampU(TileY(st->xy), r->top, r->bottom)); - st->UpdateVirtCoord(); + TileIndex new_xy = TileXY(ClampU(TileX(st->xy), r->left, r->right), ClampU(TileY(st->xy), r->top, r->bottom)); + st->MoveSign(new_xy); if (!Station::IsExpected(st)) return; Station *full_station = Station::From(st); @@ -672,9 +691,9 @@ static void UpdateStationSignCoord(BaseStation *st) static CommandCost BuildStationPart(Station **st, DoCommandFlag flags, bool reuse, TileArea area, StationNaming name_class) { /* Find a deleted station close to us */ - if (*st == NULL && reuse) *st = GetClosestDeletedStation(area.tile); + if (*st == nullptr && reuse) *st = GetClosestDeletedStation(area.tile); - if (*st != NULL) { + if (*st != nullptr) { if ((*st)->owner != _current_company) { return_cmd_error(CMD_ERROR); } @@ -687,6 +706,7 @@ static CommandCost BuildStationPart(Station **st, DoCommandFlag flags, bool reus if (flags & DC_EXEC) { *st = new Station(area.tile); + _station_kdtree.Insert((*st)->index); (*st)->town = ClosestTownFromTile(area.tile, UINT_MAX); (*st)->string_id = GenerateStationName(*st, area.tile, name_class); @@ -723,7 +743,7 @@ static void DeleteStationIfEmpty(BaseStation *st) void Station::AfterStationTileSetChange(bool adding, StationType type) { this->UpdateVirtCoord(); - this->RecomputeIndustriesNear(); + this->RecomputeCatchment(); DirtyCompanyInfrastructureWindows(this->owner); if (adding) InvalidateWindowData(WC_STATION_LIST, this->owner, 0); @@ -845,14 +865,14 @@ static CommandCost CheckFlatLandAirport(AirportTileTableIterator tile_iter, DoCo * @param numtracks Number of platforms. * @return The cost in case of success, or an error code if it failed. */ -static CommandCost CheckFlatLandRailStation(TileArea tile_area, DoCommandFlag flags, Axis axis, StationID *station, RailType rt, SmallVector &affected_vehicles, StationClassID spec_class, byte spec_index, byte plat_len, byte numtracks) +static CommandCost CheckFlatLandRailStation(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); int allowed_z = -1; uint invalid_dirs = 5 << axis; const StationSpec *statspec = StationClass::Get(spec_class)->GetSpec(spec_index); - bool slope_cb = statspec != NULL && HasBit(statspec->callback_mask, CBM_STATION_SLOPE_CHECK); + bool slope_cb = statspec != nullptr && HasBit(statspec->callback_mask, CBM_STATION_SLOPE_CHECK); TILE_AREA_LOOP(tile_cur, tile_area) { CommandCost ret = CheckBuildableTile(tile_cur, invalid_dirs, allowed_z, false); @@ -868,7 +888,7 @@ static CommandCost CheckFlatLandRailStation(TileArea tile_area, DoCommandFlag fl /* if station is set, then we have special handling to allow building on top of already existing stations. * so station points to INVALID_STATION if we can build on any station. * Or it points to a station if we're only allowed to build on exactly that station. */ - if (station != NULL && IsTileType(tile_cur, MP_STATION)) { + if (station != nullptr && IsTileType(tile_cur, MP_STATION)) { if (!IsRailStation(tile_cur)) { return ClearTile_Station(tile_cur, DC_AUTO); // get error message } else { @@ -899,8 +919,8 @@ static CommandCost CheckFlatLandRailStation(TileArea tile_area, DoCommandFlag fl /* Check for trains having a reservation for this tile. */ if (HasBit(GetRailReservationTrackBits(tile_cur), track)) { Train *v = GetTrainForReservation(tile_cur, track); - if (v != NULL) { - *affected_vehicles.Append() = v; + if (v != nullptr) { + affected_vehicles.push_back(v); } } CommandCost ret = DoCommand(tile_cur, 0, track, flags, CMD_REMOVE_SINGLE_RAIL); @@ -928,10 +948,10 @@ static CommandCost CheckFlatLandRailStation(TileArea tile_area, DoCommandFlag fl * @param is_truck_stop True when building a truck stop, false otherwise. * @param axis Axis of a drive-through road stop. * @param station StationID to be queried and returned if available. - * @param rts Road types to build. + * @param rt Road type to build. * @return The cost in case of success, or an error code if it failed. */ -static CommandCost CheckFlatLandRoadStop(TileArea tile_area, DoCommandFlag flags, uint invalid_dirs, bool is_drive_through, bool is_truck_stop, Axis axis, StationID *station, RoadTypes rts) +static CommandCost CheckFlatLandRoadStop(TileArea tile_area, DoCommandFlag flags, uint invalid_dirs, bool is_drive_through, bool is_truck_stop, Axis axis, StationID *station, RoadType rt) { CommandCost cost(EXPENSES_CONSTRUCTION); int allowed_z = -1; @@ -944,7 +964,7 @@ static CommandCost CheckFlatLandRoadStop(TileArea tile_area, DoCommandFlag flags /* If station is set, then we have special handling to allow building on top of already existing stations. * Station points to INVALID_STATION if we can build on any station. * Or it points to a station if we're only allowed to build on exactly that station. */ - if (station != NULL && IsTileType(cur_tile, MP_STATION)) { + if (station != nullptr && IsTileType(cur_tile, MP_STATION)) { if (!IsRoadStop(cur_tile)) { return ClearTile_Station(cur_tile, DC_AUTO); // Get error message. } else { @@ -982,47 +1002,57 @@ static CommandCost CheckFlatLandRoadStop(TileArea tile_area, DoCommandFlag flags } } - RoadTypes cur_rts = IsNormalRoadTile(cur_tile) ? GetRoadTypes(cur_tile) : ROADTYPES_NONE; - uint num_roadbits = 0; if (build_over_road) { /* There is a road, check if we can build road+tram stop over it. */ - if (HasBit(cur_rts, ROADTYPE_ROAD)) { - Owner road_owner = GetRoadOwner(cur_tile, ROADTYPE_ROAD); + RoadType road_rt = GetRoadType(cur_tile, RTT_ROAD); + if (road_rt != INVALID_ROADTYPE) { + Owner road_owner = GetRoadOwner(cur_tile, RTT_ROAD); 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); if (ret.Failed()) return ret; } - num_roadbits += CountBits(GetRoadBits(cur_tile, ROADTYPE_ROAD)); + uint num_pieces = CountBits(GetRoadBits(cur_tile, RTT_ROAD)); + + 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); + if (ret.Failed()) return ret; + } + + cost.AddCost(RoadBuildCost(road_rt) * (2 - num_pieces)); + } else if (RoadTypeIsRoad(rt)) { + cost.AddCost(RoadBuildCost(rt) * 2); } - if (GetDisallowedRoadDirections(cur_tile) != DRD_NONE) return_cmd_error(STR_ERROR_DRIVE_THROUGH_ON_ONEWAY_ROAD); - /* There is a tram, check if we can build road+tram stop over it. */ - if (HasBit(cur_rts, ROADTYPE_TRAM)) { - Owner tram_owner = GetRoadOwner(cur_tile, ROADTYPE_TRAM); + RoadType tram_rt = GetRoadType(cur_tile, RTT_TRAM); + if (tram_rt != INVALID_ROADTYPE) { + Owner tram_owner = GetRoadOwner(cur_tile, RTT_TRAM); if (Company::IsValidID(tram_owner) && (!_settings_game.construction.road_stop_on_competitor_road || /* Disallow breaking end-of-line of someone else * so trams can still reverse on this tile. */ - HasExactlyOneBit(GetRoadBits(cur_tile, ROADTYPE_TRAM)))) { + HasExactlyOneBit(GetRoadBits(cur_tile, RTT_TRAM)))) { CommandCost ret = CheckOwnership(tram_owner); if (ret.Failed()) return ret; } - num_roadbits += CountBits(GetRoadBits(cur_tile, ROADTYPE_TRAM)); - } + uint num_pieces = CountBits(GetRoadBits(cur_tile, RTT_TRAM)); - /* Take into account existing roadbits. */ - rts |= cur_rts; + if (RoadTypeIsTram(rt) && !HasPowerOnRoad(rt, tram_rt)) return_cmd_error(STR_ERROR_NO_SUITABLE_ROAD); + + cost.AddCost(RoadBuildCost(tram_rt) * (2 - num_pieces)); + } else if (RoadTypeIsTram(rt)) { + cost.AddCost(RoadBuildCost(rt) * 2); + } } else { ret = DoCommand(cur_tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); if (ret.Failed()) return ret; cost.AddCost(ret); + cost.AddCost(RoadBuildCost(rt) * 2); } - - uint roadbits_to_build = CountBits(rts) * 2 - num_roadbits; - cost.AddCost(_price[PR_BUILD_ROAD] * roadbits_to_build); } } @@ -1083,7 +1113,7 @@ static inline byte *CreateMulti(byte *layout, int n, byte b) */ void GetStationLayout(byte *layout, int numtracks, int plat_len, const StationSpec *statspec) { - if (statspec != NULL && statspec->lengths >= plat_len && + if (statspec != nullptr && statspec->lengths >= plat_len && statspec->platforms[plat_len - 1] >= numtracks && statspec->layouts[plat_len - 1][numtracks - 1]) { /* Custom layout defined, follow it. */ @@ -1119,7 +1149,7 @@ void GetStationLayout(byte *layout, int numtracks, int plat_len, const StationSp template CommandCost FindJoiningBaseStation(StationID existing_station, StationID station_to_join, bool adjacent, TileArea ta, T **st) { - assert(*st == NULL); + assert(*st == nullptr); bool check_surrounding = true; if (_settings_game.station.adjacent_stations) { @@ -1132,7 +1162,7 @@ CommandCost FindJoiningBaseStation(StationID existing_station, StationID station /* Extend the current station, and don't check whether it will * be near any other stations. */ *st = T::GetIfValid(existing_station); - check_surrounding = (*st == NULL); + check_surrounding = (*st == nullptr); } } else { /* There's no station here. Don't check the tiles surrounding this @@ -1148,7 +1178,7 @@ CommandCost FindJoiningBaseStation(StationID existing_station, StationID station } /* Distant join */ - if (*st == NULL && station_to_join != INVALID_STATION) *st = T::GetIfValid(station_to_join); + if (*st == nullptr && station_to_join != INVALID_STATION) *st = T::GetIfValid(station_to_join); return CommandCost(); } @@ -1268,7 +1298,7 @@ CommandCost CmdBuildRailStation(TileIndex tile_org, DoCommandFlag flags, uint32 /* Make sure the area below consists of clear tiles. (OR tiles belonging to a certain rail station) */ StationID est = INVALID_STATION; - SmallVector affected_vehicles; + 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); if (cost.Failed()) return cost; @@ -1276,14 +1306,14 @@ CommandCost CmdBuildRailStation(TileIndex tile_org, DoCommandFlag flags, uint32 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 = NULL; + Station *st = nullptr; ret = FindJoiningStation(est, station_to_join, adjacent, new_location, &st); if (ret.Failed()) return ret; ret = BuildStationPart(&st, flags, reuse, new_location, STATIONNAMING_RAIL); if (ret.Failed()) return ret; - if (st != NULL && st->train_station.tile != INVALID_TILE) { + if (st != nullptr && st->train_station.tile != INVALID_TILE) { CommandCost ret = CanExpandRailStation(st, new_location, axis); if (ret.Failed()) return ret; } @@ -1293,7 +1323,7 @@ CommandCost CmdBuildRailStation(TileIndex tile_org, DoCommandFlag flags, uint32 int specindex = AllocateSpecToStation(statspec, st, (flags & DC_EXEC) != 0); if (specindex == -1) return_cmd_error(STR_ERROR_TOO_MANY_STATION_SPECS); - if (statspec != NULL) { + if (statspec != nullptr) { /* Perform NewStation checks */ /* Check if the station size is permitted */ @@ -1303,7 +1333,7 @@ CommandCost CmdBuildRailStation(TileIndex tile_org, DoCommandFlag flags, uint32 /* Check if the station is buildable */ if (HasBit(statspec->callback_mask, CBM_STATION_AVAIL)) { - uint16 cb_res = GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, NULL, INVALID_TILE); + uint16 cb_res = GetStationCallback(CBID_STATION_AVAILABILITY, 0, 0, statspec, nullptr, INVALID_TILE); if (cb_res != CALLBACK_FAILED && !Convert8bitBooleanCallback(statspec->grf_prop.grffile, CBID_STATION_AVAILABILITY, cb_res)) return CMD_ERROR; } } @@ -1319,7 +1349,7 @@ CommandCost CmdBuildRailStation(TileIndex tile_org, DoCommandFlag flags, uint32 st->rect.BeforeAddRect(tile_org, w_org, h_org, StationRect::ADD_TRY); - if (statspec != NULL) { + if (statspec != nullptr) { /* Include this station spec's animation trigger bitmask * in the station's cached copy. */ st->cached_anim_triggers |= statspec->animation.triggers; @@ -1343,8 +1373,8 @@ CommandCost CmdBuildRailStation(TileIndex tile_org, DoCommandFlag flags, uint32 if (IsRailStationTile(tile) && HasStationReservation(tile)) { /* Check for trains having a reservation for this tile. */ Train *v = GetTrainForReservation(tile, AxisToTrack(GetRailStationAxis(tile))); - if (v != NULL) { - *affected_vehicles.Append() = v; + if (v != nullptr) { + affected_vehicles.push_back(v); FreeTrainReservation(v); } } @@ -1369,12 +1399,12 @@ CommandCost CmdBuildRailStation(TileIndex tile_org, DoCommandFlag flags, uint32 if (!IsStationTileBlocked(tile)) c->infrastructure.rail[rt]++; c->infrastructure.station++; - if (statspec != NULL) { + if (statspec != nullptr) { /* Use a fixed axis for GetPlatformInfo as our platforms / numtracks are always the right way around */ uint32 platinfo = GetPlatformInfo(AXIS_X, GetStationGfx(tile), plat_len, numtracks_orig, plat_len - w, numtracks_orig - numtracks, false); /* As the station is not yet completely finished, the station does not yet exist. */ - uint16 callback = GetStationCallback(CBID_STATION_TILE_LAYOUT, platinfo, 0, statspec, NULL, tile); + uint16 callback = GetStationCallback(CBID_STATION_TILE_LAYOUT, platinfo, 0, statspec, nullptr, tile); if (callback != CALLBACK_FAILED) { if (callback < 8) { SetStationGfx(tile, (callback & ~1) + axis); @@ -1394,7 +1424,7 @@ CommandCost CmdBuildRailStation(TileIndex tile_org, DoCommandFlag flags, uint32 tile_track += tile_delta ^ TileDiffXY(1, 1); // perpendicular to tile_delta } while (--numtracks); - for (uint i = 0; i < affected_vehicles.Length(); ++i) { + for (uint i = 0; i < affected_vehicles.size(); ++i) { /* Restore reservations of trains. */ RestoreTrainReservation(affected_vehicles[i]); } @@ -1442,16 +1472,14 @@ CommandCost CmdBuildRailStation(TileIndex tile_org, DoCommandFlag flags, uint32 return cost; } -static void MakeRailStationAreaSmaller(BaseStation *st) +static TileArea MakeStationAreaSmaller(BaseStation *st, TileArea ta, bool (*func)(BaseStation *, TileIndex)) { - TileArea ta = st->train_station; - restart: /* too small? */ if (ta.w != 0 && ta.h != 0) { /* check the left side, x = constant, y changes */ - for (uint i = 0; !st->TileBelongsToRailStation(ta.tile + TileDiffXY(0, i));) { + for (uint i = 0; !func(st, ta.tile + TileDiffXY(0, i));) { /* the left side is unused? */ if (++i == ta.h) { ta.tile += TileDiffXY(1, 0); @@ -1461,7 +1489,7 @@ restart: } /* check the right side, x = constant, y changes */ - for (uint i = 0; !st->TileBelongsToRailStation(ta.tile + TileDiffXY(ta.w - 1, i));) { + for (uint i = 0; !func(st, ta.tile + TileDiffXY(ta.w - 1, i));) { /* the right side is unused? */ if (++i == ta.h) { ta.w--; @@ -1470,7 +1498,7 @@ restart: } /* check the upper side, y = constant, x changes */ - for (uint i = 0; !st->TileBelongsToRailStation(ta.tile + TileDiffXY(i, 0));) { + for (uint i = 0; !func(st, ta.tile + TileDiffXY(i, 0));) { /* the left side is unused? */ if (++i == ta.w) { ta.tile += TileDiffXY(0, 1); @@ -1480,7 +1508,7 @@ restart: } /* check the lower side, y = constant, x changes */ - for (uint i = 0; !st->TileBelongsToRailStation(ta.tile + TileDiffXY(i, ta.h - 1));) { + for (uint i = 0; !func(st, ta.tile + TileDiffXY(i, ta.h - 1));) { /* the left side is unused? */ if (++i == ta.w) { ta.h--; @@ -1491,7 +1519,28 @@ restart: ta.Clear(); } - st->train_station = ta; + return ta; +} + +static bool TileBelongsToRailStation(BaseStation *st, TileIndex tile) +{ + return st->TileBelongsToRailStation(tile); +} + +static void MakeRailStationAreaSmaller(BaseStation *st) +{ + st->train_station = MakeStationAreaSmaller(st, st->train_station, TileBelongsToRailStation); +} + +static bool TileBelongsToShipStation(BaseStation *st, TileIndex tile) +{ + return IsDockTile(tile) && GetStationIndex(tile) == st->index; +} + +static void MakeShipStationAreaSmaller(Station *st) +{ + st->ship_station = MakeStationAreaSmaller(st, st->ship_station, TileBelongsToShipStation); + UpdateStationDockingTiles(st); } /** @@ -1505,7 +1554,7 @@ restart: * @return the number of cleared tiles or an error. */ template -CommandCost RemoveFromRailBaseStation(TileArea ta, SmallVector &affected_stations, DoCommandFlag flags, Money removal_cost, bool keep_rail) +CommandCost RemoveFromRailBaseStation(TileArea ta, std::vector &affected_stations, DoCommandFlag flags, Money removal_cost, bool keep_rail) { /* Count of the number of tiles removed */ int quantity = 0; @@ -1527,7 +1576,7 @@ CommandCost RemoveFromRailBaseStation(TileArea ta, SmallVector &affected /* Check ownership of station */ T *st = T::GetByTile(tile); - if (st == NULL) continue; + if (st == nullptr) continue; if (_current_company != OWNER_WATER) { CommandCost ret = CheckOwnership(st->owner); @@ -1550,11 +1599,11 @@ CommandCost RemoveFromRailBaseStation(TileArea ta, SmallVector &affected Track track = GetRailStationTrack(tile); Owner owner = GetTileOwner(tile); RailType rt = GetRailType(tile); - Train *v = NULL; + Train *v = nullptr; if (HasStationReservation(tile)) { v = GetTrainForReservation(tile, track); - if (v != NULL) FreeTrainReservation(v); + if (v != nullptr) FreeTrainReservation(v); } bool build_rail = keep_rail && !IsStationTileBlocked(tile); @@ -1572,16 +1621,15 @@ CommandCost RemoveFromRailBaseStation(TileArea ta, SmallVector &affected DeallocateSpecFromStation(st, specindex); - affected_stations.Include(st); + include(affected_stations, st); - if (v != NULL) RestoreTrainReservation(v); + if (v != nullptr) RestoreTrainReservation(v); } } if (quantity == 0) return error.Failed() ? error : CommandCost(STR_ERROR_THERE_IS_NO_STATION); - for (T **stp = affected_stations.Begin(); stp != affected_stations.End(); stp++) { - T *st = *stp; + for (T *st : affected_stations) { /* now we need to make the "spanned" area of the railway station smaller * if we deleted something at the edges. @@ -1619,18 +1667,17 @@ CommandCost CmdRemoveFromRailStation(TileIndex start, DoCommandFlag flags, uint3 if (start >= MapSize() || end >= MapSize()) return CMD_ERROR; TileArea ta(start, end); - SmallVector affected_stations; + std::vector affected_stations; CommandCost ret = RemoveFromRailBaseStation(ta, affected_stations, flags, _price[PR_CLEAR_STATION_RAIL], HasBit(p2, 0)); if (ret.Failed()) return ret; /* Do all station specific functions here. */ - for (Station **stp = affected_stations.Begin(); stp != affected_stations.End(); stp++) { - Station *st = *stp; + for (Station *st : affected_stations) { if (st->train_station.tile == INVALID_TILE) SetWindowWidgetDirty(WC_STATION_VIEW, st->index, WID_SV_TRAINS); st->MarkTilesDirty(false); - st->RecomputeIndustriesNear(); + st->RecomputeCatchment(); } /* Now apply the rail cost to the number that we deleted */ @@ -1654,7 +1701,7 @@ CommandCost CmdRemoveFromRailWaypoint(TileIndex start, DoCommandFlag flags, uint if (start >= MapSize() || end >= MapSize()) return CMD_ERROR; TileArea ta(start, end); - SmallVector affected_stations; + std::vector affected_stations; return RemoveFromRailBaseStation(ta, affected_stations, flags, _price[PR_CLEAR_WAYPOINT_RAIL], HasBit(p2, 0)); } @@ -1687,7 +1734,7 @@ CommandCost RemoveRailStation(T *st, DoCommandFlag flags, Money removal_cost) TILE_AREA_LOOP(tile, ta) { /* only remove tiles that are actually train station tiles */ if (st->TileBelongsToRailStation(tile)) { - SmallVector affected_stations; // dummy + std::vector affected_stations; // dummy CommandCost ret = RemoveFromRailBaseStation(TileArea(tile, 1, 1), affected_stations, flags, removal_cost, false); if (ret.Failed()) return ret; cost.AddCost(ret); @@ -1713,7 +1760,7 @@ static CommandCost RemoveRailStation(TileIndex tile, DoCommandFlag flags) Station *st = Station::GetByTile(tile); CommandCost cost = RemoveRailStation(st, flags, _price[PR_CLEAR_STATION_RAIL]); - if (flags & DC_EXEC) st->RecomputeIndustriesNear(); + if (flags & DC_EXEC) st->RecomputeCatchment(); return cost; } @@ -1744,13 +1791,13 @@ static RoadStop **FindRoadStopSpot(bool truck_station, Station *st) { RoadStop **primary_stop = (truck_station) ? &st->truck_stops : &st->bus_stops; - if (*primary_stop == NULL) { + if (*primary_stop == nullptr) { /* we have no roadstop of the type yet, so write a "primary stop" */ return primary_stop; } else { /* there are stops already, so append to the end of the list */ RoadStop *stop = *primary_stop; - while (stop->next != NULL) stop = stop->next; + while (stop->next != nullptr) stop = stop->next; return &stop->next; } } @@ -1779,10 +1826,10 @@ static CommandCost FindJoiningRoadStop(StationID existing_stop, StationID statio * bit 8..15: Length of the road stop. * @param p2 bit 0: 0 For bus stops, 1 for truck stops. * bit 1: 0 For normal stops, 1 for drive-through. - * bit 2..3: The roadtypes. - * bit 5: Allow stations directly adjacent to other stations. - * bit 6..7: Entrance direction (#DiagDirection) for normal stops. - * bit 6: #Axis of the road for drive-through stops. + * bit 2: Allow stations directly adjacent to other stations. + * bit 3..4: Entrance direction (#DiagDirection) for normal stops. + * bit 3: #Axis of the road for drive-through stops. + * bit 5..10: The roadtype. * bit 16..31: Station ID to join (NEW_STATION if build new one). * @param text Unused. * @return The cost of this operation or an error. @@ -1791,7 +1838,8 @@ CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uin { bool type = HasBit(p2, 0); bool is_drive_through = HasBit(p2, 1); - RoadTypes rts = Extract(p2); + RoadType rt = Extract(p2); + if (!ValParamRoadType(rt)) return CMD_ERROR; StationID station_to_join = GB(p2, 16, 16); bool reuse = (station_to_join != NEW_STATION); if (!reuse) station_to_join = INVALID_STATION; @@ -1811,20 +1859,18 @@ CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uin if (distant_join && (!_settings_game.station.distant_join_stations || !Station::IsValidID(station_to_join))) return CMD_ERROR; - if (!HasExactlyOneBit(rts) || !HasRoadTypesAvail(_current_company, rts)) return CMD_ERROR; - /* Trams only have drive through stops */ - if (!is_drive_through && HasBit(rts, ROADTYPE_TRAM)) return CMD_ERROR; + if (!is_drive_through && RoadTypeIsTram(rt)) return CMD_ERROR; DiagDirection ddir; Axis axis; if (is_drive_through) { /* By definition axis is valid, due to there being 2 axes and reading 1 bit. */ - axis = Extract(p2); + axis = Extract(p2); ddir = AxisToDiagDir(axis); } else { /* By definition ddir is valid, due to there being 4 diagonal directions and reading 2 bits. */ - ddir = Extract(p2); + ddir = Extract(p2); axis = DiagDirToAxis(ddir); } @@ -1834,12 +1880,12 @@ CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uin /* Total road stop cost. */ CommandCost cost(EXPENSES_CONSTRUCTION, roadstop_area.w * roadstop_area.h * _price[type ? 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, type, axis, &est, rts); + ret = CheckFlatLandRoadStop(roadstop_area, flags, is_drive_through ? 5 << axis : 1 << ddir, is_drive_through, type, axis, &est, rt); if (ret.Failed()) return ret; cost.AddCost(ret); - Station *st = NULL; - ret = FindJoiningRoadStop(est, station_to_join, HasBit(p2, 5), roadstop_area, &st); + Station *st = nullptr; + ret = FindJoiningRoadStop(est, station_to_join, HasBit(p2, 2), roadstop_area, &st); if (ret.Failed()) return ret; /* Check if this number of road stops can be allocated. */ @@ -1851,9 +1897,11 @@ CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uin if (flags & DC_EXEC) { /* Check every tile in the area. */ TILE_AREA_LOOP(cur_tile, roadstop_area) { - RoadTypes cur_rts = GetRoadTypes(cur_tile); - Owner road_owner = HasBit(cur_rts, ROADTYPE_ROAD) ? GetRoadOwner(cur_tile, ROADTYPE_ROAD) : _current_company; - Owner tram_owner = HasBit(cur_rts, ROADTYPE_TRAM) ? GetRoadOwner(cur_tile, ROADTYPE_TRAM) : _current_company; + /* Get existing road types and owners before any tile clearing */ + RoadType road_rt = MayHaveRoad(cur_tile) ? GetRoadType(cur_tile, RTT_ROAD) : INVALID_ROADTYPE; + RoadType tram_rt = MayHaveRoad(cur_tile) ? GetRoadType(cur_tile, RTT_TRAM) : INVALID_ROADTYPE; + Owner road_owner = road_rt != INVALID_ROADTYPE ? GetRoadOwner(cur_tile, RTT_ROAD) : _current_company; + 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); @@ -1877,23 +1925,27 @@ CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uin RoadStopType rs_type = type ? ROADSTOP_TRUCK : ROADSTOP_BUS; if (is_drive_through) { - /* Update company infrastructure counts. If the current tile is a normal - * road tile, count only the new road bits needed to get a full diagonal road. */ - RoadType rt; - FOR_EACH_SET_ROADTYPE(rt, cur_rts | rts) { - Company *c = Company::GetIfValid(rt == ROADTYPE_ROAD ? road_owner : tram_owner); - if (c != NULL) { - c->infrastructure.road[rt] += 2 - (IsNormalRoadTile(cur_tile) && HasBit(cur_rts, rt) ? CountBits(GetRoadBits(cur_tile, rt)) : 0); - DirtyCompanyInfrastructureWindows(c->index); - } + /* Update company infrastructure counts. If the current tile is a normal road tile, remove the old + * bits first. */ + if (IsNormalRoadTile(cur_tile)) { + UpdateCompanyRoadInfrastructure(road_rt, road_owner, -(int)CountBits(GetRoadBits(cur_tile, RTT_ROAD))); + UpdateCompanyRoadInfrastructure(tram_rt, tram_owner, -(int)CountBits(GetRoadBits(cur_tile, RTT_TRAM))); } - MakeDriveThroughRoadStop(cur_tile, st->owner, road_owner, tram_owner, st->index, rs_type, rts | cur_rts, axis); + 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, 2); + UpdateCompanyRoadInfrastructure(tram_rt, tram_owner, 2); + + 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[FIND_FIRST_BIT(rts)] += 2; - MakeRoadStop(cur_tile, st->owner, st->index, rs_type, rts, ddir); + Company::Get(st->owner)->infrastructure.road[rt] += 2; + MakeRoadStop(cur_tile, st->owner, st->index, rs_type, road_rt, tram_rt, ddir); } Company::Get(st->owner)->infrastructure.station++; @@ -1901,7 +1953,7 @@ CommandCost CmdBuildRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, uin } } - if (st != NULL) { + if (st != nullptr) { st->AfterStationTileSetChange(true, type ? STATION_TRUCK: STATION_BUS); } return cost; @@ -1921,7 +1973,7 @@ static Vehicle *ClearRoadStopStatusEnum(Vehicle *v, void *) if (HasBit(rv->state, RVS_IN_DT_ROAD_STOP)) rv->state &= RVSB_ROAD_STOP_TRACKDIR_MASK; } - return NULL; + return nullptr; } @@ -1952,12 +2004,12 @@ static CommandCost RemoveRoadStop(TileIndex tile, DoCommandFlag flags) cur_stop = RoadStop::GetByTile(tile, ROADSTOP_BUS); } - assert(cur_stop != NULL); + assert(cur_stop != nullptr); /* don't do the check for drive-through road stops when company bankrupts */ if (IsDriveThroughStopTile(tile) && (flags & DC_BANKRUPT)) { /* remove the 'going through road stop' status from all vehicles on that tile */ - if (flags & DC_EXEC) FindVehicleOnPos(tile, NULL, &ClearRoadStopStatusEnum); + if (flags & DC_EXEC) FindVehicleOnPos(tile, nullptr, &ClearRoadStopStatusEnum); } else { CommandCost ret = EnsureNoVehicleOnGround(tile); if (ret.Failed()) return ret; @@ -1968,7 +2020,7 @@ static CommandCost RemoveRoadStop(TileIndex tile, DoCommandFlag flags) /* removed the first stop in the list */ *primary_stop = cur_stop->next; /* removed the only stop? */ - if (*primary_stop == NULL) { + if (*primary_stop == nullptr) { st->facilities &= (is_truck ? ~FACIL_TRUCK_STOP : ~FACIL_BUS_STOP); } } else { @@ -1979,14 +2031,11 @@ static CommandCost RemoveRoadStop(TileIndex tile, DoCommandFlag flags) } /* Update company infrastructure counts. */ - RoadType rt; - FOR_EACH_SET_ROADTYPE(rt, GetRoadTypes(tile)) { - Company *c = Company::GetIfValid(GetRoadOwner(tile, rt)); - if (c != NULL) { - c->infrastructure.road[rt] -= 2; - DirtyCompanyInfrastructureWindows(c->index); - } + FOR_ALL_ROADTRAMTYPES(rtt) { + RoadType rt = GetRoadType(tile, rtt); + UpdateCompanyRoadInfrastructure(rt, GetRoadOwner(tile, rtt), -2); } + Company::Get(st->owner)->infrastructure.station--; DirtyCompanyInfrastructureWindows(st->owner); @@ -2000,8 +2049,7 @@ static CommandCost RemoveRoadStop(TileIndex tile, DoCommandFlag flags) delete cur_stop; /* Make sure no vehicle is going to the old roadstop */ - RoadVehicle *v; - FOR_ALL_ROADVEHICLES(v) { + for (RoadVehicle *v : RoadVehicle::Iterate()) { if (v->First() == v && v->current_order.IsType(OT_GOTO_STATION) && v->dest_tile == tile) { v->SetDestTile(v->GetOrderStationLocation(st->index)); @@ -2015,10 +2063,10 @@ static CommandCost RemoveRoadStop(TileIndex tile, DoCommandFlag flags) /* Update the tile area of the truck/bus stop */ if (is_truck) { st->truck_station.Clear(); - for (const RoadStop *rs = st->truck_stops; rs != NULL; rs = rs->next) st->truck_station.Add(rs->xy); + for (const RoadStop *rs = st->truck_stops; rs != nullptr; rs = rs->next) st->truck_station.Add(rs->xy); } else { st->bus_station.Clear(); - for (const RoadStop *rs = st->bus_stops; rs != NULL; rs = rs->next) st->bus_station.Add(rs->xy); + for (const RoadStop *rs = st->bus_stops; rs != nullptr; rs = rs->next) st->bus_station.Add(rs->xy); } } @@ -2060,16 +2108,16 @@ CommandCost CmdRemoveRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, ui if (!IsTileType(cur_tile, MP_STATION) || !IsRoadStop(cur_tile) || (uint32)GetRoadStopType(cur_tile) != GB(p2, 0, 1)) continue; /* Save information on to-be-restored roads before the stop is removed. */ - RoadTypes rts = ROADTYPES_NONE; RoadBits road_bits = ROAD_NONE; + RoadType road_type[] = { INVALID_ROADTYPE, INVALID_ROADTYPE }; Owner road_owner[] = { OWNER_NONE, OWNER_NONE }; - assert_compile(lengthof(road_owner) == ROADTYPE_END); if (IsDriveThroughStopTile(cur_tile)) { - RoadType rt; - FOR_EACH_SET_ROADTYPE(rt, GetRoadTypes(cur_tile)) { - road_owner[rt] = GetRoadOwner(cur_tile, rt); + FOR_ALL_ROADTRAMTYPES(rtt) { + road_type[rtt] = GetRoadType(cur_tile, rtt); + if (road_type[rtt] == INVALID_ROADTYPE) continue; + road_owner[rtt] = GetRoadOwner(cur_tile, rtt); /* If we don't want to preserve our roads then restore only roads of others. */ - if (keep_drive_through_roads || road_owner[rt] != _current_company) SetBit(rts, rt); + if (!keep_drive_through_roads && road_owner[rtt] == _current_company) road_type[rtt] = INVALID_ROADTYPE; } road_bits = AxisToRoadBits(DiagDirToAxis(GetRoadStopDir(cur_tile))); } @@ -2083,59 +2131,34 @@ CommandCost CmdRemoveRoadStop(TileIndex tile, DoCommandFlag flags, uint32 p1, ui had_success = true; /* Restore roads. */ - if ((flags & DC_EXEC) && rts != ROADTYPES_NONE) { - MakeRoadNormal(cur_tile, road_bits, rts, ClosestTownFromTile(cur_tile, UINT_MAX)->index, - road_owner[ROADTYPE_ROAD], road_owner[ROADTYPE_TRAM]); + if ((flags & DC_EXEC) && (road_type[RTT_ROAD] != INVALID_ROADTYPE || road_type[RTT_TRAM] != INVALID_ROADTYPE)) { + MakeRoadNormal(cur_tile, road_bits, road_type[RTT_ROAD], road_type[RTT_TRAM], ClosestTownFromTile(cur_tile, UINT_MAX)->index, + road_owner[RTT_ROAD], road_owner[RTT_TRAM]); /* Update company infrastructure counts. */ - RoadType rt; - FOR_EACH_SET_ROADTYPE(rt, rts) { - Company *c = Company::GetIfValid(GetRoadOwner(cur_tile, rt)); - if (c != NULL) { - c->infrastructure.road[rt] += CountBits(road_bits); - DirtyCompanyInfrastructureWindows(c->index); - } - } + int count = CountBits(road_bits); + UpdateCompanyRoadInfrastructure(road_type[RTT_ROAD], road_owner[RTT_ROAD], count); + UpdateCompanyRoadInfrastructure(road_type[RTT_TRAM], road_owner[RTT_TRAM], count); } } return had_success ? cost : last_error; } -/** - * Computes the minimal distance from town's xy to any airport's tile. - * @param it An iterator over all airport tiles. - * @param town_tile town's tile (t->xy) - * @return minimal manhattan distance from town_tile to any airport's tile - */ -static uint GetMinimalAirportDistanceToTile(TileIterator &it, TileIndex town_tile) -{ - uint mindist = UINT_MAX; - - for (TileIndex cur_tile = it; cur_tile != INVALID_TILE; cur_tile = ++it) { - mindist = min(mindist, DistanceManhattan(town_tile, cur_tile)); - } - - return mindist; -} - /** * Get a possible noise reduction factor based on distance from town center. * The further you get, the less noise you generate. * So all those folks at city council can now happily slee... work in their offices * @param as airport information - * @param it An iterator over all airport tiles. - * @param town_tile TileIndex of town's center, the one who will receive the airport's candidature + * @param distance minimum distance between town and airport * @return the noise that will be generated, according to distance */ -uint8 GetAirportNoiseLevelForTown(const AirportSpec *as, TileIterator &it, TileIndex town_tile) +uint8 GetAirportNoiseLevelForDistance(const AirportSpec *as, uint distance) { /* 0 cannot be accounted, and 1 is the lowest that can be reduced from town. * So no need to go any further*/ if (as->noise_level < 2) return as->noise_level; - uint distance = GetMinimalAirportDistanceToTile(it, town_tile); - /* The steps for measuring noise reduction are based on the "magical" (and arbitrary) 8 base distance * adding the town_council_tolerance 4 times, as a way to graduate, depending of the tolerance. * Basically, it says that the less tolerant a town is, the bigger the distance before @@ -2156,18 +2179,30 @@ uint8 GetAirportNoiseLevelForTown(const AirportSpec *as, TileIterator &it, TileI * If two towns have the same distance, town with lower index is returned. * @param as airport's description * @param it An iterator over all airport tiles + * @param[out] mindist Minimum distance to town * @return nearest town to airport */ -Town *AirportGetNearestTown(const AirportSpec *as, const TileIterator &it) +Town *AirportGetNearestTown(const AirportSpec *as, const TileIterator &it, uint &mindist) { - Town *t, *nearest = NULL; - uint add = as->size_x + as->size_y - 2; // GetMinimalAirportDistanceToTile can differ from DistanceManhattan by this much - uint mindist = UINT_MAX - add; // prevent overflow - FOR_ALL_TOWNS(t) { - if (DistanceManhattan(t->xy, it) < mindist + add) { // avoid calling GetMinimalAirportDistanceToTile too often - TileIterator *copy = it.Clone(); - uint dist = GetMinimalAirportDistanceToTile(*copy, t->xy); - delete copy; + assert(Town::GetNumItems() > 0); + + Town *nearest = nullptr; + + uint perimeter_min_x = TileX(it); + uint perimeter_min_y = TileY(it); + uint perimeter_max_x = perimeter_min_x + as->size_x - 1; + uint perimeter_max_y = perimeter_min_y + as->size_y - 1; + + mindist = UINT_MAX - 1; // prevent overflow + + std::unique_ptr copy(it.Clone()); + for (TileIndex cur_tile = *copy; cur_tile != INVALID_TILE; cur_tile = ++*copy) { + if (TileX(cur_tile) == perimeter_min_x || TileX(cur_tile) == perimeter_max_x || TileY(cur_tile) == perimeter_min_y || TileY(cur_tile) == perimeter_max_y) { + Town *t = CalcClosestTownFromTile(cur_tile, mindist + 1); + if (t == nullptr) continue; + + uint dist = DistanceManhattan(t->xy, cur_tile); + if (dist == mindist && t->index < nearest->index) nearest = t; if (dist < mindist) { nearest = t; mindist = dist; @@ -2182,17 +2217,15 @@ Town *AirportGetNearestTown(const AirportSpec *as, const TileIterator &it) /** Recalculate the noise generated by the airports of each town */ void UpdateAirportsNoise() { - Town *t; - const Station *st; + for (Town *t : Town::Iterate()) t->noise_reached = 0; - FOR_ALL_TOWNS(t) t->noise_reached = 0; - - FOR_ALL_STATIONS(st) { + for (const Station *st : Station::Iterate()) { if (st->airport.tile != INVALID_TILE && st->airport.type != AT_OILRIG) { const AirportSpec *as = st->airport.GetSpec(); AirportTileIterator it(st); - Town *nearest = AirportGetNearestTown(as, it); - nearest->noise_reached += GetAirportNoiseLevelForTown(as, it, nearest->xy); + uint dist; + Town *nearest = AirportGetNearestTown(as, it, dist); + nearest->noise_reached += GetAirportNoiseLevelForDistance(as, dist); } } } @@ -2229,6 +2262,7 @@ CommandCost CmdBuildAirport(TileIndex tile, DoCommandFlag flags, uint32 p1, uint /* Check if a valid, buildable airport was chosen for construction */ const AirportSpec *as = AirportSpec::Get(airport_type); if (!as->IsAvailable() || layout >= as->num_table) return CMD_ERROR; + if (!as->IsWithinMapBounds(layout, tile)) return CMD_ERROR; Direction rotation = as->rotation[layout]; int w = as->size_x; @@ -2245,12 +2279,13 @@ CommandCost CmdBuildAirport(TileIndex tile, DoCommandFlag flags, uint32 p1, uint 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. */ - Town *nearest = AirportGetNearestTown(as, iter); - uint newnoise_level = GetAirportNoiseLevelForTown(as, iter, nearest->xy); + uint dist; + Town *nearest = AirportGetNearestTown(as, iter, dist); + uint newnoise_level = GetAirportNoiseLevelForDistance(as, dist); /* Check if local auth would allow a new airport */ StringID authority_refuse_message = STR_NULL; - Town *authority_refuse_town = NULL; + Town *authority_refuse_town = nullptr; if (_settings_game.economy.station_noise_level) { /* do not allow to build a new airport if this raise the town noise over the maximum allowed by town */ @@ -2261,8 +2296,7 @@ CommandCost CmdBuildAirport(TileIndex tile, DoCommandFlag flags, uint32 p1, uint } else { Town *t = ClosestTownFromTile(tile, UINT_MAX); uint num = 0; - const Station *st; - FOR_ALL_STATIONS(st) { + for (const Station *st : Station::Iterate()) { if (st->town == t && (st->facilities & FACIL_AIRPORT) && st->airport.type != AT_OILRIG) num++; } if (num >= 2) { @@ -2276,17 +2310,17 @@ CommandCost CmdBuildAirport(TileIndex tile, DoCommandFlag flags, uint32 p1, uint return_cmd_error(authority_refuse_message); } - Station *st = NULL; + Station *st = nullptr; ret = FindJoiningStation(INVALID_STATION, station_to_join, HasBit(p2, 0), airport_area, &st); if (ret.Failed()) return ret; /* Distant join */ - if (st == NULL && distant_join) st = Station::GetIfValid(station_to_join); + if (st == nullptr && distant_join) st = Station::GetIfValid(station_to_join); ret = BuildStationPart(&st, flags, reuse, airport_area, (GetAirport(airport_type)->flags & AirportFTAClass::AIRPLANES) ? STATIONNAMING_AIRPORT : STATIONNAMING_HELIPORT); if (ret.Failed()) return ret; - if (st != NULL && st->airport.tile != INVALID_TILE) { + if (st != nullptr && st->airport.tile != INVALID_TILE) { return_cmd_error(STR_ERROR_TOO_CLOSE_TO_ANOTHER_AIRPORT); } @@ -2353,10 +2387,11 @@ static CommandCost RemoveAirport(TileIndex tile, DoCommandFlag flags) CommandCost cost(EXPENSES_CONSTRUCTION); - const Aircraft *a; - FOR_ALL_AIRCRAFT(a) { + for (const Aircraft *a : Aircraft::Iterate()) { if (!a->IsNormalAircraft()) continue; - if (a->targetairport == st->index && a->state != FLYING) return CMD_ERROR; + if (a->targetairport == st->index && a->state != FLYING) { + return_cmd_error(STR_ERROR_AIRCRAFT_IN_THE_WAY); + } } if (flags & DC_EXEC) { @@ -2365,8 +2400,9 @@ static CommandCost RemoveAirport(TileIndex tile, DoCommandFlag flags) * And as for construction, always remove it, even if the setting is not set, in order to avoid the * need of recalculation */ AirportTileIterator it(st); - Town *nearest = AirportGetNearestTown(as, it); - nearest->noise_reached -= GetAirportNoiseLevelForTown(as, it, nearest->xy); + uint dist; + Town *nearest = AirportGetNearestTown(as, it, dist); + nearest->noise_reached -= GetAirportNoiseLevelForDistance(as, dist); } TILE_AREA_LOOP(tile_cur, st->airport) { @@ -2450,8 +2486,7 @@ CommandCost CmdOpenCloseAirport(TileIndex tile, DoCommandFlag flags, uint32 p1, */ bool HasStationInUse(StationID station, bool include_company, CompanyID company) { - const Vehicle *v; - FOR_ALL_VEHICLES(v) { + for (const Vehicle *v : Vehicle::Iterate()) { if ((v->owner == company) == include_company) { const Order *order; FOR_VEHICLE_ORDERS(v, order) { @@ -2529,20 +2564,19 @@ CommandCost CmdBuildDock(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 _dock_w_chk[direction], _dock_h_chk[direction]); /* middle */ - Station *st = NULL; + Station *st = nullptr; ret = FindJoiningStation(INVALID_STATION, station_to_join, HasBit(p1, 0), dock_area, &st); if (ret.Failed()) return ret; /* Distant join */ - if (st == NULL && distant_join) st = Station::GetIfValid(station_to_join); + if (st == nullptr && distant_join) st = Station::GetIfValid(station_to_join); ret = BuildStationPart(&st, flags, reuse, dock_area, STATIONNAMING_DOCK); if (ret.Failed()) return ret; - if (st != NULL && st->dock_tile != INVALID_TILE) return_cmd_error(STR_ERROR_TOO_CLOSE_TO_ANOTHER_DOCK); - if (flags & DC_EXEC) { - st->dock_tile = tile; + st->ship_station.Add(tile); + st->ship_station.Add(tile + TileOffsByDiagDir(direction)); st->AddFacility(FACIL_DOCK, tile); st->rect.BeforeAddRect(dock_area.tile, dock_area.w, dock_area.h, StationRect::ADD_TRY); @@ -2555,6 +2589,7 @@ CommandCost CmdBuildDock(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 Company::Get(st->owner)->infrastructure.station += 2; MakeDock(tile, st->owner, st->index, direction, wc); + UpdateStationDockingTiles(st); st->AfterStationTileSetChange(true, STATION_DOCK); } @@ -2562,6 +2597,86 @@ CommandCost CmdBuildDock(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 return CommandCost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_STATION_DOCK]); } +void RemoveDockingTile(TileIndex t) +{ + for (DiagDirection d = DIAGDIR_BEGIN; d != DIAGDIR_END; d++) { + TileIndex tile = t + TileOffsByDiagDir(d); + if (!IsValidTile(tile)) continue; + + if (IsTileType(tile, MP_STATION)) { + UpdateStationDockingTiles(Station::GetByTile(tile)); + } else if (IsTileType(tile, MP_INDUSTRY)) { + Station *neutral = Industry::GetByTile(tile)->neutral_station; + if (neutral != nullptr) UpdateStationDockingTiles(neutral); + } + } +} + +/** + * Clear docking tile status from tiles around a removed dock, if the tile has + * no neighbours which would keep it as a docking tile. + * @param tile Ex-dock tile to check. + */ +void ClearDockingTilesCheckingNeighbours(TileIndex tile) +{ + assert(IsValidTile(tile)); + + /* Clear and maybe re-set docking tile */ + for (DiagDirection d = DIAGDIR_BEGIN; d != DIAGDIR_END; d++) { + TileIndex docking_tile = tile + TileOffsByDiagDir(d); + if (!IsValidTile(docking_tile)) continue; + + if (IsPossibleDockingTile(docking_tile)) { + SetDockingTile(docking_tile, false); + CheckForDockingTile(docking_tile); + } + } +} + +/** + * Check if a dock tile can be docked from the given direction. + * @param t Tile index of dock. + * @param d DiagDirection adjacent to dock being tested. + * @return True iff the dock can be docked from the given direction. + */ +bool IsValidDockingDirectionForDock(TileIndex t, DiagDirection d) +{ + assert(IsDockTile(t)); + + /** Bitmap of valid directions for each dock tile part. */ + static const uint8 _valid_docking_tile[] = { + 0, 0, 0, 0, // No docking against the slope part. + 1 << DIAGDIR_NE | 1 << DIAGDIR_SW, // Docking permitted at the end + 1 << DIAGDIR_NW | 1 << DIAGDIR_SE, // of the flat piers. + }; + + StationGfx gfx = GetStationGfx(t); + assert(gfx < lengthof(_valid_docking_tile)); + return HasBit(_valid_docking_tile[gfx], d); +} + +/** + * Find the part of a dock that is land-based + * @param t Dock tile to find land part of + * @return tile of land part of dock + */ +static TileIndex FindDockLandPart(TileIndex t) +{ + assert(IsDockTile(t)); + + StationGfx gfx = GetStationGfx(t); + if (gfx < GFX_DOCK_BASE_WATER_PART) return t; + + for (DiagDirection d = DIAGDIR_BEGIN; d != DIAGDIR_END; d++) { + TileIndex tile = t + TileOffsByDiagDir(d); + if (!IsValidTile(tile)) continue; + if (!IsDockTile(tile)) continue; + if (GetStationGfx(tile) < GFX_DOCK_BASE_WATER_PART && tile + TileOffsByDiagDir(GetDockDirection(tile)) == t) return tile; + } + + return INVALID_TILE; +} + /** * Remove a dock * @param tile TileIndex been queried @@ -2574,9 +2689,10 @@ static CommandCost RemoveDock(TileIndex tile, DoCommandFlag flags) CommandCost ret = CheckOwnership(st->owner); if (ret.Failed()) return ret; - TileIndex docking_location = TILE_ADD(st->dock_tile, ToTileIndexDiff(GetDockOffset(st->dock_tile))); + if (!IsDockTile(tile)) return CMD_ERROR; - TileIndex tile1 = st->dock_tile; + TileIndex tile1 = FindDockLandPart(tile); + if (tile1 == INVALID_TILE) return CMD_ERROR; TileIndex tile2 = tile1 + TileOffsByDiagDir(GetDockDirection(tile1)); ret = EnsureNoVehicleOnGround(tile1); @@ -2591,26 +2707,33 @@ static CommandCost RemoveDock(TileIndex tile, DoCommandFlag flags) st->rect.AfterRemoveTile(st, tile1); st->rect.AfterRemoveTile(st, tile2); - st->dock_tile = INVALID_TILE; - st->facilities &= ~FACIL_DOCK; + MakeShipStationAreaSmaller(st); + if (st->ship_station.tile == INVALID_TILE) { + st->ship_station.Clear(); + st->docking_station.Clear(); + st->facilities &= ~FACIL_DOCK; + } Company::Get(st->owner)->infrastructure.station -= 2; st->AfterStationTileSetChange(false, STATION_DOCK); + ClearDockingTilesCheckingNeighbours(tile1); + ClearDockingTilesCheckingNeighbours(tile2); + /* All ships that were going to our station, can't go to it anymore. * Just clear the order, then automatically the next appropriate order * will be selected and in case of no appropriate order it will just * wander around the world. */ - Ship *s; - FOR_ALL_SHIPS(s) { - if (s->current_order.IsType(OT_LOADING) && s->tile == docking_location) { - s->LeaveStation(); - } + if (!(st->facilities & FACIL_DOCK)) { + for (Ship *s : Ship::Iterate()) { + if (s->current_order.IsType(OT_LOADING) && s->current_order.GetDestination() == st->index) { + s->LeaveStation(); + } - if (s->dest_tile == docking_location) { - s->SetDestTile(0); - s->current_order.Free(); + if (s->current_order.IsType(OT_GOTO_STATION) && s->current_order.GetDestination() == st->index) { + s->SetDestTile(s->GetOrderStationLocation(st->index)); + } } } } @@ -2629,7 +2752,7 @@ const DrawTileSprites *GetStationTileLayout(StationType st, byte gfx) * Check whether a sprite is a track sprite, which can be replaced by a non-track ground sprite and a rail overlay. * If the ground sprite is suitable, \a ground is replaced with the new non-track ground sprite, and \a overlay_offset * is set to the overlay to draw. - * @param ti Positional info for the tile to decide snowyness etc. May be NULL. + * @param ti Positional info for the tile to decide snowyness etc. May be nullptr. * @param[in,out] ground Groundsprite to draw. * @param[out] overlay_offset Overlay to draw. * @return true if overlay can be drawn. @@ -2639,21 +2762,29 @@ bool SplitGroundSpriteForOverlay(const TileInfo *ti, SpriteID *ground, RailTrack bool snow_desert; switch (*ground) { case SPR_RAIL_TRACK_X: + case SPR_MONO_TRACK_X: + case SPR_MGLV_TRACK_X: snow_desert = false; *overlay_offset = RTO_X; break; case SPR_RAIL_TRACK_Y: + case SPR_MONO_TRACK_Y: + case SPR_MGLV_TRACK_Y: snow_desert = false; *overlay_offset = RTO_Y; break; case SPR_RAIL_TRACK_X_SNOW: + case SPR_MONO_TRACK_X_SNOW: + case SPR_MGLV_TRACK_X_SNOW: snow_desert = true; *overlay_offset = RTO_X; break; case SPR_RAIL_TRACK_Y_SNOW: + case SPR_MONO_TRACK_Y_SNOW: + case SPR_MGLV_TRACK_Y_SNOW: snow_desert = true; *overlay_offset = RTO_Y; break; @@ -2662,7 +2793,7 @@ bool SplitGroundSpriteForOverlay(const TileInfo *ti, SpriteID *ground, RailTrack return false; } - if (ti != NULL) { + if (ti != nullptr) { /* Decide snow/desert from tile */ switch (_settings_game.game_creation.landscape) { case LT_ARCTIC: @@ -2684,21 +2815,19 @@ bool SplitGroundSpriteForOverlay(const TileInfo *ti, SpriteID *ground, RailTrack static void DrawTile_Station(TileInfo *ti) { - const NewGRFSpriteLayout *layout = NULL; + const NewGRFSpriteLayout *layout = nullptr; DrawTileSprites tmp_rail_layout; - const DrawTileSprites *t = NULL; - RoadTypes roadtypes; + const DrawTileSprites *t = nullptr; int32 total_offset; - const RailtypeInfo *rti = NULL; + const RailtypeInfo *rti = nullptr; uint32 relocation = 0; uint32 ground_relocation = 0; - BaseStation *st = NULL; - const StationSpec *statspec = NULL; + BaseStation *st = nullptr; + const StationSpec *statspec = nullptr; uint tile_layout = 0; if (HasStationRail(ti->tile)) { rti = GetRailTypeInfo(GetRailType(ti->tile)); - roadtypes = ROADTYPES_NONE; total_offset = rti->GetRailtypeSpriteOffset(); if (IsCustomStationSpecIndex(ti->tile)) { @@ -2706,7 +2835,7 @@ static void DrawTile_Station(TileInfo *ti) st = BaseStation::GetByTile(ti->tile); statspec = st->speclist[GetCustomStationSpecIndex(ti->tile)].spec; - if (statspec != NULL) { + if (statspec != nullptr) { tile_layout = GetStationGfx(ti->tile); if (HasBit(statspec->callback_mask, CBM_STATION_SPRITE_LAYOUT)) { @@ -2715,17 +2844,16 @@ static void DrawTile_Station(TileInfo *ti) } /* Ensure the chosen tile layout is valid for this custom station */ - if (statspec->renderdata != NULL) { + if (statspec->renderdata != nullptr) { layout = &statspec->renderdata[tile_layout < statspec->tiles ? tile_layout : (uint)GetRailStationAxis(ti->tile)]; if (!layout->NeedsPreprocessing()) { t = layout; - layout = NULL; + layout = nullptr; } } } } } else { - roadtypes = IsRoadStop(ti->tile) ? GetRoadTypes(ti->tile) : ROADTYPES_NONE; total_offset = 0; } @@ -2734,7 +2862,7 @@ static void DrawTile_Station(TileInfo *ti) gfx = GetAirportGfx(ti->tile); if (gfx >= NEW_AIRPORTTILE_OFFSET) { const AirportTileSpec *ats = AirportTileSpec::Get(gfx); - if (ats->grf_prop.spritegroup[0] != NULL && DrawNewAirportTile(ti, Station::GetByTile(ti->tile), gfx, ats)) { + if (ats->grf_prop.spritegroup[0] != nullptr && DrawNewAirportTile(ti, Station::GetByTile(ti->tile), gfx, ats)) { return; } /* No sprite group (or no valid one) found, meaning no graphics associated. @@ -2771,11 +2899,11 @@ static void DrawTile_Station(TileInfo *ti) palette = PALETTE_TO_GREY; } - if (layout == NULL && (t == NULL || t->seq == NULL)) t = GetStationTileLayout(GetStationType(ti->tile), gfx); + if (layout == nullptr && (t == nullptr || t->seq == nullptr)) t = GetStationTileLayout(GetStationType(ti->tile), gfx); /* don't show foundation for docks */ if (ti->tileh != SLOPE_FLAT && !IsDock(ti->tile)) { - if (statspec != NULL && HasBit(statspec->flags, SSF_CUSTOM_FOUNDATIONS)) { + if (statspec != nullptr && HasBit(statspec->flags, SSF_CUSTOM_FOUNDATIONS)) { /* Station has custom foundations. * Check whether the foundation continues beyond the tile's upper sides. */ uint edge_info = 0; @@ -2854,7 +2982,7 @@ draw_default_foundation: } else { assert(IsDock(ti->tile)); TileIndex water_tile = ti->tile + TileOffsByDiagDir(GetDockDirection(ti->tile)); - WaterClass wc = GetWaterClass(water_tile); + WaterClass wc = HasTileWaterClass(water_tile) ? GetWaterClass(water_tile) : WATER_CLASS_INVALID; if (wc == WATER_CLASS_SEA) { DrawShoreTile(ti->tileh); } else { @@ -2862,7 +2990,7 @@ draw_default_foundation: } } } else { - if (layout != NULL) { + if (layout != nullptr) { /* Sprite layout which needs preprocessing */ bool separate_ground = HasBit(statspec->flags, SSF_SEPARATE_GROUND); uint32 var10_values = layout->PrepareLayout(total_offset, rti->fallback_railtype, 0, 0, separate_ground); @@ -2874,7 +3002,7 @@ draw_default_foundation: tmp_rail_layout.seq = layout->GetLayout(&tmp_rail_layout.ground); t = &tmp_rail_layout; total_offset = 0; - } else if (statspec != NULL) { + } else if (statspec != nullptr) { /* Simple sprite layout */ ground_relocation = relocation = GetCustomStationRelocation(statspec, st, ti->tile, 0); if (HasBit(statspec->flags, SSF_SEPARATE_GROUND)) { @@ -2886,7 +3014,7 @@ draw_default_foundation: SpriteID image = t->ground.sprite; PaletteID pal = t->ground.pal; RailTrackOffset overlay_offset; - if (rti != NULL && rti->UsesOverlay() && SplitGroundSpriteForOverlay(ti, &image, &overlay_offset)) { + if (rti != nullptr && rti->UsesOverlay() && SplitGroundSpriteForOverlay(ti, &image, &overlay_offset)) { SpriteID ground = GetCustomRailSprite(rti, ti->tile, RTSG_GROUND); DrawGroundSprite(image, PAL_NONE); DrawGroundSprite(ground + overlay_offset, PAL_NONE); @@ -2910,10 +3038,30 @@ draw_default_foundation: if (HasStationRail(ti->tile) && HasRailCatenaryDrawn(GetRailType(ti->tile))) DrawRailCatenary(ti); - if (HasBit(roadtypes, ROADTYPE_TRAM)) { - Axis axis = GetRoadStopDir(ti->tile) == DIAGDIR_NE ? AXIS_X : AXIS_Y; - DrawGroundSprite((HasBit(roadtypes, ROADTYPE_ROAD) ? SPR_TRAMWAY_OVERLAY : SPR_TRAMWAY_TRAM) + (axis ^ 1), PAL_NONE); - DrawRoadCatenary(ti, axis == AXIS_X ? ROAD_X : ROAD_Y); + if (IsRoadStop(ti->tile)) { + RoadType road_rt = GetRoadTypeRoad(ti->tile); + RoadType tram_rt = GetRoadTypeTram(ti->tile); + const RoadTypeInfo* road_rti = road_rt == INVALID_ROADTYPE ? nullptr : GetRoadTypeInfo(road_rt); + const RoadTypeInfo* tram_rti = tram_rt == INVALID_ROADTYPE ? nullptr : GetRoadTypeInfo(tram_rt); + + 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); + } else { + /* 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); + SpriteID ground = GetCustomRoadSprite(road_rti, ti->tile, ROTSG_ROADSTOP); + DrawGroundSprite(ground + dir, PAL_NONE); + } + } + + /* Draw road, tram catenary */ + DrawRoadCatenary(ti); } if (IsRailWaypoint(ti->tile)) { @@ -2929,7 +3077,7 @@ 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 = NULL; + const RailtypeInfo *rti = nullptr; if (railtype != INVALID_RAILTYPE) { rti = GetRailTypeInfo(railtype); @@ -2938,7 +3086,7 @@ void StationPickerDrawSprite(int x, int y, StationType st, RailType railtype, Ro SpriteID img = t->ground.sprite; RailTrackOffset overlay_offset; - if (rti != NULL && rti->UsesOverlay() && SplitGroundSpriteForOverlay(NULL, &img, &overlay_offset)) { + if (rti != nullptr && rti->UsesOverlay() && SplitGroundSpriteForOverlay(nullptr, &img, &overlay_offset)) { SpriteID ground = GetCustomRailSprite(rti, INVALID_TILE, RTSG_GROUND); DrawSprite(img, PAL_NONE, x, y); DrawSprite(ground + overlay_offset, PAL_NONE, x, y); @@ -2946,8 +3094,29 @@ void StationPickerDrawSprite(int x, int y, StationType st, RailType railtype, Ro DrawSprite(img + total_offset, HasBit(img, PALETTE_MODIFIER_COLOUR) ? pal : PAL_NONE, x, y); } - if (roadtype == ROADTYPE_TRAM) { - DrawSprite(SPR_TRAMWAY_TRAM + (t->ground.sprite == SPR_ROAD_PAVED_STRAIGHT_X ? 1 : 0), PAL_NONE, x, y); + if (roadtype != INVALID_ROADTYPE) { + const RoadTypeInfo* rti = 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); + 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 (RoadTypeIsRoad(roadtype) && rti->UsesOverlay()) { + SpriteID ground = GetCustomRoadSprite(rti, INVALID_TILE, ROTSG_ROADSTOP); + DrawSprite(ground + image, PAL_NONE, x, y); + } + } } /* Default waypoint has no railtype specific sprites */ @@ -2967,38 +3136,54 @@ static Foundation GetFoundation_Station(TileIndex tile, Slope tileh) static void GetTileDesc_Station(TileIndex tile, TileDesc *td) { td->owner[0] = GetTileOwner(tile); - if (IsDriveThroughStopTile(tile)) { + + if (IsRoadStopTile(tile)) { + RoadType road_rt = GetRoadTypeRoad(tile); + RoadType tram_rt = GetRoadTypeTram(tile); Owner road_owner = INVALID_OWNER; Owner tram_owner = INVALID_OWNER; - RoadTypes rts = GetRoadTypes(tile); - if (HasBit(rts, ROADTYPE_ROAD)) road_owner = GetRoadOwner(tile, ROADTYPE_ROAD); - if (HasBit(rts, ROADTYPE_TRAM)) tram_owner = GetRoadOwner(tile, ROADTYPE_TRAM); + 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); + } - /* 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; + 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); - if (spec != NULL) { + if (spec != nullptr) { td->station_class = StationClass::Get(spec->cls_id)->name; td->station_name = spec->name; - if (spec->grf_prop.grffile != NULL) { + if (spec->grf_prop.grffile != nullptr) { const GRFConfig *gc = GetGRFConfig(spec->grf_prop.grffile->grfid); td->grf = gc->GetName(); } @@ -3017,10 +3202,10 @@ static void GetTileDesc_Station(TileIndex tile, TileDesc *td) const AirportTileSpec *ats = AirportTileSpec::GetByTile(tile); td->airport_tile_name = ats->name; - if (as->grf_prop.grffile != NULL) { + 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 != NULL) { + } else if (ats->grf_prop.grffile != nullptr) { const GRFConfig *gc = GetGRFConfig(ats->grf_prop.grffile->grfid); td->grf = gc->GetName(); } @@ -3035,7 +3220,14 @@ static void GetTileDesc_Station(TileIndex tile, TileDesc *td) break; case STATION_TRUCK: str = STR_LAI_STATION_DESCRIPTION_TRUCK_LOADING_AREA; break; case STATION_BUS: str = STR_LAI_STATION_DESCRIPTION_BUS_STATION; break; - case STATION_OILRIG: str = STR_INDUSTRY_NAME_OIL_RIG; break; + case STATION_OILRIG: { + const Industry *i = Station::GetByTile(tile)->industry; + const IndustrySpec *is = GetIndustrySpec(i->type); + td->owner[0] = i->owner; + str = is->name; + if (is->grf_prop.grffile != nullptr) td->grf = GetGRFConfig(is->grf_prop.grffile->grfid)->GetName(); + break; + } case STATION_DOCK: str = STR_LAI_STATION_DESCRIPTION_SHIP_DOCK; break; case STATION_BUOY: str = STR_LAI_STATION_DESCRIPTION_BUOY; break; case STATION_WAYPOINT: str = STR_LAI_STATION_DESCRIPTION_WAYPOINT; break; @@ -3067,7 +3259,10 @@ static TrackStatus GetTileTrackStatus_Station(TileIndex tile, TransportType mode break; case TRANSPORT_ROAD: - if ((GetRoadTypes(tile) & sub_mode) != 0 && IsRoadStop(tile)) { + if (IsRoadStop(tile)) { + RoadTramType rtt = (RoadTramType)sub_mode; + if (!HasTileRoadType(tile, rtt)) break; + DiagDirection dir = GetRoadStopDir(tile); Axis axis = DiagDirToAxis(dir); @@ -3202,9 +3397,8 @@ void TriggerWatchedCargoCallbacks(Station *st) if (cargoes == 0) return; /* Loop over all houses in the catchment. */ - Rect r = st->GetCatchmentRect(); - TileArea ta(TileXY(r.left, r.top), TileXY(r.right, r.bottom)); - TILE_AREA_LOOP(tile, ta) { + BitmapTileIterator it(st->catchment_tiles); + for (TileIndex tile = it; tile != INVALID_TILE; tile = ++it) { if (IsTileType(tile, MP_HOUSE)) { WatchedCargoCallback(tile, cargoes); } @@ -3259,7 +3453,7 @@ static void TruncateCargo(const CargoSpec *cs, GoodsEntry *ge, uint amount = UIN ge->cargo.Truncate(amount, &waiting_per_source); for (StationCargoAmountMap::iterator i(waiting_per_source.begin()); i != waiting_per_source.end(); ++i) { Station *source_station = Station::GetIfValid(i->first); - if (source_station == NULL) continue; + if (source_station == nullptr) continue; GoodsEntry &source_ge = source_station->goods[cs->Index()]; source_ge.max_waiting_cargo = max(source_ge.max_waiting_cargo, i->second); @@ -3337,27 +3531,25 @@ static void UpdateStationRating(Station *st) byte waittime = ge->time_since_pickup; if (st->last_vehicle_type == VEH_SHIP) waittime >>= 2; - (waittime > 21) || - (rating += 25, waittime > 12) || - (rating += 25, waittime > 6) || - (rating += 45, waittime > 3) || - (rating += 35, true); + if (waittime <= 21) rating += 25; + if (waittime <= 12) rating += 25; + if (waittime <= 6) rating += 45; + if (waittime <= 3) rating += 35; - (rating -= 90, ge->max_waiting_cargo > 1500) || - (rating += 55, ge->max_waiting_cargo > 1000) || - (rating += 35, ge->max_waiting_cargo > 600) || - (rating += 10, ge->max_waiting_cargo > 300) || - (rating += 20, ge->max_waiting_cargo > 100) || - (rating += 10, true); + rating -= 90; + if (ge->max_waiting_cargo <= 1500) rating += 55; + if (ge->max_waiting_cargo <= 1000) rating += 35; + if (ge->max_waiting_cargo <= 600) rating += 10; + if (ge->max_waiting_cargo <= 300) rating += 20; + if (ge->max_waiting_cargo <= 100) rating += 10; } if (Company::IsValidID(st->owner) && HasBit(st->town->statues, st->owner)) rating += 26; byte age = ge->last_age; - (age >= 3) || - (rating += 10, age >= 2) || - (rating += 10, age >= 1) || - (rating += 13, true); + if (age < 3) rating += 10; + if (age < 2) rating += 10; + if (age < 1) rating += 13; { int or_ = ge->rating; // old rating @@ -3440,7 +3632,7 @@ void RerouteCargo(Station *st, CargoID c, StationID avoid, StationID avoid2) /* Reroute cargo staged to be transferred. */ for (std::list::iterator it(st->loading_vehicles.begin()); it != st->loading_vehicles.end(); ++it) { - for (Vehicle *v = *it; v != NULL; v = v->Next()) { + for (Vehicle *v = *it; v != nullptr; v = v->Next()) { if (v->cargo_type != c) continue; v->cargo.Reroute(UINT_MAX, &v->cargo, avoid, avoid2, &ge); } @@ -3461,7 +3653,7 @@ void DeleteStaleLinks(Station *from) const bool auto_distributed = (_settings_game.linkgraph.GetDistributionType(c) != DT_MANUAL); GoodsEntry &ge = from->goods[c]; LinkGraph *lg = LinkGraph::GetIfValid(ge.link_graph); - if (lg == NULL) continue; + if (lg == nullptr) continue; Node node = (*lg)[ge.node]; for (EdgeIterator it(node.Begin()); it != node.End();) { Edge edge = it->second; @@ -3476,12 +3668,11 @@ void DeleteStaleLinks(Station *from) if (auto_distributed) { /* Have all vehicles refresh their next hops before deciding to * remove the node. */ - OrderList *l; - SmallVector vehicles; - FOR_ALL_ORDER_LISTS(l) { + std::vector vehicles; + for (OrderList *l : OrderList::Iterate()) { bool found_from = false; bool found_to = false; - for (Order *order = l->GetFirstOrder(); order != NULL; order = order->next) { + for (Order *order = l->GetFirstOrder(); order != nullptr; order = order->next) { if (!order->IsType(OT_GOTO_STATION) && !order->IsType(OT_IMPLICIT)) continue; if (order->GetDestination() == from->index) { found_from = true; @@ -3492,11 +3683,11 @@ void DeleteStaleLinks(Station *from) } } if (!found_to || !found_from) continue; - *(vehicles.Append()) = l->GetFirstSharedVehicle(); + vehicles.push_back(l->GetFirstSharedVehicle()); } - Vehicle **iter = vehicles.Begin(); - while (iter != vehicles.End()) { + auto iter = vehicles.begin(); + while (iter != vehicles.end()) { Vehicle *v = *iter; LinkRefresher::Run(v, false); // Don't allow merging. Otherwise lg might get deleted. @@ -3510,10 +3701,10 @@ void DeleteStaleLinks(Station *from) *iter = next_shared; ++iter; } else { - vehicles.Erase(iter); + iter = vehicles.erase(iter); } - if (iter == vehicles.End()) iter = vehicles.Begin(); + if (iter == vehicles.end()) iter = vehicles.begin(); } } @@ -3552,7 +3743,7 @@ void IncreaseStats(Station *st, CargoID cargo, StationID next_station_id, uint c GoodsEntry &ge1 = st->goods[cargo]; Station *st2 = Station::Get(next_station_id); GoodsEntry &ge2 = st2->goods[cargo]; - LinkGraph *lg = NULL; + LinkGraph *lg = nullptr; if (ge1.link_graph == INVALID_LINK_GRAPH) { if (ge2.link_graph == INVALID_LINK_GRAPH) { if (LinkGraph::CanAllocateItem()) { @@ -3588,7 +3779,7 @@ void IncreaseStats(Station *st, CargoID cargo, StationID next_station_id, uint c } } } - if (lg != NULL) { + if (lg != nullptr) { (*lg)[ge1.node].UpdateEdge(ge2.node, capacity, usage, mode); } } @@ -3601,7 +3792,7 @@ void IncreaseStats(Station *st, CargoID cargo, StationID next_station_id, uint c */ void IncreaseStats(Station *st, const Vehicle *front, StationID next_station_id) { - for (const Vehicle *v = front; v != NULL; v = v->Next()) { + for (const Vehicle *v = front; v != nullptr; v = v->Next()) { if (v->refit_cap > 0) { /* The cargo count can indeed be higher than the refit_cap if * wagons have been auto-replaced and subsequently auto- @@ -3610,7 +3801,7 @@ void IncreaseStats(Station *st, const Vehicle *front, StationID next_station_id) * As usage is not such an important figure anyway we just * ignore the additional cargo then.*/ IncreaseStats(st, v->cargo_type, next_station_id, v->refit_cap, - min(v->refit_cap, v->cargo.StoredCount()), EUM_INCREASE); + min(v->refit_cap, v->cargo.StoredCount()), EUM_INCREASE); } } } @@ -3631,8 +3822,7 @@ void OnTick_Station() { if (_game_mode == GM_EDITOR) return; - BaseStation *st; - FOR_ALL_BASE_STATIONS(st) { + for (BaseStation *st : BaseStation::Iterate()) { StationHandleSmallTick(st); /* Clean up the link graph about once a week. */ @@ -3655,9 +3845,7 @@ void OnTick_Station() /** Monthly loop for stations. */ void StationMonthlyLoop() { - Station *st; - - FOR_ALL_STATIONS(st) { + for (Station *st : Station::Iterate()) { for (CargoID i = 0; i < NUM_CARGO; i++) { GoodsEntry *ge = &st->goods[i]; SB(ge->status, GoodsEntry::GES_LAST_MONTH, 1, GB(ge->status, GoodsEntry::GES_CURRENT_MONTH, 1)); @@ -3669,11 +3857,8 @@ void StationMonthlyLoop() void ModifyStationRatingAround(TileIndex tile, Owner owner, int amount, uint radius) { - Station *st; - - FOR_ALL_STATIONS(st) { - if (st->owner == owner && - DistanceManhattan(tile, st->xy) <= radius) { + ForAllStationsRadius(tile, radius, [&](Station *st) { + if (st->owner == owner && DistanceManhattan(tile, st->xy) <= radius) { for (CargoID i = 0; i < NUM_CARGO; i++) { GoodsEntry *ge = &st->goods[i]; @@ -3682,7 +3867,7 @@ void ModifyStationRatingAround(TileIndex tile, Owner owner, int amount, uint rad } } } - } + }); } static uint UpdateStationWaiting(Station *st, CargoID type, uint amount, SourceType source_type, SourceID source_id) @@ -3701,7 +3886,7 @@ static uint UpdateStationWaiting(Station *st, CargoID type, uint amount, SourceT StationID next = ge.GetVia(st->index); ge.cargo.Append(new CargoPacket(st->index, st->xy, amount, source_type, source_id), next); - LinkGraph *lg = NULL; + LinkGraph *lg = nullptr; if (ge.link_graph == INVALID_LINK_GRAPH) { if (LinkGraph::CanAllocateItem()) { lg = new LinkGraph(type); @@ -3714,7 +3899,7 @@ static uint UpdateStationWaiting(Station *st, CargoID type, uint amount, SourceT } else { lg = LinkGraph::Get(ge.link_graph); } - if (lg != NULL) (*lg)[ge.node].UpdateSupply(amount); + if (lg != nullptr) (*lg)[ge.node].UpdateSupply(amount); if (!ge.HasRating()) { InvalidateWindowData(WC_STATION_LIST, st->index); @@ -3732,10 +3917,8 @@ static uint UpdateStationWaiting(Station *st, CargoID type, uint amount, SourceT static bool IsUniqueStationName(const char *name) { - const Station *st; - - FOR_ALL_STATIONS(st) { - if (st->name != NULL && strcmp(st->name, name) == 0) return false; + for (const Station *st : Station::Iterate()) { + if (st->name != nullptr && strcmp(st->name, name) == 0) return false; } return true; @@ -3753,7 +3936,7 @@ static bool IsUniqueStationName(const char *name) CommandCost CmdRenameStation(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { Station *st = Station::GetIfValid(p1); - if (st == NULL) return CMD_ERROR; + if (st == nullptr) return CMD_ERROR; CommandCost ret = CheckOwnership(st->owner); if (ret.Failed()) return ret; @@ -3766,8 +3949,9 @@ CommandCost CmdRenameStation(TileIndex tile, DoCommandFlag flags, uint32 p1, uin } if (flags & DC_EXEC) { + st->cached_name.clear(); free(st->name); - st->name = reset ? NULL : stredup(text); + st->name = reset ? nullptr : stredup(text); st->UpdateVirtCoord(); InvalidateWindowData(WC_STATION_LIST, st->owner, 1); @@ -3776,52 +3960,60 @@ CommandCost CmdRenameStation(TileIndex tile, DoCommandFlag flags, uint32 p1, uin return CommandCost(); } +static void AddNearbyStationsByCatchment(TileIndex tile, StationList *stations, StationList &nearby) +{ + for (Station *st : nearby) { + if (st->TileIsInCatchment(tile)) stations->insert(st); + } +} + /** * Find all stations around a rectangular producer (industry, house, headquarter, ...) * * @param location The location/area of the producer - * @param stations The list to store the stations in + * @param[out] stations The list to store the stations in + * @param use_nearby Use nearby station list of industry/town associated with location.tile */ -void FindStationsAroundTiles(const TileArea &location, StationList *stations) +void FindStationsAroundTiles(const TileArea &location, StationList * const stations, bool use_nearby) { - /* area to search = producer plus station catchment radius */ - uint max_rad = (_settings_game.station.modified_catchment ? MAX_CATCHMENT : CA_UNMODIFIED); + if (use_nearby) { + /* Industries and towns maintain a list of nearby stations */ + if (IsTileType(location.tile, MP_INDUSTRY)) { + /* Industry nearby stations are already filtered by catchment. */ + *stations = Industry::GetByTile(location.tile)->stations_near; + return; + } else if (IsTileType(location.tile, MP_HOUSE)) { + /* Town nearby stations need to be filtered per tile. */ + assert(location.w == 1 && location.h == 1); + AddNearbyStationsByCatchment(location.tile, stations, Town::GetByTile(location.tile)->stations_near); + return; + } + } - uint x = TileX(location.tile); - uint y = TileY(location.tile); + /* Not using, or don't have a nearby stations list, so we need to scan. */ + std::set seen_stations; - uint min_x = (x > max_rad) ? x - max_rad : 0; - uint max_x = x + location.w + max_rad; - uint min_y = (y > max_rad) ? y - max_rad : 0; - uint max_y = y + location.h + max_rad; + /* Scan an area around the building covering the maximum possible station + * to find the possible nearby stations. */ + uint max_c = _settings_game.station.modified_catchment ? MAX_CATCHMENT : CA_UNMODIFIED; + TileArea ta = TileArea(location).Expand(max_c); + TILE_AREA_LOOP(tile, ta) { + if (IsTileType(tile, MP_STATION)) seen_stations.insert(GetStationIndex(tile)); + } - if (min_x == 0 && _settings_game.construction.freeform_edges) min_x = 1; - if (min_y == 0 && _settings_game.construction.freeform_edges) min_y = 1; - if (max_x >= MapSizeX()) max_x = MapSizeX() - 1; - if (max_y >= MapSizeY()) max_y = MapSizeY() - 1; + for (StationID stationid : seen_stations) { + Station *st = Station::GetIfValid(stationid); + if (st == nullptr) continue; /* Waypoint */ - for (uint cy = min_y; cy < max_y; cy++) { - for (uint cx = min_x; cx < max_x; cx++) { - TileIndex cur_tile = TileXY(cx, cy); - if (!IsTileType(cur_tile, MP_STATION)) continue; + /* Check if station is attached to an industry */ + if (!_settings_game.station.serve_neutral_industries && st->industry != nullptr) continue; - Station *st = Station::GetByTile(cur_tile); - /* st can be NULL in case of waypoints */ - if (st == NULL) continue; - - if (_settings_game.station.modified_catchment) { - int rad = st->GetCatchmentRadius(); - int rad_x = cx - x; - int rad_y = cy - y; - - if (rad_x < -rad || rad_x >= rad + location.w) continue; - if (rad_y < -rad || rad_y >= rad + location.h) continue; + /* Test if the tile is within the station's catchment */ + TILE_AREA_LOOP(tile, location) { + if (st->TileIsInCatchment(tile)) { + stations->insert(st); + break; } - - /* Insert the station in the set. This will fail if it has - * already been added. - */ - stations->Include(st); } } } @@ -3839,70 +4031,135 @@ const StationList *StationFinder::GetStations() return &this->stations; } +static bool CanMoveGoodsToStation(const Station *st, CargoID type) +{ + /* Is the station reserved exclusively for somebody else? */ + if (st->owner != OWNER_NONE && st->town->exclusive_counter > 0 && st->town->exclusivity != st->owner) return false; + + /* Lowest possible rating, better not to give cargo anymore. */ + if (st->goods[type].rating == 0) return false; + + /* Selectively servicing stations, and not this one. */ + if (_settings_game.order.selectgoods && !st->goods[type].HasVehicleEverTriedLoading()) return false; + + if (IsCargoInClass(type, CC_PASSENGERS)) { + /* Passengers are never served by just a truck stop. */ + if (st->facilities == FACIL_TRUCK_STOP) return false; + } else { + /* Non-passengers are never served by just a bus stop. */ + if (st->facilities == FACIL_BUS_STOP) return false; + } + return true; +} + uint MoveGoodsToStation(CargoID type, uint amount, SourceType source_type, SourceID source_id, const StationList *all_stations) { /* Return if nothing to do. Also the rounding below fails for 0. */ + if (all_stations->empty()) return 0; if (amount == 0) return 0; - Station *st1 = NULL; // Station with best rating - Station *st2 = NULL; // Second best station - uint best_rating1 = 0; // rating of st1 - uint best_rating2 = 0; // rating of st2 + Station *first_station = nullptr; + typedef std::pair StationInfo; + std::vector used_stations; - for (Station * const *st_iter = all_stations->Begin(); st_iter != all_stations->End(); ++st_iter) { - Station *st = *st_iter; + for (Station *st : *all_stations) { + if (!CanMoveGoodsToStation(st, type)) continue; - /* Is the station reserved exclusively for somebody else? */ - if (st->owner != OWNER_NONE && st->town->exclusive_counter > 0 && st->town->exclusivity != st->owner) continue; - - if (st->goods[type].rating == 0) continue; // Lowest possible rating, better not to give cargo anymore - - if (_settings_game.order.selectgoods && !st->goods[type].HasVehicleEverTriedLoading()) continue; // Selectively servicing stations, and not this one - - if (IsCargoInClass(type, CC_PASSENGERS)) { - if (st->facilities == FACIL_TRUCK_STOP) continue; // passengers are never served by just a truck stop - } else { - if (st->facilities == FACIL_BUS_STOP) continue; // non-passengers are never served by just a bus stop + /* Avoid allocating a vector if there is only one station to significantly + * improve performance in this common case. */ + if (first_station == nullptr) { + first_station = st; + continue; } - - /* This station can be used, add it to st1/st2 */ - if (st1 == NULL || st->goods[type].rating >= best_rating1) { - st2 = st1; best_rating2 = best_rating1; st1 = st; best_rating1 = st->goods[type].rating; - } else if (st2 == NULL || st->goods[type].rating >= best_rating2) { - st2 = st; best_rating2 = st->goods[type].rating; + if (used_stations.empty()) { + used_stations.reserve(2); + used_stations.emplace_back(std::make_pair(first_station, 0)); } + used_stations.emplace_back(std::make_pair(st, 0)); } /* no stations around at all? */ - if (st1 == NULL) return 0; + if (first_station == nullptr) return 0; - /* From now we'll calculate with fractal cargo amounts. - * First determine how much cargo we really have. */ - amount *= best_rating1 + 1; - - if (st2 == NULL) { + if (used_stations.empty()) { /* only one station around */ - return UpdateStationWaiting(st1, type, amount, source_type, source_id); + amount *= first_station->goods[type].rating + 1; + return UpdateStationWaiting(first_station, type, amount, source_type, source_id); } - /* several stations around, the best two (highest rating) are in st1 and st2 */ - assert(st1 != NULL); - assert(st2 != NULL); - assert(best_rating1 != 0 || best_rating2 != 0); + uint company_best[OWNER_NONE + 1] = {}; // best rating for each company, including OWNER_NONE + uint company_sum[OWNER_NONE + 1] = {}; // sum of ratings for each company + uint best_rating = 0; + uint best_sum = 0; // sum of best ratings for each company - /* Then determine the amount the worst station gets. We do it this way as the - * best should get a bonus, which in this case is the rounding difference from - * this calculation. In reality that will mean the bonus will be pretty low. - * Nevertheless, the best station should always get the most cargo regardless - * of rounding issues. */ - uint worst_cargo = amount * best_rating2 / (best_rating1 + best_rating2); - assert(worst_cargo <= (amount - worst_cargo)); + for (auto &p : used_stations) { + auto owner = p.first->owner; + auto rating = p.first->goods[type].rating; + if (rating > company_best[owner]) { + best_sum += rating - company_best[owner]; // it's usually faster than iterating companies later + company_best[owner] = rating; + if (rating > best_rating) best_rating = rating; + } + company_sum[owner] += rating; + } - /* And then send the cargo to the stations! */ - uint moved = UpdateStationWaiting(st1, type, amount - worst_cargo, source_type, source_id); - /* These two UpdateStationWaiting's can't be in the statement as then the order - * of execution would be undefined and that could cause desyncs with callbacks. */ - return moved + UpdateStationWaiting(st2, type, worst_cargo, source_type, source_id); + /* From now we'll calculate with fractional cargo amounts. + * First determine how much cargo we really have. */ + amount *= best_rating + 1; + + uint moving = 0; + for (auto &p : used_stations) { + uint owner = p.first->owner; + /* Multiply the amount by (company best / sum of best for each company) to get cargo allocated to a company + * and by (station rating / sum of ratings in a company) to get the result for a single station. */ + p.second = amount * company_best[owner] * p.first->goods[type].rating / best_sum / company_sum[owner]; + moving += p.second; + } + + /* If there is some cargo left due to rounding issues distribute it among the best rated stations. */ + if (amount > moving) { + std::sort(used_stations.begin(), used_stations.end(), [type] (const StationInfo &a, const StationInfo &b) { + return b.first->goods[type].rating < a.first->goods[type].rating; + }); + + assert(amount - moving <= used_stations.size()); + for (uint i = 0; i < amount - moving; i++) { + used_stations[i].second++; + } + } + + uint moved = 0; + for (auto &p : used_stations) { + moved += UpdateStationWaiting(p.first, type, p.second, source_type, source_id); + } + + return moved; +} + +void UpdateStationDockingTiles(Station *st) +{ + st->docking_station.Clear(); + + /* For neutral stations, start with the industry area instead of dock area */ + const TileArea *area = st->industry != nullptr ? &st->industry->location : &st->ship_station; + + if (area->tile == INVALID_TILE) return; + + int x = TileX(area->tile); + int y = TileY(area->tile); + + /* Expand the area by a tile on each side while + * making sure that we remain inside the map. */ + int x2 = min(x + area->w + 1, MapSizeX()); + int x1 = max(x - 1, 0); + + int y2 = min(y + area->h + 1, MapSizeY()); + int y1 = max(y - 1, 0); + + TileArea ta(TileXY(x1, y1), TileXY(x2 - 1, y2 - 1)); + TILE_AREA_LOOP(tile, ta) { + if (IsValidTile(tile) && IsPossibleDockingTile(tile)) CheckForDockingTile(tile); + } } void BuildOilRig(TileIndex tile) @@ -3913,26 +4170,31 @@ void BuildOilRig(TileIndex tile) } Station *st = new Station(tile); + _station_kdtree.Insert(st->index); st->town = ClosestTownFromTile(tile, UINT_MAX); st->string_id = GenerateStationName(st, tile, STATIONNAMING_OILRIG); assert(IsTileType(tile, MP_INDUSTRY)); + /* Mark industry as associated both ways */ + st->industry = Industry::GetByTile(tile); + st->industry->neutral_station = st; DeleteAnimatedTile(tile); MakeOilrig(tile, st->index, GetWaterClass(tile)); st->owner = OWNER_NONE; st->airport.type = AT_OILRIG; st->airport.Add(tile); - st->dock_tile = tile; + st->ship_station.Add(tile); st->facilities = FACIL_AIRPORT | FACIL_DOCK; st->build_date = _date; + UpdateStationDockingTiles(st); st->rect.BeforeAddTile(tile, StationRect::ADD_FORCE); st->UpdateVirtCoord(); + st->RecomputeCatchment(); UpdateStationAcceptance(st, false); - st->RecomputeIndustriesNear(); } void DeleteOilRig(TileIndex tile) @@ -3941,30 +4203,28 @@ void DeleteOilRig(TileIndex tile) MakeWaterKeepingClass(tile, OWNER_NONE); - st->dock_tile = INVALID_TILE; - st->airport.Clear(); - st->facilities &= ~(FACIL_AIRPORT | FACIL_DOCK); - st->airport.flags = 0; - - st->rect.AfterRemoveTile(st, tile); - - st->UpdateVirtCoord(); - st->RecomputeIndustriesNear(); - if (!st->IsInUse()) delete st; + /* The oil rig station is not supposed to be shared with anything else */ + assert(st->facilities == (FACIL_AIRPORT | FACIL_DOCK) && st->airport.type == AT_OILRIG); + if (st->industry != nullptr && st->industry->neutral_station == st) { + /* Don't leave dangling neutral station pointer */ + st->industry->neutral_station = nullptr; + } + delete st; } static void ChangeTileOwner_Station(TileIndex tile, Owner old_owner, Owner new_owner) { if (IsRoadStopTile(tile)) { - for (RoadType rt = ROADTYPE_ROAD; rt < ROADTYPE_END; rt++) { + FOR_ALL_ROADTRAMTYPES(rtt) { /* Update all roadtypes, no matter if they are present */ - if (GetRoadOwner(tile, rt) == old_owner) { - if (HasTileRoadType(tile, rt)) { + if (GetRoadOwner(tile, rtt) == old_owner) { + RoadType rt = GetRoadType(tile, rtt); + if (rt != INVALID_ROADTYPE) { /* A drive-through road-stop has always two road bits. No need to dirty windows here, we'll redraw the whole screen anyway. */ Company::Get(old_owner)->infrastructure.road[rt] -= 2; if (new_owner != INVALID_OWNER) Company::Get(new_owner)->infrastructure.road[rt] += 2; } - SetRoadOwner(tile, rt, new_owner == INVALID_OWNER ? OWNER_NONE : new_owner); + SetRoadOwner(tile, rtt, new_owner == INVALID_OWNER ? OWNER_NONE : new_owner); } } } @@ -4045,17 +4305,16 @@ static bool CanRemoveRoadWithStop(TileIndex tile, DoCommandFlag flags) /* Yeah... water can always remove stops, right? */ if (_current_company == OWNER_WATER) return true; - RoadTypes rts = GetRoadTypes(tile); - if (HasBit(rts, ROADTYPE_TRAM)) { - Owner tram_owner = GetRoadOwner(tile, ROADTYPE_TRAM); + if (GetRoadTypeTram(tile) != INVALID_ROADTYPE) { + Owner tram_owner = GetRoadOwner(tile, RTT_TRAM); if (tram_owner != OWNER_NONE && CheckOwnership(tram_owner).Failed()) return false; } - if (HasBit(rts, ROADTYPE_ROAD)) { - Owner road_owner = GetRoadOwner(tile, ROADTYPE_ROAD); + if (GetRoadTypeRoad(tile) != INVALID_ROADTYPE) { + Owner road_owner = GetRoadOwner(tile, RTT_ROAD); if (road_owner != OWNER_TOWN) { if (road_owner != OWNER_NONE && CheckOwnership(road_owner).Failed()) return false; } else { - if (CheckAllowRemoveRoad(tile, GetAnyRoadBits(tile, ROADTYPE_ROAD), OWNER_TOWN, ROADTYPE_ROAD, flags).Failed()) return false; + if (CheckAllowRemoveRoad(tile, GetAnyRoadBits(tile, RTT_ROAD), OWNER_TOWN, RTT_ROAD, flags).Failed()) return false; } } @@ -4076,8 +4335,8 @@ CommandCost ClearTile_Station(TileIndex tile, DoCommandFlag flags) case STATION_RAIL: return_cmd_error(STR_ERROR_MUST_DEMOLISH_RAILROAD); case STATION_WAYPOINT: return_cmd_error(STR_ERROR_BUILDING_MUST_BE_DEMOLISHED); case STATION_AIRPORT: return_cmd_error(STR_ERROR_MUST_DEMOLISH_AIRPORT_FIRST); - case STATION_TRUCK: return_cmd_error(HasTileRoadType(tile, ROADTYPE_TRAM) ? STR_ERROR_MUST_DEMOLISH_CARGO_TRAM_STATION_FIRST : STR_ERROR_MUST_DEMOLISH_TRUCK_STATION_FIRST); - case STATION_BUS: return_cmd_error(HasTileRoadType(tile, ROADTYPE_TRAM) ? STR_ERROR_MUST_DEMOLISH_PASSENGER_TRAM_STATION_FIRST : STR_ERROR_MUST_DEMOLISH_BUS_STATION_FIRST); + case STATION_TRUCK: return_cmd_error(HasTileRoadType(tile, RTT_TRAM) ? STR_ERROR_MUST_DEMOLISH_CARGO_TRAM_STATION_FIRST : STR_ERROR_MUST_DEMOLISH_TRUCK_STATION_FIRST); + case STATION_BUS: return_cmd_error(HasTileRoadType(tile, RTT_TRAM) ? STR_ERROR_MUST_DEMOLISH_PASSENGER_TRAM_STATION_FIRST : STR_ERROR_MUST_DEMOLISH_BUS_STATION_FIRST); case STATION_BUOY: return_cmd_error(STR_ERROR_BUOY_IN_THE_WAY); case STATION_DOCK: return_cmd_error(STR_ERROR_MUST_DEMOLISH_DOCK_FIRST); case STATION_OILRIG: @@ -4533,14 +4792,14 @@ extern const TileTypeProcs _tile_type_station_procs = { DrawTile_Station, // draw_tile_proc GetSlopePixelZ_Station, // get_slope_z_proc ClearTile_Station, // clear_tile_proc - NULL, // add_accepted_cargo_proc + nullptr, // add_accepted_cargo_proc GetTileDesc_Station, // get_tile_desc_proc GetTileTrackStatus_Station, // get_tile_track_status_proc ClickTile_Station, // click_tile_proc AnimateTile_Station, // animate_tile_proc TileLoop_Station, // tile_loop_proc ChangeTileOwner_Station, // change_tile_owner_proc - NULL, // add_produced_cargo_proc + nullptr, // add_produced_cargo_proc VehicleEnter_Station, // vehicle_enter_tile_proc GetFoundation_Station, // get_foundation_proc TerraformTile_Station, // terraform_tile_proc diff --git a/src/station_func.h b/src/station_func.h index 9748297f21..f9959089ee 100644 --- a/src/station_func.h +++ b/src/station_func.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. @@ -18,17 +16,20 @@ #include "vehicle_type.h" #include "economy_func.h" #include "rail.h" +#include "road.h" #include "linkgraph/linkgraph_type.h" +#include "industry_type.h" void ModifyStationRatingAround(TileIndex tile, Owner owner, int amount, uint radius); -void FindStationsAroundTiles(const TileArea &location, StationList *stations); +void FindStationsAroundTiles(const TileArea &location, StationList *stations, bool use_nearby = true); void ShowStationViewWindow(StationID station); void UpdateAllStationVirtCoords(); +void ClearAllStationCachedNames(); CargoArray GetProductionAroundTiles(TileIndex tile, int w, int h, int rad); -CargoArray GetAcceptanceAroundTiles(TileIndex tile, int w, int h, int rad, CargoTypes *always_accepted = NULL); +CargoArray GetAcceptanceAroundTiles(TileIndex tile, int w, int h, int rad, CargoTypes *always_accepted = nullptr); void UpdateStationAcceptance(Station *st, bool show_msg); @@ -38,6 +39,10 @@ void StationPickerDrawSprite(int x, int y, StationType st, RailType railtype, Ro bool HasStationInUse(StationID station, bool include_company, CompanyID company); void DeleteOilRig(TileIndex t); +void UpdateStationDockingTiles(Station *st); +void RemoveDockingTile(TileIndex t); +void ClearDockingTilesCheckingNeighbours(TileIndex tile); +bool IsValidDockingDirectionForDock(TileIndex t, DiagDirection d); /* Check if a rail station tile is traversable. */ bool IsStationTileBlocked(TileIndex tile); diff --git a/src/station_gui.cpp b/src/station_gui.cpp index b64942d479..041967b7f2 100644 --- a/src/station_gui.cpp +++ b/src/station_gui.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. @@ -80,6 +78,46 @@ int DrawStationCoverageAreaText(int left, int right, int top, StationCoverageTyp return DrawStringMultiLine(left, right, top, INT32_MAX, supplies ? STR_STATION_BUILD_SUPPLIES_CARGO : STR_STATION_BUILD_ACCEPTS_CARGO); } +/** + * Find stations adjacent to the current tile highlight area, so that existing coverage + * area can be drawn. + */ +static void FindStationsAroundSelection() +{ + /* With distant join we don't know which station will be selected, so don't show any */ + if (_ctrl_pressed) { + SetViewportCatchmentStation(nullptr, true); + return; + } + + /* Tile area for TileHighlightData */ + TileArea location(TileVirtXY(_thd.pos.x, _thd.pos.y), _thd.size.x / TILE_SIZE - 1, _thd.size.y / TILE_SIZE - 1); + + /* Extended area by one tile */ + uint x = TileX(location.tile); + uint y = TileY(location.tile); + + int max_c = 1; + TileArea ta(TileXY(max(0, x - max_c), max(0, y - max_c)), TileXY(min(MapMaxX(), x + location.w + max_c), min(MapMaxY(), y + location.h + max_c))); + + Station *adjacent = nullptr; + + /* Direct loop instead of FindStationsAroundTiles as we are not interested in catchment area */ + TILE_AREA_LOOP(tile, ta) { + if (IsTileType(tile, MP_STATION) && GetTileOwner(tile) == _local_company) { + Station *st = Station::GetByTile(tile); + if (st == nullptr) continue; + if (adjacent != nullptr && st != adjacent) { + /* Multiple nearby, distant join is required. */ + adjacent = nullptr; + break; + } + adjacent = st; + } + } + SetViewportCatchmentStation(adjacent, true); +} + /** * Check whether we need to redraw the station coverage text. * If it is needed actually make the window for redrawing. @@ -87,9 +125,20 @@ int DrawStationCoverageAreaText(int left, int right, int top, StationCoverageTyp */ void CheckRedrawStationCoverage(const Window *w) { + /* Test if ctrl state changed */ + static bool _last_ctrl_pressed; + if (_ctrl_pressed != _last_ctrl_pressed) { + _thd.dirty = 0xff; + _last_ctrl_pressed = _ctrl_pressed; + } + if (_thd.dirty & 1) { _thd.dirty &= ~1; w->SetDirty(); + + if (_settings_client.gui.station_show_coverage && _thd.drawstyle == HT_RECT) { + FindStationsAroundSelection(); + } } } @@ -158,7 +207,6 @@ protected: static bool include_empty; // whether we should include stations without waiting cargo static const CargoTypes cargo_filter_max; static CargoTypes cargo_filter; // bitmap of cargo types to include - static const Station *last_station; /* Constants for sorting stations */ static const StringID sorter_names[]; @@ -178,10 +226,9 @@ protected: DEBUG(misc, 3, "Building station list for company %d", owner); - this->stations.Clear(); + this->stations.clear(); - const Station *st; - FOR_ALL_STATIONS(st) { + for (const Station *st : Station::Iterate()) { if (st->owner == owner || (st->owner == OWNER_NONE && HasStationInUse(st->index, true, owner))) { if (this->facilities & st->facilities) { // only stations with selected facilities int num_waiting_cargo = 0; @@ -189,105 +236,93 @@ protected: if (st->goods[j].HasRating()) { num_waiting_cargo++; // count number of waiting cargo if (HasBit(this->cargo_filter, j)) { - *this->stations.Append() = st; + this->stations.push_back(st); break; } } } /* stations without waiting cargo */ if (num_waiting_cargo == 0 && this->include_empty) { - *this->stations.Append() = st; + this->stations.push_back(st); } } } } - this->stations.Compact(); + this->stations.shrink_to_fit(); this->stations.RebuildDone(); - this->vscroll->SetCount(this->stations.Length()); // Update the scrollbar + this->vscroll->SetCount((uint)this->stations.size()); // Update the scrollbar } /** Sort stations by their name */ - static int CDECL StationNameSorter(const Station * const *a, const Station * const *b) + static bool StationNameSorter(const Station * const &a, const Station * const &b) { - static char buf_cache[64]; - char buf[64]; - - SetDParam(0, (*a)->index); - GetString(buf, STR_STATION_NAME, lastof(buf)); - - if (*b != last_station) { - last_station = *b; - SetDParam(0, (*b)->index); - GetString(buf_cache, STR_STATION_NAME, lastof(buf_cache)); - } - - int r = strnatcmp(buf, buf_cache); // Sort by name (natural sorting). - if (r == 0) return (*a)->index - (*b)->index; - return r; + int r = strnatcmp(a->GetCachedName(), b->GetCachedName()); // Sort by name (natural sorting). + if (r == 0) return a->index < b->index; + return r < 0; } /** Sort stations by their type */ - static int CDECL StationTypeSorter(const Station * const *a, const Station * const *b) + static bool StationTypeSorter(const Station * const &a, const Station * const &b) { - return (*a)->facilities - (*b)->facilities; + return a->facilities < b->facilities; } /** Sort stations by their waiting cargo */ - static int CDECL StationWaitingTotalSorter(const Station * const *a, const Station * const *b) + static bool StationWaitingTotalSorter(const Station * const &a, const Station * const &b) { int diff = 0; CargoID j; FOR_EACH_SET_CARGO_ID(j, cargo_filter) { - diff += (*a)->goods[j].cargo.TotalCount() - (*b)->goods[j].cargo.TotalCount(); + diff += a->goods[j].cargo.TotalCount() - b->goods[j].cargo.TotalCount(); } - return diff; + return diff < 0; } /** Sort stations by their available waiting cargo */ - static int CDECL StationWaitingAvailableSorter(const Station * const *a, const Station * const *b) + static bool StationWaitingAvailableSorter(const Station * const &a, const Station * const &b) { int diff = 0; CargoID j; FOR_EACH_SET_CARGO_ID(j, cargo_filter) { - diff += (*a)->goods[j].cargo.AvailableCount() - (*b)->goods[j].cargo.AvailableCount(); + diff += a->goods[j].cargo.AvailableCount() - b->goods[j].cargo.AvailableCount(); } - return diff; + return diff < 0; } /** Sort stations by their rating */ - static int CDECL StationRatingMaxSorter(const Station * const *a, const Station * const *b) + static bool StationRatingMaxSorter(const Station * const &a, const Station * const &b) { byte maxr1 = 0; byte maxr2 = 0; CargoID j; FOR_EACH_SET_CARGO_ID(j, cargo_filter) { - if ((*a)->goods[j].HasRating()) maxr1 = max(maxr1, (*a)->goods[j].rating); - if ((*b)->goods[j].HasRating()) maxr2 = max(maxr2, (*b)->goods[j].rating); + if (a->goods[j].HasRating()) maxr1 = max(maxr1, a->goods[j].rating); + if (b->goods[j].HasRating()) maxr2 = max(maxr2, b->goods[j].rating); } - return maxr1 - maxr2; + return maxr1 < maxr2; } /** Sort stations by their rating */ - static int CDECL StationRatingMinSorter(const Station * const *a, const Station * const *b) + static bool StationRatingMinSorter(const Station * const &a, const Station * const &b) { byte minr1 = 255; byte minr2 = 255; for (CargoID j = 0; j < NUM_CARGO; j++) { if (!HasBit(cargo_filter, j)) continue; - if ((*a)->goods[j].HasRating()) minr1 = min(minr1, (*a)->goods[j].rating); - if ((*b)->goods[j].HasRating()) minr2 = min(minr2, (*b)->goods[j].rating); + if (a->goods[j].HasRating()) minr1 = min(minr1, a->goods[j].rating); + if (b->goods[j].HasRating()) minr2 = min(minr2, b->goods[j].rating); } - return -(minr1 - minr2); + return minr1 > minr2; } /** Sort the stations list */ @@ -295,9 +330,6 @@ protected: { if (!this->stations.Sort()) return; - /* Reset name sorter sort cache */ - this->last_station = NULL; - /* Set the modified widget dirty */ this->SetWidgetDirty(WID_STL_LIST); } @@ -337,7 +369,7 @@ public: this->last_sorting = this->stations.GetListing(); } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_STL_SORTBY: { @@ -393,7 +425,7 @@ public: } } - virtual void OnPaint() + void OnPaint() override { this->BuildStationsList((Owner)this->window_number); this->SortStationsList(); @@ -401,7 +433,7 @@ public: this->DrawWidgets(); } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { switch (widget) { case WID_STL_SORTBY: @@ -411,7 +443,7 @@ public: case WID_STL_LIST: { bool rtl = _current_text_dir == TD_RTL; - int max = min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->stations.Length()); + int max = min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), (uint)this->stations.size()); uint line_height = GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL); int y = Center(r.top + WD_FRAMERECT_TOP, line_height); for (int i = this->vscroll->GetPosition(); i < max; ++i) { // do until max number of stations of owner @@ -488,7 +520,7 @@ public: } } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { if (widget == WID_STL_CAPTION) { SetDParam(0, this->window_number); @@ -496,12 +528,12 @@ public: } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_STL_LIST: { uint id_v = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_STL_LIST, 0, this->resize.step_height); - if (id_v >= this->stations.Length()) return; // click out of list bound + if (id_v >= this->stations.size()) return; // click out of list bound const Station *st = this->stations[id_v]; /* do not check HasStationInUse - it is slow and may be invalid */ @@ -612,7 +644,7 @@ public: } } - virtual void OnDropdownSelect(int widget, int index) + void OnDropdownSelect(int widget, int index) override { if (this->stations.SortType() != index) { this->stations.SetSortType(index); @@ -624,7 +656,7 @@ public: } } - virtual void OnGameTick() + void OnGameTick() override { if (this->stations.NeedResort()) { DEBUG(misc, 3, "Periodic rebuild station list company %d", this->window_number); @@ -632,7 +664,7 @@ public: } } - virtual void OnResize() + void OnResize() override { this->vscroll->SetCapacityFromWidget(this, WID_STL_LIST, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM); } @@ -642,7 +674,7 @@ public: * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + 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 */ @@ -658,7 +690,6 @@ byte CompanyStationsWindow::facilities = FACIL_TRAIN | FACIL_TRUCK_STOP | FACIL_ bool CompanyStationsWindow::include_empty = true; const CargoTypes CompanyStationsWindow::cargo_filter_max = ALL_CARGOTYPES; CargoTypes CompanyStationsWindow::cargo_filter = ALL_CARGOTYPES; -const Station *CompanyStationsWindow::last_station = NULL; /* Available station sorting functions */ GUIStationList::SortFunction * const CompanyStationsWindow::sorter_funcs[] = { @@ -788,6 +819,7 @@ static const NWidgetPart _nested_station_view_widgets[] = { EndContainer(), NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SV_CLOSE_AIRPORT), SetMinimalSize(45, 12), SetResize(1, 0), SetFill(1, 1), SetDataTip(STR_STATION_VIEW_CLOSE_AIRPORT, STR_STATION_VIEW_CLOSE_AIRPORT_TOOLTIP), + NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_SV_CATCHMENT), SetMinimalSize(14, 12), SetFill(0, 1), SetDataTip(STR_BUTTON_CATCHMENT, STR_TOOLTIP_CATCHMENT), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SV_TRAINS), SetMinimalSize(14, 12), SetFill(0, 1), SetDataTip(STR_TRAIN, STR_STATION_VIEW_SCHEDULED_TRAINS_TOOLTIP), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SV_ROADVEHS), SetMinimalSize(14, 12), SetFill(0, 1), SetDataTip(STR_LORRY, STR_STATION_VIEW_SCHEDULED_ROAD_VEHICLES_TOOLTIP), NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SV_SHIPS), SetMinimalSize(14, 12), SetFill(0, 1), SetDataTip(STR_SHIP, STR_STATION_VIEW_SCHEDULED_SHIPS_TOOLTIP), @@ -906,9 +938,9 @@ public: } /** - * Retrieve a child for the given station. Return NULL if it doesn't exist. + * Retrieve a child for the given station. Return nullptr if it doesn't exist. * @param station ID of the station the child we're looking for is associated with. - * @return a child entry for the given station or NULL. + * @return a child entry for the given station or nullptr. */ CargoDataEntry *Retrieve(StationID station) const { @@ -917,9 +949,9 @@ public: } /** - * Retrieve a child for the given cargo. Return NULL if it doesn't exist. + * Retrieve a child for the given cargo. Return nullptr if it doesn't exist. * @param cargo ID of the cargo the child we're looking for is associated with. - * @return a child entry for the given cargo or NULL. + * @return a child entry for the given cargo or nullptr. */ CargoDataEntry *Retrieve(CargoID cargo) const { @@ -1004,7 +1036,7 @@ private: }; CargoDataEntry::CargoDataEntry() : - parent(NULL), + parent(nullptr), station(INVALID_STATION), num_children(0), count(0), @@ -1028,19 +1060,19 @@ CargoDataEntry::CargoDataEntry(StationID station, uint count, CargoDataEntry *pa {} CargoDataEntry::CargoDataEntry(StationID station) : - parent(NULL), + parent(nullptr), station(station), num_children(0), count(0), - children(NULL) + children(nullptr) {} CargoDataEntry::CargoDataEntry(CargoID cargo) : - parent(NULL), + parent(nullptr), cargo(cargo), num_children(0), count(0), - children(NULL) + children(nullptr) {} CargoDataEntry::~CargoDataEntry() @@ -1054,14 +1086,14 @@ CargoDataEntry::~CargoDataEntry() */ void CargoDataEntry::Clear() { - if (this->children != NULL) { + if (this->children != nullptr) { for (CargoDataSet::iterator i = this->children->begin(); i != this->children->end(); ++i) { assert(*i != this); delete *i; } this->children->clear(); } - if (this->parent != NULL) this->parent->count -= this->count; + if (this->parent != nullptr) this->parent->count -= this->count; this->count = 0; this->num_children = 0; } @@ -1110,7 +1142,7 @@ CargoDataEntry *CargoDataEntry::InsertOrRetrieve(Tid child_id) void CargoDataEntry::Update(uint count) { this->count += count; - if (this->parent != NULL) this->parent->Update(count); + if (this->parent != nullptr) this->parent->Update(count); } /** @@ -1119,7 +1151,7 @@ void CargoDataEntry::Update(uint count) void CargoDataEntry::IncrementSize() { ++this->num_children; - if (this->parent != NULL) this->parent->IncrementSize(); + if (this->parent != nullptr) this->parent->IncrementSize(); } void CargoDataEntry::Resort(CargoSortType type, SortOrder order) @@ -1132,7 +1164,7 @@ void CargoDataEntry::Resort(CargoSortType type, SortOrder order) CargoDataEntry *CargoDataEntry::Retrieve(CargoDataSet::iterator i) const { if (i == this->children->end()) { - return NULL; + return nullptr; } else { assert(this->children->value_comp().GetSortType() != ST_COUNT); return *i; @@ -1176,21 +1208,13 @@ bool CargoSorter::SortCount(const CargoDataEntry *cd1, const CargoDataEntry *cd2 bool CargoSorter::SortStation(StationID st1, StationID st2) const { - static char buf1[MAX_LENGTH_STATION_NAME_CHARS]; - static char buf2[MAX_LENGTH_STATION_NAME_CHARS]; - if (!Station::IsValidID(st1)) { return Station::IsValidID(st2) ? this->order == SO_ASCENDING : this->SortId(st1, st2); } else if (!Station::IsValidID(st2)) { return order == SO_DESCENDING; } - SetDParam(0, st1); - GetString(buf1, STR_STATION_NAME, lastof(buf1)); - SetDParam(0, st2); - GetString(buf2, STR_STATION_NAME, lastof(buf2)); - - int res = strnatcmp(buf1, buf2); // Sort by name (natural sorting). + int res = strnatcmp(Station::Get(st1)->GetCachedName(), Station::Get(st2)->GetCachedName()); // Sort by name (natural sorting). if (res == 0) { return this->SortId(st1, st2); } else { @@ -1316,6 +1340,8 @@ struct StationViewWindow : public Window { DeleteWindowById(WC_ROADVEH_LIST, VehicleListIdentifier(VL_STATION_LIST, VEH_ROAD, this->owner, this->window_number).Pack(), false); DeleteWindowById(WC_SHIPS_LIST, VehicleListIdentifier(VL_STATION_LIST, VEH_SHIP, this->owner, this->window_number).Pack(), false); DeleteWindowById(WC_AIRCRAFT_LIST, VehicleListIdentifier(VL_STATION_LIST, VEH_AIRCRAFT, this->owner, this->window_number).Pack(), false); + + SetViewportCatchmentStation(Station::Get(this->window_number), false); } /** @@ -1333,7 +1359,7 @@ struct StationViewWindow : public Window { if (count == 0) return; bool auto_distributed = _settings_game.linkgraph.GetDistributionType(cargo) != DT_MANUAL; const CargoDataEntry *expand = &this->expanded_rows; - for (int i = 0; i < NUM_COLUMNS && expand != NULL; ++i) { + for (int i = 0; i < NUM_COLUMNS && expand != nullptr; ++i) { switch (groupings[i]) { case GR_CARGO: assert(i == 0); @@ -1364,7 +1390,7 @@ struct StationViewWindow : public Window { data->Update(count); } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_SV_WAITING: @@ -1394,7 +1420,7 @@ struct StationViewWindow : public Window { } } - virtual void OnPaint() + void OnPaint() override { const Station *st = Station::Get(this->window_number); CargoDataEntry cargo; @@ -1411,6 +1437,10 @@ struct StationViewWindow : public Window { this->SetWidgetDisabledState(WID_SV_CLOSE_AIRPORT, !(st->facilities & FACIL_AIRPORT) || st->owner != _local_company || st->owner == OWNER_NONE); // Also consider SE, where _local_company == OWNER_NONE this->SetWidgetLoweredState(WID_SV_CLOSE_AIRPORT, (st->facilities & FACIL_AIRPORT) && (st->airport.flags & AIRPORT_CLOSED_block) != 0); + extern const Station *_viewport_highlight_station; + this->SetWidgetDisabledState(WID_SV_CATCHMENT, st->facilities == FACIL_NONE); + this->SetWidgetLoweredState(WID_SV_CATCHMENT, _viewport_highlight_station == st); + this->DrawWidgets(); if (!this->IsShaded()) { @@ -1450,7 +1480,7 @@ struct StationViewWindow : public Window { } } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { const Station *st = Station::Get(this->window_number); SetDParam(0, st->index); @@ -1580,13 +1610,13 @@ struct StationViewWindow : public Window { StationID next = it.GetKey(); const CargoDataEntry *source_entry = source_dest->Retrieve(cp->SourceStation()); - if (source_entry == NULL) { + if (source_entry == nullptr) { this->ShowCargo(cargo, i, cp->SourceStation(), next, INVALID_STATION, cp->Count()); continue; } const CargoDataEntry *via_entry = source_entry->Retrieve(next); - if (via_entry == NULL) { + if (via_entry == nullptr) { this->ShowCargo(cargo, i, cp->SourceStation(), next, INVALID_STATION, cp->Count()); continue; } @@ -1609,7 +1639,7 @@ struct StationViewWindow : public Window { { for (CargoID i = 0; i < NUM_CARGO; i++) { - if (this->cached_destinations.Retrieve(i) == NULL) { + if (this->cached_destinations.Retrieve(i) == nullptr) { this->RecalcDestinations(i); } @@ -1629,13 +1659,13 @@ struct StationViewWindow : public Window { { std::list stations; const CargoDataEntry *parent = data->GetParent(); - if (parent->GetParent() == NULL) { + if (parent->GetParent() == nullptr) { this->displayed_rows.push_back(RowDisplay(&this->expanded_rows, data->GetCargo())); return; } StationID next = data->GetStation(); - while (parent->GetParent()->GetParent() != NULL) { + while (parent->GetParent()->GetParent() != nullptr) { stations.push_back(parent->GetStation()); parent = parent->GetParent(); } @@ -1773,7 +1803,7 @@ struct StationViewWindow : public Window { DrawString(text_left, text_right, y, str); if (column < NUM_COLUMNS - 1) { - const char *sym = NULL; + const char *sym = nullptr; if (cd->GetNumChildren() > 0) { sym = "-"; } else if (auto_distributed && str != STR_STATION_VIEW_RESERVED) { @@ -1841,7 +1871,7 @@ struct StationViewWindow : public Window { const LinkGraph *lg = LinkGraph::GetIfValid(ge->link_graph); SetDParam(0, cs->name); - SetDParam(1, lg != NULL ? 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); @@ -1858,7 +1888,7 @@ struct StationViewWindow : public Window { template void HandleCargoWaitingClick(CargoDataEntry *filter, Tid next) { - if (filter->Retrieve(next) != NULL) { + if (filter->Retrieve(next) != nullptr) { filter->Remove(next); } else { filter->InsertOrRetrieve(next); @@ -1885,13 +1915,17 @@ struct StationViewWindow : public Window { this->SetWidgetDirty(WID_SV_WAITING); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_SV_WAITING: this->HandleCargoWaitingClick(this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SV_WAITING, WD_FRAMERECT_TOP, FONT_HEIGHT_NORMAL) - this->vscroll->GetPosition()); break; + case WID_SV_CATCHMENT: + SetViewportCatchmentStation(Station::Get(this->window_number), !this->IsWidgetLowered(WID_SV_CATCHMENT)); + break; + case WID_SV_LOCATION: if (_ctrl_pressed) { ShowExtraViewPortWindow(Station::Get(this->window_number)->xy); @@ -2046,7 +2080,7 @@ struct StationViewWindow : public Window { this->SetDirty(); } - virtual void OnDropdownSelect(int widget, int index) + void OnDropdownSelect(int widget, int index) override { if (widget == WID_SV_SORT_BY) { this->SelectSortBy(index); @@ -2055,14 +2089,14 @@ struct StationViewWindow : public Window { } } - virtual void OnQueryTextFinished(char *str) + void OnQueryTextFinished(char *str) override { - if (str == NULL) return; + if (str == nullptr) return; - DoCommandP(0, this->window_number, 0, CMD_RENAME_STATION | CMD_MSG(STR_ERROR_CAN_T_RENAME_STATION), NULL, str); + DoCommandP(0, this->window_number, 0, CMD_RENAME_STATION | CMD_MSG(STR_ERROR_CAN_T_RENAME_STATION), nullptr, str); } - virtual void OnResize() + void OnResize() override { this->vscroll->SetCapacityFromWidget(this, WID_SV_WAITING, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM); } @@ -2072,7 +2106,7 @@ struct StationViewWindow : public Window { * @param data Information about the changed data. If it's a valid cargo ID, invalidate the cargo 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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (gui_scope) { if (data >= 0 && data < NUM_CARGO) { @@ -2125,8 +2159,8 @@ struct TileAndStation { StationID station; ///< StationID }; -static SmallVector _deleted_stations_nearby; -static SmallVector _stations_nearby_list; +static std::vector _deleted_stations_nearby; +static std::vector _stations_nearby_list; /** * Add station on this tile to _stations_nearby_list if it's fully within the @@ -2141,11 +2175,11 @@ static bool AddNearbyStation(TileIndex tile, void *user_data) TileArea *ctx = (TileArea *)user_data; /* First check if there were deleted stations here */ - for (uint i = 0; i < _deleted_stations_nearby.Length(); i++) { - TileAndStation *ts = _deleted_stations_nearby.Get(i); + for (uint i = 0; i < _deleted_stations_nearby.size(); i++) { + auto ts = _deleted_stations_nearby.begin() + i; if (ts->tile == tile) { - *_stations_nearby_list.Append() = _deleted_stations_nearby[i].station; - _deleted_stations_nearby.Erase(ts); + _stations_nearby_list.push_back(_deleted_stations_nearby[i].station); + _deleted_stations_nearby.erase(ts); i--; } } @@ -2159,10 +2193,10 @@ static bool AddNearbyStation(TileIndex tile, void *user_data) if (!T::IsValidID(sid)) return false; T *st = T::Get(sid); - if (st->owner != _local_company || _stations_nearby_list.Contains(sid)) return false; + if (st->owner != _local_company || std::find(_stations_nearby_list.begin(), _stations_nearby_list.end(), sid) != _stations_nearby_list.end()) return false; if (st->rect.BeforeAddRect(ctx->tile, ctx->w, ctx->h, StationRect::ADD_TEST).Succeeded()) { - *_stations_nearby_list.Append() = sid; + _stations_nearby_list.push_back(sid); } return false; // We want to include *all* nearby stations @@ -2182,8 +2216,8 @@ static const T *FindStationsNearby(TileArea ta, bool distant_join) { TileArea ctx = ta; - _stations_nearby_list.Clear(); - _deleted_stations_nearby.Clear(); + _stations_nearby_list.clear(); + _deleted_stations_nearby.clear(); /* Check the inside, to return, if we sit on another station */ TILE_AREA_LOOP(t, ta) { @@ -2191,14 +2225,11 @@ static const T *FindStationsNearby(TileArea ta, bool distant_join) } /* Look for deleted stations */ - const BaseStation *st; - FOR_ALL_BASE_STATIONS(st) { + for (const BaseStation *st : BaseStation::Iterate()) { if (T::IsExpected(st) && !st->IsInUse() && st->owner == _local_company) { /* Include only within station spread (yes, it is strictly less than) */ if (max(DistanceMax(ta.tile, st->xy), DistanceMax(TILE_ADDXY(ta.tile, ta.w - 1, ta.h - 1), st->xy)) < _settings_game.station.station_spread) { - TileAndStation *ts = _deleted_stations_nearby.Append(); - ts->tile = st->xy; - ts->station = st->index; + _deleted_stations_nearby.push_back({st->xy, st->index}); /* Add the station when it's within where we're going to build */ if (IsInsideBS(TileX(st->xy), TileX(ctx.tile), ctx.w) && @@ -2212,13 +2243,13 @@ static const T *FindStationsNearby(TileArea ta, bool distant_join) /* Only search tiles where we have a chance to stay within the station spread. * The complete check needs to be done in the callback as we don't know the * extent of the found station, yet. */ - if (distant_join && min(ta.w, ta.h) >= _settings_game.station.station_spread) return NULL; + if (distant_join && min(ta.w, ta.h) >= _settings_game.station.station_spread) return nullptr; uint max_dist = distant_join ? _settings_game.station.station_spread - min(ta.w, ta.h) : 1; TileIndex tile = TileAddByDir(ctx.tile, DIR_N); CircularTileSearch(&tile, max_dist, ta.w, ta.h, AddNearbyStation, &ctx); - return NULL; + return nullptr; } static const NWidgetPart _nested_select_station_widgets[] = { @@ -2256,15 +2287,24 @@ struct SelectStationWindow : Window { this->GetWidget(WID_JS_CAPTION)->widget_data = T::EXPECTED_FACIL == FACIL_WAYPOINT ? STR_JOIN_WAYPOINT_CAPTION : STR_JOIN_STATION_CAPTION; this->FinishInitNested(0); this->OnInvalidateData(0); + + _thd.freeze = true; } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + ~SelectStationWindow() + { + if (_settings_client.gui.station_show_coverage) SetViewportCatchmentStation(nullptr, true); + + _thd.freeze = false; + } + + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { if (widget != WID_JS_PANEL) return; /* Determine the widest string */ Dimension d = GetStringBoundingBox(T::EXPECTED_FACIL == FACIL_WAYPOINT ? STR_JOIN_WAYPOINT_CREATE_SPLITTED_WAYPOINT : STR_JOIN_STATION_CREATE_SPLITTED_STATION); - for (uint i = 0; i < _stations_nearby_list.Length(); i++) { + for (uint i = 0; i < _stations_nearby_list.size(); i++) { const T *st = T::Get(_stations_nearby_list[i]); SetDParam(0, st->index); SetDParam(1, st->facilities); @@ -2278,7 +2318,7 @@ struct SelectStationWindow : Window { *size = d; } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { if (widget != WID_JS_PANEL) return; @@ -2288,7 +2328,7 @@ struct SelectStationWindow : Window { y += this->resize.step_height; } - for (uint i = max(1, this->vscroll->GetPosition()); i <= _stations_nearby_list.Length(); ++i, y += this->resize.step_height) { + for (uint i = max(1, this->vscroll->GetPosition()); i <= _stations_nearby_list.size(); ++i, y += 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; @@ -2299,7 +2339,7 @@ struct SelectStationWindow : Window { } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { if (widget != WID_JS_PANEL) return; @@ -2307,7 +2347,7 @@ struct SelectStationWindow : Window { bool distant_join = (st_index > 0); if (distant_join) st_index--; - if (distant_join && st_index >= _stations_nearby_list.Length()) return; + if (distant_join && st_index >= _stations_nearby_list.size()) return; /* Insert station to be joined into stored command */ SB(this->select_station_cmd.p2, 16, 16, @@ -2320,7 +2360,7 @@ struct SelectStationWindow : Window { DeleteWindowById(WC_SELECT_STATION, 0); } - virtual void OnRealtimeTick(uint delta_ms) + void OnRealtimeTick(uint delta_ms) override { if (_thd.dirty & 2) { _thd.dirty &= ~2; @@ -2328,7 +2368,7 @@ struct SelectStationWindow : Window { } } - virtual void OnResize() + void OnResize() override { this->vscroll->SetCapacityFromWidget(this, WID_JS_PANEL, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM); } @@ -2338,13 +2378,30 @@ struct SelectStationWindow : Window { * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; FindStationsNearby(this->area, true); - this->vscroll->SetCount(_stations_nearby_list.Length() + 1); + this->vscroll->SetCount((uint)_stations_nearby_list.size() + 1); this->SetDirty(); } + + void OnMouseOver(Point pt, int widget) override + { + if (widget != WID_JS_PANEL || T::EXPECTED_FACIL == FACIL_WAYPOINT) { + SetViewportCatchmentStation(nullptr, true); + return; + } + + /* Show coverage area of station under cursor */ + uint st_index = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_JS_PANEL, WD_FRAMERECT_TOP); + if (st_index == 0 || st_index > _stations_nearby_list.size()) { + SetViewportCatchmentStation(nullptr, true); + } else { + st_index--; + SetViewportCatchmentStation(Station::Get(_stations_nearby_list[st_index]), true); + } + } }; static WindowDesc _select_station_desc( @@ -2371,7 +2428,7 @@ static bool StationJoinerNeeded(const CommandContainer &cmd, TileArea ta) /* If a window is already opened and we didn't ctrl-click, * return true (i.e. just flash the old window) */ Window *selection_window = FindWindowById(WC_SELECT_STATION, 0); - if (selection_window != NULL) { + if (selection_window != nullptr) { /* Abort current distant-join and start new one */ delete selection_window; UpdateTileSelection(); @@ -2387,7 +2444,7 @@ static bool StationJoinerNeeded(const CommandContainer &cmd, TileArea ta) * If adjacent-stations is disabled and we are building next to a station, do not show the selection window. * but join the other station immediately. */ const T *st = FindStationsNearby(ta, false); - return st == NULL && (_settings_game.station.adjacent_stations || _stations_nearby_list.Length() == 0); + return st == nullptr && (_settings_game.station.adjacent_stations || _stations_nearby_list.size() == 0); } /** diff --git a/src/station_gui.h b/src/station_gui.h index 6640856246..ac2fa2fc32 100644 --- a/src/station_gui.h +++ b/src/station_gui.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/station_kdtree.h b/src/station_kdtree.h new file mode 100644 index 0000000000..321bbacc6f --- /dev/null +++ b/src/station_kdtree.h @@ -0,0 +1,42 @@ +/* + * 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 station_kdtree.h Declarations for accessing the k-d tree of stations */ + +#ifndef STATION_KDTREE_H +#define STATION_KDTREE_H + +#include "core/kdtree.hpp" +#include "core/math_func.hpp" +#include "station_base.h" +#include "map_func.h" + +inline uint16 Kdtree_StationXYFunc(StationID stid, int dim) { return (dim == 0) ? TileX(BaseStation::Get(stid)->xy) : TileY(BaseStation::Get(stid)->xy); } +typedef Kdtree StationKdtree; +extern StationKdtree _station_kdtree; + +/** + * Call a function on all stations whose sign is within a radius of a center tile. + * @param center Central tile to search around. + * @param radius Distance in both X and Y to search within. + * @param func The function to call, must take a single parameter which is Station*. + */ +template +void ForAllStationsRadius(TileIndex center, uint radius, Func func) +{ + uint16 x1, y1, x2, y2; + x1 = (uint16)max(0, TileX(center) - radius); + x2 = (uint16)min(TileX(center) + radius + 1, MapSizeX()); + y1 = (uint16)max(0, TileY(center) - radius); + y2 = (uint16)min(TileY(center) + radius + 1, MapSizeY()); + + _station_kdtree.FindContained(x1, y1, x2, y2, [&](StationID id) { + func(Station::Get(id)); + }); +} + +#endif diff --git a/src/station_map.h b/src/station_map.h index e591787e3b..dbb00ef2f5 100644 --- a/src/station_map.h +++ b/src/station_map.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. @@ -17,6 +15,7 @@ #include "water_map.h" #include "station_func.h" #include "rail.h" +#include "road.h" typedef byte StationGfx; ///< Index of station graphics. @see _station_display_datas @@ -535,6 +534,7 @@ static inline void MakeStation(TileIndex t, Owner o, StationID sid, StationType 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; @@ -583,15 +583,16 @@ static inline void MakeRailWaypoint(TileIndex t, Owner o, StationID sid, Axis a, * @param o the owner of the roadstop * @param sid the station to which this tile belongs * @param rst the type of roadstop to make this tile - * @param rt the roadtypes on this tile + * @param road_rt the road roadtype on this tile + * @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, RoadTypes rt, DiagDirection d) +static inline void MakeRoadStop(TileIndex 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, rt); - SetRoadOwner(t, ROADTYPE_ROAD, o); - SetRoadOwner(t, ROADTYPE_TRAM, o); + SetRoadTypes(t, road_rt, tram_rt); + SetRoadOwner(t, RTT_ROAD, o); + SetRoadOwner(t, RTT_TRAM, o); } /** @@ -602,15 +603,16 @@ static inline void MakeRoadStop(TileIndex t, Owner o, StationID sid, RoadStopTyp * @param tram the owner of the tram * @param sid the station to which this tile belongs * @param rst the type of roadstop to make this tile - * @param rt the roadtypes on this tile + * @param road_rt the road roadtype on this tile + * @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, RoadTypes rt, Axis a) +static inline void MakeDriveThroughRoadStop(TileIndex 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, rt); - SetRoadOwner(t, ROADTYPE_ROAD, road); - SetRoadOwner(t, ROADTYPE_TRAM, tram); + SetRoadTypes(t, road_rt, tram_rt); + SetRoadOwner(t, RTT_ROAD, road); + SetRoadOwner(t, RTT_TRAM, tram); } /** diff --git a/src/station_type.h b/src/station_type.h index 495e95a082..36ce7c3ce7 100644 --- a/src/station_type.h +++ b/src/station_type.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. @@ -12,9 +10,9 @@ #ifndef STATION_TYPE_H #define STATION_TYPE_H -#include "core/smallvec_type.hpp" #include "core/smallstack_type.hpp" #include "tilearea_type.h" +#include typedef uint16 StationID; typedef uint16 RoadStopID; @@ -49,7 +47,7 @@ enum RoadStopType { }; /** The facilities a station might be having */ -enum StationFacility { +enum StationFacility : byte { FACIL_NONE = 0, ///< The station has no facilities at all FACIL_TRAIN = 1 << 0, ///< Station with train station FACIL_TRUCK_STOP = 1 << 1, ///< Station with truck stops @@ -59,10 +57,9 @@ enum StationFacility { FACIL_WAYPOINT = 1 << 7, ///< Station is a waypoint }; DECLARE_ENUM_AS_BIT_SET(StationFacility) -typedef SimpleTinyEnumT StationFacilityByte; /** The vehicles that may have visited a station */ -enum StationHadVehicleOfType { +enum StationHadVehicleOfType : byte { HVOT_NONE = 0, ///< Station has seen no vehicles HVOT_TRAIN = 1 << 1, ///< Station has seen a train HVOT_BUS = 1 << 2, ///< Station has seen a bus @@ -73,7 +70,6 @@ enum StationHadVehicleOfType { HVOT_WAYPOINT = 1 << 6, ///< Station is a waypoint (NewGRF only!) }; DECLARE_ENUM_AS_BIT_SET(StationHadVehicleOfType) -typedef SimpleTinyEnumT StationHadVehicleOfTypeByte; /** The different catchment areas used */ enum CatchmentArea { @@ -90,8 +86,12 @@ enum CatchmentArea { static const uint MAX_LENGTH_STATION_NAME_CHARS = 32; ///< The maximum length of a station name in characters including '\0' +struct StationCompare { + bool operator() (const Station *lhs, const Station *rhs) const; +}; + /** List of stations */ -typedef SmallVector StationList; +typedef std::set StationList; /** * Structure contains cached list of stations nearby. The list diff --git a/src/statusbar_gui.cpp b/src/statusbar_gui.cpp index 278f85d8b3..e3568a5794 100644 --- a/src/statusbar_gui.cpp +++ b/src/statusbar_gui.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. @@ -28,6 +26,7 @@ #include "core/geometry_func.hpp" #include "guitimer_func.h" #include "settings_gui.h" +#include "zoom_func.h" #include "widgets/statusbar_widget.h" @@ -100,18 +99,18 @@ struct StatusBarWindow : Window { PositionStatusbar(this); } - virtual Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number) + Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number) override { Point pt = { 0, _screen.height - sm_height }; return pt; } - virtual void FindWindowPlacementAndResize(int def_width, int def_height) + void FindWindowPlacementAndResize(int def_width, int def_height) override { Window::FindWindowPlacementAndResize(min(_toolbar_width, _screen.width - GetMinSizing(NWST_STEP) * 2), def_height); } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { Dimension d; switch (widget) { @@ -122,8 +121,7 @@ struct StatusBarWindow : Window { d = GetStringBoundingBox(STR_WHITE_DATE_LONG); int64 max_money = UINT32_MAX; - const Company *c; - FOR_ALL_COMPANIES(c) max_money = max(c->money, max_money); + for (const Company *c : Company::Iterate()) max_money = max(c->money, max_money); SetDParam(0, 100LL * max_money); d = maxdim(d, GetStringBoundingBox(STR_COMPANY_MONEY)); break; @@ -148,7 +146,7 @@ struct StatusBarWindow : Window { *size = maxdim(d, *size); } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { StringID str = INVALID_STRING_ID; @@ -162,7 +160,7 @@ struct StatusBarWindow : Window { case WID_S_RIGHT: { /* Draw company money, if any */ const Company *c = Company::GetIfValid(_local_company); - if (c != NULL) { + if (c != nullptr) { SetDParam(0, c->money); str = STR_COMPANY_MONEY; } @@ -176,10 +174,10 @@ struct StatusBarWindow : Window { } else if (_do_autosave) { str = STR_STATUSBAR_AUTOSAVE; } else if (_pause_mode != PM_UNPAUSED) { - str = STR_STATUSBAR_PAUSED; - } else if (this->ticker_scroll < TICKER_STOP && FindWindowById(WC_NEWS_WINDOW, 0) == NULL && _statusbar_news_item != NULL && _statusbar_news_item->string_id != 0) { + DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, STR_STATUSBAR_PAUSED, TC_FROMSTRING, SA_HOR_CENTER); + } else if (this->ticker_scroll < TICKER_STOP && FindWindowById(WC_NEWS_WINDOW, 0) == NULL && _statusbar_news_item != nullptr && _statusbar_news_item->string_id != 0) { /* Draw the scrolling news text */ - if (!DrawScrollingStatusText(_statusbar_news_item, 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), r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, r.bottom)) { InvalidateWindowData(WC_STATUS_BAR, 0, SBI_NEWS_DELETED); if (Company::IsValidID(_local_company)) { /* This is the default text */ @@ -212,7 +210,7 @@ struct StatusBarWindow : Window { * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; switch (data) { @@ -228,7 +226,7 @@ struct StatusBarWindow : Window { } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_S_MIDDLE: ShowLastNewsMessage(); break; @@ -237,7 +235,7 @@ struct StatusBarWindow : Window { } } - virtual void OnRealtimeTick(uint delta_ms) + void OnRealtimeTick(uint delta_ms) override { if (_pause_mode != PM_UNPAUSED) return; @@ -265,7 +263,7 @@ static const NWidgetPart _nested_main_status_widgets[] = { }; static WindowDesc _main_status_desc( - WDP_MANUAL, NULL, 0, 0, + WDP_MANUAL, nullptr, 0, 0, WC_STATUS_BAR, WC_NONE, WDF_NO_FOCUS, _nested_main_status_widgets, lengthof(_nested_main_status_widgets) @@ -277,7 +275,7 @@ static WindowDesc _main_status_desc( bool IsNewsTickerShown() { const StatusBarWindow *w = dynamic_cast(FindWindowById(WC_STATUS_BAR, 0)); - return w != NULL && w->ticker_scroll < StatusBarWindow::TICKER_STOP; + return w != nullptr && w->ticker_scroll < StatusBarWindow::TICKER_STOP; } /** diff --git a/src/statusbar_gui.h b/src/statusbar_gui.h index 574a75c73f..26503dbff1 100644 --- a/src/statusbar_gui.h +++ b/src/statusbar_gui.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/stdafx.h b/src/stdafx.h index 6e96e98fde..4fb84a956e 100644 --- a/src/stdafx.h +++ b/src/stdafx.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. @@ -16,22 +14,22 @@ #include "os/macosx/osx_stdafx.h" #endif /* __APPLE__ */ -#if defined(__BEOS__) || defined(__HAIKU__) +#if defined(__HAIKU__) #include #include #define _GNU_SOURCE #define TROUBLED_INTS - #include -#elif defined(__NDS__) - #include - #define TROUBLED_INTS +#endif + +#if defined(__HAIKU__) || defined(__CYGWIN__) +# include /* strncasecmp */ #endif /* It seems that we need to include stdint.h before anything else * We need INT64_MAX, which for most systems comes from stdint.h. However, MSVC - * does not have stdint.h and apparently neither does MorphOS. + * does not have stdint.h. * For OSX the inclusion is already done in osx_stdafx.h. */ -#if !defined(__APPLE__) && (!defined(_MSC_VER) || _MSC_VER >= 1600) && !defined(__MORPHOS__) +#if !defined(__APPLE__) && (!defined(_MSC_VER) || _MSC_VER >= 1600) #if defined(SUNOS) /* SunOS/Solaris does not have stdint.h, but inttypes.h defines everything * stdint.h defines and we need. */ @@ -86,6 +84,7 @@ #include #include #include +#include #ifndef SIZE_MAX #define SIZE_MAX ((size_t)-1) @@ -100,34 +99,10 @@ #define strcasecmp stricmp #endif -#if defined(SUNOS) || defined(HPUX) +#if defined(SUNOS) || defined(HPUX) || defined(__CYGWIN__) #include #endif -#if defined(__MORPHOS__) - /* MorphOS defines certain Amiga defines per default, we undefine them - * here to make the rest of source less messy and more clear what is - * required for morphos and what for AmigaOS */ - #if defined(amigaos) - #undef amigaos - #endif - #if defined(__amigaos__) - #undef __amigaos__ - # endif - #if defined(__AMIGA__) - #undef __AMIGA__ - #endif - #if defined(AMIGA) - #undef AMIGA - #endif - #if defined(amiga) - #undef amiga - #endif - /* Act like we already included this file, as it somehow gives linkage problems - * (mismatch linkage of C++ and C between this include and unistd.h). */ - #define CLIB_USERGROUP_PROTOS_H -#endif /* __MORPHOS__ */ - /* Stuff for GCC */ #if defined(__GNUC__) #define NORETURN __attribute__ ((noreturn)) @@ -163,7 +138,7 @@ #include #endif /* __WATCOMC__ */ -#if defined(__MINGW32__) || defined(__CYGWIN__) +#if defined(__MINGW32__) #include // alloca() #endif @@ -257,6 +232,13 @@ # if !defined(FT_EXPORT) # define FT_EXPORT( x ) extern "C" x CDECL # endif +# endif + + /* liblzma from vcpkg (before 5.2.4-2) used to patch lzma.h to define LZMA_API_STATIC for static builds */ +# if defined(WITH_LIBLZMA) +# if !defined(LZMA_API_STATIC) +# define LZMA_API_STATIC +# endif # endif #define strcasecmp stricmp @@ -269,15 +251,6 @@ #endif /* defined(_MSC_VER) */ -#if defined(DOS) - /* The DOS port does not have all signals/signal functions. */ - #define strsignal(sig) "" - /* Use 'no floating point' for bus errors; SIGBUS does not exist - * for DOS, SIGNOFP for other platforms. So it's fairly safe - * to interchange those. */ - #define SIGBUS SIGNOFP -#endif - /* NOTE: the string returned by these functions is only valid until the next * call to the same function and is not thread- or reentrancy-safe */ #if !defined(STRGEN) && !defined(SETTINGSGEN) @@ -319,29 +292,37 @@ /* MSVCRT of course has to have a different syntax for long long *sigh* */ #if defined(_MSC_VER) || defined(__MINGW32__) - #define OTTD_PRINTF64 "%I64d" - #define OTTD_PRINTFHEX64 "%I64x" - #define PRINTF_SIZE "%Iu" +# define OTTD_PRINTF64 "%I64d" +# define OTTD_PRINTFHEX64 "%I64x" +# define PRINTF_SIZE "%Iu" +# define PRINTF_SIZEX "%IX" #else - #define OTTD_PRINTF64 "%lld" - #define OTTD_PRINTFHEX64 "%llx" - #define PRINTF_SIZE "%zu" +# define OTTD_PRINTF64 "%lld" +# define OTTD_PRINTFHEX64 "%llx" +# define PRINTF_SIZE "%zu" +# define PRINTF_SIZEX "%zX" #endif typedef unsigned char byte; /* This is already defined in unix, but not in QNX Neutrino (6.x)*/ -#if (!defined(UNIX) && !defined(__CYGWIN__) && !defined(__BEOS__) && !defined(__HAIKU__) && !defined(__MORPHOS__)) || defined(__QNXNTO__) +#if (!defined(UNIX) && !defined(__HAIKU__)) || defined(__QNXNTO__) typedef unsigned int uint; #endif #if defined(TROUBLED_INTS) - /* NDS'/BeOS'/Haiku's types for uint32/int32 are based on longs, which causes - * trouble all over the place in OpenTTD. */ - #define uint32 uint32_ugly_hack - #define int32 int32_ugly_hack + /* Haiku's types for uint32/int32/uint64/int64 are different than what + * they are on other platforms; not in length, but how to print them. + * So make them more like the other platforms, to make printf() etc a + * little bit easier. */ +# define uint32 uint32_ugly_hack +# define int32 int32_ugly_hack +# define uint64 uint64_ugly_hack +# define int64 int64_ugly_hack typedef unsigned int uint32_ugly_hack; typedef signed int int32_ugly_hack; + typedef unsigned __int64 uint64_ugly_hack; + typedef signed __int64 int64_ugly_hack; #else typedef unsigned char uint8; typedef signed char int8; @@ -457,10 +438,7 @@ void NORETURN CDECL error(const char *str, ...) WARN_FORMAT(1, 2); #define OTTD_ASSERT #endif -#if defined(MORPHOS) || defined(__NDS__) || defined(__DJGPP__) - /* MorphOS and NDS don't have C++ conformant _stricmp... */ - #define _stricmp stricmp -#elif defined(OPENBSD) +#if defined(OPENBSD) /* OpenBSD uses strcasecmp(3) */ #define _stricmp strcasecmp #endif diff --git a/src/story.cpp b/src/story.cpp index 602dc27248..0d465fde85 100644 --- a/src/story.cpp +++ b/src/story.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. @@ -45,7 +43,7 @@ INSTANTIATE_POOL_METHODS(StoryPage) * @param tile The tile parameter of the DoCommand proc * @param reference The reference parameter of the DoCommand proc (p2) * @param text The text parameter of the DoCommand proc - * @return true, if and only if the given parameters are valid for the given page elment type and page id. + * @return true, if and only if the given parameters are valid for the given page element type and page id. */ static bool VerifyElementContentParameters(StoryPageID page_id, StoryPageElementType type, TileIndex tile, uint32 reference, const char *text) { @@ -124,7 +122,7 @@ CommandCost CmdCreateStoryPage(TileIndex tile, DoCommandFlag flags, uint32 p1, u s->date = _date; s->company = company; if (StrEmpty(text)) { - s->title = NULL; + s->title = nullptr; } else { s->title = stredup(text); } @@ -154,13 +152,12 @@ CommandCost CmdCreateStoryPageElement(TileIndex tile, DoCommandFlag flags, uint3 { if (!StoryPageElement::CanAllocateItem()) return CMD_ERROR; - StoryPageID page_id = (CompanyID)GB(p1, 0, 16); + StoryPageID page_id = (StoryPageID)GB(p1, 0, 16); StoryPageElementType type = Extract(p1); /* Allow at most 128 elements per page. */ uint16 element_count = 0; - StoryPageElement *iter; - FOR_ALL_STORY_PAGE_ELEMENTS(iter) { + for (StoryPageElement *iter : StoryPageElement::Iterate()) { if (iter->page == page_id) element_count++; } if (element_count >= 128) return CMD_ERROR; @@ -241,7 +238,7 @@ CommandCost CmdSetStoryPageTitle(TileIndex tile, DoCommandFlag flags, uint32 p1, StoryPage *p = StoryPage::Get(page_id); free(p->title); if (StrEmpty(text)) { - p->title = NULL; + p->title = nullptr; } else { p->title = stredup(text); } @@ -319,8 +316,7 @@ CommandCost CmdRemoveStoryPage(TileIndex tile, DoCommandFlag flags, uint32 p1, u if (flags & DC_EXEC) { StoryPage *p = StoryPage::Get(page_id); - StoryPageElement *pe; - FOR_ALL_STORY_PAGE_ELEMENTS(pe) { + for (StoryPageElement *pe : StoryPageElement::Iterate()) { if (pe->page == p->index) { delete pe; } diff --git a/src/story_base.h b/src/story_base.h index 3db1ba4a86..e82b9d6964 100644 --- a/src/story_base.h +++ b/src/story_base.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. @@ -27,7 +25,7 @@ extern uint32 _story_page_next_sort_value; /* * Each story page element is one of these types. */ -enum StoryPageElementType { +enum StoryPageElementType : byte { SPET_TEXT = 0, ///< A text element. SPET_LOCATION, ///< An element that references a tile along with a one-line text. SPET_GOAL, ///< An element that references a goal. @@ -37,7 +35,6 @@ enum StoryPageElementType { /** Define basic enum properties */ template <> struct EnumPropsT : MakeEnumPropsT {}; -typedef TinyEnumT StoryPageElementTypeByte; ///< typedefing-enumification of Direction /** * Struct about story page elements. @@ -47,7 +44,7 @@ typedef TinyEnumT StoryPageElementTypeByte; ///< typedefin struct StoryPageElement : StoryPageElementPool::PoolItem<&_story_page_element_pool> { uint32 sort_value; ///< A number that increases for every created story page element. Used for sorting. The id of a story page element is the pool index. StoryPageID page; ///< Id of the page which the page element belongs to - StoryPageElementTypeByte type; ///< Type of page element + StoryPageElementType type; ///< Type of page element uint32 referenced_id; ///< Id of referenced object (location, goal etc.) char *text; ///< Static content text of page element @@ -58,19 +55,16 @@ struct StoryPageElement : StoryPageElementPool::PoolItem<&_story_page_element_po inline StoryPageElement() { } /** - * (Empty) destructor has to be defined else operator delete might be called with NULL parameter + * (Empty) destructor has to be defined else operator delete might be called with nullptr parameter */ inline ~StoryPageElement() { free(this->text); } }; -#define FOR_ALL_STORY_PAGE_ELEMENTS_FROM(var, start) FOR_ALL_ITEMS_FROM(StoryPageElement, story_page_element_index, var, start) -#define FOR_ALL_STORY_PAGE_ELEMENTS(var) FOR_ALL_STORY_PAGE_ELEMENTS_FROM(var, 0) - /** Struct about stories, current and completed */ struct StoryPage : StoryPagePool::PoolItem<&_story_page_pool> { uint32 sort_value; ///< A number that increases for every created story page. Used for sorting. The id of a story page is the pool index. Date date; ///< Date when the page was created. - CompanyByte company; ///< StoryPage is for a specific company; INVALID_COMPANY if it is global + CompanyID company; ///< StoryPage is for a specific company; INVALID_COMPANY if it is global char *title; ///< Title of story page @@ -80,13 +74,12 @@ struct StoryPage : StoryPagePool::PoolItem<&_story_page_pool> { inline StoryPage() { } /** - * (Empty) destructor has to be defined else operator delete might be called with NULL parameter + * (Empty) destructor has to be defined else operator delete might be called with nullptr parameter */ inline ~StoryPage() { if (!this->CleaningPool()) { - StoryPageElement *spe; - FOR_ALL_STORY_PAGE_ELEMENTS(spe) { + for (StoryPageElement *spe : StoryPageElement::Iterate()) { if (spe->page == this->index) delete spe; } } @@ -94,8 +87,5 @@ struct StoryPage : StoryPagePool::PoolItem<&_story_page_pool> { } }; -#define FOR_ALL_STORY_PAGES_FROM(var, start) FOR_ALL_ITEMS_FROM(StoryPage, story_page_index, var, start) -#define FOR_ALL_STORY_PAGES(var) FOR_ALL_STORY_PAGES_FROM(var, 0) - #endif /* STORY_BASE_H */ diff --git a/src/story_gui.cpp b/src/story_gui.cpp index 003843310e..677d88bba8 100644 --- a/src/story_gui.cpp +++ b/src/story_gui.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. @@ -52,16 +50,15 @@ protected: void BuildStoryPageList() { if (this->story_pages.NeedRebuild()) { - this->story_pages.Clear(); + this->story_pages.clear(); - const StoryPage *p; - FOR_ALL_STORY_PAGES(p) { + for (const StoryPage *p : StoryPage::Iterate()) { if (this->IsPageAvailable(p)) { - *this->story_pages.Append() = p; + this->story_pages.push_back(p); } } - this->story_pages.Compact(); + this->story_pages.shrink_to_fit(); this->story_pages.RebuildDone(); } @@ -69,28 +66,27 @@ protected: } /** Sort story pages by order value. */ - static int CDECL PageOrderSorter(const StoryPage * const *a, const StoryPage * const *b) + static bool PageOrderSorter(const StoryPage * const &a, const StoryPage * const &b) { - return (*a)->sort_value - (*b)->sort_value; + return a->sort_value < b->sort_value; } /** (Re)Build story page element list. */ void BuildStoryPageElementList() { if (this->story_page_elements.NeedRebuild()) { - this->story_page_elements.Clear(); + this->story_page_elements.clear(); const StoryPage *p = GetSelPage(); - if (p != NULL) { - const StoryPageElement *pe; - FOR_ALL_STORY_PAGE_ELEMENTS(pe) { + if (p != nullptr) { + for (const StoryPageElement *pe : StoryPageElement::Iterate()) { if (pe->page == p->index) { - *this->story_page_elements.Append() = pe; + this->story_page_elements.push_back(pe); } } } - this->story_page_elements.Compact(); + this->story_page_elements.shrink_to_fit(); this->story_page_elements.RebuildDone(); } @@ -98,9 +94,9 @@ protected: } /** Sort story page elements by order value. */ - static int CDECL PageElementOrderSorter(const StoryPageElement * const *a, const StoryPageElement * const *b) + static bool PageElementOrderSorter(const StoryPageElement * const &a, const StoryPageElement * const &b) { - return (*a)->sort_value - (*b)->sort_value; + return a->sort_value < b->sort_value; } /* @@ -115,11 +111,11 @@ protected: /** * Get instance of selected page. - * @return Instance of selected page or NULL if no page is selected. + * @return Instance of selected page or nullptr if no page is selected. */ StoryPage *GetSelPage() const { - if (!_story_page_pool.IsValidID(selected_page_id)) return NULL; + if (!_story_page_pool.IsValidID(selected_page_id)) return nullptr; return _story_page_pool.Get(selected_page_id); } @@ -130,8 +126,7 @@ protected: int GetSelPageNum() const { int page_number = 0; - for (const StoryPage *const*iter = this->story_pages.Begin(); iter != this->story_pages.End(); iter++) { - const StoryPage *p = *iter; + for (const StoryPage *p : this->story_pages) { if (p->index == this->selected_page_id) { return page_number; } @@ -148,7 +143,7 @@ protected: /* Verify that the selected page exist. */ if (!_story_page_pool.IsValidID(this->selected_page_id)) return false; - return (*this->story_pages.Begin())->index == this->selected_page_id; + return this->story_pages.front()->index == this->selected_page_id; } /** @@ -159,8 +154,8 @@ protected: /* Verify that the selected page exist. */ if (!_story_page_pool.IsValidID(this->selected_page_id)) return false; - if (this->story_pages.Length() <= 1) return true; - const StoryPage *last = *(this->story_pages.End() - 1); + if (this->story_pages.size() <= 1) return true; + const StoryPage *last = this->story_pages.back(); return last->index == this->selected_page_id; } @@ -171,7 +166,7 @@ protected: { /* Generate generic title if selected page have no custom title. */ StoryPage *page = this->GetSelPage(); - if (page != NULL && page->title == NULL) { + if (page != nullptr && page->title == nullptr) { SetDParam(0, GetSelPageNum() + 1); GetString(selected_generic_title, STR_STORY_BOOK_GENERIC_PAGE_ITEM, lastof(selected_generic_title)); } @@ -194,11 +189,10 @@ protected: /* Find the last available page which is previous to the current selected page. */ const StoryPage *last_available; - last_available = NULL; - for (const StoryPage *const*iter = this->story_pages.Begin(); iter != this->story_pages.End(); iter++) { - const StoryPage *p = *iter; + last_available = nullptr; + for (const StoryPage *p : this->story_pages) { if (p->index == this->selected_page_id) { - if (last_available == NULL) return; // No previous page available. + if (last_available == nullptr) return; // No previous page available. this->SetSelectedPage(last_available->index); return; } @@ -214,12 +208,12 @@ protected: if (!_story_page_pool.IsValidID(this->selected_page_id)) return; /* Find selected page. */ - for (const StoryPage *const*iter = this->story_pages.Begin(); iter != this->story_pages.End(); iter++) { + for (auto iter = this->story_pages.begin(); iter != this->story_pages.end(); iter++) { const StoryPage *p = *iter; if (p->index == this->selected_page_id) { /* Select the page after selected page. */ iter++; - if (iter != this->story_pages.End()) { + if (iter != this->story_pages.end()) { this->SetSelectedPage((*iter)->index); } return; @@ -230,15 +224,14 @@ protected: /** * Builds the page selector drop down list. */ - DropDownList *BuildDropDownList() const + DropDownList BuildDropDownList() const { - DropDownList *list = new DropDownList(); + DropDownList list; uint16 page_num = 1; - for (const StoryPage *const*iter = this->story_pages.Begin(); iter != this->story_pages.End(); iter++) { - const StoryPage *p = *iter; + for (const StoryPage *p : this->story_pages) { bool current_page = p->index == this->selected_page_id; - DropDownListStringItem *item = NULL; - if (p->title != NULL) { + DropDownListStringItem *item = nullptr; + if (p->title != nullptr) { item = new DropDownListCharStringItem(p->title, p->index, current_page); } else { /* No custom title => use a generic page title with page number. */ @@ -248,16 +241,10 @@ protected: item = str_item; } - *list->Append() = item; + list.emplace_back(item); page_num++; } - /* Check if list is empty. */ - if (list->Length() == 0) { - delete list; - list = NULL; - } - return list; } @@ -272,19 +259,19 @@ protected: /** * Counts how many pixels of height that are used by Date and Title * (excluding marginal after Title, as each body element has - * an empty row before the elment). + * an empty row before the element). * @param max_width Available width to display content. * @return the height in pixels. */ uint GetHeadHeight(int max_width) const { StoryPage *page = this->GetSelPage(); - if (page == NULL) return 0; + if (page == nullptr) return 0; int height = 0; /* Title lines */ height += FONT_HEIGHT_NORMAL; // Date always use exactly one line. - SetDParamStr(0, page->title != NULL ? page->title : this->selected_generic_title); + SetDParamStr(0, page->title != nullptr ? page->title : this->selected_generic_title); height += GetStringHeight(STR_STORY_BOOK_TITLE, max_width); return height; @@ -301,7 +288,7 @@ protected: switch (pe.type) { case SPET_GOAL: { Goal *g = Goal::Get((GoalID) pe.referenced_id); - if (g == NULL) return SPR_IMG_GOAL_BROKEN_REF; + if (g == nullptr) return SPR_IMG_GOAL_BROKEN_REF; return g->completed ? SPR_IMG_GOAL_COMPLETED : SPR_IMG_GOAL; } case SPET_LOCATION: @@ -345,7 +332,7 @@ protected: uint GetContentHeight() { StoryPage *page = this->GetSelPage(); - if (page == NULL) return 0; + if (page == nullptr) return 0; int max_width = GetAvailablePageContentWidth(); uint element_vertical_dist = FONT_HEIGHT_NORMAL; @@ -353,8 +340,7 @@ protected: uint height = GetHeadHeight(max_width); /* Body */ - for (const StoryPageElement **iter = this->story_page_elements.Begin(); iter != this->story_page_elements.End(); iter++) { - const StoryPageElement *pe = *iter; + for (const StoryPageElement *pe : this->story_page_elements) { height += element_vertical_dist; height += GetPageElementHeight(*pe, max_width); } @@ -422,7 +408,7 @@ public: this->vscroll = this->GetScrollbar(WID_SB_SCROLLBAR); this->vscroll->SetStepSize(FONT_HEIGHT_NORMAL); - /* Initalize page sort. */ + /* Initialize page sort. */ this->story_pages.SetSortFuncs(StoryBookWindow::page_sorter_funcs); this->story_pages.ForceRebuild(); this->BuildStoryPageList(); @@ -444,8 +430,8 @@ public: */ void UpdatePrevNextDisabledState() { - this->SetWidgetDisabledState(WID_SB_PREV_PAGE, story_pages.Length() == 0 || this->IsFirstPageSelected()); - this->SetWidgetDisabledState(WID_SB_NEXT_PAGE, story_pages.Length() == 0 || this->IsLastPageSelected()); + this->SetWidgetDisabledState(WID_SB_PREV_PAGE, story_pages.size() == 0 || this->IsFirstPageSelected()); + this->SetWidgetDisabledState(WID_SB_NEXT_PAGE, story_pages.size() == 0 || this->IsLastPageSelected()); this->SetWidgetDirty(WID_SB_PREV_PAGE); this->SetWidgetDirty(WID_SB_NEXT_PAGE); } @@ -463,12 +449,12 @@ public: } } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { switch (widget) { case WID_SB_SEL_PAGE: { StoryPage *page = this->GetSelPage(); - SetDParamStr(0, page != NULL && page->title != NULL ? page->title : this->selected_generic_title); + SetDParamStr(0, page != nullptr && page->title != nullptr ? page->title : this->selected_generic_title); break; } case WID_SB_CAPTION: @@ -482,7 +468,7 @@ public: } } - virtual void OnPaint() + void OnPaint() override { /* Detect if content has changed height. This can happen if a * multi-line text contains eg. {COMPANY} and that company is @@ -497,12 +483,12 @@ public: this->DrawWidgets(); } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { if (widget != WID_SB_PAGE_PANEL) return; StoryPage *page = this->GetSelPage(); - if (page == NULL) return; + if (page == nullptr) return; const int x = r.left + WD_FRAMETEXT_LEFT; const int y = r.top + WD_FRAMETEXT_TOP; @@ -528,12 +514,11 @@ public: y_offset += line_height; /* Title */ - SetDParamStr(0, page->title != NULL ? page->title : this->selected_generic_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); /* Page elements */ - for (const StoryPageElement *const*iter = this->story_page_elements.Begin(); iter != this->story_page_elements.End(); iter++) { - const StoryPageElement *const pe = *iter; + for (const StoryPageElement *const pe : this->story_page_elements) { y_offset += line_height; // margin to previous element switch (pe->type) { @@ -544,8 +529,8 @@ public: case SPET_GOAL: { Goal *g = Goal::Get((GoalID) pe->referenced_id); - StringID string_id = g == NULL ? STR_STORY_BOOK_INVALID_GOAL_REF : STR_JUST_RAW_STRING; - if (g != NULL) SetDParamStr(0, g->text); + StringID string_id = g == nullptr ? STR_STORY_BOOK_INVALID_GOAL_REF : STR_JUST_RAW_STRING; + if (g != nullptr) SetDParamStr(0, g->text); DrawActionElement(y_offset, right - x, line_height, GetPageElementSprite(*pe), string_id); break; } @@ -563,7 +548,7 @@ public: _cur_dpi = old_dpi; } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { if (widget != WID_SB_SEL_PAGE && widget != WID_SB_PAGE_PANEL) return; @@ -575,10 +560,10 @@ public: case WID_SB_SEL_PAGE: { /* Get max title width. */ - for (uint16 i = 0; i < this->story_pages.Length(); i++) { + for (uint16 i = 0; i < this->story_pages.size(); i++) { const StoryPage *s = this->story_pages[i]; - if (s->title != NULL) { + if (s->title != nullptr) { SetDParamStr(0, s->title); } else { SetDParamStr(0, this->selected_generic_title); @@ -606,27 +591,27 @@ public: } - virtual void OnResize() + void OnResize() override { this->vscroll->SetCapacityFromWidget(this, WID_SB_PAGE_PANEL, WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM); this->vscroll->SetCount(this->GetContentHeight()); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_SB_SEL_PAGE: { - DropDownList *list = this->BuildDropDownList(); - if (list != NULL) { + DropDownList list = this->BuildDropDownList(); + if (!list.empty()) { /* Get the index of selected page. */ int selected = 0; - for (uint16 i = 0; i < this->story_pages.Length(); i++) { + for (uint16 i = 0; i < this->story_pages.size(); i++) { const StoryPage *p = this->story_pages[i]; if (p->index == this->selected_page_id) break; selected++; } - ShowDropDownList(this, list, selected, widget); + ShowDropDownList(this, std::move(list), selected, widget); } break; } @@ -650,8 +635,7 @@ public: /* Detect if a page element was clicked. */ uint y = head_height; uint element_vertical_dist = FONT_HEIGHT_NORMAL; - for (const StoryPageElement *const*iter = this->story_page_elements.Begin(); iter != this->story_page_elements.End(); iter++) { - const StoryPageElement *const pe = *iter; + for (const StoryPageElement *const pe : this->story_page_elements) { y += element_vertical_dist; // margin row @@ -667,7 +651,7 @@ public: } } - virtual void OnDropdownSelect(int widget, int index) + void OnDropdownSelect(int widget, int index) override { if (widget != WID_SB_SEL_PAGE) return; @@ -682,7 +666,7 @@ public: * >= 0 Id of the page that needs to be refreshed. If it is not the current page, nothing happens. * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; @@ -694,7 +678,7 @@ public: this->BuildStoryPageList(); /* Was the last page removed? */ - if (this->story_pages.Length() == 0) { + if (this->story_pages.size() == 0) { this->selected_generic_title[0] = '\0'; } @@ -702,14 +686,14 @@ public: if (!_story_page_pool.IsValidID(this->selected_page_id)) { this->selected_page_id = INVALID_STORY_PAGE; } - if (this->selected_page_id == INVALID_STORY_PAGE && this->story_pages.Length() > 0) { + if (this->selected_page_id == INVALID_STORY_PAGE && this->story_pages.size() > 0) { /* No page is selected, but there exist at least one available. * => Select first page. */ this->SetSelectedPage(this->story_pages[0]->index); } - this->SetWidgetDisabledState(WID_SB_SEL_PAGE, this->story_pages.Length() == 0); + this->SetWidgetDisabledState(WID_SB_SEL_PAGE, this->story_pages.size() == 0); this->SetWidgetDirty(WID_SB_SEL_PAGE); this->UpdatePrevNextDisabledState(); } else if (data >= 0 && this->selected_page_id == data) { diff --git a/src/story_type.h b/src/story_type.h index 392249da23..1dce00008b 100644 --- a/src/story_type.h +++ b/src/story_type.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/strgen/strgen.cpp b/src/strgen/strgen.cpp index 98e11e2eb6..c59be0021d 100644 --- a/src/strgen/strgen.cpp +++ b/src/strgen/strgen.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. @@ -30,13 +28,6 @@ #include #endif /* _WIN32 || __WATCOMC__ */ -#ifdef __MORPHOS__ -#ifdef stderr -#undef stderr -#endif -#define stderr stdout -#endif /* __MORPHOS__ */ - #include "../table/strgen_tables.h" #include "../safeguards.h" @@ -113,7 +104,7 @@ struct FileStringReader : StringReader { StringReader(data, file, master, translation) { this->fh = fopen(file, "rb"); - if (this->fh == NULL) error("Could not open %s", file); + if (this->fh == nullptr) error("Could not open %s", file); } /** Free/close the file. */ @@ -122,14 +113,14 @@ struct FileStringReader : StringReader { fclose(this->fh); } - /* virtual */ char *ReadLine(char *buffer, const char *last) + char *ReadLine(char *buffer, const char *last) override { return fgets(buffer, ClampToU16(last - buffer + 1), this->fh); } - /* virtual */ void HandlePragma(char *str); + void HandlePragma(char *str) override; - /* virtual */ void ParseFile() + void ParseFile() override { this->StringReader::ParseFile(); @@ -142,7 +133,7 @@ struct FileStringReader : StringReader { void FileStringReader::HandlePragma(char *str) { if (!memcmp(str, "id ", 3)) { - this->data.next_string_id = strtoul(str + 3, NULL, 0); + this->data.next_string_id = strtoul(str + 3, nullptr, 0); } else if (!memcmp(str, "name ", 5)) { strecpy(_lang.name, str + 5, lastof(_lang.name)); } else if (!memcmp(str, "ownname ", 8)) { @@ -168,14 +159,14 @@ void FileStringReader::HandlePragma(char *str) strecpy(_lang.digit_decimal_separator, strcmp(str, "{NBSP}") == 0 ? NBSP : str, lastof(_lang.digit_decimal_separator)); } else if (!memcmp(str, "winlangid ", 10)) { const char *buf = str + 10; - long langid = strtol(buf, NULL, 16); + long langid = strtol(buf, nullptr, 16); if (langid > (long)UINT16_MAX || langid < 0) { error("Invalid winlangid %s", buf); } _lang.winlangid = (uint16)langid; } else if (!memcmp(str, "grflangid ", 10)) { const char *buf = str + 10; - long langid = strtol(buf, NULL, 16); + long langid = strtol(buf, nullptr, 16); if (langid >= 0x7F || langid < 0) { error("Invalid grflangid %s", buf); } @@ -187,7 +178,7 @@ void FileStringReader::HandlePragma(char *str) for (;;) { const char *s = ParseWord(&buf); - if (s == NULL) break; + if (s == nullptr) break; if (_lang.num_genders >= MAX_NUM_GENDERS) error("Too many genders, max %d", MAX_NUM_GENDERS); strecpy(_lang.genders[_lang.num_genders], s, lastof(_lang.genders[_lang.num_genders])); _lang.num_genders++; @@ -199,7 +190,7 @@ void FileStringReader::HandlePragma(char *str) for (;;) { const char *s = ParseWord(&buf); - if (s == NULL) break; + if (s == nullptr) break; if (_lang.num_cases >= MAX_NUM_CASES) error("Too many cases, max %d", MAX_NUM_CASES); strecpy(_lang.cases[_lang.num_cases], s, lastof(_lang.cases[_lang.num_cases])); _lang.num_cases++; @@ -212,10 +203,10 @@ void FileStringReader::HandlePragma(char *str) bool CompareFiles(const char *n1, const char *n2) { FILE *f2 = fopen(n2, "rb"); - if (f2 == NULL) return false; + if (f2 == nullptr) return false; FILE *f1 = fopen(n1, "rb"); - if (f1 == NULL) { + if (f1 == nullptr) { fclose(f2); error("can't open %s", n1); } @@ -253,7 +244,7 @@ struct FileWriter { this->filename = stredup(filename); this->fh = fopen(this->filename, "wb"); - if (this->fh == NULL) { + if (this->fh == nullptr) { error("Could not open %s", this->filename); } } @@ -262,14 +253,14 @@ struct FileWriter { void Finalise() { fclose(this->fh); - this->fh = NULL; + this->fh = nullptr; } /** Make sure the file is closed. */ virtual ~FileWriter() { /* If we weren't closed an exception was thrown, so remove the temporary file. */ - if (fh != NULL) { + if (fh != nullptr) { fclose(this->fh); unlink(this->filename); } @@ -399,11 +390,13 @@ static inline char *mkpath(char *buf, const char *last, const char *path, const return buf; } -#if defined(__MINGW32__) +#if defined(_WIN32) /** * On MingW, it is common that both / as \ are accepted in the * params. To go with those flow, we rewrite all incoming / - * simply to \, so internally we can safely assume \. + * simply to \, so internally we can safely assume \, and do + * this for all Windows machines to keep identical behaviour, + * no matter what your compiler was. */ static inline char *replace_pathsep(char *s) { @@ -423,7 +416,7 @@ static const OptionData _opts[] = { GETOPT_NOVAL( 't', "--todo"), GETOPT_NOVAL( 'w', "--warning"), GETOPT_NOVAL( 'h', "--help"), - GETOPT_GENERAL('h', '?', NULL, ODF_NO_VALUE), + GETOPT_GENERAL('h', '?', nullptr, ODF_NO_VALUE), GETOPT_VALUE( 's', "--source_dir"), GETOPT_VALUE( 'd', "--dest_dir"), GETOPT_END(), @@ -433,7 +426,7 @@ int CDECL main(int argc, char *argv[]) { char pathbuf[MAX_PATH]; const char *src_dir = "."; - const char *dest_dir = NULL; + const char *dest_dir = nullptr; GetOptData mgo(argc - 1, argv + 1, _opts); for (;;) { @@ -517,7 +510,7 @@ int CDECL main(int argc, char *argv[]) } } - if (dest_dir == NULL) dest_dir = src_dir; // if dest_dir is not specified, it equals src_dir + if (dest_dir == nullptr) dest_dir = src_dir; // if dest_dir is not specified, it equals src_dir try { /* strgen has two modes of operation. If no (free) arguments are passed @@ -556,17 +549,17 @@ int CDECL main(int argc, char *argv[]) const char *translation = replace_pathsep(mgo.argv[i]); const char *file = strrchr(translation, PATHSEPCHAR); - FileStringReader translation_reader(data, translation, false, file == NULL || strcmp(file + 1, "english.txt") != 0); + FileStringReader translation_reader(data, translation, false, file == nullptr || strcmp(file + 1, "english.txt") != 0); translation_reader.ParseFile(); // target file if (_errors != 0) return 1; /* get the targetfile, strip any directories and append to destination path */ r = strrchr(mgo.argv[i], PATHSEPCHAR); - mkpath(pathbuf, lastof(pathbuf), dest_dir, (r != NULL) ? &r[1] : mgo.argv[i]); + mkpath(pathbuf, lastof(pathbuf), dest_dir, (r != nullptr) ? &r[1] : mgo.argv[i]); /* rename the .txt (input-extension) to .lng */ r = strrchr(pathbuf, '.'); - if (r == NULL || strcmp(r, ".txt") != 0) r = strchr(pathbuf, '\0'); + if (r == nullptr || strcmp(r, ".txt") != 0) r = strchr(pathbuf, '\0'); strecpy(r, ".lng", lastof(pathbuf)); LanguageFileWriter writer(pathbuf); diff --git a/src/strgen/strgen.h b/src/strgen/strgen.h index ecae71a72a..2110d30876 100644 --- a/src/strgen/strgen.h +++ b/src/strgen/strgen.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. @@ -29,12 +27,12 @@ struct LangString { char *name; ///< Name of the string. char *english; ///< English text. char *translated; ///< Translated text. - uint16 hash_next; ///< Next hash entry. - uint16 index; ///< The index in the language file. + size_t hash_next; ///< Next hash entry. + size_t index; ///< The index in the language file. int line; ///< Line of string in source-file. Case *translated_case; ///< Cases of the translation. - LangString(const char *name, const char *english, int index, int line); + LangString(const char *name, const char *english, size_t index, int line); ~LangString(); void FreeTranslation(); }; @@ -42,10 +40,10 @@ struct LangString { /** Information about the currently known strings. */ struct StringData { LangString **strings; ///< Array of all known strings. - uint16 *hash_heads; ///< Hash table for the strings. + size_t *hash_heads; ///< Hash table for the strings. size_t tabs; ///< The number of 'tabs' of strings. size_t max_strings; ///< The maximum number of strings. - int next_string_id; ///< The next string ID to allocate. + size_t next_string_id;///< The next string ID to allocate. StringData(size_t tabs); ~StringData(); @@ -73,7 +71,7 @@ struct StringReader { * Read a single line from the source of strings. * @param buffer The buffer to read the data in to. * @param last The last element in the buffer. - * @return The buffer, or NULL if at the end of the file. + * @return The buffer, or nullptr if at the end of the file. */ virtual char *ReadLine(char *buffer, const char *last) = 0; diff --git a/src/strgen/strgen_base.cpp b/src/strgen/strgen_base.cpp index 8d46b1b271..7e43471b26 100644 --- a/src/strgen/strgen_base.cpp +++ b/src/strgen/strgen_base.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. @@ -58,9 +56,9 @@ Case::~Case() * @param index The index in the string table. * @param line The line this string was found on. */ -LangString::LangString(const char *name, const char *english, int index, int line) : - name(stredup(name)), english(stredup(english)), translated(NULL), - hash_next(0), index(index), line(line), translated_case(NULL) +LangString::LangString(const char *name, const char *english, size_t index, int line) : + name(stredup(name)), english(stredup(english)), translated(nullptr), + hash_next(0), index(index), line(line), translated_case(nullptr) { } @@ -77,10 +75,10 @@ LangString::~LangString() void LangString::FreeTranslation() { free(this->translated); - this->translated = NULL; + this->translated = nullptr; delete this->translated_case; - this->translated_case = NULL; + this->translated_case = nullptr; } /** @@ -90,7 +88,7 @@ void LangString::FreeTranslation() StringData::StringData(size_t tabs) : tabs(tabs), max_strings(tabs * TAB_SIZE) { this->strings = CallocT(max_strings); - this->hash_heads = CallocT(max_strings); + this->hash_heads = CallocT(max_strings); this->next_string_id = 0; } @@ -107,7 +105,7 @@ void StringData::FreeTranslation() { for (size_t i = 0; i < this->max_strings; i++) { LangString *ls = this->strings[i]; - if (ls != NULL) ls->FreeTranslation(); + if (ls != nullptr) ls->FreeTranslation(); } } @@ -140,19 +138,19 @@ void StringData::Add(const char *s, LangString *ls) /** * Find a LangString based on the string name. * @param s The string name to search on. - * @return The LangString or NULL if it is not known. + * @return The LangString or nullptr if it is not known. */ LangString *StringData::Find(const char *s) { - int idx = this->hash_heads[this->HashStr(s)]; + size_t idx = this->hash_heads[this->HashStr(s)]; - while (--idx >= 0) { + while (idx-- > 0) { LangString *ls = this->strings[idx]; if (strcmp(ls->name, s) == 0) return ls; idx = ls->hash_next; } - return NULL; + return nullptr; } /** @@ -181,7 +179,7 @@ uint StringData::Version() const for (size_t i = 0; i < this->max_strings; i++) { const LangString *ls = this->strings[i]; - if (ls != NULL) { + if (ls != nullptr) { const CmdStruct *cs; const char *s; char buf[MAX_COMMAND_PARAM_SIZE]; @@ -194,7 +192,7 @@ uint StringData::Version() const hash = this->VersionHashStr(hash, s + 1); s = ls->english; - while ((cs = ParseCommandString(&s, buf, &argno, &casei)) != NULL) { + while ((cs = ParseCommandString(&s, buf, &argno, &casei)) != nullptr) { if (cs->flags & C_DONTCOUNT) continue; hash ^= (cs - _cmd_structs) * 0x1234567; @@ -213,7 +211,7 @@ uint StringData::Version() const uint StringData::CountInUse(uint tab) const { int i; - for (i = TAB_SIZE; --i >= 0;) if (this->strings[(tab * TAB_SIZE) + i] != NULL) break; + for (i = TAB_SIZE; --i >= 0;) if (this->strings[(tab * TAB_SIZE) + i] != nullptr) break; return i + 1; } @@ -235,14 +233,14 @@ static ParsedCommandStruct _cur_pcs; static int _cur_argidx; /** The buffer for writing a single string. */ -struct Buffer : SmallVector { +struct Buffer : std::vector { /** * Convenience method for adding a byte. * @param value The value to add. */ void AppendByte(byte value) { - *this->Append() = value; + this->push_back(value); } /** @@ -252,19 +250,19 @@ struct Buffer : SmallVector { void AppendUtf8(uint32 value) { if (value < 0x80) { - *this->Append() = value; + this->push_back(value); } else if (value < 0x800) { - *this->Append() = 0xC0 + GB(value, 6, 5); - *this->Append() = 0x80 + GB(value, 0, 6); + this->push_back(0xC0 + GB(value, 6, 5)); + this->push_back(0x80 + GB(value, 0, 6)); } else if (value < 0x10000) { - *this->Append() = 0xE0 + GB(value, 12, 4); - *this->Append() = 0x80 + GB(value, 6, 6); - *this->Append() = 0x80 + GB(value, 0, 6); + this->push_back(0xE0 + GB(value, 12, 4)); + this->push_back(0x80 + GB(value, 6, 6)); + this->push_back(0x80 + GB(value, 0, 6)); } else if (value < 0x110000) { - *this->Append() = 0xF0 + GB(value, 18, 3); - *this->Append() = 0x80 + GB(value, 12, 6); - *this->Append() = 0x80 + GB(value, 6, 6); - *this->Append() = 0x80 + GB(value, 0, 6); + this->push_back(0xF0 + GB(value, 18, 3)); + this->push_back(0x80 + GB(value, 12, 6)); + this->push_back(0x80 + GB(value, 6, 6)); + this->push_back(0x80 + GB(value, 0, 6)); } else { strgen_warning("Invalid unicode value U+0x%X", value); } @@ -327,7 +325,7 @@ bool ParseRelNum(char **buf, int *value, int *offset) } else { *value = v; } - if (offset != NULL && *end == ':') { + if (offset != nullptr && *end == ':') { /* Take the Nth within */ s = end + 1; *offset = strtol(s, &end, 0); @@ -337,13 +335,13 @@ bool ParseRelNum(char **buf, int *value, int *offset) return true; } -/* Parse out the next word, or NULL */ +/* Parse out the next word, or nullptr */ char *ParseWord(char **buf) { char *s = *buf, *r; while (*s == ' ' || *s == '\t') s++; - if (*s == '\0') return NULL; + if (*s == '\0') return nullptr; if (*s == '"') { r = ++s; @@ -399,8 +397,8 @@ void EmitPlural(Buffer *buffer, char *buf, int value) const CmdStruct *cmd = _cur_pcs.cmd[argidx]; if (offset == -1) { /* Use default offset */ - if (cmd == NULL || cmd->default_plural_offset < 0) { - strgen_fatal("Command '%s' has no (default) plural position", cmd == NULL ? "" : cmd->cmd); + if (cmd == nullptr || cmd->default_plural_offset < 0) { + strgen_fatal("Command '%s' has no (default) plural position", cmd == nullptr ? "" : cmd->cmd); } offset = cmd->default_plural_offset; } @@ -408,7 +406,7 @@ void EmitPlural(Buffer *buffer, char *buf, int value) /* Parse each string */ for (nw = 0; nw < MAX_PLURALS; nw++) { words[nw] = ParseWord(&buf); - if (words[nw] == NULL) break; + if (words[nw] == nullptr) break; } if (nw == 0) { @@ -462,13 +460,13 @@ void EmitGender(Buffer *buffer, char *buf, int value) if (!ParseRelNum(&buf, &argidx, &offset)) {} const CmdStruct *cmd = _cur_pcs.cmd[argidx]; - if (cmd == NULL || (cmd->flags & C_GENDER) == 0) { - strgen_fatal("Command '%s' can't have a gender", cmd == NULL ? "" : cmd->cmd); + if (cmd == nullptr || (cmd->flags & C_GENDER) == 0) { + strgen_fatal("Command '%s' can't have a gender", cmd == nullptr ? "" : cmd->cmd); } for (nw = 0; nw < MAX_NUM_GENDERS; nw++) { words[nw] = ParseWord(&buf); - if (words[nw] == NULL) break; + if (words[nw] == nullptr) break; } if (nw != _lang.num_genders) strgen_fatal("Bad # of arguments for gender command"); @@ -484,7 +482,7 @@ static const CmdStruct *FindCmd(const char *s, int len) for (const CmdStruct *cs = _cmd_structs; cs != endof(_cmd_structs); cs++) { if (strncmp(cs->cmd, s, len) == 0 && cs->cmd[len] == '\0') return cs; } - return NULL; + return nullptr; } static uint ResolveCaseName(const char *str, size_t len) @@ -501,7 +499,7 @@ static uint ResolveCaseName(const char *str, size_t len) } -/* returns NULL on eof +/* returns nullptr on eof * else returns command struct */ static const CmdStruct *ParseCommandString(const char **str, char *param, int *argno, int *casei) { @@ -513,7 +511,7 @@ static const CmdStruct *ParseCommandString(const char **str, char *param, int *a /* Scan to the next command, exit if there's no next command. */ for (; *s != '{'; s++) { - if (*s == '\0') return NULL; + if (*s == '\0') return nullptr; } s++; // Skip past the { @@ -532,9 +530,9 @@ static const CmdStruct *ParseCommandString(const char **str, char *param, int *a } while (c != '}' && c != ' ' && c != '=' && c != '.' && c != 0); const CmdStruct *cmd = FindCmd(start, s - start - 1); - if (cmd == NULL) { + if (cmd == nullptr) { strgen_error("Undefined command '%.*s'", (int)(s - start - 1), start); - return NULL; + return nullptr; } if (c == '.') { @@ -552,7 +550,7 @@ static const CmdStruct *ParseCommandString(const char **str, char *param, int *a if (c == '\0') { strgen_error("Missing } from command '%s'", start); - return NULL; + return nullptr; } @@ -565,7 +563,7 @@ static const CmdStruct *ParseCommandString(const char **str, char *param, int *a if (c == '}') break; if (c == '\0') { strgen_error("Missing } from command '%s'", start); - return NULL; + return nullptr; } if (s - start == MAX_COMMAND_PARAM_SIZE) error("param command too long"); *param++ = c; @@ -609,7 +607,7 @@ static void ExtractCommandString(ParsedCommandStruct *p, const char *s, bool war /* read until next command from a. */ const CmdStruct *ar = ParseCommandString(&s, param, &argno, &casei); - if (ar == NULL) break; + if (ar == nullptr) break; /* Sanity checking */ if (argno != -1 && ar->consumes == 0) strgen_fatal("Non consumer param can't have a paramindex"); @@ -617,7 +615,7 @@ static void ExtractCommandString(ParsedCommandStruct *p, const char *s, bool war if (ar->consumes) { if (argno != -1) argidx = argno; if (argidx < 0 || (uint)argidx >= lengthof(p->cmd)) strgen_fatal("invalid param idx %d", argidx); - if (p->cmd[argidx] != NULL && p->cmd[argidx] != ar) strgen_fatal("duplicate param idx %d", argidx); + if (p->cmd[argidx] != nullptr && p->cmd[argidx] != ar) strgen_fatal("duplicate param idx %d", argidx); p->cmd[argidx++] = ar; } else if (!(ar->flags & C_DONTCOUNT)) { // Ignore some of them @@ -632,7 +630,7 @@ static void ExtractCommandString(ParsedCommandStruct *p, const char *s, bool war static const CmdStruct *TranslateCmdForCompare(const CmdStruct *a) { - if (a == NULL) return NULL; + if (a == nullptr) return nullptr; if (strcmp(a->cmd, "STRING1") == 0 || strcmp(a->cmd, "STRING2") == 0 || @@ -677,7 +675,7 @@ static bool CheckCommandsMatch(char *a, char *b, const char *name) if (templ.pairs[i].a == lang.pairs[j].a && strcmp(templ.pairs[i].v, lang.pairs[j].v) == 0) { /* it was found in both. zero it out from lang so we don't find it again */ - lang.pairs[j].a = NULL; + lang.pairs[j].a = nullptr; found = true; break; } @@ -694,8 +692,8 @@ static bool CheckCommandsMatch(char *a, char *b, const char *name) for (uint i = 0; i < lengthof(templ.cmd); i++) { if (TranslateCmdForCompare(templ.cmd[i]) != lang.cmd[i]) { strgen_warning("%s: Param idx #%d '%s' doesn't match with template command '%s'", name, i, - lang.cmd[i] == NULL ? "" : TranslateCmdForCompare(lang.cmd[i])->cmd, - templ.cmd[i] == NULL ? "" : templ.cmd[i]->cmd); + lang.cmd[i] == nullptr ? "" : TranslateCmdForCompare(lang.cmd[i])->cmd, + templ.cmd[i] == nullptr ? "" : templ.cmd[i]->cmd); result = false; } } @@ -714,7 +712,7 @@ void StringReader::HandleString(char *str) if (*str == ';' || *str == ' ' || *str == '\0') return; char *s = strchr(str, ':'); - if (s == NULL) { + if (s == nullptr) { strgen_error("Line has no ':' delimiter"); return; } @@ -747,36 +745,36 @@ void StringReader::HandleString(char *str) /* Check if the string has a case.. * The syntax for cases is IDENTNAME.case */ char *casep = strchr(str, '.'); - if (casep != NULL) *casep++ = '\0'; + if (casep != nullptr) *casep++ = '\0'; /* Check if this string already exists.. */ LangString *ent = this->data.Find(str); if (this->master) { - if (casep != NULL) { + if (casep != nullptr) { strgen_error("Cases in the base translation are not supported."); return; } - if (ent != NULL) { + if (ent != nullptr) { strgen_error("String name '%s' is used multiple times", str); return; } - if (this->data.strings[this->data.next_string_id] != NULL) { - strgen_error("String ID 0x%X for '%s' already in use by '%s'", this->data.next_string_id, str, this->data.strings[this->data.next_string_id]->name); + if (this->data.strings[this->data.next_string_id] != nullptr) { + strgen_error("String ID 0x" PRINTF_SIZEX " for '%s' already in use by '%s'", this->data.next_string_id, str, this->data.strings[this->data.next_string_id]->name); return; } /* Allocate a new LangString */ this->data.Add(str, new LangString(str, s, this->data.next_string_id++, _cur_line)); } else { - if (ent == NULL) { + if (ent == nullptr) { strgen_warning("String name '%s' does not exist in master file", str); return; } - if (ent->translated && casep == NULL) { + if (ent->translated && casep == nullptr) { strgen_error("String name '%s' is used multiple times", str); return; } @@ -784,7 +782,7 @@ void StringReader::HandleString(char *str) /* make sure that the commands match */ if (!CheckCommandsMatch(s, ent->english, str)) return; - if (casep != NULL) { + if (casep != nullptr) { ent->translated_case = new Case(ResolveCaseName(casep, strlen(casep)), s, ent->translated_case); } else { ent->translated = stredup(s); @@ -830,11 +828,15 @@ void StringReader::ParseFile() strecpy(_lang.digit_decimal_separator, ".", lastof(_lang.digit_decimal_separator)); _cur_line = 1; - while (this->ReadLine(buf, lastof(buf)) != NULL) { + while (this->data.next_string_id < this->data.max_strings && this->ReadLine(buf, lastof(buf)) != nullptr) { rstrip(buf); this->HandleString(buf); _cur_line++; } + + if (this->data.next_string_id == this->data.max_strings) { + strgen_error("Too many strings, maximum allowed is " PRINTF_SIZE, this->data.max_strings); + } } /** @@ -845,7 +847,7 @@ void HeaderWriter::WriteHeader(const StringData &data) { int last = 0; for (size_t i = 0; i < data.max_strings; i++) { - if (data.strings[i] != NULL) { + if (data.strings[i] != nullptr) { this->WriteStringID(data.strings[i]->name, (int)i); last = (int)i; } @@ -862,18 +864,18 @@ static int TranslateArgumentIdx(int argidx, int offset) strgen_fatal("invalid argidx %d", argidx); } const CmdStruct *cs = _cur_pcs.cmd[argidx]; - if (cs != NULL && cs->consumes <= offset) { + if (cs != nullptr && cs->consumes <= offset) { strgen_fatal("invalid argidx offset %d:%d", argidx, offset); } - if (_cur_pcs.cmd[argidx] == NULL) { + if (_cur_pcs.cmd[argidx] == nullptr) { strgen_fatal("no command for this argidx %d", argidx); } for (int i = sum = 0; i < argidx; i++) { const CmdStruct *cs = _cur_pcs.cmd[i]; - sum += (cs != NULL) ? cs->consumes : 1; + sum += (cs != nullptr) ? cs->consumes : 1; } return sum + offset; @@ -901,7 +903,7 @@ static void PutCommandString(Buffer *buffer, const char *str) int argno; int casei; const CmdStruct *cs = ParseCommandString(&str, param, &argno, &casei); - if (cs == NULL) break; + if (cs == nullptr) break; if (casei != -1) { buffer->AppendUtf8(SCC_SET_CASE); // {SET_CASE} @@ -918,7 +920,7 @@ static void PutCommandString(Buffer *buffer, const char *str) /* Output the one from the master string... it's always accurate. */ cs = _cur_pcs.cmd[_cur_argidx++]; - if (cs == NULL) { + if (cs == nullptr) { strgen_fatal("%s: No argument exists at position %d", _cur_ident, _cur_argidx - 1); } } @@ -961,7 +963,7 @@ void LanguageWriter::WriteLang(const StringData &data) for (uint j = 0; j != in_use[tab]; j++) { const LangString *ls = data.strings[(tab * TAB_SIZE) + j]; - if (ls != NULL && ls->translated == NULL) _lang.missing++; + if (ls != nullptr && ls->translated == nullptr) _lang.missing++; } } @@ -980,7 +982,7 @@ void LanguageWriter::WriteLang(const StringData &data) const char *cmdp; /* For undefined strings, just set that it's an empty string */ - if (ls == NULL) { + if (ls == nullptr) { this->WriteLength(0); continue; } @@ -989,7 +991,7 @@ void LanguageWriter::WriteLang(const StringData &data) _cur_line = ls->line; /* Produce a message if a string doesn't have a translation. */ - if (_show_todo > 0 && ls->translated == NULL) { + if (_show_todo > 0 && ls->translated == nullptr) { if ((_show_todo & 2) != 0) { strgen_warning("'%s' is untranslated", ls->name); } @@ -1002,17 +1004,17 @@ void LanguageWriter::WriteLang(const StringData &data) /* Extract the strings and stuff from the english command string */ ExtractCommandString(&_cur_pcs, ls->english, false); - if (ls->translated_case != NULL || ls->translated != NULL) { + if (ls->translated_case != nullptr || ls->translated != nullptr) { casep = ls->translated_case; cmdp = ls->translated; } else { - casep = NULL; + casep = nullptr; cmdp = ls->english; } _translated = cmdp != ls->english; - if (casep != NULL) { + if (casep != nullptr) { const Case *c; uint num; @@ -1026,27 +1028,27 @@ void LanguageWriter::WriteLang(const StringData &data) buffer.AppendByte(num); /* Write each case */ - for (c = casep; c != NULL; c = c->next) { + for (c = casep; c != nullptr; c = c->next) { buffer.AppendByte(c->caseidx); /* Make some space for the 16-bit length */ - uint pos = buffer.Length(); + uint pos = (uint)buffer.size(); buffer.AppendByte(0); buffer.AppendByte(0); /* Write string */ PutCommandString(&buffer, c->string); buffer.AppendByte(0); // terminate with a zero /* Fill in the length */ - uint size = buffer.Length() - (pos + 2); + uint size = (uint)buffer.size() - (pos + 2); buffer[pos + 0] = GB(size, 8, 8); buffer[pos + 1] = GB(size, 0, 8); } } - if (cmdp != NULL) PutCommandString(&buffer, cmdp); + if (cmdp != nullptr) PutCommandString(&buffer, cmdp); - this->WriteLength(buffer.Length()); - this->Write(buffer.Begin(), buffer.Length()); - buffer.Clear(); + this->WriteLength((uint)buffer.size()); + this->Write(buffer.data(), buffer.size()); + buffer.clear(); } } } diff --git a/src/string.cpp b/src/string.cpp index ae1b556aff..dea369037b 100644 --- a/src/string.cpp +++ b/src/string.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. @@ -37,12 +35,12 @@ #include "os/macosx/string_osx.h" #endif -#ifdef WITH_ICU_SORT +#ifdef WITH_ICU_I18N /* Required by strnatcmp. */ #include #include "language.h" #include "gfx_func.h" -#endif /* WITH_ICU_SORT */ +#endif /* WITH_ICU_I18N */ /* The function vsnprintf is used internally to perform the required formatting * tasks. As such this one must be allowed, and makes sure it's terminated. */ @@ -71,7 +69,7 @@ int CDECL vseprintf(char *str, const char *last, const char *format, va_list ap) * * Appends the source string to the destination string with respect of the * terminating null-character and and the last pointer to the last element - * in the destination buffer. If the last pointer is set to NULL no + * in the destination buffer. If the last pointer is set to nullptr no * boundary check is performed. * * @note usage: strecat(dst, src, lastof(dst)); @@ -99,7 +97,7 @@ char *strecat(char *dst, const char *src, const char *last) * * Copies the source string to the destination buffer with respect of the * terminating null-character and the last pointer to the last element in - * the destination buffer. If the last pointer is set to NULL no boundary + * the destination buffer. If the last pointer is set to nullptr no boundary * check is performed. * * @note usage: strecpy(dst, src, lastof(dst)); @@ -131,13 +129,13 @@ char *strecpy(char *dst, const char *src, const char *last) /** * Create a duplicate of the given string. * @param s The string to duplicate. - * @param last The last character that is safe to duplicate. If NULL, the whole string is duplicated. + * @param last The last character that is safe to duplicate. If nullptr, the whole string is duplicated. * @note The maximum length of the resulting string might therefore be last - s + 1. * @return The duplicate of the string. */ char *stredup(const char *s, const char *last) { - size_t len = last == NULL ? strlen(s) : ttd_strnlen(s, last - s + 1); + size_t len = last == nullptr ? strlen(s) : ttd_strnlen(s, last - s + 1); char *tmp = CallocT(len + 1); memcpy(tmp, s, len); return tmp; @@ -447,7 +445,7 @@ char *md5sumToString(char *buf, const char *last, const uint8 md5sum[16]) */ size_t Utf8Decode(WChar *c, const char *s) { - assert(c != NULL); + assert(c != nullptr); if (!HasBit(s[0], 7)) { /* Single byte character: 0xxxxxxx */ @@ -551,7 +549,7 @@ char *strcasestr(const char *haystack, const char *needle) hay_len--; } - return NULL; + return nullptr; } #endif /* DEFINE_STRCASESTR */ @@ -584,13 +582,13 @@ int strnatcmp(const char *s1, const char *s2, bool ignore_garbage_at_front) s2 = SkipGarbage(s2); } -#ifdef WITH_ICU_SORT - if (_current_collator != NULL) { +#ifdef WITH_ICU_I18N + if (_current_collator != nullptr) { UErrorCode status = U_ZERO_ERROR; int result = _current_collator->compareUTF8(s1, s2, status); if (U_SUCCESS(status)) return result; } -#endif /* WITH_ICU_SORT */ +#endif /* WITH_ICU_I18N */ #if defined(_WIN32) && !defined(STRGEN) && !defined(SETTINGSGEN) int res = OTTDStringCompare(s1, s2); @@ -613,7 +611,7 @@ int strnatcmp(const char *s1, const char *s2, bool ignore_garbage_at_front) return new UniscribeStringIterator(); } -#elif defined(WITH_ICU_SORT) +#elif defined(WITH_ICU_I18N) #include #include @@ -624,27 +622,27 @@ class IcuStringIterator : public StringIterator icu::BreakIterator *char_itr; ///< ICU iterator for characters. icu::BreakIterator *word_itr; ///< ICU iterator for words. - SmallVector utf16_str; ///< UTF-16 copy of the string. - SmallVector utf16_to_utf8; ///< Mapping from UTF-16 code point position to index in the UTF-8 source string. + std::vector utf16_str; ///< UTF-16 copy of the string. + std::vector utf16_to_utf8; ///< Mapping from UTF-16 code point position to index in the UTF-8 source string. public: - IcuStringIterator() : char_itr(NULL), word_itr(NULL) + IcuStringIterator() : char_itr(nullptr), word_itr(nullptr) { UErrorCode status = U_ZERO_ERROR; - this->char_itr = icu::BreakIterator::createCharacterInstance(icu::Locale(_current_language != NULL ? _current_language->isocode : "en"), status); - this->word_itr = icu::BreakIterator::createWordInstance(icu::Locale(_current_language != NULL ? _current_language->isocode : "en"), status); + this->char_itr = icu::BreakIterator::createCharacterInstance(icu::Locale(_current_language != nullptr ? _current_language->isocode : "en"), status); + this->word_itr = icu::BreakIterator::createWordInstance(icu::Locale(_current_language != nullptr ? _current_language->isocode : "en"), status); - *this->utf16_str.Append() = '\0'; - *this->utf16_to_utf8.Append() = 0; + this->utf16_str.push_back('\0'); + this->utf16_to_utf8.push_back(0); } - virtual ~IcuStringIterator() + ~IcuStringIterator() override { delete this->char_itr; delete this->word_itr; } - virtual void SetString(const char *s) + void SetString(const char *s) override { const char *string_base = s; @@ -652,40 +650,40 @@ public: * for word break iterators (especially for CJK languages) in combination * with UTF-8 input. As a work around we have to convert the input to * UTF-16 and create a mapping back to UTF-8 character indices. */ - this->utf16_str.Clear(); - this->utf16_to_utf8.Clear(); + this->utf16_str.clear(); + this->utf16_to_utf8.clear(); while (*s != '\0') { size_t idx = s - string_base; WChar c = Utf8Consume(&s); if (c < 0x10000) { - *this->utf16_str.Append() = (UChar)c; + this->utf16_str.push_back((UChar)c); } else { /* Make a surrogate pair. */ - *this->utf16_str.Append() = (UChar)(0xD800 + ((c - 0x10000) >> 10)); - *this->utf16_str.Append() = (UChar)(0xDC00 + ((c - 0x10000) & 0x3FF)); - *this->utf16_to_utf8.Append() = idx; + this->utf16_str.push_back((UChar)(0xD800 + ((c - 0x10000) >> 10))); + this->utf16_str.push_back((UChar)(0xDC00 + ((c - 0x10000) & 0x3FF))); + this->utf16_to_utf8.push_back(idx); } - *this->utf16_to_utf8.Append() = idx; + this->utf16_to_utf8.push_back(idx); } - *this->utf16_str.Append() = '\0'; - *this->utf16_to_utf8.Append() = s - string_base; + this->utf16_str.push_back('\0'); + this->utf16_to_utf8.push_back(s - string_base); UText text = UTEXT_INITIALIZER; UErrorCode status = U_ZERO_ERROR; - utext_openUChars(&text, this->utf16_str.Begin(), this->utf16_str.Length() - 1, &status); + utext_openUChars(&text, this->utf16_str.data(), this->utf16_str.size() - 1, &status); this->char_itr->setText(&text, status); this->word_itr->setText(&text, status); this->char_itr->first(); this->word_itr->first(); } - virtual size_t SetCurPosition(size_t pos) + size_t SetCurPosition(size_t pos) override { /* Convert incoming position to an UTF-16 string index. */ uint utf16_pos = 0; - for (uint i = 0; i < this->utf16_to_utf8.Length(); i++) { + for (uint i = 0; i < this->utf16_to_utf8.size(); i++) { if (this->utf16_to_utf8[i] == pos) { utf16_pos = i; break; @@ -699,7 +697,7 @@ public: return this->utf16_to_utf8[this->char_itr->current()]; } - virtual size_t Next(IterType what) + size_t Next(IterType what) override { int32_t pos; switch (what) { @@ -731,7 +729,7 @@ public: return pos == icu::BreakIterator::DONE ? END : this->utf16_to_utf8[pos]; } - virtual size_t Prev(IterType what) + size_t Prev(IterType what) override { int32_t pos; switch (what) { @@ -779,7 +777,7 @@ class DefaultStringIterator : public StringIterator size_t cur_pos; ///< Current iteration position. public: - DefaultStringIterator() : string(NULL), len(0), cur_pos(0) + DefaultStringIterator() : string(nullptr), len(0), cur_pos(0) { } @@ -792,7 +790,7 @@ public: virtual size_t SetCurPosition(size_t pos) { - assert(this->string != NULL && pos <= this->len); + assert(this->string != nullptr && pos <= this->len); /* Sanitize in case we get a position inside an UTF-8 sequence. */ while (pos > 0 && IsUtf8Part(this->string[pos])) pos--; return this->cur_pos = pos; @@ -800,7 +798,7 @@ public: virtual size_t Next(IterType what) { - assert(this->string != NULL); + assert(this->string != nullptr); /* Already at the end? */ if (this->cur_pos >= this->len) return END; @@ -838,7 +836,7 @@ public: virtual size_t Prev(IterType what) { - assert(this->string != NULL); + assert(this->string != nullptr); /* Already at the beginning? */ if (this->cur_pos == 0) return END; @@ -878,7 +876,7 @@ public: /* static */ StringIterator *StringIterator::Create() { StringIterator *i = OSXStringIterator::Create(); - if (i != NULL) return i; + if (i != nullptr) return i; return new DefaultStringIterator(); } diff --git a/src/string_base.h b/src/string_base.h index 02856cf1c6..a22be65713 100644 --- a/src/string_base.h +++ b/src/string_base.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/string_func.h b/src/string_func.h index ff12f3747a..9942e9a6a7 100644 --- a/src/string_func.h +++ b/src/string_func.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. @@ -33,7 +31,7 @@ char *strecat(char *dst, const char *src, const char *last); char *strecpy(char *dst, const char *src, const char *last); -char *stredup(const char *src, const char *last = NULL); +char *stredup(const char *src, const char *last = nullptr); int CDECL seprintf(char *str, const char *last, const char *format, ...) WARN_FORMAT(3, 4); int CDECL vseprintf(char *str, const char *last, const char *format, va_list ap); @@ -54,11 +52,11 @@ bool StrValid(const char *str, const char *last); * * @param s The pointer to the first element of the buffer * @return true if the buffer starts with the terminating null-character or - * if the given pointer points to NULL else return false + * if the given pointer points to nullptr else return false */ static inline bool StrEmpty(const char *s) { - return s == NULL || s[0] == '\0'; + return s == nullptr || s[0] == '\0'; } /** diff --git a/src/string_type.h b/src/string_type.h index 94d4304dfe..ced1ab1def 100644 --- a/src/string_type.h +++ b/src/string_type.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. @@ -13,6 +11,8 @@ #define STRING_TYPE_H #include "core/enum_type.hpp" +#include +#include /** A non-breaking space. */ #define NBSP "\xC2\xA0" @@ -53,4 +53,8 @@ enum StringValidationSettings { }; DECLARE_ENUM_AS_BIT_SET(StringValidationSettings) + +/** Type for a list of strings. */ +typedef std::vector StringList; + #endif /* STRING_TYPE_H */ diff --git a/src/stringfilter.cpp b/src/stringfilter.cpp index 6045c19ef4..30876a82d8 100644 --- a/src/stringfilter.cpp +++ b/src/stringfilter.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. @@ -28,18 +26,19 @@ static const WChar STATE_QUOTE2 = '"'; */ void StringFilter::SetFilterTerm(const char *str) { - this->word_index.Reset(); + this->word_index.clear(); + this->word_index.shrink_to_fit(); this->word_matches = 0; free(this->filter_buffer); - assert(str != NULL); + assert(str != nullptr); char *dest = MallocT(strlen(str) + 1); this->filter_buffer = dest; WChar state = STATE_WHITESPACE; const char *pos = str; - WordState *word = NULL; + WordState *word = nullptr; size_t len; for (;; pos += len) { WChar c; @@ -47,9 +46,9 @@ void StringFilter::SetFilterTerm(const char *str) if (c == 0 || (state == STATE_WORD && IsWhitespace(c))) { /* Finish word */ - if (word != NULL) { + if (word != nullptr) { *(dest++) = '\0'; - word = NULL; + word = nullptr; } state = STATE_WHITESPACE; if (c != 0) continue; else break; @@ -74,10 +73,9 @@ void StringFilter::SetFilterTerm(const char *str) } /* Add to word */ - if (word == NULL) { - word = this->word_index.Append(); - word->start = dest; - word->match = false; + if (word == nullptr) { + /*C++17: word = &*/ this->word_index.push_back({dest, false}); + word = &this->word_index.back(); } memcpy(dest, pos, len); @@ -91,9 +89,8 @@ void StringFilter::SetFilterTerm(const char *str) void StringFilter::ResetState() { this->word_matches = 0; - const WordState *end = this->word_index.End(); - for (WordState *it = this->word_index.Begin(); it != end; ++it) { - it->match = false; + for (WordState &ws : this->word_index) { + ws.match = false; } } @@ -107,14 +104,13 @@ void StringFilter::ResetState() */ void StringFilter::AddLine(const char *str) { - if (str == NULL) return; + if (str == nullptr) return; - bool match_case = this->case_sensitive != NULL && *this->case_sensitive; - const WordState *end = this->word_index.End(); - for (WordState *it = this->word_index.Begin(); it != end; ++it) { - if (!it->match) { - if ((match_case ? strstr(str, it->start) : strcasestr(str, it->start)) != NULL) { - it->match = true; + bool match_case = this->case_sensitive != nullptr && *this->case_sensitive; + for (WordState &ws : this->word_index) { + if (!ws.match) { + if ((match_case ? strstr(str, ws.start) : strcasestr(str, ws.start)) != nullptr) { + ws.match = true; this->word_matches++; } } diff --git a/src/stringfilter_type.h b/src/stringfilter_type.h index f78b133cb4..92db480a6f 100644 --- a/src/stringfilter_type.h +++ b/src/stringfilter_type.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. @@ -39,7 +37,7 @@ private: }; const char *filter_buffer; ///< Parsed filter string. Words separated by 0. - SmallVector word_index; ///< Word index and filter state. + std::vector word_index; ///< Word index and filter state. uint word_matches; ///< Summary of filter state: Number of words matched. const bool *case_sensitive; ///< Match case-sensitively (usually a static variable). @@ -47,9 +45,9 @@ private: public: /** * Constructor for filter. - * @param case_sensitive Pointer to a (usually static) variable controlling the case-sensitivity. NULL means always case-insensitive. + * @param case_sensitive Pointer to a (usually static) variable controlling the case-sensitivity. nullptr means always case-insensitive. */ - StringFilter(const bool *case_sensitive = NULL) : filter_buffer(NULL), word_matches(0), case_sensitive(case_sensitive) {} + StringFilter(const bool *case_sensitive = nullptr) : filter_buffer(nullptr), word_matches(0), case_sensitive(case_sensitive) {} ~StringFilter() { free(this->filter_buffer); } void SetFilterTerm(const char *str); @@ -58,7 +56,7 @@ public: * Check whether any filter words were entered. * @return true if no words were entered. */ - bool IsEmpty() const { return this->word_index.Length() == 0; } + bool IsEmpty() const { return this->word_index.size() == 0; } void ResetState(); void AddLine(const char *str); @@ -68,7 +66,7 @@ public: * Get the matching state of the current item. * @return true if matched. */ - bool GetState() const { return this->word_matches == this->word_index.Length(); } + bool GetState() const { return this->word_matches == this->word_index.size(); } }; #endif /* STRINGFILTER_TYPE_H */ diff --git a/src/strings.cpp b/src/strings.cpp index 34b923830b..e55b728dc3 100644 --- a/src/strings.cpp +++ b/src/strings.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. @@ -35,9 +33,7 @@ #include "window_func.h" #include "debug.h" #include "game/game_text.hpp" -#ifdef ENABLE_NETWORK -# include "network/network_content_gui.h" -#endif /* ENABLE_NETWORK */ +#include "network/network_content_gui.h" #include #include "table/strings.h" @@ -47,13 +43,13 @@ char _config_language_file[MAX_PATH]; ///< The file (name) stored in the configuration. LanguageList _languages; ///< The actual list of language meta data. -const LanguageMetadata *_current_language = NULL; ///< The currently loaded language. +const LanguageMetadata *_current_language = nullptr; ///< The currently loaded language. TextDirection _current_text_dir; ///< Text direction of the currently selected language. -#ifdef WITH_ICU_SORT -icu::Collator *_current_collator = NULL; ///< Collator for the language currently in use. -#endif /* WITH_ICU_SORT */ +#ifdef WITH_ICU_I18N +icu::Collator *_current_collator = nullptr; ///< Collator for the language currently in use. +#endif /* WITH_ICU_I18N */ static uint64 _global_string_params_data[20]; ///< Global array of string parameters. To access, use #SetDParam. static WChar _global_string_params_type[20]; ///< Type of parameters stored in #_global_string_params @@ -62,7 +58,7 @@ StringParameters _global_string_params(_global_string_params_data, 20, _global_s /** Reset the type array. */ void StringParameters::ClearTypeInformation() { - assert(this->type != NULL); + assert(this->type != nullptr); MemSetT(this->type, 0, this->num_param); } @@ -77,8 +73,11 @@ int64 StringParameters::GetInt64(WChar type) DEBUG(misc, 0, "Trying to read invalid string parameter"); return 0; } - if (this->type != NULL) { - assert(this->type[this->offset] == 0 || this->type[this->offset] == type); + if (this->type != nullptr) { + if (this->type[this->offset] != 0 && this->type[this->offset] != type) { + DEBUG(misc, 0, "Trying to read string parameter with wrong type"); + return 0; + } this->type[this->offset] = type; } return this->data[this->offset++]; @@ -120,7 +119,8 @@ void SetDParamMaxValue(uint n, uint64 max_value, uint min_count, FontSize size) */ void SetDParamMaxDigits(uint n, uint count, FontSize size) { - uint front, next; + uint front = 0; + uint next = 0; GetBroadestDigit(&front, &next, size); uint64 val = count > 1 ? front : next; for (; count > 1; count--) { @@ -170,7 +170,7 @@ void CopyOutDParam(uint64 *dst, const char **strings, StringID string, int num) strings[i] = stredup((const char *)(size_t)_global_string_params.GetParam(i)); dst[i] = (size_t)strings[i]; } else { - strings[i] = NULL; + strings[i] = nullptr; } } } @@ -318,7 +318,7 @@ static char *FormatNumber(char *buff, int64 number, const char *last, const char for (int i = 0; i < max_digits; i++) { if (i == max_digits - fractional_digits) { const char *decimal_separator = _settings_game.locale.digit_decimal_separator; - if (decimal_separator == NULL) decimal_separator = _langpack->digit_decimal_separator; + if (decimal_separator == nullptr) decimal_separator = _langpack->digit_decimal_separator; buff += seprintf(buff, last, "%s", decimal_separator); } @@ -343,7 +343,7 @@ static char *FormatNumber(char *buff, int64 number, const char *last, const char static char *FormatCommaNumber(char *buff, int64 number, const char *last, int fractional_digits = 0) { const char *separator = _settings_game.locale.digit_group_separator; - if (separator == NULL) separator = _langpack->digit_group_separator; + if (separator == nullptr) separator = _langpack->digit_group_separator; return FormatNumber(buff, number, last, separator, 1, fractional_digits); } @@ -382,7 +382,7 @@ static char *FormatBytes(char *buff, int64 number, const char *last) } const char *decimal_separator = _settings_game.locale.digit_decimal_separator; - if (decimal_separator == NULL) decimal_separator = _langpack->digit_decimal_separator; + if (decimal_separator == nullptr) decimal_separator = _langpack->digit_decimal_separator; if (number < 1024) { id = 0; @@ -476,8 +476,8 @@ static char *FormatGenericCurrency(char *buff, const CurrencySpec *spec, Money n } const char *separator = _settings_game.locale.digit_group_separator_currency; - if (separator == NULL && !StrEmpty(_currency->separator)) separator = _currency->separator; - if (separator == NULL) separator = _langpack->digit_group_separator_currency; + if (separator == nullptr && !StrEmpty(_currency->separator)) separator = _currency->separator; + if (separator == nullptr) separator = _langpack->digit_group_separator_currency; buff = FormatNumber(buff, number, last, separator); buff = strecpy(buff, multiplier, last); @@ -935,7 +935,7 @@ static char *FormatString(char *buff, const char *str_arg, StringParameters *arg char buf[256]; bool old_sgd = _scan_for_gender_data; _scan_for_gender_data = true; - StringParameters tmp_params(args->GetPointerToOffset(offset), args->num_param - offset, NULL); + StringParameters tmp_params(args->GetPointerToOffset(offset), args->num_param - offset, nullptr); p = FormatString(buf, input, &tmp_params, lastof(buf)); _scan_for_gender_data = old_sgd; *p = '\0'; @@ -1014,8 +1014,8 @@ static char *FormatString(char *buff, const char *str_arg, StringParameters *arg if (game_script && GetStringTab(str) != 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 NULL and it will tell you */ - StringParameters tmp_params(args->GetDataPointer(), args->GetDataLeft(), NULL); + * 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); next_substr_case_index = 0; break; @@ -1268,9 +1268,9 @@ static char *FormatString(char *buff, const char *str_arg, StringParameters *arg case SCC_COMPANY_NAME: { // {COMPANY} const Company *c = Company::GetIfValid(args->GetInt32()); - if (c == NULL) break; + if (c == nullptr) break; - if (c->name != NULL) { + if (c->name != nullptr) { int64 args_array[] = {(int64)(size_t)c->name}; StringParameters tmp_params(args_array); buff = GetStringWithArgs(buff, STR_JUST_RAW_STRING, &tmp_params, last); @@ -1305,7 +1305,7 @@ static char *FormatString(char *buff, const char *str_arg, StringParameters *arg } const Depot *d = Depot::Get(args->GetInt32()); - if (d->name != NULL) { + if (d->name != nullptr) { int64 args_array[] = {(int64)(size_t)d->name}; StringParameters tmp_params(args_array); buff = GetStringWithArgs(buff, STR_JUST_RAW_STRING, &tmp_params, last); @@ -1319,14 +1319,14 @@ 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)); - if (e == NULL) break; + if (e == nullptr) break; - if (e->name != NULL && e->IsEnabled()) { + if (e->name != nullptr && e->IsEnabled()) { int64 args_array[] = {(int64)(size_t)e->name}; StringParameters tmp_params(args_array); buff = GetStringWithArgs(buff, STR_JUST_RAW_STRING, &tmp_params, last); } else { - StringParameters tmp_params(NULL, 0, NULL); + StringParameters tmp_params(nullptr, 0, nullptr); buff = GetStringWithArgs(buff, e->info.string_id, &tmp_params, last); } break; @@ -1334,9 +1334,9 @@ static char *FormatString(char *buff, const char *str_arg, StringParameters *arg case SCC_GROUP_NAME: { // {GROUP} const Group *g = Group::GetIfValid(args->GetInt32()); - if (g == NULL) break; + if (g == nullptr) break; - if (g->name != NULL) { + if (g->name != nullptr) { int64 args_array[] = {(int64)(size_t)g->name}; StringParameters tmp_params(args_array); buff = GetStringWithArgs(buff, STR_JUST_RAW_STRING, &tmp_params, last); @@ -1351,12 +1351,12 @@ static char *FormatString(char *buff, const char *str_arg, StringParameters *arg case SCC_INDUSTRY_NAME: { // {INDUSTRY} const Industry *i = Industry::GetIfValid(args->GetInt32(SCC_INDUSTRY_NAME)); - if (i == NULL) break; + if (i == nullptr) break; if (_scan_for_gender_data) { /* Gender is defined by the industry type. * STR_FORMAT_INDUSTRY_NAME may have the town first, so it would result in the gender of the town name */ - StringParameters tmp_params(NULL, 0, NULL); + StringParameters tmp_params(nullptr, 0, nullptr); buff = FormatString(buff, GetStringPtr(GetIndustrySpec(i->type)->name), &tmp_params, last, next_substr_case_index); } else { /* First print the town name and the industry type name. */ @@ -1371,9 +1371,9 @@ static char *FormatString(char *buff, const char *str_arg, StringParameters *arg case SCC_PRESIDENT_NAME: { // {PRESIDENT_NAME} const Company *c = Company::GetIfValid(args->GetInt32(SCC_PRESIDENT_NAME)); - if (c == NULL) break; + if (c == nullptr) break; - if (c->president_name != NULL) { + if (c->president_name != nullptr) { int64 args_array[] = {(int64)(size_t)c->president_name}; StringParameters tmp_params(args_array); buff = GetStringWithArgs(buff, STR_JUST_RAW_STRING, &tmp_params, last); @@ -1389,16 +1389,16 @@ static char *FormatString(char *buff, const char *str_arg, StringParameters *arg StationID sid = args->GetInt32(SCC_STATION_NAME); const Station *st = Station::GetIfValid(sid); - if (st == NULL) { + if (st == nullptr) { /* The station doesn't exist anymore. The only place where we might * be "drawing" an invalid station is in the case of cargo that is * in transit. */ - StringParameters tmp_params(NULL, 0, NULL); + StringParameters tmp_params(nullptr, 0, nullptr); buff = GetStringWithArgs(buff, STR_UNKNOWN_STATION, &tmp_params, last); break; } - if (st->name != NULL) { + if (st->name != nullptr) { int64 args_array[] = {(int64)(size_t)st->name}; StringParameters tmp_params(args_array); buff = GetStringWithArgs(buff, STR_JUST_RAW_STRING, &tmp_params, last); @@ -1416,8 +1416,9 @@ static char *FormatString(char *buff, const char *str_arg, StringParameters *arg } } - int64 args_array[] = {STR_TOWN_NAME, st->town->index, st->index}; - StringParameters tmp_params(args_array); + 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); } break; @@ -1425,9 +1426,9 @@ static char *FormatString(char *buff, const char *str_arg, StringParameters *arg case SCC_TOWN_NAME: { // {TOWN} const Town *t = Town::GetIfValid(args->GetInt32(SCC_TOWN_NAME)); - if (t == NULL) break; + if (t == nullptr) break; - if (t->name != NULL) { + if (t->name != nullptr) { int64 args_array[] = {(int64)(size_t)t->name}; StringParameters tmp_params(args_array); buff = GetStringWithArgs(buff, STR_JUST_RAW_STRING, &tmp_params, last); @@ -1439,9 +1440,9 @@ static char *FormatString(char *buff, const char *str_arg, StringParameters *arg case SCC_WAYPOINT_NAME: { // {WAYPOINT} Waypoint *wp = Waypoint::GetIfValid(args->GetInt32(SCC_WAYPOINT_NAME)); - if (wp == NULL) break; + if (wp == nullptr) break; - if (wp->name != NULL) { + if (wp->name != nullptr) { int64 args_array[] = {(int64)(size_t)wp->name}; StringParameters tmp_params(args_array); buff = GetStringWithArgs(buff, STR_JUST_RAW_STRING, &tmp_params, last); @@ -1457,9 +1458,9 @@ static char *FormatString(char *buff, const char *str_arg, StringParameters *arg case SCC_VEHICLE_NAME: { // {VEHICLE} const Vehicle *v = Vehicle::GetIfValid(args->GetInt32(SCC_VEHICLE_NAME)); - if (v == NULL) break; + if (v == nullptr) break; - if (v->name != NULL) { + if (v->name != nullptr) { int64 args_array[] = {(int64)(size_t)v->name}; StringParameters tmp_params(args_array); buff = GetStringWithArgs(buff, STR_JUST_RAW_STRING, &tmp_params, last); @@ -1483,14 +1484,14 @@ static char *FormatString(char *buff, const char *str_arg, StringParameters *arg case SCC_SIGN_NAME: { // {SIGN} const Sign *si = Sign::GetIfValid(args->GetInt32()); - if (si == NULL) break; + if (si == nullptr) break; - if (si->name != NULL) { + if (si->name != nullptr) { int64 args_array[] = {(int64)(size_t)si->name}; StringParameters tmp_params(args_array); buff = GetStringWithArgs(buff, STR_JUST_RAW_STRING, &tmp_params, last); } else { - StringParameters tmp_params(NULL, 0, NULL); + StringParameters tmp_params(nullptr, 0, nullptr); buff = GetStringWithArgs(buff, STR_DEFAULT_SIGN_NAME, &tmp_params, last); } break; @@ -1670,7 +1671,7 @@ static char *GetSpecialNameString(char *buff, int ind, StringParameters *args, c } /* resolution size? */ - if (IsInsideMM(ind, (SPECSTR_RESOLUTION_START - 0x70E4), (SPECSTR_RESOLUTION_END - 0x70E4) + 1)) { + if (IsInsideBS(ind, (SPECSTR_RESOLUTION_START - 0x70E4), _resolutions.size())) { int i = ind - (SPECSTR_RESOLUTION_START - 0x70E4); buff += seprintf( buff, last, "%ux%u", _resolutions[i].width, _resolutions[i].height @@ -1681,11 +1682,7 @@ static char *GetSpecialNameString(char *buff, int ind, StringParameters *args, c NOT_REACHED(); } -#ifdef ENABLE_NETWORK extern void SortNetworkLanguages(); -#else /* ENABLE_NETWORK */ -static inline void SortNetworkLanguages() {} -#endif /* ENABLE_NETWORK */ /** * Check whether the header is a valid header for OpenTTD. @@ -1718,7 +1715,7 @@ bool ReadLanguagePack(const LanguageMetadata *lang) /* Current language pack */ size_t len; LanguagePack *lang_pack = (LanguagePack *)ReadFileToMem(lang->file, &len, 1U << 20); - if (lang_pack == NULL) return false; + if (lang_pack == nullptr) return false; /* End of read data (+ terminating zero added in ReadFileToMem()) */ const char *end = (char *)lang_pack + len + 1; @@ -1796,24 +1793,24 @@ bool ReadLanguagePack(const LanguageMetadata *lang) MacOSSetCurrentLocaleName(_current_language->isocode); #endif -#ifdef WITH_ICU_SORT +#ifdef WITH_ICU_I18N /* Delete previous collator. */ - if (_current_collator != NULL) { + if (_current_collator != nullptr) { delete _current_collator; - _current_collator = NULL; + _current_collator = nullptr; } /* Create a collator instance for our current locale. */ UErrorCode status = U_ZERO_ERROR; _current_collator = icu::Collator::createInstance(icu::Locale(_current_language->isocode), status); /* Sort number substrings by their numerical value. */ - if (_current_collator != NULL) _current_collator->setAttribute(UCOL_NUMERIC_COLLATION, UCOL_ON, status); + if (_current_collator != nullptr) _current_collator->setAttribute(UCOL_NUMERIC_COLLATION, UCOL_ON, status); /* Avoid using the collator if it is not correctly set. */ if (U_FAILURE(status)) { delete _current_collator; - _current_collator = NULL; + _current_collator = nullptr; } -#endif /* WITH_ICU_SORT */ +#endif /* WITH_ICU_I18N */ /* Some lists need to be sorted again after a language change. */ ReconsiderGameScriptLanguage(); @@ -1821,9 +1818,7 @@ bool ReadLanguagePack(const LanguageMetadata *lang) SortIndustryTypes(); BuildIndustriesLegend(); SortNetworkLanguages(); -#ifdef ENABLE_NETWORK BuildContentTypeStringList(); -#endif /* ENABLE_NETWORK */ InvalidateWindowClassesData(WC_BUILD_VEHICLE); // Build vehicle window. InvalidateWindowClassesData(WC_TRAINS_LIST); // Train group window. InvalidateWindowClassesData(WC_ROADVEH_LIST); // Road vehicle group window. @@ -1843,22 +1838,22 @@ bool ReadLanguagePack(const LanguageMetadata *lang) * First check some default values, after this one we passed ourselves * and if none exist return the value for $LANG * @param param environment variable to check conditionally if default ones are not - * set. Pass NULL if you don't want additional checks. - * @return return string containing current charset, or NULL if not-determinable + * set. Pass nullptr if you don't want additional checks. + * @return return string containing current charset, or nullptr if not-determinable */ const char *GetCurrentLocale(const char *param) { const char *env; env = getenv("LANGUAGE"); - if (env != NULL) return env; + if (env != nullptr) return env; env = getenv("LC_ALL"); - if (env != NULL) return env; + if (env != nullptr) return env; - if (param != NULL) { + if (param != nullptr) { env = getenv(param); - if (env != NULL) return env; + if (env != nullptr) return env; } return getenv("LANG"); @@ -1867,28 +1862,28 @@ const char *GetCurrentLocale(const char *param) const char *GetCurrentLocale(const char *param); #endif /* !(defined(_WIN32) || defined(__APPLE__)) */ -int CDECL StringIDSorter(const StringID *a, const StringID *b) +bool StringIDSorter(const StringID &a, const StringID &b) { char stra[512]; char strb[512]; - GetString(stra, *a, lastof(stra)); - GetString(strb, *b, lastof(strb)); + GetString(stra, a, lastof(stra)); + GetString(strb, b, lastof(strb)); - return strnatcmp(stra, strb); + return strnatcmp(stra, strb) < 0; } /** * Get the language with the given NewGRF language ID. * @param newgrflangid NewGRF languages ID to check. - * @return The language's metadata, or NULL if it is not known. + * @return The language's metadata, or nullptr if it is not known. */ const LanguageMetadata *GetLanguage(byte newgrflangid) { - for (const LanguageMetadata *lang = _languages.Begin(); lang != _languages.End(); lang++) { - if (newgrflangid == lang->newgrflangid) return lang; + for (const LanguageMetadata &lang : _languages) { + if (newgrflangid == lang.newgrflangid) return ⟨ } - return NULL; + return nullptr; } /** @@ -1900,7 +1895,7 @@ const LanguageMetadata *GetLanguage(byte newgrflangid) static bool GetLanguageFileHeader(const char *file, LanguagePackHeader *hdr) { FILE *f = fopen(file, "rb"); - if (f == NULL) return false; + if (f == nullptr) return false; size_t read = fread(hdr, sizeof(*hdr), 1, f); fclose(f); @@ -1922,14 +1917,14 @@ static bool GetLanguageFileHeader(const char *file, LanguagePackHeader *hdr) static void GetLanguageList(const char *path) { DIR *dir = ttd_opendir(path); - if (dir != NULL) { + if (dir != nullptr) { struct dirent *dirent; - while ((dirent = readdir(dir)) != NULL) { + while ((dirent = readdir(dir)) != nullptr) { const char *d_name = FS2OTTD(dirent->d_name); const char *extension = strrchr(d_name, '.'); /* Not a language file */ - if (extension == NULL || strcmp(extension, ".lng") != 0) continue; + if (extension == nullptr || strcmp(extension, ".lng") != 0) continue; LanguageMetadata lmd; seprintf(lmd.file, lastof(lmd.file), "%s%s", path, d_name); @@ -1937,10 +1932,10 @@ static void GetLanguageList(const char *path) /* Check whether the file is of the correct version */ if (!GetLanguageFileHeader(lmd.file, &lmd)) { DEBUG(misc, 3, "%s is not a valid language file", lmd.file); - } else if (GetLanguage(lmd.newgrflangid) != NULL) { + } else if (GetLanguage(lmd.newgrflangid) != nullptr) { DEBUG(misc, 3, "%s's language ID is already known", lmd.file); } else { - *_languages.Append() = lmd; + _languages.push_back(lmd); } } closedir(dir); @@ -1960,36 +1955,36 @@ void InitializeLanguagePacks() FioAppendDirectory(path, lastof(path), sp, LANG_DIR); GetLanguageList(path); } - if (_languages.Length() == 0) usererror("No available language packs (invalid versions?)"); + if (_languages.size() == 0) usererror("No available language packs (invalid versions?)"); /* Acquire the locale of the current system */ const char *lang = GetCurrentLocale("LC_MESSAGES"); - if (lang == NULL) lang = "en_GB"; + if (lang == nullptr) lang = "en_GB"; - const LanguageMetadata *chosen_language = NULL; ///< Matching the language in the configuration file or the current locale - const LanguageMetadata *language_fallback = NULL; ///< Using pt_PT for pt_BR locale when pt_BR is not available - const LanguageMetadata *en_GB_fallback = _languages.Begin(); ///< Fallback when no locale-matching language has been found + const LanguageMetadata *chosen_language = nullptr; ///< Matching the language in the configuration file or the current locale + const LanguageMetadata *language_fallback = nullptr; ///< Using pt_PT for pt_BR locale when pt_BR is not available + const LanguageMetadata *en_GB_fallback = _languages.data(); ///< Fallback when no locale-matching language has been found /* Find a proper language. */ - for (const LanguageMetadata *lng = _languages.Begin(); lng != _languages.End(); lng++) { + for (const LanguageMetadata &lng : _languages) { /* We are trying to find a default language. The priority is by * configuration file, local environment and last, if nothing found, * English. */ - const char *lang_file = strrchr(lng->file, PATHSEPCHAR) + 1; + const char *lang_file = strrchr(lng.file, PATHSEPCHAR) + 1; if (strcmp(lang_file, _config_language_file) == 0) { - chosen_language = lng; + chosen_language = &lng; break; } - if (strcmp (lng->isocode, "en_GB") == 0) en_GB_fallback = lng; - if (strncmp(lng->isocode, lang, 5) == 0) chosen_language = lng; - if (strncmp(lng->isocode, lang, 2) == 0) language_fallback = lng; + if (strcmp (lng.isocode, "en_GB") == 0) en_GB_fallback = &lng; + if (strncmp(lng.isocode, lang, 5) == 0) chosen_language = &lng; + if (strncmp(lng.isocode, lang, 2) == 0) language_fallback = &lng; } /* We haven't found the language in the config nor the one in the locale. * Now we set it to one of the fallback languages */ - if (chosen_language == NULL) { - chosen_language = (language_fallback != NULL) ? language_fallback : en_GB_fallback; + if (chosen_language == nullptr) { + chosen_language = (language_fallback != nullptr) ? language_fallback : en_GB_fallback; } if (!ReadLanguagePack(chosen_language)) usererror("Can't read language pack '%s'", chosen_language->file); @@ -2008,7 +2003,7 @@ const char *GetCurrentLanguageIsoCode() * Check whether there are glyphs missing in the current language. * @param[out] str Pointer to an address for storing the text pointer. * @return If glyphs are missing, return \c true, else return \c false. - * @post If \c true is returned and str is not NULL, *str points to a string that is found to contain at least one missing glyph. + * @post If \c true is returned and str is not nullptr, *str points to a string that is found to contain at least one missing glyph. */ int MissingGlyphSearcher::FindMissingGlyphs(const char **str) { @@ -2021,9 +2016,9 @@ int MissingGlyphSearcher::FindMissingGlyphs(const char **str) this->Reset(); int missing = 0; - for (const char *text = this->NextString(); text != NULL; text = this->NextString()) { + for (const char *text = this->NextString(); text != nullptr; text = this->NextString()) { FontSize size = this->DefaultSize(); - if (str != NULL) *str = text; + if (str != nullptr) *str = text; for (WChar c = Utf8Consume(&text); c != '\0'; c = Utf8Consume(&text)) { if (c >= SCC_FIRST_FONT && c <= SCC_LAST_FONT) { size = (FontSize)(c - SCC_FIRST_FONT); @@ -2041,20 +2036,20 @@ class LanguagePackGlyphSearcher : public MissingGlyphSearcher { uint i; ///< Iterator for the primary language tables. uint j; ///< Iterator for the secondary language tables. - /* virtual */ void Reset() + void Reset() override { this->i = 0; this->j = 0; } - /* virtual */ FontSize DefaultSize() + FontSize DefaultSize() override { return FS_NORMAL; } - /* virtual */ const char *NextString() + const char *NextString() override { - if (this->i >= TEXT_TAB_END) return NULL; + if (this->i >= TEXT_TAB_END) return nullptr; const char *ret = _langpack_offs[_langtab_start[this->i] + this->j]; @@ -2067,18 +2062,23 @@ class LanguagePackGlyphSearcher : public MissingGlyphSearcher { return ret; } - /* virtual */ bool Monospace() + bool Monospace() override { return false; } - /* virtual */ void SetFontNames(FreeTypeSettings *settings, const char *font_name) + void SetFontNames(FreeTypeSettings *settings, const char *font_name, const void *os_data) override { -#ifdef WITH_FREETYPE +#if defined(WITH_FREETYPE) || defined(_WIN32) strecpy(settings->small.font, font_name, lastof(settings->small.font)); strecpy(settings->medium.font, font_name, lastof(settings->medium.font)); strecpy(settings->large.font, font_name, lastof(settings->large.font)); -#endif /* WITH_FREETYPE */ + + free(settings->medium.os_handle); // Only free one, they are all the same pointer. + settings->small.os_handle = os_data; + settings->medium.os_handle = os_data; + settings->large.os_handle = os_data; +#endif } }; @@ -2093,22 +2093,28 @@ class LanguagePackGlyphSearcher : public MissingGlyphSearcher { * been added. * @param base_font Whether to look at the base font as well. * @param searcher The methods to use to search for strings to check. - * If NULL the loaded language pack searcher is used. + * If nullptr the loaded language pack searcher is used. */ void CheckForMissingGlyphs(bool base_font, MissingGlyphSearcher *searcher) { static LanguagePackGlyphSearcher pack_searcher; - if (searcher == NULL) searcher = &pack_searcher; - bool bad_font = !base_font || searcher->FindMissingGlyphs(NULL); -#ifdef WITH_FREETYPE + if (searcher == nullptr) searcher = &pack_searcher; + bool bad_font = !base_font || searcher->FindMissingGlyphs(nullptr); +#if defined(WITH_FREETYPE) || defined(_WIN32) if (bad_font) { /* We found an unprintable character... lets try whether we can find * a fallback font that can print the characters in the current language. */ FreeTypeSettings backup; memcpy(&backup, &_freetype, sizeof(backup)); + _freetype.mono.os_handle = nullptr; + _freetype.medium.os_handle = nullptr; + bad_font = !SetFallbackFont(&_freetype, _langpack->isocode, _langpack->winlangid, searcher); + free(_freetype.mono.os_handle); + free(_freetype.medium.os_handle); + memcpy(&_freetype, &backup, sizeof(backup)); if (bad_font && base_font) { @@ -2139,7 +2145,7 @@ void CheckForMissingGlyphs(bool base_font, MissingGlyphSearcher *searcher) /* Update the font with cache */ LoadStringWidthTable(searcher->Monospace()); -#if !defined(WITH_ICU_LAYOUT) && !defined(WITH_UNISCRIBE) && !defined(WITH_COCOA) +#if !defined(WITH_ICU_LX) && !defined(WITH_UNISCRIBE) && !defined(WITH_COCOA) /* * For right-to-left languages we need the ICU library. If * we do not have support for that library we warn the user @@ -2159,5 +2165,5 @@ void CheckForMissingGlyphs(bool base_font, MissingGlyphSearcher *searcher) SetDParamStr(0, err_str); ShowErrorMessage(STR_JUST_RAW_STRING, INVALID_STRING_ID, WL_ERROR); } -#endif /* !WITH_ICU_LAYOUT */ +#endif /* !WITH_ICU_LX */ } diff --git a/src/strings_func.h b/src/strings_func.h index 41ecc305eb..71b12136ae 100644 --- a/src/strings_func.h +++ b/src/strings_func.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. @@ -60,9 +58,9 @@ static inline StringID MakeStringID(StringTab tab, uint index) } class StringParameters { - StringParameters *parent; ///< If not NULL, this instance references data from this parent instance. + StringParameters *parent; ///< If not nullptr, this instance references data from this parent instance. uint64 *data; ///< Array with the actual data. - WChar *type; ///< Array with type information about the data. Can be NULL when no type information is needed. See #StringControlCode. + WChar *type; ///< Array with type information about the data. Can be nullptr when no type information is needed. See #StringControlCode. public: uint offset; ///< Current offset in the data/type arrays. @@ -70,7 +68,7 @@ public: /** Create a new StringParameters instance. */ StringParameters(uint64 *data, uint num_param, WChar *type) : - parent(NULL), + parent(nullptr), data(data), type(type), offset(0), @@ -80,9 +78,9 @@ public: /** Create a new StringParameters instance. */ template StringParameters(int64 (&data)[Tnum_param]) : - parent(NULL), + parent(nullptr), data((uint64 *)data), - type(NULL), + type(nullptr), offset(0), num_param(Tnum_param) { @@ -100,8 +98,8 @@ public: num_param(size) { assert(size <= parent.GetDataLeft()); - if (parent.type == NULL) { - this->type = NULL; + if (parent.type == nullptr) { + this->type = nullptr; } else { this->type = parent.type + parent.offset; } @@ -109,7 +107,7 @@ public: ~StringParameters() { - if (this->parent != NULL) { + if (this->parent != nullptr) { this->parent->offset += this->num_param; } } @@ -148,7 +146,7 @@ public: /** Does this instance store information about the type of the parameters. */ bool HasTypeInformation() const { - return this->type != NULL; + return this->type != nullptr; } /** Get the type of a specific element. */ @@ -238,7 +236,7 @@ extern TextDirection _current_text_dir; ///< Text direction of the currently sel void InitializeLanguagePacks(); const char *GetCurrentLanguageIsoCode(); -int CDECL StringIDSorter(const StringID *a, const StringID *b); +bool StringIDSorter(const StringID &a, const StringID &b); /** * A searcher for missing glyphs. @@ -250,7 +248,7 @@ public: /** * Get the next string to search through. - * @return The next string or NULL if there is none. + * @return The next string or nullptr if there is none. */ virtual const char *NextString() = 0; @@ -275,12 +273,13 @@ public: * Set the right font names. * @param settings The settings to modify. * @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) = 0; + virtual void SetFontNames(struct FreeTypeSettings *settings, const char *font_name, const void *os_data = nullptr) = 0; int FindMissingGlyphs(const char **str); }; -void CheckForMissingGlyphs(bool base_font = true, MissingGlyphSearcher *search = NULL); +void CheckForMissingGlyphs(bool base_font = true, MissingGlyphSearcher *search = nullptr); #endif /* STRINGS_FUNC_H */ diff --git a/src/strings_type.h b/src/strings_type.h index 9862196ece..41ddfa957e 100644 --- a/src/strings_type.h +++ b/src/strings_type.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. @@ -93,9 +91,8 @@ enum SpecialStrings { SPECSTR_LANGUAGE_START = 0x7100, SPECSTR_LANGUAGE_END = SPECSTR_LANGUAGE_START + MAX_LANG - 1, - /* reserve 100 strings for various screen resolutions */ + /* reserve strings for various screen resolutions MUST BE THE LAST VALUE IN THIS ENUM */ SPECSTR_RESOLUTION_START = SPECSTR_LANGUAGE_END + 1, - SPECSTR_RESOLUTION_END = SPECSTR_RESOLUTION_START + 99, }; #endif /* STRINGS_TYPE_H */ diff --git a/src/subsidy.cpp b/src/subsidy.cpp index d1fda0f0ac..e3913a2891 100644 --- a/src/subsidy.cpp +++ b/src/subsidy.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. @@ -132,14 +130,11 @@ static inline void SetPartOfSubsidyFlag(SourceType type, SourceID index, PartOfS /** Perform a full rebuild of the subsidies cache. */ void RebuildSubsidisedSourceAndDestinationCache() { - Town *t; - FOR_ALL_TOWNS(t) t->cache.part_of_subsidy = POS_NONE; + for (Town *t : Town::Iterate()) t->cache.part_of_subsidy = POS_NONE; - Industry *i; - FOR_ALL_INDUSTRIES(i) i->part_of_subsidy = POS_NONE; + for (Industry *i : Industry::Iterate()) i->part_of_subsidy = POS_NONE; - const Subsidy *s; - FOR_ALL_SUBSIDIES(s) { + for (const Subsidy *s : Subsidy::Iterate()) { SetPartOfSubsidyFlag(s->src_type, s->src, POS_SRC); SetPartOfSubsidyFlag(s->dst_type, s->dst, POS_DST); } @@ -154,8 +149,7 @@ void DeleteSubsidyWith(SourceType type, SourceID index) { bool dirty = false; - Subsidy *s; - FOR_ALL_SUBSIDIES(s) { + for (Subsidy *s : Subsidy::Iterate()) { if ((s->src_type == type && s->src == index) || (s->dst_type == type && s->dst == index)) { delete s; dirty = true; @@ -179,8 +173,7 @@ void DeleteSubsidyWith(SourceType type, SourceID index) */ static bool CheckSubsidyDuplicate(CargoID cargo, SourceType src_type, SourceID src, SourceType dst_type, SourceID dst) { - const Subsidy *s; - FOR_ALL_SUBSIDIES(s) { + for (const Subsidy *s : Subsidy::Iterate()) { if (s->cargo_type == cargo && s->src_type == src_type && s->src == src && s->dst_type == dst_type && s->dst == dst) { @@ -333,6 +326,7 @@ bool FindSubsidyTownCargoRoute() /* Select a random town. */ const Town *src_town = Town::GetRandom(); + if (src_town->cache.population < SUBSIDY_CARGO_MIN_POPULATION) return false; CargoTypes town_cargo_produced = src_town->cargo_produced; @@ -376,7 +370,7 @@ bool FindSubsidyIndustryCargoRoute() /* Select a random industry. */ const Industry *src_ind = Industry::GetRandom(); - if (src_ind == NULL) return false; + if (src_ind == nullptr) return false; uint trans, total; @@ -441,7 +435,7 @@ bool FindSubsidyCargoDestination(CargoID cid, SourceType src_type, SourceID src) case ST_INDUSTRY: { /* Select a random industry. */ const Industry *dst_ind = Industry::GetRandom(); - if (dst_ind == NULL) return false; + if (dst_ind == nullptr) return false; /* The industry must accept the cargo */ bool valid = std::find(dst_ind->accepts_cargo, endof(dst_ind->accepts_cargo), cid) != endof(dst_ind->accepts_cargo); @@ -473,8 +467,7 @@ void SubsidyMonthlyLoop() { bool modified = false; - Subsidy *s; - FOR_ALL_SUBSIDIES(s) { + for (Subsidy *s : Subsidy::Iterate()) { if (--s->remaining == 0) { if (!s->IsAwarded()) { Pair reftype = SetupSubsidyDecodeParam(s, true); @@ -564,24 +557,19 @@ bool CheckSubsidised(CargoID cargo_type, CompanyID company, SourceType src_type, /* Remember all towns near this station (at least one house in its catchment radius) * which are destination of subsidised path. Do that only if needed */ - SmallVector towns_near; + std::vector towns_near; if (!st->rect.IsEmpty()) { - Subsidy *s; - FOR_ALL_SUBSIDIES(s) { + for (const Subsidy *s : Subsidy::Iterate()) { /* Don't create the cache if there is no applicable subsidy with town as destination */ if (s->dst_type != ST_TOWN) continue; if (s->cargo_type != cargo_type || s->src_type != src_type || s->src != src) continue; if (s->IsAwarded() && s->awarded != company) continue; - Rect rect = st->GetCatchmentRect(); - - for (int y = rect.top; y <= rect.bottom; y++) { - for (int x = rect.left; x <= rect.right; x++) { - TileIndex tile = TileXY(x, y); - if (!IsTileType(tile, MP_HOUSE)) continue; - const Town *t = Town::GetByTile(tile); - if (t->cache.part_of_subsidy & POS_DST) towns_near.Include(t); - } + BitmapTileIterator it(st->catchment_tiles); + for (TileIndex tile = it; tile != INVALID_TILE; tile = ++it) { + if (!IsTileType(tile, MP_HOUSE)) continue; + const Town *t = Town::GetByTile(tile); + if (t->cache.part_of_subsidy & POS_DST) include(towns_near, t); } break; } @@ -591,23 +579,22 @@ bool CheckSubsidised(CargoID cargo_type, CompanyID company, SourceType src_type, /* Check if there's a (new) subsidy that applies. There can be more subsidies triggered by this delivery! * Think about the case that subsidies are A->B and A->C and station has both B and C in its catchment area */ - Subsidy *s; - FOR_ALL_SUBSIDIES(s) { + for (Subsidy *s : Subsidy::Iterate()) { if (s->cargo_type == cargo_type && s->src_type == src_type && s->src == src && (!s->IsAwarded() || s->awarded == company)) { switch (s->dst_type) { case ST_INDUSTRY: - for (const Industry * const *ip = st->industries_near.Begin(); ip != st->industries_near.End(); ip++) { - if (s->dst == (*ip)->index) { - assert((*ip)->part_of_subsidy & POS_DST); + for (Industry *ind : st->industries_near) { + if (s->dst == ind->index) { + assert(ind->part_of_subsidy & POS_DST); subsidised = true; if (!s->IsAwarded()) s->AwardTo(company); } } break; case ST_TOWN: - for (const Town * const *tp = towns_near.Begin(); tp != towns_near.End(); tp++) { - if (s->dst == (*tp)->index) { - assert((*tp)->cache.part_of_subsidy & POS_DST); + for (const Town *tp : towns_near) { + if (s->dst == tp->index) { + assert(tp->cache.part_of_subsidy & POS_DST); subsidised = true; if (!s->IsAwarded()) s->AwardTo(company); } diff --git a/src/subsidy_base.h b/src/subsidy_base.h index f12fbc4b9b..ef26f64167 100644 --- a/src/subsidy_base.h +++ b/src/subsidy_base.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. @@ -22,13 +20,13 @@ extern SubsidyPool _subsidy_pool; /** Struct about subsidies, offered and awarded */ struct Subsidy : SubsidyPool::PoolItem<&_subsidy_pool> { - CargoID cargo_type; ///< Cargo type involved in this subsidy, CT_INVALID for invalid subsidy - byte remaining; ///< Remaining months when this subsidy is valid - CompanyByte awarded; ///< Subsidy is awarded to this company; INVALID_COMPANY if it's not awarded to anyone - SourceTypeByte src_type; ///< Source of subsidised path (ST_INDUSTRY or ST_TOWN) - SourceTypeByte dst_type; ///< Destination of subsidised path (ST_INDUSTRY or ST_TOWN) - SourceID src; ///< Index of source. Either TownID or IndustryID - SourceID dst; ///< Index of destination. Either TownID or IndustryID + CargoID cargo_type; ///< Cargo type involved in this subsidy, CT_INVALID for invalid subsidy + byte remaining; ///< Remaining months when this subsidy is valid + CompanyID awarded; ///< Subsidy is awarded to this company; INVALID_COMPANY if it's not awarded to anyone + SourceType src_type; ///< Source of subsidised path (ST_INDUSTRY or ST_TOWN) + SourceType dst_type; ///< Destination of subsidised path (ST_INDUSTRY or ST_TOWN) + SourceID src; ///< Index of source. Either TownID or IndustryID + SourceID dst; ///< Index of destination. Either TownID or IndustryID /** * We need an (empty) constructor so struct isn't zeroed (as C++ standard states) @@ -36,7 +34,7 @@ struct Subsidy : SubsidyPool::PoolItem<&_subsidy_pool> { inline Subsidy() { } /** - * (Empty) destructor has to be defined else operator delete might be called with NULL parameter + * (Empty) destructor has to be defined else operator delete might be called with nullptr parameter */ inline ~Subsidy() { } @@ -60,7 +58,4 @@ static const uint SUBSIDY_CARGO_MIN_POPULATION = 900; ///< Min. population of de static const uint SUBSIDY_MAX_PCT_TRANSPORTED = 42; ///< Subsidy will be created only for towns/industries with less % transported static const uint SUBSIDY_MAX_DISTANCE = 70; ///< Max. length of subsidised route (DistanceManhattan) -#define FOR_ALL_SUBSIDIES_FROM(var, start) FOR_ALL_ITEMS_FROM(Subsidy, subsidy_index, var, start) -#define FOR_ALL_SUBSIDIES(var) FOR_ALL_SUBSIDIES_FROM(var, 0) - #endif /* SUBSIDY_BASE_H */ diff --git a/src/subsidy_func.h b/src/subsidy_func.h index 2e53e14d7a..4889ead249 100644 --- a/src/subsidy_func.h +++ b/src/subsidy_func.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/subsidy_gui.cpp b/src/subsidy_gui.cpp index 0e7c35d0e5..d3f5a9d31d 100644 --- a/src/subsidy_gui.cpp +++ b/src/subsidy_gui.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. @@ -38,14 +36,13 @@ struct SubsidyListWindow : Window { this->OnInvalidateData(0); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { if (widget != WID_SUL_PANEL) return; int y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SUL_PANEL, WD_FRAMERECT_TOP); int num = 0; - const Subsidy *s; - FOR_ALL_SUBSIDIES(s) { + for (const Subsidy *s : Subsidy::Iterate()) { if (!s->IsAwarded()) { y--; if (y == 0) { @@ -64,7 +61,7 @@ struct SubsidyListWindow : Window { y -= 2; // "Services already subsidised:" if (y < 0) return; - FOR_ALL_SUBSIDIES(s) { + for (const Subsidy *s : Subsidy::Iterate()) { if (s->IsAwarded()) { y--; if (y == 0) { @@ -112,8 +109,7 @@ struct SubsidyListWindow : Window { /* Count number of (non) awarded subsidies */ uint num_awarded = 0; uint num_not_awarded = 0; - const Subsidy *s; - FOR_ALL_SUBSIDIES(s) { + for (const Subsidy *s : Subsidy::Iterate()) { if (!s->IsAwarded()) { num_not_awarded++; } else { @@ -129,7 +125,7 @@ struct SubsidyListWindow : Window { return 3 + num_awarded + num_not_awarded; } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { if (widget != WID_SUL_PANEL) return; Dimension d = maxdim(GetStringBoundingBox(STR_SUBSIDIES_OFFERED_TITLE), GetStringBoundingBox(STR_SUBSIDIES_SUBSIDISED_TITLE)); @@ -143,7 +139,7 @@ struct SubsidyListWindow : Window { *size = maxdim(*size, d); } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { if (widget != WID_SUL_PANEL) return; @@ -163,8 +159,7 @@ struct SubsidyListWindow : Window { pos++; uint num = 0; - const Subsidy *s; - FOR_ALL_SUBSIDIES(s) { + for (const Subsidy *s : Subsidy::Iterate()) { if (!s->IsAwarded()) { if (IsInsideMM(pos, 0, cap)) { /* Displays the two offered towns */ @@ -188,7 +183,7 @@ struct SubsidyListWindow : Window { pos++; num = 0; - FOR_ALL_SUBSIDIES(s) { + for (const Subsidy *s : Subsidy::Iterate()) { if (s->IsAwarded()) { if (IsInsideMM(pos, 0, cap)) { SetupSubsidyDecodeParam(s, true); @@ -209,7 +204,7 @@ struct SubsidyListWindow : Window { } } - virtual void OnResize() + void OnResize() override { this->vscroll->SetCapacityFromWidget(this, WID_SUL_PANEL); } @@ -219,7 +214,7 @@ struct SubsidyListWindow : Window { * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; this->vscroll->SetCount(this->CountLines()); diff --git a/src/subsidy_type.h b/src/subsidy_type.h index 83c33a00a9..6ee80ca3c1 100644 --- a/src/subsidy_type.h +++ b/src/subsidy_type.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. @@ -15,14 +13,11 @@ #include "core/enum_type.hpp" /** What part of a subsidy is something? */ -enum PartOfSubsidy { +enum PartOfSubsidy : byte { POS_NONE = 0, ///< nothing POS_SRC = 1 << 0, ///< bit 0 set -> town/industry is source of subsidised path POS_DST = 1 << 1, ///< bit 1 set -> town/industry is destination of subsidised path }; -/** Helper to store the PartOfSubsidy data in a single byte. */ -typedef SimpleTinyEnumT PartOfSubsidyByte; - DECLARE_ENUM_AS_BIT_SET(PartOfSubsidy) typedef uint16 SubsidyID; ///< ID of a subsidy diff --git a/src/table/airport_defaults.h b/src/table/airport_defaults.h index 593e157ac3..ec30874f71 100644 --- a/src/table/airport_defaults.h +++ b/src/table/airport_defaults.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. @@ -386,7 +384,7 @@ static const Direction _default_airports_rotation[] = { /** AirportSpec definition for airports without any depot. */ #define AS_ND(ap_name, size_x, size_y, min_year, max_year, catchment, noise, maint_cost, ttdpatch_type, class_id, name, preview) \ - AS_GENERIC(&_airportfta_##ap_name, _tile_table_##ap_name, _default_airports_rotation, lengthof(_tile_table_##ap_name), NULL, 0, \ + AS_GENERIC(&_airportfta_##ap_name, _tile_table_##ap_name, _default_airports_rotation, lengthof(_tile_table_##ap_name), nullptr, 0, \ size_x, size_y, noise, catchment, min_year, max_year, maint_cost, ttdpatch_type, class_id, name, preview, true) /** AirportSpec definition for airports with at least one depot. */ @@ -405,12 +403,12 @@ extern const AirportSpec _origin_airport_specs[] = { AS(helidepot, 2, 2, 1976, MAX_YEAR, 4, 2, 7, ATP_TTDP_SMALL, APC_HELIPORT, STR_AIRPORT_HELIDEPOT, SPR_AIRPORT_PREVIEW_HELIDEPOT), AS(intercontinental, 9, 11, 2002, MAX_YEAR, 10, 25, 72, ATP_TTDP_LARGE, APC_HUB, STR_AIRPORT_INTERCONTINENTAL, SPR_AIRPORT_PREVIEW_INTERCONTINENTAL), AS(helistation, 4, 2, 1980, MAX_YEAR, 4, 3, 14, ATP_TTDP_SMALL, APC_HELIPORT, STR_AIRPORT_HELISTATION, SPR_AIRPORT_PREVIEW_HELISTATION), - AS_GENERIC(&_airportfta_oilrig, NULL, _default_airports_rotation, 0, NULL, 0, 1, 1, 0, 4, 0, 0, 0, ATP_TTDP_OILRIG, APC_HELIPORT, STR_NULL, 0, false), + AS_GENERIC(&_airportfta_oilrig, nullptr, _default_airports_rotation, 0, nullptr, 0, 1, 1, 0, 4, 0, 0, 0, ATP_TTDP_OILRIG, APC_HELIPORT, STR_NULL, 0, false), }; assert_compile(NEW_AIRPORT_OFFSET == lengthof(_origin_airport_specs)); -const AirportSpec AirportSpec::dummy = AS_GENERIC(&_airportfta_dummy, NULL, _default_airports_rotation, 0, NULL, 0, 0, 0, 0, 0, MIN_YEAR, MIN_YEAR, 0, ATP_TTDP_LARGE, APC_BEGIN, STR_NULL, 0, false); +const AirportSpec AirportSpec::dummy = AS_GENERIC(&_airportfta_dummy, nullptr, _default_airports_rotation, 0, nullptr, 0, 0, 0, 0, 0, MIN_YEAR, MIN_YEAR, 0, ATP_TTDP_LARGE, APC_BEGIN, STR_NULL, 0, false); #undef AS #undef AS_ND diff --git a/src/table/airport_movement.h b/src/table/airport_movement.h index d9030f652c..14fe1c9abb 100644 --- a/src/table/airport_movement.h +++ b/src/table/airport_movement.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. @@ -34,7 +32,7 @@ struct AirportFTAbuildup { * @param flags Movement flags. * @param dir Direction. */ -#define AMD(x, y, flags, dir) { x, y, flags, {dir} } +#define AMD(x, y, flags, dir) { x, y, flags, dir } /** Dummy airport. */ static const AirportMovingData _airport_moving_data_dummy[] = { @@ -71,10 +69,10 @@ static const AirportMovingData _airport_moving_data_country[22] = { }; /** Commuter Airfield (small) 5x4. */ -static const AirportMovingData _airport_moving_data_commuter[37] = { +static const AirportMovingData _airport_moving_data_commuter[38] = { AMD( 69, 3, AMED_EXACTPOS, DIR_SE), // 00 In Hangar AMD( 72, 22, 0, DIR_N ), // 01 Taxi to right outside depot - AMD( 8, 22, AMED_EXACTPOS, DIR_SW), // 01 Taxi to right outside depot + AMD( 8, 22, AMED_EXACTPOS, DIR_SW), // 02 Taxi to right outside depot AMD( 24, 36, AMED_EXACTPOS, DIR_SE), // 03 Terminal 1 AMD( 40, 36, AMED_EXACTPOS, DIR_SE), // 04 Terminal 2 AMD( 56, 36, AMED_EXACTPOS, DIR_SE), // 05 Terminal 3 @@ -108,8 +106,9 @@ static const AirportMovingData _airport_moving_data_commuter[37] = { AMD( 48, 8, AMED_HELI_RAISE, DIR_N ), // 32 Takeoff Helipad2 AMD( 64, 22, AMED_NOSPDCLAMP | AMED_SLOWTURN, DIR_N ), // 33 Go to position for Hangarentrance in air AMD( 64, 22, AMED_HELI_LOWER, DIR_N ), // 34 Land in front of hangar - AMD( 40, 8, AMED_EXACTPOS, DIR_N ), // pre-helitakeoff helipad 1 - AMD( 56, 8, AMED_EXACTPOS, DIR_N ), // pre-helitakeoff helipad 2 + AMD( 40, 8, AMED_EXACTPOS, DIR_N ), // 35 pre-helitakeoff helipad 1 + AMD( 56, 8, AMED_EXACTPOS, DIR_N ), // 36 pre-helitakeoff helipad 2 + AMD( 64, 25, AMED_HELI_RAISE, DIR_N ), // 37 Take off in front of hangar }; /** City Airport (large) 6x6. */ @@ -179,11 +178,11 @@ static const AirportMovingData _airport_moving_data_metropolitan[28] = { }; /** International Airport (international) - 2 runways, 6 terminals, dedicated helipad. */ -static const AirportMovingData _airport_moving_data_international[51] = { +static const AirportMovingData _airport_moving_data_international[53] = { AMD( 7, 55, AMED_EXACTPOS, DIR_SE), // 00 In Hangar 1 AMD( 100, 21, AMED_EXACTPOS, DIR_SE), // 01 In Hangar 2 - AMD( 7, 70, 0, DIR_N ), // 02 Taxi to right outside depot - AMD( 100, 36, 0, DIR_N ), // 03 Taxi to right outside depot + AMD( 7, 70, 0, DIR_N ), // 02 Taxi to right outside depot (Hangar 1) + AMD( 100, 36, 0, DIR_N ), // 03 Taxi to right outside depot (Hangar 2) AMD( 38, 70, AMED_EXACTPOS, DIR_SW), // 04 Terminal 1 AMD( 38, 54, AMED_EXACTPOS, DIR_SW), // 05 Terminal 2 AMD( 38, 38, AMED_EXACTPOS, DIR_SW), // 06 Terminal 3 @@ -232,6 +231,8 @@ static const AirportMovingData _airport_moving_data_international[51] = { AMD( 104, 55, AMED_HELI_RAISE, DIR_N ), // 48 Takeoff Helipad2 AMD( 104, 32, AMED_NOSPDCLAMP | AMED_SLOWTURN, DIR_N ), // 49 Go to position for Hangarentrance in air AMD( 104, 32, AMED_HELI_LOWER, DIR_N ), // 50 Land in HANGAR2_AREA to go to hangar + AMD( 7, 70, AMED_HELI_RAISE, DIR_N ), // 51 Takeoff from HANGAR1_AREA + AMD( 100, 36, AMED_HELI_RAISE, DIR_N ), // 52 Takeoff from HANGAR2_AREA }; /** Intercontinental Airport - 4 runways, 8 terminals, 2 dedicated helipads. */ @@ -408,11 +409,11 @@ static const AirportMovingData _airport_moving_data_oilrig[9] = { /////**********Movement Machine on Airports*********************/////// static const byte _airport_entries_dummy[] = {0, 1, 2, 3}; static const AirportFTAbuildup _airport_fta_dummy[] = { - { 0, 0, 0, 3}, - { 1, 0, 0, 0}, - { 2, 0, 0, 1}, - { 3, 0, 0, 2}, - { MAX_ELEMENTS, 0, 0, 0 } // end marker. DO NOT REMOVE + { 0, TO_ALL, 0, 3}, + { 1, TO_ALL, 0, 0}, + { 2, TO_ALL, 0, 1}, + { 3, TO_ALL, 0, 2}, + { MAX_ELEMENTS, TO_ALL, 0, 0 } // end marker. DO NOT REMOVE }; /* First element of terminals array tells us how many depots there are (to know size of array) @@ -422,11 +423,11 @@ static const byte _airport_terminal_country[] = {1, 2}; static const byte _airport_entries_country[] = {16, 15, 18, 17}; static const AirportFTAbuildup _airport_fta_country[] = { { 0, HANGAR, NOTHING_block, 1 }, - { 1, 255, AIRPORT_BUSY_block, 0 }, { 1, HANGAR, 0, 0 }, { 1, TERM1, TERM1_block, 2 }, { 1, TERM2, 0, 4 }, { 1, HELITAKEOFF, 0, 19 }, { 1, 0, 0, 6 }, + { 1, TERMGROUP, AIRPORT_BUSY_block, 0 }, { 1, HANGAR, 0, 0 }, { 1, TERM1, TERM1_block, 2 }, { 1, TERM2, 0, 4 }, { 1, HELITAKEOFF, 0, 19 }, { 1, TO_ALL, 0, 6 }, { 2, TERM1, TERM1_block, 1 }, { 3, TERM2, TERM2_block, 5 }, - { 4, 255, AIRPORT_BUSY_block, 0 }, { 4, TERM2, 0, 5 }, { 4, HANGAR, 0, 1 }, { 4, TAKEOFF, 0, 6 }, { 4, HELITAKEOFF, 0, 1 }, - { 5, 255, AIRPORT_BUSY_block, 0 }, { 5, TERM2, TERM2_block, 3 }, { 5, 0, 0, 4 }, + { 4, TERMGROUP, AIRPORT_BUSY_block, 0 }, { 4, TERM2, 0, 5 }, { 4, HANGAR, 0, 1 }, { 4, TAKEOFF, 0, 6 }, { 4, HELITAKEOFF, 0, 1 }, + { 5, TERMGROUP, AIRPORT_BUSY_block, 0 }, { 5, TERM2, TERM2_block, 3 }, { 5, TO_ALL, 0, 4 }, { 6, 0, AIRPORT_BUSY_block, 7 }, /* takeoff */ { 7, TAKEOFF, AIRPORT_BUSY_block, 8 }, @@ -435,82 +436,83 @@ static const AirportFTAbuildup _airport_fta_country[] = { /* landing */ { 10, FLYING, NOTHING_block, 15 }, { 10, LANDING, 0, 11 }, { 10, HELILANDING, 0, 20 }, { 11, LANDING, AIRPORT_BUSY_block, 12 }, - { 12, 0, AIRPORT_BUSY_block, 13 }, - { 13, ENDLANDING, AIRPORT_BUSY_block, 14 }, { 13, TERM2, 0, 5 }, { 13, 0, 0, 14 }, - { 14, 0, AIRPORT_BUSY_block, 1 }, + { 12, TO_ALL, AIRPORT_BUSY_block, 13 }, + { 13, ENDLANDING, AIRPORT_BUSY_block, 14 }, { 13, TERM2, 0, 5 }, { 13, TO_ALL, 0, 14 }, + { 14, TO_ALL, AIRPORT_BUSY_block, 1 }, /* In air */ - { 15, 0, NOTHING_block, 16 }, - { 16, 0, NOTHING_block, 17 }, - { 17, 0, NOTHING_block, 18 }, - { 18, 0, NOTHING_block, 10 }, + { 15, TO_ALL, NOTHING_block, 16 }, + { 16, TO_ALL, NOTHING_block, 17 }, + { 17, TO_ALL, NOTHING_block, 18 }, + { 18, TO_ALL, NOTHING_block, 10 }, { 19, HELITAKEOFF, NOTHING_block, 0 }, { 20, HELILANDING, AIRPORT_BUSY_block, 21 }, { 21, HELIENDLANDING, AIRPORT_BUSY_block, 1 }, - { MAX_ELEMENTS, 0, 0, 0 } // end marker. DO NOT REMOVE + { MAX_ELEMENTS, TO_ALL, 0, 0 } // end marker. DO NOT REMOVE }; static const HangarTileTable _airport_depots_commuter[] = { {{4, 0}, DIR_SE, 0} }; static const byte _airport_terminal_commuter[] = { 1, 3 }; static const byte _airport_entries_commuter[] = {22, 21, 24, 23}; static const AirportFTAbuildup _airport_fta_commuter[] = { - { 0, HANGAR, NOTHING_block, 1 }, { 0, HELITAKEOFF, HELIPAD2_block, 1 }, { 0, 0, 0, 1 }, - { 1, 255, TAXIWAY_BUSY_block, 0 }, { 1, HANGAR, 0, 0 }, { 1, TAKEOFF, 0, 11 }, { 1, TERM1, TAXIWAY_BUSY_block, 10 }, { 1, TERM2, TAXIWAY_BUSY_block, 10 }, { 1, TERM3, TAXIWAY_BUSY_block, 10 }, { 1, HELIPAD1, TAXIWAY_BUSY_block, 10 }, { 1, HELIPAD2, TAXIWAY_BUSY_block, 10 }, { 1, HELITAKEOFF, TAXIWAY_BUSY_block, 10 }, { 1, 0, 0, 0 }, - { 2, 255, AIRPORT_ENTRANCE_block, 2 }, { 2, HANGAR, 0, 8 }, { 2, TERM1, 0, 8 }, { 2, TERM2, 0, 8 }, { 2, TERM3, 0, 8 }, { 2, HELIPAD1, 0, 8 }, { 2, HELIPAD2, 0, 8 }, { 2, HELITAKEOFF, 0, 8 }, { 2, 0, 0, 2 }, - { 3, TERM1, TERM1_block, 8 }, { 3, HANGAR, 0, 8 }, { 3, TAKEOFF, 0, 8 }, { 3, 0, 0, 3 }, - { 4, TERM2, TERM2_block, 9 }, { 4, HANGAR, 0, 9 }, { 4, TAKEOFF, 0, 9 }, { 4, 0, 0, 4 }, - { 5, TERM3, TERM3_block, 10 }, { 5, HANGAR, 0, 10 }, { 5, TAKEOFF, 0, 10 }, { 5, 0, 0, 5 }, + { 0, HANGAR, NOTHING_block, 1 }, { 0, HELITAKEOFF, TAXIWAY_BUSY_block, 1 }, { 0, TO_ALL, 0, 1 }, + { 1, TERMGROUP, TAXIWAY_BUSY_block, 0 }, { 1, HANGAR, 0, 0 }, { 1, TAKEOFF, 0, 11 }, { 1, TERM1, TAXIWAY_BUSY_block, 10 }, { 1, TERM2, TAXIWAY_BUSY_block, 10 }, { 1, TERM3, TAXIWAY_BUSY_block, 10 }, { 1, HELIPAD1, TAXIWAY_BUSY_block, 10 }, { 1, HELIPAD2, TAXIWAY_BUSY_block, 10 }, { 1, HELITAKEOFF, TAXIWAY_BUSY_block, 37 }, { 1, TO_ALL, 0, 0 }, + { 2, TERMGROUP, AIRPORT_ENTRANCE_block, 2 }, { 2, HANGAR, 0, 8 }, { 2, TERM1, 0, 8 }, { 2, TERM2, 0, 8 }, { 2, TERM3, 0, 8 }, { 2, HELIPAD1, 0, 8 }, { 2, HELIPAD2, 0, 8 }, { 2, HELITAKEOFF, 0, 8 }, { 2, TO_ALL, 0, 2 }, + { 3, TERM1, TERM1_block, 8 }, { 3, HANGAR, 0, 8 }, { 3, TAKEOFF, 0, 8 }, { 3, TO_ALL, 0, 3 }, + { 4, TERM2, TERM2_block, 9 }, { 4, HANGAR, 0, 9 }, { 4, TAKEOFF, 0, 9 }, { 4, TO_ALL, 0, 4 }, + { 5, TERM3, TERM3_block, 10 }, { 5, HANGAR, 0, 10 }, { 5, TAKEOFF, 0, 10 }, { 5, TO_ALL, 0, 5 }, { 6, HELIPAD1, HELIPAD1_block, 6 }, { 6, HANGAR, TAXIWAY_BUSY_block, 9 }, { 6, HELITAKEOFF, 0, 35 }, { 7, HELIPAD2, HELIPAD2_block, 7 }, { 7, HANGAR, TAXIWAY_BUSY_block, 10 }, { 7, HELITAKEOFF, 0, 36 }, - { 8, 255, TAXIWAY_BUSY_block, 8 }, { 8, TAKEOFF, TAXIWAY_BUSY_block, 9 }, { 8, HANGAR, TAXIWAY_BUSY_block, 9 }, { 8, TERM1, TERM1_block, 3 }, { 8, 0, TAXIWAY_BUSY_block, 9 }, - { 9, 255, TAXIWAY_BUSY_block, 9 }, { 9, TAKEOFF, TAXIWAY_BUSY_block, 10 }, { 9, HANGAR, TAXIWAY_BUSY_block, 10 }, { 9, TERM2, TERM2_block, 4 }, { 9, HELIPAD1, HELIPAD1_block, 6 }, { 9, HELITAKEOFF, HELIPAD1_block, 6 }, { 9, TERM1, TAXIWAY_BUSY_block, 8 }, { 9, 0, TAXIWAY_BUSY_block, 10 }, - { 10, 255, TAXIWAY_BUSY_block, 10 }, { 10, TERM3, TERM3_block, 5 }, { 10, HELIPAD1, 0, 9 }, { 10, HELIPAD2, HELIPAD2_block, 7 }, { 10, HELITAKEOFF, HELIPAD2_block, 7 }, { 10, TAKEOFF, TAXIWAY_BUSY_block, 1 }, { 10, HANGAR, TAXIWAY_BUSY_block, 1 }, { 10, 0, TAXIWAY_BUSY_block, 9 }, - { 11, 0, OUT_WAY_block, 12 }, + { 8, TERMGROUP, TAXIWAY_BUSY_block, 8 }, { 8, TAKEOFF, TAXIWAY_BUSY_block, 9 }, { 8, HANGAR, TAXIWAY_BUSY_block, 9 }, { 8, TERM1, TERM1_block, 3 }, { 8, TO_ALL, TAXIWAY_BUSY_block, 9 }, + { 9, TERMGROUP, TAXIWAY_BUSY_block, 9 }, { 9, TAKEOFF, TAXIWAY_BUSY_block, 10 }, { 9, HANGAR, TAXIWAY_BUSY_block, 10 }, { 9, TERM2, TERM2_block, 4 }, { 9, HELIPAD1, HELIPAD1_block, 6 }, { 9, HELITAKEOFF, HELIPAD1_block, 6 }, { 9, TERM1, TAXIWAY_BUSY_block, 8 }, { 9, TO_ALL, TAXIWAY_BUSY_block, 10 }, + { 10, TERMGROUP, TAXIWAY_BUSY_block, 10 }, { 10, TERM3, TERM3_block, 5 }, { 10, HELIPAD1, 0, 9 }, { 10, HELIPAD2, HELIPAD2_block, 7 }, { 10, HELITAKEOFF, 0, 1 }, { 10, TAKEOFF, TAXIWAY_BUSY_block, 1 }, { 10, HANGAR, TAXIWAY_BUSY_block, 1 }, { 10, TO_ALL, TAXIWAY_BUSY_block, 9 }, + { 11, TO_ALL, OUT_WAY_block, 12 }, /* takeoff */ { 12, TAKEOFF, RUNWAY_IN_OUT_block, 13 }, - { 13, 0, RUNWAY_IN_OUT_block, 14 }, + { 13, TO_ALL, RUNWAY_IN_OUT_block, 14 }, { 14, STARTTAKEOFF, RUNWAY_IN_OUT_block, 15 }, { 15, ENDTAKEOFF, NOTHING_block, 0 }, /* landing */ { 16, FLYING, NOTHING_block, 21 }, { 16, LANDING, IN_WAY_block, 17 }, { 16, HELILANDING, 0, 25 }, { 17, LANDING, RUNWAY_IN_OUT_block, 18 }, - { 18, 0, RUNWAY_IN_OUT_block, 19 }, - { 19, 0, RUNWAY_IN_OUT_block, 20 }, + { 18, TO_ALL, RUNWAY_IN_OUT_block, 19 }, + { 19, TO_ALL, RUNWAY_IN_OUT_block, 20 }, { 20, ENDLANDING, IN_WAY_block, 2 }, /* In Air */ - { 21, 0, NOTHING_block, 22 }, - { 22, 0, NOTHING_block, 23 }, - { 23, 0, NOTHING_block, 24 }, - { 24, 0, NOTHING_block, 16 }, + { 21, TO_ALL, NOTHING_block, 22 }, + { 22, TO_ALL, NOTHING_block, 23 }, + { 23, TO_ALL, NOTHING_block, 24 }, + { 24, TO_ALL, NOTHING_block, 16 }, /* Helicopter -- stay in air in special place as a buffer to choose from helipads */ { 25, HELILANDING, PRE_HELIPAD_block, 26 }, { 26, HELIENDLANDING, PRE_HELIPAD_block, 26 }, { 26, HELIPAD1, 0, 27 }, { 26, HELIPAD2, 0, 28 }, { 26, HANGAR, 0, 33 }, - { 27, 0, NOTHING_block, 29 }, // helipad1 approach - { 28, 0, NOTHING_block, 30 }, + { 27, TO_ALL, NOTHING_block, 29 }, // helipad1 approach + { 28, TO_ALL, NOTHING_block, 30 }, /* landing */ - { 29, 255, NOTHING_block, 0 }, { 29, HELIPAD1, HELIPAD1_block, 6 }, - { 30, 255, NOTHING_block, 0 }, { 30, HELIPAD2, HELIPAD2_block, 7 }, + { 29, TERMGROUP, NOTHING_block, 0 }, { 29, HELIPAD1, HELIPAD1_block, 6 }, + { 30, TERMGROUP, NOTHING_block, 0 }, { 30, HELIPAD2, HELIPAD2_block, 7 }, /* Helicopter -- takeoff */ { 31, HELITAKEOFF, NOTHING_block, 0 }, { 32, HELITAKEOFF, NOTHING_block, 0 }, - { 33, 0, TAXIWAY_BUSY_block, 34 }, // need to go to hangar when waiting in air - { 34, 0, TAXIWAY_BUSY_block, 1 }, - { 35, 0, HELIPAD1_block, 31 }, - { 36, 0, HELIPAD2_block, 32 }, - { MAX_ELEMENTS, 0, 0, 0 } // end marker. DO NOT REMOVE + { 33, TO_ALL, TAXIWAY_BUSY_block, 34 }, // need to go to hangar when waiting in air + { 34, TO_ALL, TAXIWAY_BUSY_block, 1 }, + { 35, TO_ALL, HELIPAD1_block, 31 }, + { 36, TO_ALL, HELIPAD2_block, 32 }, + { 37, HELITAKEOFF, NOTHING_block, 0 }, + { MAX_ELEMENTS, TO_ALL, 0, 0 } // end marker. DO NOT REMOVE }; static const HangarTileTable _airport_depots_city[] = { {{5, 0}, DIR_SE, 0} }; static const byte _airport_terminal_city[] = { 1, 3 }; static const byte _airport_entries_city[] = {26, 29, 27, 28}; static const AirportFTAbuildup _airport_fta_city[] = { - { 0, HANGAR, NOTHING_block, 1 }, { 0, TAKEOFF, OUT_WAY_block, 1 }, { 0, 0, 0, 1 }, - { 1, 255, TAXIWAY_BUSY_block, 0 }, { 1, HANGAR, 0, 0 }, { 1, TERM2, 0, 6 }, { 1, TERM3, 0, 6 }, { 1, 0, 0, 7 }, // for all else, go to 7 - { 2, TERM1, TERM1_block, 7 }, { 2, TAKEOFF, OUT_WAY_block, 7 }, { 2, 0, 0, 7 }, - { 3, TERM2, TERM2_block, 5 }, { 3, TAKEOFF, OUT_WAY_block, 6 }, { 3, 0, 0, 6 }, - { 4, TERM3, TERM3_block, 5 }, { 4, TAKEOFF, OUT_WAY_block, 5 }, { 4, 0, 0, 5 }, - { 5, 255, TAXIWAY_BUSY_block, 0 }, { 5, TERM2, TERM2_block, 3 }, { 5, TERM3, TERM3_block, 4 }, { 5, 0, 0, 6 }, - { 6, 255, TAXIWAY_BUSY_block, 0 }, { 6, TERM2, TERM2_block, 3 }, { 6, TERM3, 0, 5 }, { 6, HANGAR, 0, 1 }, { 6, 0, 0, 7 }, - { 7, 255, TAXIWAY_BUSY_block, 0 }, { 7, TERM1, TERM1_block, 2 }, { 7, TAKEOFF, OUT_WAY_block, 8 }, { 7, HELITAKEOFF, 0, 22 }, { 7, HANGAR, 0, 1 }, { 7, 0, 0, 6 }, + { 0, HANGAR, NOTHING_block, 1 }, { 0, TAKEOFF, OUT_WAY_block, 1 }, { 0, TO_ALL, 0, 1 }, + { 1, TERMGROUP, TAXIWAY_BUSY_block, 0 }, { 1, HANGAR, 0, 0 }, { 1, TERM2, 0, 6 }, { 1, TERM3, 0, 6 }, { 1, TO_ALL, 0, 7 }, // for all else, go to 7 + { 2, TERM1, TERM1_block, 7 }, { 2, TAKEOFF, OUT_WAY_block, 7 }, { 2, TO_ALL, 0, 7 }, + { 3, TERM2, TERM2_block, 5 }, { 3, TAKEOFF, OUT_WAY_block, 6 }, { 3, TO_ALL, 0, 6 }, + { 4, TERM3, TERM3_block, 5 }, { 4, TAKEOFF, OUT_WAY_block, 5 }, { 4, TO_ALL, 0, 5 }, + { 5, TERMGROUP, TAXIWAY_BUSY_block, 0 }, { 5, TERM2, TERM2_block, 3 }, { 5, TERM3, TERM3_block, 4 }, { 5, TO_ALL, 0, 6 }, + { 6, TERMGROUP, TAXIWAY_BUSY_block, 0 }, { 6, TERM2, TERM2_block, 3 }, { 6, TERM3, 0, 5 }, { 6, HANGAR, 0, 1 }, { 6, TO_ALL, 0, 7 }, + { 7, TERMGROUP, TAXIWAY_BUSY_block, 0 }, { 7, TERM1, TERM1_block, 2 }, { 7, TAKEOFF, OUT_WAY_block, 8 }, { 7, HELITAKEOFF, 0, 22 }, { 7, HANGAR, 0, 1 }, { 7, TO_ALL, 0, 6 }, { 8, 0, OUT_WAY_block, 9 }, { 9, 0, RUNWAY_IN_OUT_block, 10 }, /* takeoff */ @@ -520,24 +522,24 @@ static const AirportFTAbuildup _airport_fta_city[] = { /* landing */ { 13, FLYING, NOTHING_block, 18 }, { 13, LANDING, 0, 14 }, { 13, HELILANDING, 0, 23 }, { 14, LANDING, RUNWAY_IN_OUT_block, 15 }, - { 15, 0, RUNWAY_IN_OUT_block, 17 }, - { 16, 0, RUNWAY_IN_OUT_block, 17 }, // not used, left for compatibility + { 15, TO_ALL, RUNWAY_IN_OUT_block, 17 }, + { 16, TO_ALL, RUNWAY_IN_OUT_block, 17 }, // not used, left for compatibility { 17, ENDLANDING, IN_WAY_block, 7 }, /* In Air */ - { 18, 0, NOTHING_block, 25 }, - { 19, 0, NOTHING_block, 20 }, - { 20, 0, NOTHING_block, 21 }, - { 21, 0, NOTHING_block, 13 }, + { 18, TO_ALL, NOTHING_block, 25 }, + { 19, TO_ALL, NOTHING_block, 20 }, + { 20, TO_ALL, NOTHING_block, 21 }, + { 21, TO_ALL, NOTHING_block, 13 }, /* helicopter */ { 22, HELITAKEOFF, NOTHING_block, 0 }, { 23, HELILANDING, IN_WAY_block, 24 }, { 24, HELIENDLANDING, IN_WAY_block, 17 }, - { 25, 0, NOTHING_block, 20}, - { 26, 0, NOTHING_block, 19}, - { 27, 0, NOTHING_block, 28}, - { 28, 0, NOTHING_block, 19}, - { 29, 0, NOTHING_block, 26}, - { MAX_ELEMENTS, 0, 0, 0 } // end marker. DO NOT REMOVE + { 25, TO_ALL, NOTHING_block, 20}, + { 26, TO_ALL, NOTHING_block, 19}, + { 27, TO_ALL, NOTHING_block, 28}, + { 28, TO_ALL, NOTHING_block, 19}, + { 29, TO_ALL, NOTHING_block, 26}, + { MAX_ELEMENTS, TO_ALL, 0, 0 } // end marker. DO NOT REMOVE }; static const HangarTileTable _airport_depots_metropolitan[] = { {{5, 0}, DIR_SE, 0} }; @@ -545,13 +547,13 @@ static const byte _airport_terminal_metropolitan[] = { 1, 3 }; static const byte _airport_entries_metropolitan[] = {20, 19, 22, 21}; static const AirportFTAbuildup _airport_fta_metropolitan[] = { { 0, HANGAR, NOTHING_block, 1 }, - { 1, 255, TAXIWAY_BUSY_block, 0 }, { 1, HANGAR, 0, 0 }, { 1, TERM2, 0, 6 }, { 1, TERM3, 0, 6 }, { 1, 0, 0, 7 }, // for all else, go to 7 + { 1, TERMGROUP, TAXIWAY_BUSY_block, 0 }, { 1, HANGAR, 0, 0 }, { 1, TERM2, 0, 6 }, { 1, TERM3, 0, 6 }, { 1, TO_ALL, 0, 7 }, // for all else, go to 7 { 2, TERM1, TERM1_block, 7 }, { 3, TERM2, TERM2_block, 6 }, { 4, TERM3, TERM3_block, 5 }, - { 5, 255, TAXIWAY_BUSY_block, 0 }, { 5, TERM2, TERM2_block, 3 }, { 5, TERM3, TERM3_block, 4 }, { 5, 0, 0, 6 }, - { 6, 255, TAXIWAY_BUSY_block, 0 }, { 6, TERM2, TERM2_block, 3 }, { 6, TERM3, 0, 5 }, { 6, HANGAR, 0, 1 }, { 6, 0, 0, 7 }, - { 7, 255, TAXIWAY_BUSY_block, 0 }, { 7, TERM1, TERM1_block, 2 }, { 7, TAKEOFF, 0, 8 }, { 7, HELITAKEOFF, 0, 23 }, { 7, HANGAR, 0, 1 }, { 7, 0, 0, 6 }, + { 5, TERMGROUP, TAXIWAY_BUSY_block, 0 }, { 5, TERM2, TERM2_block, 3 }, { 5, TERM3, TERM3_block, 4 }, { 5, TO_ALL, 0, 6 }, + { 6, TERMGROUP, TAXIWAY_BUSY_block, 0 }, { 6, TERM2, TERM2_block, 3 }, { 6, TERM3, 0, 5 }, { 6, HANGAR, 0, 1 }, { 6, TO_ALL, 0, 7 }, + { 7, TERMGROUP, TAXIWAY_BUSY_block, 0 }, { 7, TERM1, TERM1_block, 2 }, { 7, TAKEOFF, 0, 8 }, { 7, HELITAKEOFF, 0, 23 }, { 7, HANGAR, 0, 1 }, { 7, TO_ALL, 0, 6 }, { 8, 0, OUT_WAY_block, 9 }, { 9, 0, RUNWAY_OUT_block, 10 }, /* takeoff */ @@ -561,86 +563,88 @@ static const AirportFTAbuildup _airport_fta_metropolitan[] = { /* landing */ { 13, FLYING, NOTHING_block, 19 }, { 13, LANDING, 0, 14 }, { 13, HELILANDING, 0, 25 }, { 14, LANDING, RUNWAY_IN_block, 15 }, - { 15, 0, RUNWAY_IN_block, 16 }, - { 16, 255, RUNWAY_IN_block, 0 }, { 16, ENDLANDING, IN_WAY_block, 17 }, - { 17, 255, RUNWAY_OUT_block, 0 }, { 17, ENDLANDING, IN_WAY_block, 18 }, + { 15, TO_ALL, RUNWAY_IN_block, 16 }, + { 16, TERMGROUP, RUNWAY_IN_block, 0 }, { 16, ENDLANDING, IN_WAY_block, 17 }, + { 17, TERMGROUP, RUNWAY_OUT_block, 0 }, { 17, ENDLANDING, IN_WAY_block, 18 }, { 18, ENDLANDING, IN_WAY_block, 27 }, /* In Air */ - { 19, 0, NOTHING_block, 20 }, - { 20, 0, NOTHING_block, 21 }, - { 21, 0, NOTHING_block, 22 }, - { 22, 0, NOTHING_block, 13 }, + { 19, TO_ALL, NOTHING_block, 20 }, + { 20, TO_ALL, NOTHING_block, 21 }, + { 21, TO_ALL, NOTHING_block, 22 }, + { 22, TO_ALL, NOTHING_block, 13 }, /* helicopter */ - { 23, 0, NOTHING_block, 24 }, + { 23, TO_ALL, NOTHING_block, 24 }, { 24, HELITAKEOFF, NOTHING_block, 0 }, { 25, HELILANDING, IN_WAY_block, 26 }, { 26, HELIENDLANDING, IN_WAY_block, 18 }, - { 27, 255, TAXIWAY_BUSY_block, 27 }, { 27, TERM1, TERM1_block, 2 }, { 27, 0, 0, 7 }, - { MAX_ELEMENTS, 0, 0, 0 } // end marker. DO NOT REMOVE + { 27, TERMGROUP, TAXIWAY_BUSY_block, 27 }, { 27, TERM1, TERM1_block, 2 }, { 27, TO_ALL, 0, 7 }, + { MAX_ELEMENTS, TO_ALL, 0, 0 } // end marker. DO NOT REMOVE }; static const HangarTileTable _airport_depots_international[] = { {{0, 3}, DIR_SE, 0}, {{6, 1}, DIR_SE, 1} }; static const byte _airport_terminal_international[] = { 2, 3, 3 }; static const byte _airport_entries_international[] = { 38, 37, 40, 39 }; static const AirportFTAbuildup _airport_fta_international[] = { - { 0, HANGAR, NOTHING_block, 2 }, { 0, 255, TERM_GROUP1_block, 0 }, { 0, 255, TERM_GROUP2_ENTER1_block, 1 }, { 0, HELITAKEOFF, HELIPAD1_block, 2 }, { 0, 0, 0, 2 }, - { 1, HANGAR, NOTHING_block, 3 }, { 1, 255, HANGAR2_AREA_block, 1 }, { 1, HELITAKEOFF, HELIPAD2_block, 3 }, { 1, 0, 0, 3 }, - { 2, 255, AIRPORT_ENTRANCE_block, 0 }, { 2, HANGAR, 0, 0 }, { 2, TERM4, 0, 12 }, { 2, TERM5, 0, 12 }, { 2, TERM6, 0, 12 }, { 2, HELIPAD1, 0, 12 }, { 2, HELIPAD2, 0, 12 }, { 2, HELITAKEOFF, 0, 12 }, { 2, 0, 0, 23 }, - { 3, 255, HANGAR2_AREA_block, 0 }, { 3, HANGAR, 0, 1 }, { 3, 0, 0, 18 }, - { 4, TERM1, TERM1_block, 23 }, { 4, HANGAR, AIRPORT_ENTRANCE_block, 23 }, { 4, 0, 0, 23 }, - { 5, TERM2, TERM2_block, 24 }, { 5, HANGAR, AIRPORT_ENTRANCE_block, 24 }, { 5, 0, 0, 24 }, - { 6, TERM3, TERM3_block, 25 }, { 6, HANGAR, AIRPORT_ENTRANCE_block, 25 }, { 6, 0, 0, 25 }, - { 7, TERM4, TERM4_block, 16 }, { 7, HANGAR, HANGAR2_AREA_block, 16 }, { 7, 0, 0, 16 }, - { 8, TERM5, TERM5_block, 17 }, { 8, HANGAR, HANGAR2_AREA_block, 17 }, { 8, 0, 0, 17 }, - { 9, TERM6, TERM6_block, 18 }, { 9, HANGAR, HANGAR2_AREA_block, 18 }, { 9, 0, 0, 18 }, + { 0, HANGAR, NOTHING_block, 2 }, { 0, TERMGROUP, TERM_GROUP1_block, 0 }, { 0, TERMGROUP, TERM_GROUP2_ENTER1_block, 1 }, { 0, HELITAKEOFF, AIRPORT_ENTRANCE_block, 2 }, { 0, TO_ALL, 0, 2 }, + { 1, HANGAR, NOTHING_block, 3 }, { 1, TERMGROUP, HANGAR2_AREA_block, 1 }, { 1, HELITAKEOFF, HANGAR2_AREA_block, 3 }, { 1, TO_ALL, 0, 3 }, + { 2, TERMGROUP, AIRPORT_ENTRANCE_block, 0 }, { 2, HANGAR, 0, 0 }, { 2, TERM4, 0, 12 }, { 2, TERM5, 0, 12 }, { 2, TERM6, 0, 12 }, { 2, HELIPAD1, 0, 12 }, { 2, HELIPAD2, 0, 12 }, { 2, HELITAKEOFF, 0, 51 }, { 2, TO_ALL, 0, 23 }, + { 3, TERMGROUP, HANGAR2_AREA_block, 0 }, { 3, HANGAR, 0, 1 }, { 3, HELITAKEOFF, 0, 52 }, { 3, TO_ALL, 0, 18 }, + { 4, TERM1, TERM1_block, 23 }, { 4, HANGAR, AIRPORT_ENTRANCE_block, 23 }, { 4, TO_ALL, 0, 23 }, + { 5, TERM2, TERM2_block, 24 }, { 5, HANGAR, AIRPORT_ENTRANCE_block, 24 }, { 5, TO_ALL, 0, 24 }, + { 6, TERM3, TERM3_block, 25 }, { 6, HANGAR, AIRPORT_ENTRANCE_block, 25 }, { 6, TO_ALL, 0, 25 }, + { 7, TERM4, TERM4_block, 16 }, { 7, HANGAR, HANGAR2_AREA_block, 16 }, { 7, TO_ALL, 0, 16 }, + { 8, TERM5, TERM5_block, 17 }, { 8, HANGAR, HANGAR2_AREA_block, 17 }, { 8, TO_ALL, 0, 17 }, + { 9, TERM6, TERM6_block, 18 }, { 9, HANGAR, HANGAR2_AREA_block, 18 }, { 9, TO_ALL, 0, 18 }, { 10, HELIPAD1, HELIPAD1_block, 10 }, { 10, HANGAR, HANGAR2_AREA_block, 16 }, { 10, HELITAKEOFF, 0, 47 }, { 11, HELIPAD2, HELIPAD2_block, 11 }, { 11, HANGAR, HANGAR2_AREA_block, 17 }, { 11, HELITAKEOFF, 0, 48 }, - { 12, 0, TERM_GROUP2_ENTER1_block, 13 }, - { 13, 0, TERM_GROUP2_ENTER1_block, 14 }, - { 14, 0, TERM_GROUP2_ENTER2_block, 15 }, - { 15, 0, TERM_GROUP2_ENTER2_block, 16 }, - { 16, 255, TERM_GROUP2_block, 0 }, { 16, TERM4, TERM4_block, 7 }, { 16, HELIPAD1, HELIPAD1_block, 10 }, { 16, HELITAKEOFF, HELIPAD1_block, 10 }, { 16, 0, 0, 17 }, - { 17, 255, TERM_GROUP2_block, 0 }, { 17, TERM5, TERM5_block, 8 }, { 17, TERM4, 0, 16 }, { 17, HELIPAD1, 0, 16 }, { 17, HELIPAD2, HELIPAD2_block, 11 }, { 17, HELITAKEOFF, HELIPAD2_block, 11 }, { 17, 0, 0, 18 }, - { 18, 255, TERM_GROUP2_block, 0 }, { 18, TERM6, TERM6_block, 9 }, { 18, TAKEOFF, 0, 19 }, { 18, HANGAR, HANGAR2_AREA_block, 3 }, { 18, 0, 0, 17 }, - { 19, 0, TERM_GROUP2_EXIT1_block, 20 }, - { 20, 0, TERM_GROUP2_EXIT1_block, 21 }, - { 21, 0, TERM_GROUP2_EXIT2_block, 22 }, - { 22, 0, TERM_GROUP2_EXIT2_block, 26 }, - { 23, 255, TERM_GROUP1_block, 0 }, { 23, TERM1, TERM1_block, 4 }, { 23, HANGAR, AIRPORT_ENTRANCE_block, 2 }, { 23, 0, 0, 24 }, - { 24, 255, TERM_GROUP1_block, 0 }, { 24, TERM2, TERM2_block, 5 }, { 24, TERM1, 0, 23 }, { 24, HANGAR, 0, 23 }, { 24, 0, 0, 25 }, - { 25, 255, TERM_GROUP1_block, 0 }, { 25, TERM3, TERM3_block, 6 }, { 25, TAKEOFF, 0, 26 }, { 25, 0, 0, 24 }, - { 26, 255, TAXIWAY_BUSY_block, 0 }, { 26, TAKEOFF, 0, 27 }, { 26, 0, 0, 25 }, - { 27, 0, OUT_WAY_block, 28 }, + { 12, TO_ALL, TERM_GROUP2_ENTER1_block, 13 }, + { 13, TO_ALL, TERM_GROUP2_ENTER1_block, 14 }, + { 14, TO_ALL, TERM_GROUP2_ENTER2_block, 15 }, + { 15, TO_ALL, TERM_GROUP2_ENTER2_block, 16 }, + { 16, TERMGROUP, TERM_GROUP2_block, 0 }, { 16, TERM4, TERM4_block, 7 }, { 16, HELIPAD1, HELIPAD1_block, 10 }, { 16, HELITAKEOFF, HELIPAD1_block, 10 }, { 16, TO_ALL, 0, 17 }, + { 17, TERMGROUP, TERM_GROUP2_block, 0 }, { 17, TERM5, TERM5_block, 8 }, { 17, TERM4, 0, 16 }, { 17, HELIPAD1, 0, 16 }, { 17, HELIPAD2, HELIPAD2_block, 11 }, { 17, HELITAKEOFF, HELIPAD2_block, 11 }, { 17, TO_ALL, 0, 18 }, + { 18, TERMGROUP, TERM_GROUP2_block, 0 }, { 18, TERM6, TERM6_block, 9 }, { 18, TAKEOFF, 0, 19 }, { 18, HANGAR, HANGAR2_AREA_block, 3 }, { 18, TO_ALL, 0, 17 }, + { 19, TO_ALL, TERM_GROUP2_EXIT1_block, 20 }, + { 20, TO_ALL, TERM_GROUP2_EXIT1_block, 21 }, + { 21, TO_ALL, TERM_GROUP2_EXIT2_block, 22 }, + { 22, TO_ALL, TERM_GROUP2_EXIT2_block, 26 }, + { 23, TERMGROUP, TERM_GROUP1_block, 0 }, { 23, TERM1, TERM1_block, 4 }, { 23, HANGAR, AIRPORT_ENTRANCE_block, 2 }, { 23, TO_ALL, 0, 24 }, + { 24, TERMGROUP, TERM_GROUP1_block, 0 }, { 24, TERM2, TERM2_block, 5 }, { 24, TERM1, 0, 23 }, { 24, HANGAR, 0, 23 }, { 24, TO_ALL, 0, 25 }, + { 25, TERMGROUP, TERM_GROUP1_block, 0 }, { 25, TERM3, TERM3_block, 6 }, { 25, TAKEOFF, 0, 26 }, { 25, TO_ALL, 0, 24 }, + { 26, TERMGROUP, TAXIWAY_BUSY_block, 0 }, { 26, TAKEOFF, 0, 27 }, { 26, TO_ALL, 0, 25 }, + { 27, TO_ALL, OUT_WAY_block, 28 }, /* takeoff */ { 28, TAKEOFF, OUT_WAY_block, 29 }, - { 29, 0, RUNWAY_OUT_block, 30 }, + { 29, TO_ALL, RUNWAY_OUT_block, 30 }, { 30, STARTTAKEOFF, NOTHING_block, 31 }, { 31, ENDTAKEOFF, NOTHING_block, 0 }, /* landing */ { 32, FLYING, NOTHING_block, 37 }, { 32, LANDING, 0, 33 }, { 32, HELILANDING, 0, 41 }, { 33, LANDING, RUNWAY_IN_block, 34 }, - { 34, 0, RUNWAY_IN_block, 35 }, - { 35, 0, RUNWAY_IN_block, 36 }, - { 36, ENDLANDING, IN_WAY_block, 36 }, { 36, 255, TERM_GROUP1_block, 0 }, { 36, 255, TERM_GROUP2_ENTER1_block, 1 }, { 36, TERM4, 0, 12 }, { 36, TERM5, 0, 12 }, { 36, TERM6, 0, 12 }, { 36, 0, 0, 2 }, + { 34, TO_ALL, RUNWAY_IN_block, 35 }, + { 35, TO_ALL, RUNWAY_IN_block, 36 }, + { 36, ENDLANDING, IN_WAY_block, 36 }, { 36, TERMGROUP, TERM_GROUP1_block, 0 }, { 36, TERMGROUP, TERM_GROUP2_ENTER1_block, 1 }, { 36, TERM4, 0, 12 }, { 36, TERM5, 0, 12 }, { 36, TERM6, 0, 12 }, { 36, TO_ALL, 0, 2 }, /* In Air */ - { 37, 0, NOTHING_block, 38 }, - { 38, 0, NOTHING_block, 39 }, - { 39, 0, NOTHING_block, 40 }, - { 40, 0, NOTHING_block, 32 }, + { 37, TO_ALL, NOTHING_block, 38 }, + { 38, TO_ALL, NOTHING_block, 39 }, + { 39, TO_ALL, NOTHING_block, 40 }, + { 40, TO_ALL, NOTHING_block, 32 }, /* Helicopter -- stay in air in special place as a buffer to choose from helipads */ { 41, HELILANDING, PRE_HELIPAD_block, 42 }, { 42, HELIENDLANDING, PRE_HELIPAD_block, 42 }, { 42, HELIPAD1, 0, 43 }, { 42, HELIPAD2, 0, 44 }, { 42, HANGAR, 0, 49 }, - { 43, 0, NOTHING_block, 45 }, - { 44, 0, NOTHING_block, 46 }, + { 43, TO_ALL, NOTHING_block, 45 }, + { 44, TO_ALL, NOTHING_block, 46 }, /* landing */ - { 45, 255, NOTHING_block, 0 }, { 45, HELIPAD1, HELIPAD1_block, 10 }, - { 46, 255, NOTHING_block, 0 }, { 46, HELIPAD2, HELIPAD2_block, 11 }, + { 45, TERMGROUP, NOTHING_block, 0 }, { 45, HELIPAD1, HELIPAD1_block, 10 }, + { 46, TERMGROUP, NOTHING_block, 0 }, { 46, HELIPAD2, HELIPAD2_block, 11 }, /* Helicopter -- takeoff */ { 47, HELITAKEOFF, NOTHING_block, 0 }, { 48, HELITAKEOFF, NOTHING_block, 0 }, - { 49, 0, HANGAR2_AREA_block, 50 }, // need to go to hangar when waiting in air - { 50, 0, HANGAR2_AREA_block, 3 }, - { MAX_ELEMENTS, 0, 0, 0 } // end marker. DO NOT REMOVE + { 49, TO_ALL, HANGAR2_AREA_block, 50 }, // need to go to hangar when waiting in air + { 50, TO_ALL, HANGAR2_AREA_block, 3 }, + { 51, HELITAKEOFF, NOTHING_block, 0 }, + { 52, HELITAKEOFF, NOTHING_block, 0 }, + { MAX_ELEMENTS, TO_ALL, 0, 0 } // end marker. DO NOT REMOVE }; /* intercontinental */ @@ -648,92 +652,92 @@ static const HangarTileTable _airport_depots_intercontinental[] = { {{0, 5}, DIR static const byte _airport_terminal_intercontinental[] = { 2, 4, 4 }; static const byte _airport_entries_intercontinental[] = { 44, 43, 46, 45 }; static const AirportFTAbuildup _airport_fta_intercontinental[] = { - { 0, HANGAR, NOTHING_block, 2 }, { 0, 255, HANGAR1_AREA_block | TERM_GROUP1_block, 0 }, { 0, 255, HANGAR1_AREA_block | TERM_GROUP1_block, 1 }, { 0, TAKEOFF, HANGAR1_AREA_block | TERM_GROUP1_block, 2 }, { 0, 0, 0, 2 }, - { 1, HANGAR, NOTHING_block, 3 }, { 1, 255, HANGAR2_AREA_block, 1 }, { 1, 255, HANGAR2_AREA_block, 0 }, { 1, 0, 0, 3 }, - { 2, 255, HANGAR1_AREA_block, 0 }, { 2, 255, TERM_GROUP1_block, 0 }, { 2, 255, TERM_GROUP1_block, 1 }, { 2, HANGAR, 0, 0 }, { 2, TAKEOFF, TERM_GROUP1_block, 27 }, { 2, TERM5, 0, 26 }, { 2, TERM6, 0, 26 }, { 2, TERM7, 0, 26 }, { 2, TERM8, 0, 26 }, { 2, HELIPAD1, 0, 26 }, { 2, HELIPAD2, 0, 26 }, { 2, HELITAKEOFF, 0, 74 }, { 2, 0, 0, 27 }, - { 3, 255, HANGAR2_AREA_block, 0 }, { 3, HANGAR, 0, 1 }, { 3, HELITAKEOFF, 0, 75 }, {3, TAKEOFF, 0, 59}, { 3, 0, 0, 20 }, - { 4, TERM1, TERM1_block, 26 }, { 4, HANGAR, HANGAR1_AREA_block | TERM_GROUP1_block, 26 }, { 4, 0, 0, 26 }, - { 5, TERM2, TERM2_block, 27 }, { 5, HANGAR, HANGAR1_AREA_block | TERM_GROUP1_block, 27 }, { 5, 0, 0, 27 }, - { 6, TERM3, TERM3_block, 28 }, { 6, HANGAR, HANGAR1_AREA_block | TERM_GROUP1_block, 28 }, { 6, 0, 0, 28 }, - { 7, TERM4, TERM4_block, 29 }, { 7, HANGAR, HANGAR1_AREA_block | TERM_GROUP1_block, 29 }, { 7, 0, 0, 29 }, - { 8, TERM5, TERM5_block, 18 }, { 8, HANGAR, HANGAR2_AREA_block, 18 }, { 8, 0, 0, 18 }, - { 9, TERM6, TERM6_block, 19 }, { 9, HANGAR, HANGAR2_AREA_block, 19 }, { 9, 0, 0, 19 }, - { 10, TERM7, TERM7_block, 20 }, { 10, HANGAR, HANGAR2_AREA_block, 20 }, { 10, 0, 0, 20 }, - { 11, TERM8, TERM8_block, 21 }, { 11, HANGAR, HANGAR2_AREA_block, 21 }, { 11, 0, 0, 21 }, + { 0, HANGAR, NOTHING_block, 2 }, { 0, TERMGROUP, HANGAR1_AREA_block | TERM_GROUP1_block, 0 }, { 0, TERMGROUP, HANGAR1_AREA_block | TERM_GROUP1_block, 1 }, { 0, TAKEOFF, HANGAR1_AREA_block | TERM_GROUP1_block, 2 }, { 0, TO_ALL, 0, 2 }, + { 1, HANGAR, NOTHING_block, 3 }, { 1, TERMGROUP, HANGAR2_AREA_block, 1 }, { 1, TERMGROUP, HANGAR2_AREA_block, 0 }, { 1, TO_ALL, 0, 3 }, + { 2, TERMGROUP, HANGAR1_AREA_block, 0 }, { 2, TERMGROUP, TERM_GROUP1_block, 0 }, { 2, TERMGROUP, TERM_GROUP1_block, 1 }, { 2, HANGAR, 0, 0 }, { 2, TAKEOFF, TERM_GROUP1_block, 27 }, { 2, TERM5, 0, 26 }, { 2, TERM6, 0, 26 }, { 2, TERM7, 0, 26 }, { 2, TERM8, 0, 26 }, { 2, HELIPAD1, 0, 26 }, { 2, HELIPAD2, 0, 26 }, { 2, HELITAKEOFF, 0, 74 }, { 2, TO_ALL, 0, 27 }, + { 3, TERMGROUP, HANGAR2_AREA_block, 0 }, { 3, HANGAR, 0, 1 }, { 3, HELITAKEOFF, 0, 75 }, {3, TAKEOFF, 0, 59}, { 3, TO_ALL, 0, 20 }, + { 4, TERM1, TERM1_block, 26 }, { 4, HANGAR, HANGAR1_AREA_block | TERM_GROUP1_block, 26 }, { 4, TO_ALL, 0, 26 }, + { 5, TERM2, TERM2_block, 27 }, { 5, HANGAR, HANGAR1_AREA_block | TERM_GROUP1_block, 27 }, { 5, TO_ALL, 0, 27 }, + { 6, TERM3, TERM3_block, 28 }, { 6, HANGAR, HANGAR1_AREA_block | TERM_GROUP1_block, 28 }, { 6, TO_ALL, 0, 28 }, + { 7, TERM4, TERM4_block, 29 }, { 7, HANGAR, HANGAR1_AREA_block | TERM_GROUP1_block, 29 }, { 7, TO_ALL, 0, 29 }, + { 8, TERM5, TERM5_block, 18 }, { 8, HANGAR, HANGAR2_AREA_block, 18 }, { 8, TO_ALL, 0, 18 }, + { 9, TERM6, TERM6_block, 19 }, { 9, HANGAR, HANGAR2_AREA_block, 19 }, { 9, TO_ALL, 0, 19 }, + { 10, TERM7, TERM7_block, 20 }, { 10, HANGAR, HANGAR2_AREA_block, 20 }, { 10, TO_ALL, 0, 20 }, + { 11, TERM8, TERM8_block, 21 }, { 11, HANGAR, HANGAR2_AREA_block, 21 }, { 11, TO_ALL, 0, 21 }, { 12, HELIPAD1, HELIPAD1_block, 12 }, { 12, HANGAR, 0, 70 }, { 12, HELITAKEOFF, 0, 72 }, { 13, HELIPAD2, HELIPAD2_block, 13 }, { 13, HANGAR, 0, 71 }, { 13, HELITAKEOFF, 0, 73 }, - { 14, 0, TERM_GROUP2_ENTER1_block, 15 }, - { 15, 0, TERM_GROUP2_ENTER1_block, 16 }, - { 16, 0, TERM_GROUP2_ENTER2_block, 17 }, - { 17, 0, TERM_GROUP2_ENTER2_block, 18 }, - { 18, 255, TERM_GROUP2_block, 0 }, { 18, TERM5, TERM5_block, 8 }, { 18, TAKEOFF, 0, 19 }, { 18, HELITAKEOFF, HELIPAD1_block, 19 }, { 18, 0, TERM_GROUP2_EXIT1_block, 19 }, - { 19, 255, TERM_GROUP2_block, 0 }, { 19, TERM6, TERM6_block, 9 }, { 19, TERM5, 0, 18 }, { 19, TAKEOFF, 0, 57 }, { 19, HELITAKEOFF, HELIPAD1_block, 20 }, { 19, 0, TERM_GROUP2_EXIT1_block, 20 }, // add exit to runway out 2 - { 20, 255, TERM_GROUP2_block, 0 }, { 20, TERM7, TERM7_block, 10 }, { 20, TERM5, 0, 19 }, { 20, TERM6, 0, 19 }, { 20, HANGAR, HANGAR2_AREA_block, 3 }, { 20, TAKEOFF, 0, 19 }, { 20, 0, TERM_GROUP2_EXIT1_block, 21 }, - { 21, 255, TERM_GROUP2_block, 0 }, { 21, TERM8, TERM8_block, 11 }, { 21, HANGAR, HANGAR2_AREA_block, 20 }, { 21, TERM5, 0, 20 }, { 21, TERM6, 0, 20 }, { 21, TERM7, 0, 20 }, { 21, TAKEOFF, 0, 20 }, { 21, 0, TERM_GROUP2_EXIT1_block, 22 }, - { 22, 255, TERM_GROUP2_block, 0 }, { 22, HANGAR, 0, 21 }, { 22, TERM5, 0, 21 }, { 22, TERM6, 0, 21 }, { 22, TERM7, 0, 21 }, { 22, TERM8, 0, 21 }, { 22, TAKEOFF, 0, 21 }, { 22, 0, 0, 23 }, - { 23, 0, TERM_GROUP2_EXIT1_block, 70 }, - { 24, 0, TERM_GROUP2_EXIT2_block, 25 }, - { 25, 255, TERM_GROUP2_EXIT2_block, 0 }, { 25, HANGAR, HANGAR1_AREA_block | TERM_GROUP1_block, 29 }, { 25, 0, 0, 29 }, - { 26, 255, TERM_GROUP1_block, 0 }, { 26, TERM1, TERM1_block, 4 }, { 26, HANGAR, HANGAR1_AREA_block, 27 }, { 26, TERM5, TERM_GROUP2_ENTER1_block, 14 }, { 26, TERM6, TERM_GROUP2_ENTER1_block, 14 }, { 26, TERM7, TERM_GROUP2_ENTER1_block, 14 }, { 26, TERM8, TERM_GROUP2_ENTER1_block, 14 }, { 26, HELIPAD1, TERM_GROUP2_ENTER1_block, 14 }, { 26, HELIPAD2, TERM_GROUP2_ENTER1_block, 14 }, { 26, HELITAKEOFF, TERM_GROUP2_ENTER1_block, 14 }, { 26, 0, 0, 27 }, - { 27, 255, TERM_GROUP1_block, 0 }, { 27, TERM2, TERM2_block, 5 }, { 27, HANGAR, HANGAR1_AREA_block, 2 }, { 27, TERM1, 0, 26 }, { 27, TERM5, 0, 26 }, { 27, TERM6, 0, 26 }, { 27, TERM7, 0, 26 }, { 27, TERM8, 0, 26 }, { 27, HELIPAD1, 0, 14 }, { 27, HELIPAD2, 0, 14 }, { 27, 0, 0, 28 }, - { 28, 255, TERM_GROUP1_block, 0 }, { 28, TERM3, TERM3_block, 6 }, { 28, HANGAR, HANGAR1_AREA_block, 27 }, { 28, TERM1, 0, 27 }, { 28, TERM2, 0, 27 }, { 28, TERM4, 0, 29 }, { 28, TERM5, 0, 14 }, { 28, TERM6, 0, 14 }, { 28, TERM7, 0, 14 }, { 28, TERM8, 0, 14 }, { 28, HELIPAD1, 0, 14 }, { 28, HELIPAD2, 0, 14 }, { 28, 0, 0, 29 }, - { 29, 255, TERM_GROUP1_block, 0 }, { 29, TERM4, TERM4_block, 7 }, { 29, HANGAR, HANGAR1_AREA_block, 27 }, { 29, TAKEOFF, 0, 30 }, { 29, 0, 0, 28 }, - { 30, 0, OUT_WAY_block2, 31 }, - { 31, 0, OUT_WAY_block, 32 }, + { 14, TO_ALL, TERM_GROUP2_ENTER1_block, 15 }, + { 15, TO_ALL, TERM_GROUP2_ENTER1_block, 16 }, + { 16, TO_ALL, TERM_GROUP2_ENTER2_block, 17 }, + { 17, TO_ALL, TERM_GROUP2_ENTER2_block, 18 }, + { 18, TERMGROUP, TERM_GROUP2_block, 0 }, { 18, TERM5, TERM5_block, 8 }, { 18, TAKEOFF, 0, 19 }, { 18, HELITAKEOFF, HELIPAD1_block, 19 }, { 18, TO_ALL, TERM_GROUP2_EXIT1_block, 19 }, + { 19, TERMGROUP, TERM_GROUP2_block, 0 }, { 19, TERM6, TERM6_block, 9 }, { 19, TERM5, 0, 18 }, { 19, TAKEOFF, 0, 57 }, { 19, HELITAKEOFF, HELIPAD1_block, 20 }, { 19, TO_ALL, TERM_GROUP2_EXIT1_block, 20 }, // add exit to runway out 2 + { 20, TERMGROUP, TERM_GROUP2_block, 0 }, { 20, TERM7, TERM7_block, 10 }, { 20, TERM5, 0, 19 }, { 20, TERM6, 0, 19 }, { 20, HANGAR, HANGAR2_AREA_block, 3 }, { 20, TAKEOFF, 0, 19 }, { 20, TO_ALL, TERM_GROUP2_EXIT1_block, 21 }, + { 21, TERMGROUP, TERM_GROUP2_block, 0 }, { 21, TERM8, TERM8_block, 11 }, { 21, HANGAR, HANGAR2_AREA_block, 20 }, { 21, TERM5, 0, 20 }, { 21, TERM6, 0, 20 }, { 21, TERM7, 0, 20 }, { 21, TAKEOFF, 0, 20 }, { 21, TO_ALL, TERM_GROUP2_EXIT1_block, 22 }, + { 22, TERMGROUP, TERM_GROUP2_block, 0 }, { 22, HANGAR, 0, 21 }, { 22, TERM5, 0, 21 }, { 22, TERM6, 0, 21 }, { 22, TERM7, 0, 21 }, { 22, TERM8, 0, 21 }, { 22, TAKEOFF, 0, 21 }, { 22, TO_ALL, 0, 23 }, + { 23, TO_ALL, TERM_GROUP2_EXIT1_block, 70 }, + { 24, TO_ALL, TERM_GROUP2_EXIT2_block, 25 }, + { 25, TERMGROUP, TERM_GROUP2_EXIT2_block, 0 }, { 25, HANGAR, HANGAR1_AREA_block | TERM_GROUP1_block, 29 }, { 25, TO_ALL, 0, 29 }, + { 26, TERMGROUP, TERM_GROUP1_block, 0 }, { 26, TERM1, TERM1_block, 4 }, { 26, HANGAR, HANGAR1_AREA_block, 27 }, { 26, TERM5, TERM_GROUP2_ENTER1_block, 14 }, { 26, TERM6, TERM_GROUP2_ENTER1_block, 14 }, { 26, TERM7, TERM_GROUP2_ENTER1_block, 14 }, { 26, TERM8, TERM_GROUP2_ENTER1_block, 14 }, { 26, HELIPAD1, TERM_GROUP2_ENTER1_block, 14 }, { 26, HELIPAD2, TERM_GROUP2_ENTER1_block, 14 }, { 26, HELITAKEOFF, TERM_GROUP2_ENTER1_block, 14 }, { 26, TO_ALL, 0, 27 }, + { 27, TERMGROUP, TERM_GROUP1_block, 0 }, { 27, TERM2, TERM2_block, 5 }, { 27, HANGAR, HANGAR1_AREA_block, 2 }, { 27, TERM1, 0, 26 }, { 27, TERM5, 0, 26 }, { 27, TERM6, 0, 26 }, { 27, TERM7, 0, 26 }, { 27, TERM8, 0, 26 }, { 27, HELIPAD1, 0, 14 }, { 27, HELIPAD2, 0, 14 }, { 27, TO_ALL, 0, 28 }, + { 28, TERMGROUP, TERM_GROUP1_block, 0 }, { 28, TERM3, TERM3_block, 6 }, { 28, HANGAR, HANGAR1_AREA_block, 27 }, { 28, TERM1, 0, 27 }, { 28, TERM2, 0, 27 }, { 28, TERM4, 0, 29 }, { 28, TERM5, 0, 14 }, { 28, TERM6, 0, 14 }, { 28, TERM7, 0, 14 }, { 28, TERM8, 0, 14 }, { 28, HELIPAD1, 0, 14 }, { 28, HELIPAD2, 0, 14 }, { 28, TO_ALL, 0, 29 }, + { 29, TERMGROUP, TERM_GROUP1_block, 0 }, { 29, TERM4, TERM4_block, 7 }, { 29, HANGAR, HANGAR1_AREA_block, 27 }, { 29, TAKEOFF, 0, 30 }, { 29, TO_ALL, 0, 28 }, + { 30, TO_ALL, OUT_WAY_block2, 31 }, + { 31, TO_ALL, OUT_WAY_block, 32 }, /* takeoff */ { 32, TAKEOFF, RUNWAY_OUT_block, 33 }, - { 33, 0, RUNWAY_OUT_block, 34 }, + { 33, TO_ALL, RUNWAY_OUT_block, 34 }, { 34, STARTTAKEOFF, NOTHING_block, 35 }, { 35, ENDTAKEOFF, NOTHING_block, 0 }, /* landing */ - { 36, 0, 0, 0 }, + { 36, TO_ALL, 0, 0 }, { 37, LANDING, RUNWAY_IN_block, 38 }, - { 38, 0, RUNWAY_IN_block, 39 }, - { 39, 0, RUNWAY_IN_block, 40 }, + { 38, TO_ALL, RUNWAY_IN_block, 39 }, + { 39, TO_ALL, RUNWAY_IN_block, 40 }, { 40, ENDLANDING, RUNWAY_IN_block, 41 }, - { 41, 0, IN_WAY_block, 42 }, - { 42, 255, IN_WAY_block, 0 }, { 42, 255, TERM_GROUP1_block, 0 }, { 42, 255, TERM_GROUP1_block, 1 }, { 42, HANGAR, 0, 2 }, { 42, 0, 0, 26 }, + { 41, TO_ALL, IN_WAY_block, 42 }, + { 42, TERMGROUP, IN_WAY_block, 0 }, { 42, TERMGROUP, TERM_GROUP1_block, 0 }, { 42, TERMGROUP, TERM_GROUP1_block, 1 }, { 42, HANGAR, 0, 2 }, { 42, TO_ALL, 0, 26 }, /* In Air */ - { 43, 0, 0, 44 }, - { 44, FLYING, 0, 45 }, { 44, HELILANDING, 0, 47 }, { 44, LANDING, 0, 69 }, { 44, 0, 0, 45 }, - { 45, 0, 0, 46 }, - { 46, FLYING, 0, 43 }, { 46, LANDING, 0, 76 }, { 46, 0, 0, 43 }, + { 43, TO_ALL, 0, 44 }, + { 44, FLYING, 0, 45 }, { 44, HELILANDING, 0, 47 }, { 44, LANDING, 0, 69 }, { 44, TO_ALL, 0, 45 }, + { 45, TO_ALL, 0, 46 }, + { 46, FLYING, 0, 43 }, { 46, LANDING, 0, 76 }, { 46, TO_ALL, 0, 43 }, /* Helicopter -- stay in air in special place as a buffer to choose from helipads */ { 47, HELILANDING, PRE_HELIPAD_block, 48 }, { 48, HELIENDLANDING, PRE_HELIPAD_block, 48 }, { 48, HELIPAD1, 0, 49 }, { 48, HELIPAD2, 0, 50 }, { 48, HANGAR, 0, 55 }, - { 49, 0, NOTHING_block, 51 }, - { 50, 0, NOTHING_block, 52 }, + { 49, TO_ALL, NOTHING_block, 51 }, + { 50, TO_ALL, NOTHING_block, 52 }, /* landing */ - { 51, 255, NOTHING_block, 0 }, { 51, HELIPAD1, HELIPAD1_block, 12 }, { 51, HANGAR, 0, 55 }, { 51, 0, 0, 12 }, - { 52, 255, NOTHING_block, 0 }, { 52, HELIPAD2, HELIPAD2_block, 13 }, { 52, HANGAR, 0, 55 }, { 52, 0, 0, 13 }, + { 51, TERMGROUP, NOTHING_block, 0 }, { 51, HELIPAD1, HELIPAD1_block, 12 }, { 51, HANGAR, 0, 55 }, { 51, TO_ALL, 0, 12 }, + { 52, TERMGROUP, NOTHING_block, 0 }, { 52, HELIPAD2, HELIPAD2_block, 13 }, { 52, HANGAR, 0, 55 }, { 52, TO_ALL, 0, 13 }, /* Helicopter -- takeoff */ { 53, HELITAKEOFF, NOTHING_block, 0 }, { 54, HELITAKEOFF, NOTHING_block, 0 }, - { 55, 0, HANGAR2_AREA_block, 56 }, // need to go to hangar when waiting in air - { 56, 0, HANGAR2_AREA_block, 3 }, + { 55, TO_ALL, HANGAR2_AREA_block, 56 }, // need to go to hangar when waiting in air + { 56, TO_ALL, HANGAR2_AREA_block, 3 }, /* runway 2 out support */ - { 57, 255, OUT_WAY2_block, 0 }, { 57, TAKEOFF, 0, 58 }, { 57, 0, 0, 58 }, - { 58, 0, OUT_WAY2_block, 59 }, + { 57, TERMGROUP, OUT_WAY2_block, 0 }, { 57, TAKEOFF, 0, 58 }, { 57, TO_ALL, 0, 58 }, + { 58, TO_ALL, OUT_WAY2_block, 59 }, { 59, TAKEOFF, RUNWAY_OUT2_block, 60 }, // takeoff - { 60, 0, RUNWAY_OUT2_block, 61 }, + { 60, TO_ALL, RUNWAY_OUT2_block, 61 }, { 61, STARTTAKEOFF, NOTHING_block, 62 }, { 62, ENDTAKEOFF, NOTHING_block, 0 }, /* runway 2 in support */ { 63, LANDING, RUNWAY_IN2_block, 64 }, - { 64, 0, RUNWAY_IN2_block, 65 }, - { 65, 0, RUNWAY_IN2_block, 66 }, - { 66, ENDLANDING, RUNWAY_IN2_block, 0 }, { 66, 255, 0, 1 }, { 66, 255, 0, 0 }, { 66, 0, 0, 67 }, - { 67, 0, IN_WAY2_block, 68 }, - { 68, 255, IN_WAY2_block, 0 }, { 68, 255, TERM_GROUP2_block, 1 }, { 68, 255, TERM_GROUP1_block, 0 }, { 68, HANGAR, HANGAR2_AREA_block, 22 }, { 68, 0, 0, 22 }, - { 69, 255, RUNWAY_IN2_block, 0 }, { 69, 0, RUNWAY_IN2_block, 63 }, - { 70, 255, TERM_GROUP2_EXIT1_block, 0 }, { 70, HELIPAD1, HELIPAD1_block, 12 }, { 70, HELITAKEOFF, HELIPAD1_block, 12 }, { 70, 0, 0, 71 }, - { 71, 255, TERM_GROUP2_EXIT1_block, 0 }, { 71, HELIPAD2, HELIPAD2_block, 13 }, { 71, HELITAKEOFF, HELIPAD1_block, 12 }, { 71, 0, 0, 24 }, - { 72, 0, HELIPAD1_block, 53 }, - { 73, 0, HELIPAD2_block, 54 }, + { 64, TO_ALL, RUNWAY_IN2_block, 65 }, + { 65, TO_ALL, RUNWAY_IN2_block, 66 }, + { 66, ENDLANDING, RUNWAY_IN2_block, 0 }, { 66, TERMGROUP, 0, 1 }, { 66, TERMGROUP, 0, 0 }, { 66, TO_ALL, 0, 67 }, + { 67, TO_ALL, IN_WAY2_block, 68 }, + { 68, TERMGROUP, IN_WAY2_block, 0 }, { 68, TERMGROUP, TERM_GROUP2_block, 1 }, { 68, TERMGROUP, TERM_GROUP1_block, 0 }, { 68, HANGAR, HANGAR2_AREA_block, 22 }, { 68, TO_ALL, 0, 22 }, + { 69, TERMGROUP, RUNWAY_IN2_block, 0 }, { 69, TO_ALL, RUNWAY_IN2_block, 63 }, + { 70, TERMGROUP, TERM_GROUP2_EXIT1_block, 0 }, { 70, HELIPAD1, HELIPAD1_block, 12 }, { 70, HELITAKEOFF, HELIPAD1_block, 12 }, { 70, TO_ALL, 0, 71 }, + { 71, TERMGROUP, TERM_GROUP2_EXIT1_block, 0 }, { 71, HELIPAD2, HELIPAD2_block, 13 }, { 71, HELITAKEOFF, HELIPAD1_block, 12 }, { 71, TO_ALL, 0, 24 }, + { 72, TO_ALL, HELIPAD1_block, 53 }, + { 73, TO_ALL, HELIPAD2_block, 54 }, { 74, HELITAKEOFF, NOTHING_block, 0 }, { 75, HELITAKEOFF, NOTHING_block, 0 }, - { 76, 255, RUNWAY_IN_block, 0 }, { 76, 0, RUNWAY_IN_block, 37 }, - { MAX_ELEMENTS, 0, 0, 0 } // end marker. DO NOT REMOVE + { 76, TERMGROUP, RUNWAY_IN_block, 0 }, { 76, TO_ALL, RUNWAY_IN_block, 37 }, + { MAX_ELEMENTS, TO_ALL, 0, 0 } // end marker. DO NOT REMOVE }; @@ -742,15 +746,15 @@ static const byte _airport_entries_heliport[] = { 7, 7, 7, 7 }; static const AirportFTAbuildup _airport_fta_heliport[] = { { 0, HELIPAD1, HELIPAD1_block, 1 }, { 1, HELITAKEOFF, NOTHING_block, 0 }, // takeoff - { 2, 255, AIRPORT_BUSY_block, 0 }, { 2, HELILANDING, 0, 3 }, { 2, HELITAKEOFF, 0, 1 }, + { 2, TERMGROUP, AIRPORT_BUSY_block, 0 }, { 2, HELILANDING, 0, 3 }, { 2, HELITAKEOFF, 0, 1 }, { 3, HELILANDING, AIRPORT_BUSY_block, 4 }, { 4, HELIENDLANDING, AIRPORT_BUSY_block, 4 }, { 4, HELIPAD1, HELIPAD1_block, 0 }, { 4, HELITAKEOFF, 0, 2 }, /* In Air */ - { 5, 0, NOTHING_block, 6 }, - { 6, 0, NOTHING_block, 7 }, - { 7, 0, NOTHING_block, 8 }, + { 5, TO_ALL, NOTHING_block, 6 }, + { 6, TO_ALL, NOTHING_block, 7 }, + { 7, TO_ALL, NOTHING_block, 8 }, { 8, FLYING, NOTHING_block, 5 }, { 8, HELILANDING, HELIPAD1_block, 2 }, // landing - { MAX_ELEMENTS, 0, 0, 0 } // end marker. DO NOT REMOVE + { MAX_ELEMENTS, TO_ALL, 0, 0 } // end marker. DO NOT REMOVE }; #define _airport_entries_oilrig _airport_entries_heliport #define _airport_fta_oilrig _airport_fta_heliport @@ -760,7 +764,7 @@ static const HangarTileTable _airport_depots_helidepot[] = { {{1, 0}, DIR_SE, 0} static const byte _airport_entries_helidepot[] = { 4, 4, 4, 4 }; static const AirportFTAbuildup _airport_fta_helidepot[] = { { 0, HANGAR, NOTHING_block, 1 }, - { 1, 255, HANGAR2_AREA_block, 0 }, { 1, HANGAR, 0, 0 }, { 1, HELIPAD1, HELIPAD1_block, 14 }, { 1, HELITAKEOFF, 0, 15 }, { 1, 0, 0, 0 }, + { 1, TERMGROUP, HANGAR2_AREA_block, 0 }, { 1, HANGAR, 0, 0 }, { 1, HELIPAD1, HELIPAD1_block, 14 }, { 1, HELITAKEOFF, 0, 15 }, { 1, TO_ALL, 0, 0 }, { 2, FLYING, NOTHING_block, 3 }, { 2, HELILANDING, PRE_HELIPAD_block, 7 }, { 2, HANGAR, 0, 12 }, { 2, HELITAKEOFF, NOTHING_block, 16 }, /* In Air */ { 3, 0, NOTHING_block, 4 }, @@ -769,63 +773,63 @@ static const AirportFTAbuildup _airport_fta_helidepot[] = { { 6, 0, NOTHING_block, 2 }, /* Helicopter -- stay in air in special place as a buffer to choose from helipads */ { 7, HELILANDING, PRE_HELIPAD_block, 8 }, - { 8, HELIENDLANDING, PRE_HELIPAD_block, 8 }, { 8, HELIPAD1, 0, 9 }, { 8, HANGAR, 0, 12 }, { 8, 0, 0, 2 }, + { 8, HELIENDLANDING, PRE_HELIPAD_block, 8 }, { 8, HELIPAD1, 0, 9 }, { 8, HANGAR, 0, 12 }, { 8, TO_ALL, 0, 2 }, { 9, 0, NOTHING_block, 10 }, /* landing */ - { 10, 255, NOTHING_block, 10 }, { 10, HELIPAD1, HELIPAD1_block, 14 }, { 10, HANGAR, 0, 1 }, { 10, 0, 0, 14 }, + { 10, TERMGROUP, NOTHING_block, 10 }, { 10, HELIPAD1, HELIPAD1_block, 14 }, { 10, HANGAR, 0, 1 }, { 10, TO_ALL, 0, 14 }, /* Helicopter -- takeoff */ { 11, HELITAKEOFF, NOTHING_block, 0 }, - { 12, 0, HANGAR2_AREA_block, 13 }, // need to go to hangar when waiting in air - { 13, 0, HANGAR2_AREA_block, 1 }, + { 12, TO_ALL, HANGAR2_AREA_block, 13 }, // need to go to hangar when waiting in air + { 13, TO_ALL, HANGAR2_AREA_block, 1 }, { 14, HELIPAD1, HELIPAD1_block, 14 }, { 14, HANGAR, 0, 1 }, { 14, HELITAKEOFF, 0, 17 }, { 15, HELITAKEOFF, NOTHING_block, 0 }, // takeoff outside depot { 16, HELITAKEOFF, 0, 14 }, - { 17, 0, NOTHING_block, 11 }, - { MAX_ELEMENTS, 0, 0, 0 } // end marker. DO NOT REMOVE + { 17, TO_ALL, NOTHING_block, 11 }, + { MAX_ELEMENTS, TO_ALL, 0, 0 } // end marker. DO NOT REMOVE }; /* helistation */ static const HangarTileTable _airport_depots_helistation[] = { {{0, 0}, DIR_SE, 0} }; static const byte _airport_entries_helistation[] = { 25, 25, 25, 25 }; static const AirportFTAbuildup _airport_fta_helistation[] = { - { 0, HANGAR, NOTHING_block, 8 }, { 0, HELIPAD1, 0, 1 }, { 0, HELIPAD2, 0, 1 }, { 0, HELIPAD3, 0, 1 }, { 0, HELITAKEOFF, 0, 1 }, { 0, 0, 0, 0 }, - { 1, 255, HANGAR2_AREA_block, 0 }, { 1, HANGAR, 0, 0 }, { 1, HELITAKEOFF, 0, 3 }, { 1, 0, 0, 4 }, + { 0, HANGAR, NOTHING_block, 8 }, { 0, HELIPAD1, 0, 1 }, { 0, HELIPAD2, 0, 1 }, { 0, HELIPAD3, 0, 1 }, { 0, HELITAKEOFF, 0, 1 }, { 0, TO_ALL, 0, 0 }, + { 1, TERMGROUP, HANGAR2_AREA_block, 0 }, { 1, HANGAR, 0, 0 }, { 1, HELITAKEOFF, 0, 3 }, { 1, TO_ALL, 0, 4 }, /* landing */ - { 2, FLYING, NOTHING_block, 28 }, { 2, HELILANDING, 0, 15 }, { 2, 0, 0, 28 }, + { 2, FLYING, NOTHING_block, 28 }, { 2, HELILANDING, 0, 15 }, { 2, TO_ALL, 0, 28 }, /* helicopter side */ { 3, HELITAKEOFF, NOTHING_block, 0 }, // helitakeoff outside hangar2 - { 4, 255, TAXIWAY_BUSY_block, 0 }, { 4, HANGAR, HANGAR2_AREA_block, 1 }, { 4, HELITAKEOFF, 0, 1 }, { 4, 0, 0, 5 }, - { 5, 255, TAXIWAY_BUSY_block, 0 }, { 5, HELIPAD1, HELIPAD1_block, 6 }, { 5, HELIPAD2, HELIPAD2_block, 7 }, { 5, HELIPAD3, HELIPAD3_block, 8 }, { 5, 0, 0, 4 }, - { 6, HELIPAD1, HELIPAD1_block, 5 }, { 6, HANGAR, HANGAR2_AREA_block, 5 }, { 6, HELITAKEOFF, 0, 9 }, { 6, 0, 0, 6 }, - { 7, HELIPAD2, HELIPAD2_block, 5 }, { 7, HANGAR, HANGAR2_AREA_block, 5 }, { 7, HELITAKEOFF, 0, 10 }, { 7, 0, 0, 7 }, - { 8, HELIPAD3, HELIPAD3_block, 5 }, { 8, HANGAR, HANGAR2_AREA_block, 5 }, { 8, HELITAKEOFF, 0, 11 }, { 8, 0, 0, 8 }, + { 4, TERMGROUP, TAXIWAY_BUSY_block, 0 }, { 4, HANGAR, HANGAR2_AREA_block, 1 }, { 4, HELITAKEOFF, 0, 1 }, { 4, TO_ALL, 0, 5 }, + { 5, TERMGROUP, TAXIWAY_BUSY_block, 0 }, { 5, HELIPAD1, HELIPAD1_block, 6 }, { 5, HELIPAD2, HELIPAD2_block, 7 }, { 5, HELIPAD3, HELIPAD3_block, 8 }, { 5, TO_ALL, 0, 4 }, + { 6, HELIPAD1, HELIPAD1_block, 5 }, { 6, HANGAR, HANGAR2_AREA_block, 5 }, { 6, HELITAKEOFF, 0, 9 }, { 6, TO_ALL, 0, 6 }, + { 7, HELIPAD2, HELIPAD2_block, 5 }, { 7, HANGAR, HANGAR2_AREA_block, 5 }, { 7, HELITAKEOFF, 0, 10 }, { 7, TO_ALL, 0, 7 }, + { 8, HELIPAD3, HELIPAD3_block, 5 }, { 8, HANGAR, HANGAR2_AREA_block, 5 }, { 8, HELITAKEOFF, 0, 11 }, { 8, TO_ALL, 0, 8 }, { 9, 0, HELIPAD1_block, 12 }, - { 10, 0, HELIPAD2_block, 13 }, - { 11, 0, HELIPAD3_block, 14 }, + { 10, TO_ALL, HELIPAD2_block, 13 }, + { 11, TO_ALL, HELIPAD3_block, 14 }, { 12, HELITAKEOFF, NOTHING_block, 0 }, { 13, HELITAKEOFF, NOTHING_block, 0 }, { 14, HELITAKEOFF, NOTHING_block, 0 }, /* heli - in flight moves */ { 15, HELILANDING, PRE_HELIPAD_block, 16 }, { 16, HELIENDLANDING, PRE_HELIPAD_block, 16 }, { 16, HELIPAD1, 0, 17 }, { 16, HELIPAD2, 0, 18 }, { 16, HELIPAD3, 0, 19 }, { 16, HANGAR, 0, 23 }, - { 17, 0, NOTHING_block, 20 }, - { 18, 0, NOTHING_block, 21 }, - { 19, 0, NOTHING_block, 22 }, + { 17, TO_ALL, NOTHING_block, 20 }, + { 18, TO_ALL, NOTHING_block, 21 }, + { 19, TO_ALL, NOTHING_block, 22 }, /* heli landing */ - { 20, 255, NOTHING_block, 0 }, { 20, HELIPAD1, HELIPAD1_block, 6 }, { 20, HANGAR, 0, 23 }, { 20, 0, 0, 6 }, - { 21, 255, NOTHING_block, 0 }, { 21, HELIPAD2, HELIPAD2_block, 7 }, { 21, HANGAR, 0, 23 }, { 21, 0, 0, 7 }, - { 22, 255, NOTHING_block, 0 }, { 22, HELIPAD3, HELIPAD3_block, 8 }, { 22, HANGAR, 0, 23 }, { 22, 0, 0, 8 }, - { 23, 0, HANGAR2_AREA_block, 24 }, // need to go to helihangar when waiting in air - { 24, 0, HANGAR2_AREA_block, 1 }, - { 25, 0, NOTHING_block, 26 }, - { 26, 0, NOTHING_block, 27 }, - { 27, 0, NOTHING_block, 2 }, - { 28, 0, NOTHING_block, 29 }, - { 29, 0, NOTHING_block, 30 }, - { 30, 0, NOTHING_block, 31 }, - { 31, 0, NOTHING_block, 32 }, - { 32, 0, NOTHING_block, 25 }, - { MAX_ELEMENTS, 0, 0, 0 } // end marker. DO NOT REMOVE + { 20, TERMGROUP, NOTHING_block, 0 }, { 20, HELIPAD1, HELIPAD1_block, 6 }, { 20, HANGAR, 0, 23 }, { 20, TO_ALL, 0, 6 }, + { 21, TERMGROUP, NOTHING_block, 0 }, { 21, HELIPAD2, HELIPAD2_block, 7 }, { 21, HANGAR, 0, 23 }, { 21, TO_ALL, 0, 7 }, + { 22, TERMGROUP, NOTHING_block, 0 }, { 22, HELIPAD3, HELIPAD3_block, 8 }, { 22, HANGAR, 0, 23 }, { 22, TO_ALL, 0, 8 }, + { 23, TO_ALL, HANGAR2_AREA_block, 24 }, // need to go to helihangar when waiting in air + { 24, TO_ALL, HANGAR2_AREA_block, 1 }, + { 25, TO_ALL, NOTHING_block, 26 }, + { 26, TO_ALL, NOTHING_block, 27 }, + { 27, TO_ALL, NOTHING_block, 2 }, + { 28, TO_ALL, NOTHING_block, 29 }, + { 29, TO_ALL, NOTHING_block, 30 }, + { 30, TO_ALL, NOTHING_block, 31 }, + { 31, TO_ALL, NOTHING_block, 32 }, + { 32, TO_ALL, NOTHING_block, 25 }, + { MAX_ELEMENTS, TO_ALL, 0, 0 } // end marker. DO NOT REMOVE }; #endif /* AIRPORT_MOVEMENT_H */ diff --git a/src/table/airporttile_ids.h b/src/table/airporttile_ids.h index fa97753877..73eafc8595 100644 --- a/src/table/airporttile_ids.h +++ b/src/table/airporttile_ids.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/airporttiles.h b/src/table/airporttiles.h index 47a9631583..d4fb3d968e 100644 --- a/src/table/airporttiles.h +++ b/src/table/airporttiles.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/animcursors.h b/src/table/animcursors.h index 08a90757a2..ed25691a5e 100644 --- a/src/table/animcursors.h +++ b/src/table/animcursors.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/autorail.h b/src/table/autorail.h index 5b93668edc..8c5a5a492f 100644 --- a/src/table/autorail.h +++ b/src/table/autorail.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/bridge_land.h b/src/table/bridge_land.h index 4f6f94bb0f..fab0605901 100644 --- a/src/table/bridge_land.h +++ b/src/table/bridge_land.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. @@ -741,7 +739,7 @@ static const PalSpriteID * const * const _bridge_sprite_table[MAX_BRIDGES] = { * @param nrd description of the road bridge in query tool */ #define MBR(y, mnl, mxl, p, mxs, spr, plt, dsc, nrl, nrd) \ - {y, mnl, mxl, p, mxs, spr, plt, dsc, { nrl, nrd }, NULL, 0} + {y, mnl, mxl, p, mxs, spr, plt, dsc, { nrl, nrd }, nullptr, 0} const BridgeSpec _orig_bridge[] = { /* diff --git a/src/table/build_industry.h b/src/table/build_industry.h index 62264eb6f8..c045992b31 100644 --- a/src/table/build_industry.h +++ b/src/table/build_industry.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. @@ -22,22 +20,16 @@ */ #define MK(x, y, m) {{x, y}, m} -/** - * Terminator of industry tiles layout definition - */ -#define MKEND {{-0x80, 0}, 0} - -static const IndustryTileTable _tile_table_coal_mine_0[] = { +static const IndustryTileLayout _tile_table_coal_mine_0 { MK(1, 1, 0), MK(1, 2, 2), MK(0, 0, 5), MK(1, 0, 6), MK(2, 0, 3), MK(2, 2, 3), - MKEND }; -static const IndustryTileTable _tile_table_coal_mine_1[] = { +static const IndustryTileLayout _tile_table_coal_mine_1 { MK(1, 1, 0), MK(1, 2, 2), MK(2, 0, 0), @@ -47,20 +39,18 @@ static const IndustryTileTable _tile_table_coal_mine_1[] = { MK(0, 1, 4), MK(0, 2, 4), MK(2, 2, 4), - MKEND }; -static const IndustryTileTable _tile_table_coal_mine_2[] = { +static const IndustryTileLayout _tile_table_coal_mine_2 { MK(0, 0, 0), MK(0, 1, 2), MK(0, 2, 5), MK(1, 0, 3), MK(1, 1, 3), MK(1, 2, 6), - MKEND }; -static const IndustryTileTable _tile_table_coal_mine_3[] = { +static const IndustryTileLayout _tile_table_coal_mine_3 { MK(0, 1, 0), MK(0, 2, 2), MK(0, 3, 4), @@ -71,17 +61,16 @@ static const IndustryTileTable _tile_table_coal_mine_3[] = { MK(2, 0, 6), MK(2, 1, 4), MK(2, 2, 3), - MKEND }; -static const IndustryTileTable * const _tile_table_coal_mine[] = { +static const std::vector _tile_table_coal_mine { _tile_table_coal_mine_0, _tile_table_coal_mine_1, _tile_table_coal_mine_2, _tile_table_coal_mine_3, }; -static const IndustryTileTable _tile_table_power_station_0[] = { +static const IndustryTileLayout _tile_table_power_station_0 { MK(0, 0, 7), MK(0, 1, 9), MK(1, 0, 7), @@ -90,10 +79,9 @@ static const IndustryTileTable _tile_table_power_station_0[] = { MK(2, 1, 8), MK(3, 0, 10), MK(3, 1, 10), - MKEND }; -static const IndustryTileTable _tile_table_power_station_1[] = { +static const IndustryTileLayout _tile_table_power_station_1 { MK(0, 1, 7), MK(0, 2, 7), MK(1, 0, 8), @@ -102,26 +90,24 @@ static const IndustryTileTable _tile_table_power_station_1[] = { MK(2, 0, 9), MK(2, 1, 10), MK(2, 2, 9), - MKEND }; -static const IndustryTileTable _tile_table_power_station_2[] = { +static const IndustryTileLayout _tile_table_power_station_2 { MK(0, 0, 7), MK(0, 1, 7), MK(1, 0, 9), MK(1, 1, 8), MK(2, 0, 10), MK(2, 1, 9), - MKEND }; -static const IndustryTileTable * const _tile_table_power_station[] = { +static const std::vector _tile_table_power_station { _tile_table_power_station_0, _tile_table_power_station_1, _tile_table_power_station_2, }; -static const IndustryTileTable _tile_table_sawmill_0[] = { +static const IndustryTileLayout _tile_table_sawmill_0 { MK(1, 0, 14), MK(1, 1, 12), MK(1, 2, 11), @@ -130,10 +116,9 @@ static const IndustryTileTable _tile_table_sawmill_0[] = { MK(0, 0, 15), MK(0, 1, 15), MK(0, 2, 12), - MKEND }; -static const IndustryTileTable _tile_table_sawmill_1[] = { +static const IndustryTileLayout _tile_table_sawmill_1 { MK(0, 0, 15), MK(0, 1, 11), MK(0, 2, 14), @@ -142,15 +127,14 @@ static const IndustryTileTable _tile_table_sawmill_1[] = { MK(1, 2, 12), MK(2, 0, 11), MK(2, 1, 13), - MKEND }; -static const IndustryTileTable * const _tile_table_sawmill[] = { +static const std::vector _tile_table_sawmill { _tile_table_sawmill_0, _tile_table_sawmill_1, }; -static const IndustryTileTable _tile_table_forest_0[] = { +static const IndustryTileLayout _tile_table_forest_0 { MK(0, 0, 16), MK(0, 1, 16), MK(0, 2, 16), @@ -169,10 +153,9 @@ static const IndustryTileTable _tile_table_forest_0[] = { MK(3, 3, 16), MK(1, 4, 16), MK(2, 4, 16), - MKEND }; -static const IndustryTileTable _tile_table_forest_1[] = { +static const IndustryTileLayout _tile_table_forest_1 { MK(0, 0, 16), MK(1, 0, 16), MK(2, 0, 16), @@ -196,15 +179,14 @@ static const IndustryTileTable _tile_table_forest_1[] = { MK(1, 4, 16), MK(2, 4, 16), MK(3, 4, 16), - MKEND }; -static const IndustryTileTable * const _tile_table_forest[] = { +static const std::vector _tile_table_forest { _tile_table_forest_0, _tile_table_forest_1, }; -static const IndustryTileTable _tile_table_oil_refinery_0[] = { +static const IndustryTileLayout _tile_table_oil_refinery_0 { MK(0, 0, 20), MK(0, 1, 21), MK(0, 2, 22), @@ -220,10 +202,9 @@ static const IndustryTileTable _tile_table_oil_refinery_0[] = { MK(3, 3, 18), MK(2, 0, 23), MK(3, 1, 23), - MKEND }; -static const IndustryTileTable _tile_table_oil_refinery_1[] = { +static const IndustryTileLayout _tile_table_oil_refinery_1 { MK(0, 0, 18), MK(0, 1, 18), MK(0, 2, 21), @@ -239,15 +220,14 @@ static const IndustryTileTable _tile_table_oil_refinery_1[] = { MK(2, 3, 22), MK(1, 4, 23), MK(2, 4, 23), - MKEND }; -static const IndustryTileTable * const _tile_table_oil_refinery[] = { +static const std::vector _tile_table_oil_refinery { _tile_table_oil_refinery_0, _tile_table_oil_refinery_1, }; -static const IndustryTileTable _tile_table_oil_rig_0[] = { +static const IndustryTileLayout _tile_table_oil_rig_0 { MK(0, 0, 24), MK(0, 1, 24), MK(0, 2, 25), @@ -306,14 +286,13 @@ static const IndustryTileTable _tile_table_oil_rig_0[] = { MK(2, 3, 255), MK(2, 2, 255), MK(2, 1, 255), - MKEND }; -static const IndustryTileTable * const _tile_table_oil_rig[] = { +static const std::vector _tile_table_oil_rig { _tile_table_oil_rig_0, }; -static const IndustryTileTable _tile_table_factory_0[] = { +static const IndustryTileLayout _tile_table_factory_0 { MK(0, 0, 39), MK(0, 1, 40), MK(1, 0, 41), @@ -326,10 +305,9 @@ static const IndustryTileTable _tile_table_factory_0[] = { MK(2, 2, 40), MK(3, 1, 41), MK(3, 2, 42), - MKEND }; -static const IndustryTileTable _tile_table_factory_1[] = { +static const IndustryTileLayout _tile_table_factory_1 { MK(0, 0, 39), MK(0, 1, 40), MK(1, 0, 41), @@ -342,15 +320,14 @@ static const IndustryTileTable _tile_table_factory_1[] = { MK(1, 3, 40), MK(2, 2, 41), MK(2, 3, 42), - MKEND }; -static const IndustryTileTable * const _tile_table_factory[] = { +static const std::vector _tile_table_factory { _tile_table_factory_0, _tile_table_factory_1, }; -static const IndustryTileTable _tile_table_printing_works_0[] = { +static const IndustryTileLayout _tile_table_printing_works_0 { MK(0, 0, 43), MK(0, 1, 44), MK(1, 0, 45), @@ -363,10 +340,9 @@ static const IndustryTileTable _tile_table_printing_works_0[] = { MK(2, 2, 44), MK(3, 1, 45), MK(3, 2, 46), - MKEND }; -static const IndustryTileTable _tile_table_printing_works_1[] = { +static const IndustryTileLayout _tile_table_printing_works_1 { MK(0, 0, 43), MK(0, 1, 44), MK(1, 0, 45), @@ -379,15 +355,14 @@ static const IndustryTileTable _tile_table_printing_works_1[] = { MK(1, 3, 44), MK(2, 2, 45), MK(2, 3, 46), - MKEND }; -static const IndustryTileTable * const _tile_table_printing_works[] = { +static const std::vector _tile_table_printing_works { _tile_table_printing_works_0, _tile_table_printing_works_1, }; -static const IndustryTileTable _tile_table_steel_mill_0[] = { +static const IndustryTileLayout _tile_table_steel_mill_0 { MK(2, 1, 52), MK(2, 2, 53), MK(3, 1, 54), @@ -400,10 +375,9 @@ static const IndustryTileTable _tile_table_steel_mill_0[] = { MK(1, 2, 57), MK(2, 0, 56), MK(3, 0, 57), - MKEND }; -static const IndustryTileTable _tile_table_steel_mill_1[] = { +static const IndustryTileLayout _tile_table_steel_mill_1 { MK(0, 0, 52), MK(0, 1, 53), MK(1, 0, 54), @@ -418,15 +392,14 @@ static const IndustryTileTable _tile_table_steel_mill_1[] = { MK(3, 2, 57), MK(1, 3, 56), MK(2, 3, 57), - MKEND }; -static const IndustryTileTable * const _tile_table_steel_mill[] = { +static const std::vector _tile_table_steel_mill { _tile_table_steel_mill_0, _tile_table_steel_mill_1, }; -static const IndustryTileTable _tile_table_farm_0[] = { +static const IndustryTileLayout _tile_table_farm_0 { MK(1, 0, 33), MK(1, 1, 34), MK(1, 2, 36), @@ -436,10 +409,9 @@ static const IndustryTileTable _tile_table_farm_0[] = { MK(2, 0, 35), MK(2, 1, 38), MK(2, 2, 38), - MKEND }; -static const IndustryTileTable _tile_table_farm_1[] = { +static const IndustryTileLayout _tile_table_farm_1 { MK(1, 1, 33), MK(1, 2, 34), MK(0, 0, 35), @@ -452,10 +424,9 @@ static const IndustryTileTable _tile_table_farm_1[] = { MK(2, 1, 37), MK(2, 2, 38), MK(2, 3, 38), - MKEND }; -static const IndustryTileTable _tile_table_farm_2[] = { +static const IndustryTileLayout _tile_table_farm_2 { MK(2, 0, 33), MK(2, 1, 34), MK(0, 0, 36), @@ -468,16 +439,15 @@ static const IndustryTileTable _tile_table_farm_2[] = { MK(1, 3, 37), MK(2, 2, 37), MK(2, 3, 35), - MKEND }; -static const IndustryTileTable * const _tile_table_farm[] = { +static const std::vector _tile_table_farm { _tile_table_farm_0, _tile_table_farm_1, _tile_table_farm_2, }; -static const IndustryTileTable _tile_table_copper_mine_0[] = { +static const IndustryTileLayout _tile_table_copper_mine_0 { MK(0, 0, 47), MK(0, 1, 49), MK(0, 2, 51), @@ -486,10 +456,9 @@ static const IndustryTileTable _tile_table_copper_mine_0[] = { MK(1, 2, 50), MK(2, 0, 51), MK(2, 1, 51), - MKEND }; -static const IndustryTileTable _tile_table_copper_mine_1[] = { +static const IndustryTileLayout _tile_table_copper_mine_1 { MK(0, 0, 50), MK(0, 1, 47), MK(0, 2, 49), @@ -499,48 +468,44 @@ static const IndustryTileTable _tile_table_copper_mine_1[] = { MK(2, 0, 51), MK(2, 1, 47), MK(2, 2, 49), - MKEND }; -static const IndustryTileTable * const _tile_table_copper_mine[] = { +static const std::vector _tile_table_copper_mine { _tile_table_copper_mine_0, _tile_table_copper_mine_1, }; -static const IndustryTileTable _tile_table_oil_well_0[] = { +static const IndustryTileLayout _tile_table_oil_well_0 { MK(0, 0, 29), MK(1, 0, 29), MK(2, 0, 29), MK(0, 1, 29), MK(0, 2, 29), - MKEND }; -static const IndustryTileTable _tile_table_oil_well_1[] = { +static const IndustryTileLayout _tile_table_oil_well_1 { MK(0, 0, 29), MK(1, 0, 29), MK(1, 1, 29), MK(2, 2, 29), MK(2, 3, 29), - MKEND }; -static const IndustryTileTable * const _tile_table_oil_well[] = { +static const std::vector _tile_table_oil_well { _tile_table_oil_well_0, _tile_table_oil_well_1, }; -static const IndustryTileTable _tile_table_bank_0[] = { +static const IndustryTileLayout _tile_table_bank_0 { MK(0, 0, 58), MK(1, 0, 59), - MKEND }; -static const IndustryTileTable * const _tile_table_bank[] = { +static const std::vector _tile_table_bank { _tile_table_bank_0, }; -static const IndustryTileTable _tile_table_food_process_0[] = { +static const IndustryTileLayout _tile_table_food_process_0 { MK(0, 0, 60), MK(1, 0, 60), MK(2, 0, 60), @@ -553,10 +518,9 @@ static const IndustryTileTable _tile_table_food_process_0[] = { MK(0, 3, 62), MK(1, 3, 62), MK(2, 3, 63), - MKEND }; -static const IndustryTileTable _tile_table_food_process_1[] = { +static const IndustryTileLayout _tile_table_food_process_1 { MK(0, 0, 61), MK(1, 0, 60), MK(2, 0, 61), @@ -571,15 +535,14 @@ static const IndustryTileTable _tile_table_food_process_1[] = { MK(3, 2, 60), MK(0, 3, 62), MK(1, 3, 62), - MKEND }; -static const IndustryTileTable * const _tile_table_food_process[] = { +static const std::vector _tile_table_food_process { _tile_table_food_process_0, _tile_table_food_process_1, }; -static const IndustryTileTable _tile_table_paper_mill_0[] = { +static const IndustryTileLayout _tile_table_paper_mill_0 { MK(0, 0, 64), MK(1, 0, 65), MK(2, 0, 66), @@ -592,14 +555,13 @@ static const IndustryTileTable _tile_table_paper_mill_0[] = { MK(1, 2, 71), MK(2, 2, 71), MK(3, 2, 70), - MKEND }; -static const IndustryTileTable * const _tile_table_paper_mill[] = { +static const std::vector _tile_table_paper_mill { _tile_table_paper_mill_0, }; -static const IndustryTileTable _tile_table_gold_mine_0[] = { +static const IndustryTileLayout _tile_table_gold_mine_0 { MK(0, 0, 72), MK(0, 1, 73), MK(0, 2, 74), @@ -616,24 +578,22 @@ static const IndustryTileTable _tile_table_gold_mine_0[] = { MK(3, 1, 85), MK(3, 2, 86), MK(3, 3, 87), - MKEND }; -static const IndustryTileTable * const _tile_table_gold_mine[] = { +static const std::vector _tile_table_gold_mine { _tile_table_gold_mine_0, }; -static const IndustryTileTable _tile_table_bank2_0[] = { +static const IndustryTileLayout _tile_table_bank2_0 { MK(0, 0, 89), MK(1, 0, 90), - MKEND }; -static const IndustryTileTable * const _tile_table_bank2[] = { +static const std::vector _tile_table_bank2 { _tile_table_bank2_0, }; -static const IndustryTileTable _tile_table_diamond_mine_0[] = { +static const IndustryTileLayout _tile_table_diamond_mine_0 { MK(0, 0, 91), MK(0, 1, 92), MK(0, 2, 93), @@ -643,14 +603,13 @@ static const IndustryTileTable _tile_table_diamond_mine_0[] = { MK(2, 0, 97), MK(2, 1, 98), MK(2, 2, 99), - MKEND }; -static const IndustryTileTable * const _tile_table_diamond_mine[] = { +static const std::vector _tile_table_diamond_mine { _tile_table_diamond_mine_0, }; -static const IndustryTileTable _tile_table_iron_mine_0[] = { +static const IndustryTileLayout _tile_table_iron_mine_0 { MK(0, 0, 100), MK(0, 1, 101), MK(0, 2, 102), @@ -667,14 +626,13 @@ static const IndustryTileTable _tile_table_iron_mine_0[] = { MK(3, 1, 113), MK(3, 2, 114), MK(3, 3, 115), - MKEND }; -static const IndustryTileTable * const _tile_table_iron_mine[] = { +static const std::vector _tile_table_iron_mine { _tile_table_iron_mine_0, }; -static const IndustryTileTable _tile_table_fruit_plantation_0[] = { +static const IndustryTileLayout _tile_table_fruit_plantation_0 { MK(0, 0, 116), MK(0, 1, 116), MK(0, 2, 116), @@ -695,14 +653,13 @@ static const IndustryTileTable _tile_table_fruit_plantation_0[] = { MK(4, 1, 116), MK(4, 2, 116), MK(4, 3, 116), - MKEND }; -static const IndustryTileTable * const _tile_table_fruit_plantation[] = { +static const std::vector _tile_table_fruit_plantation { _tile_table_fruit_plantation_0, }; -static const IndustryTileTable _tile_table_rubber_plantation_0[] = { +static const IndustryTileLayout _tile_table_rubber_plantation_0 { MK(0, 0, 117), MK(0, 1, 117), MK(0, 2, 117), @@ -723,35 +680,32 @@ static const IndustryTileTable _tile_table_rubber_plantation_0[] = { MK(4, 1, 117), MK(4, 2, 117), MK(4, 3, 117), - MKEND }; -static const IndustryTileTable * const _tile_table_rubber_plantation[] = { +static const std::vector _tile_table_rubber_plantation { _tile_table_rubber_plantation_0, }; -static const IndustryTileTable _tile_table_water_supply_0[] = { +static const IndustryTileLayout _tile_table_water_supply_0 { MK(0, 0, 118), MK(0, 1, 119), MK(1, 0, 118), MK(1, 1, 119), - MKEND }; -static const IndustryTileTable * const _tile_table_water_supply[] = { +static const std::vector _tile_table_water_supply { _tile_table_water_supply_0, }; -static const IndustryTileTable _tile_table_water_tower_0[] = { +static const IndustryTileLayout _tile_table_water_tower_0 { MK(0, 0, 120), - MKEND }; -static const IndustryTileTable * const _tile_table_water_tower[] = { +static const std::vector _tile_table_water_tower { _tile_table_water_tower_0, }; -static const IndustryTileTable _tile_table_factory2_0[] = { +static const IndustryTileLayout _tile_table_factory2_0 { MK(0, 0, 121), MK(0, 1, 122), MK(1, 0, 123), @@ -760,10 +714,9 @@ static const IndustryTileTable _tile_table_factory2_0[] = { MK(0, 3, 122), MK(1, 2, 123), MK(1, 3, 124), - MKEND }; -static const IndustryTileTable _tile_table_factory2_1[] = { +static const IndustryTileLayout _tile_table_factory2_1 { MK(0, 0, 121), MK(0, 1, 122), MK(1, 0, 123), @@ -772,15 +725,14 @@ static const IndustryTileTable _tile_table_factory2_1[] = { MK(2, 1, 122), MK(3, 0, 123), MK(3, 1, 124), - MKEND }; -static const IndustryTileTable * const _tile_table_factory2[] = { +static const std::vector _tile_table_factory2 { _tile_table_factory2_0, _tile_table_factory2_1, }; -static const IndustryTileTable _tile_table_farm2_0[] = { +static const IndustryTileLayout _tile_table_farm2_0 { MK(1, 0, 33), MK(1, 1, 34), MK(1, 2, 36), @@ -790,10 +742,9 @@ static const IndustryTileTable _tile_table_farm2_0[] = { MK(2, 0, 35), MK(2, 1, 38), MK(2, 2, 38), - MKEND }; -static const IndustryTileTable _tile_table_farm2_1[] = { +static const IndustryTileLayout _tile_table_farm2_1 { MK(1, 1, 33), MK(1, 2, 34), MK(0, 0, 35), @@ -806,10 +757,9 @@ static const IndustryTileTable _tile_table_farm2_1[] = { MK(2, 1, 37), MK(2, 2, 38), MK(2, 3, 38), - MKEND }; -static const IndustryTileTable _tile_table_farm2_2[] = { +static const IndustryTileLayout _tile_table_farm2_2 { MK(2, 0, 33), MK(2, 1, 34), MK(0, 0, 36), @@ -822,28 +772,26 @@ static const IndustryTileTable _tile_table_farm2_2[] = { MK(1, 3, 37), MK(2, 2, 37), MK(2, 3, 35), - MKEND }; -static const IndustryTileTable * const _tile_table_farm2[] = { +static const std::vector _tile_table_farm2 { _tile_table_farm2_0, _tile_table_farm2_1, _tile_table_farm2_2, }; -static const IndustryTileTable _tile_table_lumber_mill_0[] = { +static const IndustryTileLayout _tile_table_lumber_mill_0 { MK(0, 0, 125), MK(0, 1, 126), MK(1, 0, 127), MK(1, 1, 128), - MKEND }; -static const IndustryTileTable * const _tile_table_lumber_mill[] = { +static const std::vector _tile_table_lumber_mill { _tile_table_lumber_mill_0, }; -static const IndustryTileTable _tile_table_cotton_candy_0[] = { +static const IndustryTileLayout _tile_table_cotton_candy_0 { MK(0, 0, 129), MK(0, 1, 129), MK(0, 2, 129), @@ -862,10 +810,9 @@ static const IndustryTileTable _tile_table_cotton_candy_0[] = { MK(3, 3, 129), MK(1, 4, 129), MK(2, 4, 129), - MKEND }; -static const IndustryTileTable _tile_table_cotton_candy_1[] = { +static const IndustryTileLayout _tile_table_cotton_candy_1 { MK(0, 0, 129), MK(1, 0, 129), MK(2, 0, 129), @@ -889,15 +836,14 @@ static const IndustryTileTable _tile_table_cotton_candy_1[] = { MK(1, 4, 129), MK(2, 4, 129), MK(3, 4, 129), - MKEND }; -static const IndustryTileTable * const _tile_table_cotton_candy[] = { +static const std::vector _tile_table_cotton_candy { _tile_table_cotton_candy_0, _tile_table_cotton_candy_1, }; -static const IndustryTileTable _tile_table_candy_factory_0[] = { +static const IndustryTileLayout _tile_table_candy_factory_0 { MK(0, 0, 131), MK(0, 1, 132), MK(1, 0, 133), @@ -910,10 +856,9 @@ static const IndustryTileTable _tile_table_candy_factory_0[] = { MK(2, 2, 132), MK(3, 1, 133), MK(3, 2, 134), - MKEND }; -static const IndustryTileTable _tile_table_candy_factory_1[] = { +static const IndustryTileLayout _tile_table_candy_factory_1 { MK(0, 0, 131), MK(0, 1, 132), MK(1, 0, 133), @@ -926,15 +871,14 @@ static const IndustryTileTable _tile_table_candy_factory_1[] = { MK(1, 3, 132), MK(2, 2, 133), MK(2, 3, 134), - MKEND }; -static const IndustryTileTable * const _tile_table_candy_factory[] = { +static const std::vector _tile_table_candy_factory { _tile_table_candy_factory_0, _tile_table_candy_factory_1, }; -static const IndustryTileTable _tile_table_battery_farm_0[] = { +static const IndustryTileLayout _tile_table_battery_farm_0 { MK(0, 0, 135), MK(0, 1, 135), MK(0, 2, 135), @@ -955,14 +899,13 @@ static const IndustryTileTable _tile_table_battery_farm_0[] = { MK(4, 1, 135), MK(4, 2, 135), MK(4, 3, 135), - MKEND }; -static const IndustryTileTable * const _tile_table_battery_farm[] = { +static const std::vector _tile_table_battery_farm { _tile_table_battery_farm_0, }; -static const IndustryTileTable _tile_table_cola_wells_0[] = { +static const IndustryTileLayout _tile_table_cola_wells_0 { MK(0, 0, 137), MK(0, 1, 137), MK(0, 2, 137), @@ -971,10 +914,9 @@ static const IndustryTileTable _tile_table_cola_wells_0[] = { MK(1, 2, 137), MK(2, 1, 137), MK(2, 2, 137), - MKEND }; -static const IndustryTileTable _tile_table_cola_wells_1[] = { +static const IndustryTileLayout _tile_table_cola_wells_1 { MK(0, 1, 137), MK(0, 2, 137), MK(0, 3, 137), @@ -982,27 +924,25 @@ static const IndustryTileTable _tile_table_cola_wells_1[] = { MK(1, 1, 137), MK(1, 2, 137), MK(2, 1, 137), - MKEND }; -static const IndustryTileTable * const _tile_table_cola_wells[] = { +static const std::vector _tile_table_cola_wells { _tile_table_cola_wells_0, _tile_table_cola_wells_1, }; -static const IndustryTileTable _tile_table_toy_shop_0[] = { +static const IndustryTileLayout _tile_table_toy_shop_0 { MK(0, 0, 138), MK(0, 1, 139), MK(1, 0, 140), MK(1, 1, 141), - MKEND }; -static const IndustryTileTable * const _tile_table_toy_shop[] = { +static const std::vector _tile_table_toy_shop { _tile_table_toy_shop_0, }; -static const IndustryTileTable _tile_table_toy_factory_0[] = { +static const IndustryTileLayout _tile_table_toy_factory_0 { MK(0, 0, 147), MK(0, 1, 142), MK(1, 0, 147), @@ -1011,45 +951,41 @@ static const IndustryTileTable _tile_table_toy_factory_0[] = { MK(2, 1, 144), MK(3, 0, 146), MK(3, 1, 145), - MKEND }; -static const IndustryTileTable * const _tile_table_toy_factory[] = { +static const std::vector _tile_table_toy_factory { _tile_table_toy_factory_0, }; -static const IndustryTileTable _tile_table_plastic_fountain_0[] = { +static const IndustryTileLayout _tile_table_plastic_fountain_0 { MK(0, 0, 148), MK(0, 1, 151), MK(0, 2, 154), - MKEND }; -static const IndustryTileTable _tile_table_plastic_fountain_1[] = { +static const IndustryTileLayout _tile_table_plastic_fountain_1 { MK(0, 0, 148), MK(1, 0, 151), MK(2, 0, 154), - MKEND }; -static const IndustryTileTable * const _tile_table_plastic_fountain[] = { +static const std::vector _tile_table_plastic_fountain { _tile_table_plastic_fountain_0, _tile_table_plastic_fountain_1, }; -static const IndustryTileTable _tile_table_fizzy_drink_0[] = { +static const IndustryTileLayout _tile_table_fizzy_drink_0 { MK(0, 0, 156), MK(0, 1, 157), MK(1, 0, 158), MK(1, 1, 159), - MKEND }; -static const IndustryTileTable * const _tile_table_fizzy_drink[] = { +static const std::vector _tile_table_fizzy_drink { _tile_table_fizzy_drink_0, }; -static const IndustryTileTable _tile_table_bubble_generator_0[] = { +static const IndustryTileLayout _tile_table_bubble_generator_0 { MK(0, 0, 163), MK(0, 1, 160), MK(1, 0, 163), @@ -1062,25 +998,23 @@ static const IndustryTileTable _tile_table_bubble_generator_0[] = { MK(1, 3, 161), MK(2, 2, 163), MK(2, 3, 162), - MKEND }; -static const IndustryTileTable * const _tile_table_bubble_generator[] = { +static const std::vector _tile_table_bubble_generator { _tile_table_bubble_generator_0, }; -static const IndustryTileTable _tile_table_toffee_quarry_0[] = { +static const IndustryTileLayout _tile_table_toffee_quarry_0 { MK(0, 0, 164), MK(1, 0, 165), MK(2, 0, 166), - MKEND }; -static const IndustryTileTable * const _tile_table_toffee_quarry[] = { +static const std::vector _tile_table_toffee_quarry { _tile_table_toffee_quarry_0, }; -static const IndustryTileTable _tile_table_sugar_mine_0[] = { +static const IndustryTileLayout _tile_table_sugar_mine_0 { MK(0, 0, 167), MK(0, 1, 168), MK(1, 0, 169), @@ -1089,15 +1023,13 @@ static const IndustryTileTable _tile_table_sugar_mine_0[] = { MK(2, 1, 172), MK(3, 0, 173), MK(3, 1, 174), - MKEND }; -static const IndustryTileTable * const _tile_table_sugar_mine[] = { +static const std::vector _tile_table_sugar_mine { _tile_table_sugar_mine_0, }; #undef MK -#undef MKEND /** Array with saw sound, for sawmill */ static const uint8 _sawmill_sounds[] = { SND_28_SAWMILL }; @@ -1195,7 +1127,7 @@ enum IndustryTypes { #define MI(tbl, sndc, snd, d, pc, ai1, ai2, ai3, ai4, ag1, ag2, ag3, ag4, col, \ c1, c2, c3, proc, p1, r1, p2, r2, m, a1, im1, a2, im2, a3, im3, pr, clim, bev, in, intx, s1, s2, s3) \ - {tbl, lengthof(tbl), d, 0, pc, {c1, c2, c3}, proc, \ + {tbl, d, 0, pc, {c1, c2, c3}, proc, \ {p1, p2, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID}, \ {r1, r2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}, m, \ {a1, a2, a3, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID, CT_INVALID}, \ @@ -1213,7 +1145,7 @@ enum IndustryTypes { industry name building text messages : Closure production up production down */ static const IndustrySpec _origin_industry_specs[NEW_INDUSTRYOFFSET] = { - MI(_tile_table_coal_mine, 0, NULL, + MI(_tile_table_coal_mine, 0, nullptr, 210, 0xB3333333, 2, 3, 0, 0, 8, 8, 0, 0, 1, IT_POWER_STATION, IT_INVALID, IT_INVALID, CHECK_NOTHING, CT_COAL, 15, CT_INVALID, 0, 5, @@ -1223,7 +1155,7 @@ static const IndustrySpec _origin_industry_specs[NEW_INDUSTRYOFFSET] = { STR_INDUSTRY_NAME_COAL_MINE, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_COAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL), - MI(_tile_table_power_station, 0, NULL, + MI(_tile_table_power_station, 0, nullptr, 240, 0xFFFFFFFF, 2, 2, 0, 0, 5, 5, 0, 0, 184, IT_COAL_MINE, IT_INVALID, IT_INVALID, CHECK_NOTHING, CT_INVALID, 0, CT_INVALID, 0, 5, @@ -1243,7 +1175,7 @@ static const IndustrySpec _origin_industry_specs[NEW_INDUSTRYOFFSET] = { STR_INDUSTRY_NAME_SAWMILL, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_CLOSURE_SUPPLY_PROBLEMS, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL), - MI(_tile_table_forest, 0, NULL, + MI(_tile_table_forest, 0, nullptr, 200, 0xBFFFFFFF, 3, 4, 0, 0, 5, 5, 0, 0, 86, IT_SAWMILL, IT_PAPER_MILL, IT_INVALID, CHECK_FOREST, CT_WOOD, 13, CT_INVALID, 0, 30, @@ -1253,7 +1185,7 @@ static const IndustrySpec _origin_industry_specs[NEW_INDUSTRYOFFSET] = { STR_INDUSTRY_NAME_FOREST, STR_NEWS_INDUSTRY_PLANTED, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM), - MI(_tile_table_oil_refinery, 0, NULL, + MI(_tile_table_oil_refinery, 0, nullptr, 244, 0xFFFFFFFF, 2, 2, 2, 0, 4, 4, 4, 0, 191, IT_OIL_RIG, IT_INVALID, IT_INVALID, CHECK_REFINERY, CT_GOODS, 0, CT_INVALID, 0, 5, @@ -1263,7 +1195,7 @@ static const IndustrySpec _origin_industry_specs[NEW_INDUSTRYOFFSET] = { STR_INDUSTRY_NAME_OIL_REFINERY, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_CLOSURE_SUPPLY_PROBLEMS, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL), - MI(_tile_table_oil_rig, 0, NULL, + MI(_tile_table_oil_rig, 0, nullptr, 240, 0x99999999, 6, 0, 0, 0, 0, 0, 0, 0, 152, IT_OIL_REFINERY, IT_INVALID, IT_INVALID, CHECK_OIL_RIG, CT_OIL, 15, CT_PASSENGERS, 2, 5, @@ -1293,7 +1225,7 @@ static const IndustrySpec _origin_industry_specs[NEW_INDUSTRYOFFSET] = { STR_INDUSTRY_NAME_PRINTING_WORKS, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_CLOSURE_SUPPLY_PROBLEMS, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL), - MI(_tile_table_steel_mill, 0, NULL, + MI(_tile_table_steel_mill, 0, nullptr, 215, 0xFFFFFFFF, 2, 0, 0, 0, 5, 0, 0, 0, 10, IT_IRON_MINE, IT_FACTORY, IT_INVALID, CHECK_NOTHING, CT_STEEL, 0, CT_INVALID, 0, 5, @@ -1313,7 +1245,7 @@ static const IndustrySpec _origin_industry_specs[NEW_INDUSTRYOFFSET] = { STR_INDUSTRY_NAME_FARM, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM), - MI(_tile_table_copper_mine, 0, NULL, + MI(_tile_table_copper_mine, 0, nullptr, 205, 0xB3333333, 0, 0, 3, 0, 0, 0, 4, 0, 10, IT_FACTORY_2, IT_INVALID, IT_INVALID, CHECK_NOTHING, CT_COPPER_ORE, 10, CT_INVALID, 0, 5, @@ -1323,7 +1255,7 @@ static const IndustrySpec _origin_industry_specs[NEW_INDUSTRYOFFSET] = { STR_INDUSTRY_NAME_COPPER_ORE_MINE, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL), - MI(_tile_table_oil_well, 0, NULL, + MI(_tile_table_oil_well, 0, nullptr, 220, 0x99999999, 0, 5, 3, 0, 4, 5, 5, 0, 152, IT_OIL_REFINERY, IT_INVALID, IT_INVALID, CHECK_NOTHING, CT_OIL, 12, CT_INVALID, 0, 5, @@ -1333,7 +1265,7 @@ static const IndustrySpec _origin_industry_specs[NEW_INDUSTRYOFFSET] = { STR_INDUSTRY_NAME_OIL_WELLS, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_OIL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL), - MI(_tile_table_bank, 0, NULL, + MI(_tile_table_bank, 0, nullptr, 255, 0xA6666666, 7, 0, 0, 0, 0, 0, 0, 0, 15, IT_BANK_TEMP, IT_INVALID, IT_INVALID, CHECK_NOTHING, CT_VALUABLES, 6, CT_INVALID, 0, 5, @@ -1343,7 +1275,7 @@ static const IndustrySpec _origin_industry_specs[NEW_INDUSTRYOFFSET] = { STR_INDUSTRY_NAME_BANK, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL), - MI(_tile_table_food_process, 0, NULL, + MI(_tile_table_food_process, 0, nullptr, 206, 0xFFFFFFFF, 0, 2, 2, 0, 0, 3, 4, 0, 55, IT_FRUIT_PLANTATION, IT_FARM, IT_FARM_2, CHECK_NOTHING, CT_FOOD, 0, CT_INVALID, 0, 5, @@ -1363,7 +1295,7 @@ static const IndustrySpec _origin_industry_specs[NEW_INDUSTRYOFFSET] = { STR_INDUSTRY_NAME_PAPER_MILL, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_CLOSURE_SUPPLY_PROBLEMS, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL), - MI(_tile_table_gold_mine, 0, NULL, + MI(_tile_table_gold_mine, 0, nullptr, 208, 0x99999999, 0, 3, 0, 0, 0, 4, 0, 0, 194, IT_BANK_TROPIC_ARCTIC, IT_INVALID, IT_INVALID, CHECK_NOTHING, CT_GOLD, 7, CT_INVALID, 0, 5, @@ -1373,7 +1305,7 @@ static const IndustrySpec _origin_industry_specs[NEW_INDUSTRYOFFSET] = { STR_INDUSTRY_NAME_GOLD_MINE, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL), - MI(_tile_table_bank2, 0, NULL, + MI(_tile_table_bank2, 0, nullptr, 151, 0xA6666666, 0, 3, 3, 0, 0, 6, 5, 0, 15, IT_GOLD_MINE, IT_DIAMOND_MINE, IT_INVALID, CHECK_NOTHING, CT_INVALID, 0, CT_INVALID, 0, 5, @@ -1383,7 +1315,7 @@ static const IndustrySpec _origin_industry_specs[NEW_INDUSTRYOFFSET] = { STR_INDUSTRY_NAME_BANK_TROPIC_ARCTIC, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL), - MI(_tile_table_diamond_mine, 0, NULL, + MI(_tile_table_diamond_mine, 0, nullptr, 213, 0x99999999, 0, 0, 3, 0, 0, 0, 4, 0, 184, IT_BANK_TROPIC_ARCTIC, IT_INVALID, IT_INVALID, CHECK_NOTHING, CT_DIAMONDS, 7, CT_INVALID, 0, 5, @@ -1393,7 +1325,7 @@ static const IndustrySpec _origin_industry_specs[NEW_INDUSTRYOFFSET] = { STR_INDUSTRY_NAME_DIAMOND_MINE, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL), - MI(_tile_table_iron_mine, 0, NULL, + MI(_tile_table_iron_mine, 0, nullptr, 220, 0xB3333333, 2, 0, 0, 0, 5, 0, 0, 0, 55, IT_STEEL_MILL, IT_INVALID, IT_INVALID, CHECK_NOTHING, CT_IRON_ORE, 10, CT_INVALID, 0, 5, @@ -1403,7 +1335,7 @@ static const IndustrySpec _origin_industry_specs[NEW_INDUSTRYOFFSET] = { STR_INDUSTRY_NAME_IRON_ORE_MINE, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL), - MI(_tile_table_fruit_plantation, 0, NULL, + MI(_tile_table_fruit_plantation, 0, nullptr, 225, 0xBFFFFFFF, 0, 0, 2, 0, 0, 0, 4, 0, 86, IT_FOOD_PROCESS, IT_INVALID, IT_INVALID, CHECK_PLANTATION, CT_FRUIT, 10, CT_INVALID, 0, 15, @@ -1413,7 +1345,7 @@ static const IndustrySpec _origin_industry_specs[NEW_INDUSTRYOFFSET] = { STR_INDUSTRY_NAME_FRUIT_PLANTATION, STR_NEWS_INDUSTRY_PLANTED, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM), - MI(_tile_table_rubber_plantation, 0, NULL, + MI(_tile_table_rubber_plantation, 0, nullptr, 218, 0xBFFFFFFF, 0, 0, 3, 0, 0, 0, 4, 0, 39, IT_FACTORY_2, IT_INVALID, IT_INVALID, CHECK_PLANTATION, CT_RUBBER, 10, CT_INVALID, 0, 15, @@ -1423,7 +1355,7 @@ static const IndustrySpec _origin_industry_specs[NEW_INDUSTRYOFFSET] = { STR_INDUSTRY_NAME_RUBBER_PLANTATION, STR_NEWS_INDUSTRY_PLANTED, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM), - MI(_tile_table_water_supply, 0, NULL, + MI(_tile_table_water_supply, 0, nullptr, 199, 0xB3333333, 0, 0, 3, 0, 0, 0, 4, 0, 37, IT_WATER_TOWER, IT_INVALID, IT_INVALID, CHECK_WATER, CT_WATER, 12, CT_INVALID, 0, 5, @@ -1433,7 +1365,7 @@ static const IndustrySpec _origin_industry_specs[NEW_INDUSTRYOFFSET] = { STR_INDUSTRY_NAME_WATER_SUPPLY, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL), - MI(_tile_table_water_tower, 0, NULL, + MI(_tile_table_water_tower, 0, nullptr, 115, 0xFFFFFFFF, 0, 0, 4, 0, 0, 0, 8, 0, 208, IT_WATER_SUPPLY, IT_INVALID, IT_INVALID, CHECK_WATER, CT_INVALID, 0, CT_INVALID, 0, 5, @@ -1453,7 +1385,7 @@ static const IndustrySpec _origin_industry_specs[NEW_INDUSTRYOFFSET] = { STR_INDUSTRY_NAME_FACTORY_2, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_CLOSURE_SUPPLY_PROBLEMS, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL), - MI(_tile_table_farm2, 0, NULL, + MI(_tile_table_farm2, 0, nullptr, 250, 0xD9999999, 0, 0, 1, 0, 0, 0, 2, 0, 48, IT_FOOD_PROCESS, IT_INVALID, IT_INVALID, CHECK_PLANTATION, CT_MAIZE, 11, CT_INVALID, 0, 5, @@ -1463,7 +1395,7 @@ static const IndustrySpec _origin_industry_specs[NEW_INDUSTRYOFFSET] = { STR_INDUSTRY_NAME_FARM_2, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM), - MI(_tile_table_lumber_mill, 0, NULL, + MI(_tile_table_lumber_mill, 0, nullptr, 135, 0xFFFFFFFF, 0, 0, 0, 0, 0, 0, 0, 0, 194, IT_FACTORY_2, IT_INVALID, IT_INVALID, CHECK_LUMBERMILL, CT_WOOD, 0, CT_INVALID, 0, 5, @@ -1473,7 +1405,7 @@ static const IndustrySpec _origin_industry_specs[NEW_INDUSTRYOFFSET] = { STR_INDUSTRY_NAME_LUMBER_MILL, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_CLOSURE_LACK_OF_TREES, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL), - MI(_tile_table_cotton_candy, 0, NULL, + MI(_tile_table_cotton_candy, 0, nullptr, 195, 0xBFFFFFFF, 0, 0, 0, 3, 0, 0, 0, 5, 48, IT_CANDY_FACTORY, IT_INVALID, IT_INVALID, CHECK_NOTHING, CT_COTTON_CANDY, 13, CT_INVALID, 0, 30, @@ -1483,7 +1415,7 @@ static const IndustrySpec _origin_industry_specs[NEW_INDUSTRYOFFSET] = { STR_INDUSTRY_NAME_COTTON_CANDY_FOREST, STR_NEWS_INDUSTRY_PLANTED, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL), - MI(_tile_table_candy_factory, 0, NULL, + MI(_tile_table_candy_factory, 0, nullptr, 206, 0xFFFFFFFF, 0, 0, 0, 3, 0, 0, 0, 5, 174, IT_COTTON_CANDY, IT_TOFFEE_QUARRY, IT_SUGAR_MINE, CHECK_NOTHING, CT_CANDY, 0, CT_INVALID, 0, 5, @@ -1493,7 +1425,7 @@ static const IndustrySpec _origin_industry_specs[NEW_INDUSTRYOFFSET] = { STR_INDUSTRY_NAME_CANDY_FACTORY, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_CLOSURE_SUPPLY_PROBLEMS, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL), - MI(_tile_table_battery_farm, 0, NULL, + MI(_tile_table_battery_farm, 0, nullptr, 187, 0xB3333333, 0, 0, 0, 3, 0, 0, 0, 4, 39, IT_TOY_FACTORY, IT_INVALID, IT_INVALID, CHECK_NOTHING, CT_BATTERIES, 11, CT_INVALID, 0, 30, @@ -1503,7 +1435,7 @@ static const IndustrySpec _origin_industry_specs[NEW_INDUSTRYOFFSET] = { STR_INDUSTRY_NAME_BATTERY_FARM, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_FARM, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_FARM), - MI(_tile_table_cola_wells, 0, NULL, + MI(_tile_table_cola_wells, 0, nullptr, 193, 0x99999999, 0, 0, 0, 3, 0, 0, 0, 5, 55, IT_FIZZY_DRINK_FACTORY, IT_INVALID, IT_INVALID, CHECK_NOTHING, CT_COLA, 12, CT_INVALID, 0, 5, @@ -1513,7 +1445,7 @@ static const IndustrySpec _origin_industry_specs[NEW_INDUSTRYOFFSET] = { STR_INDUSTRY_NAME_COLA_WELLS, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL), - MI(_tile_table_toy_shop, 0, NULL, + MI(_tile_table_toy_shop, 0, nullptr, 133, 0xFFFFFFFF, 0, 0, 0, 3, 0, 0, 0, 4, 208, IT_TOY_FACTORY, IT_INVALID, IT_INVALID, CHECK_NOTHING, CT_INVALID, 0, CT_INVALID, 0, 5, @@ -1523,7 +1455,7 @@ static const IndustrySpec _origin_industry_specs[NEW_INDUSTRYOFFSET] = { STR_INDUSTRY_NAME_TOY_SHOP, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_CLOSURE_SUPPLY_PROBLEMS, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL), - MI(_tile_table_toy_factory, 0, NULL, + MI(_tile_table_toy_factory, 0, nullptr, 163, 0xFFFFFFFF, 0, 0, 0, 3, 0, 0, 0, 5, 10, IT_PLASTIC_FOUNTAINS, IT_BATTERY_FARM, IT_TOY_SHOP, CHECK_NOTHING, CT_TOYS, 0, CT_INVALID, 0, 5, @@ -1543,7 +1475,7 @@ static const IndustrySpec _origin_industry_specs[NEW_INDUSTRYOFFSET] = { STR_INDUSTRY_NAME_PLASTIC_FOUNTAINS, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL), - MI(_tile_table_fizzy_drink, 0, NULL, + MI(_tile_table_fizzy_drink, 0, nullptr, 177, 0xFFFFFFFF, 0, 0, 0, 3, 0, 0, 0, 4, 184, IT_COLA_WELLS, IT_BUBBLE_GENERATOR, IT_INVALID, CHECK_NOTHING, CT_FIZZY_DRINKS, 0, CT_INVALID, 0, 5, @@ -1553,7 +1485,7 @@ static const IndustrySpec _origin_industry_specs[NEW_INDUSTRYOFFSET] = { STR_INDUSTRY_NAME_FIZZY_DRINK_FACTORY, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_CLOSURE_SUPPLY_PROBLEMS, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL), - MI(_tile_table_bubble_generator, 0, NULL, + MI(_tile_table_bubble_generator, 0, nullptr, 203, 0xB3333333, 0, 0, 0, 3, 0, 0, 0, 5, 152, IT_FIZZY_DRINK_FACTORY, IT_INVALID, IT_INVALID, CHECK_BUBBLEGEN, CT_BUBBLES, 13, CT_INVALID, 0, 5, @@ -1563,7 +1495,7 @@ static const IndustrySpec _origin_industry_specs[NEW_INDUSTRYOFFSET] = { STR_INDUSTRY_NAME_BUBBLE_GENERATOR, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL), - MI(_tile_table_toffee_quarry, 0, NULL, + MI(_tile_table_toffee_quarry, 0, nullptr, 213, 0xCCCCCCCC, 0, 0, 0, 3, 0, 0, 0, 5, 194, IT_CANDY_FACTORY, IT_INVALID, IT_INVALID, CHECK_NOTHING, CT_TOFFEE, 10, CT_INVALID, 0, 5, @@ -1573,7 +1505,7 @@ static const IndustrySpec _origin_industry_specs[NEW_INDUSTRYOFFSET] = { STR_INDUSTRY_NAME_TOFFEE_QUARRY, STR_NEWS_INDUSTRY_CONSTRUCTION, STR_NEWS_INDUSTRY_CLOSURE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_INCREASE_GENERAL, STR_NEWS_INDUSTRY_PRODUCTION_DECREASE_GENERAL), - MI(_tile_table_sugar_mine, 0, NULL, + MI(_tile_table_sugar_mine, 0, nullptr, 210, 0xBFFFFFFF, 0, 0, 0, 2, 0, 0, 0, 4, 15, IT_CANDY_FACTORY, IT_INVALID, IT_INVALID, CHECK_NOTHING, CT_SUGAR, 11, CT_INVALID, 0, 5, diff --git a/src/table/cargo_const.h b/src/table/cargo_const.h index c2ce5bc78b..ad1ed8a215 100644 --- a/src/table/cargo_const.h +++ b/src/table/cargo_const.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. @@ -11,7 +9,7 @@ /** Construction macro for a #CargoSpec structure. */ #define MK(bt, label, c, e, f, g, h, fr, te, ks1, ks2, ks3, ks4, ks5, l, m, cmult) \ - {bt, label, c, c, e, cmult, f, {g, h}, fr, te, 0, 0, ks1, ks2, ks3, ks4, ks5, l, m, NULL, NULL, 0} + {bt, label, c, c, e, cmult, f, {g, h}, fr, te, 0, 0, ks1, ks2, ks3, ks4, ks5, l, m, nullptr, nullptr, 0} /** Cargo types available by default. */ static const CargoSpec _default_cargo[] = { MK( 0, 'PASS', 152, 1, 3185, 0, 24, false, TE_PASSENGERS, diff --git a/src/table/clear_land.h b/src/table/clear_land.h index 345f055c6f..bc6718c6b5 100644 --- a/src/table/clear_land.h +++ b/src/table/clear_land.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/company_settings.ini b/src/table/company_settings.ini index a6e873f659..86035b9d77 100644 --- a/src/table/company_settings.ini +++ b/src/table/company_settings.ini @@ -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. ; 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. @@ -29,8 +27,8 @@ interval = 0 str = STR_NULL strhelp = STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT strval = STR_NULL -proc = NULL -load = NULL +proc = nullptr +load = nullptr from = SL_MIN_VERSION to = SL_MAX_VERSION cat = SC_ADVANCED @@ -43,6 +41,7 @@ var = engine_renew def = false str = STR_CONFIG_SETTING_AUTORENEW_VEHICLE strhelp = STR_CONFIG_SETTING_AUTORENEW_VEHICLE_HELPTEXT +cat = SC_BASIC [SDT_VAR] base = CompanySettings diff --git a/src/table/control_codes.h b/src/table/control_codes.h index d8e9673e9f..7f42d2c4f6 100644 --- a/src/table/control_codes.h +++ b/src/table/control_codes.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/currency_settings.ini b/src/table/currency_settings.ini index bcce65801b..34199501f3 100644 --- a/src/table/currency_settings.ini +++ b/src/table/currency_settings.ini @@ -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. ; 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. @@ -18,13 +16,13 @@ SDT_END = SDT_END() [defaults] flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC -guiflags = 0 +guiflags = SGF_NONE interval = 0 str = STR_NULL strhelp = STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT strval = STR_NULL -proc = NULL -load = NULL +proc = nullptr +load = nullptr from = SL_MIN_VERSION to = SL_MAX_VERSION cat = SC_ADVANCED @@ -57,7 +55,7 @@ max = MAX_YEAR base = CurrencySpec var = prefix type = SLE_STRBQ -def = NULL +def = nullptr [SDT_STR] base = CurrencySpec diff --git a/src/table/elrail_data.h b/src/table/elrail_data.h index 6915360035..12132848b8 100644 --- a/src/table/elrail_data.h +++ b/src/table/elrail_data.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. @@ -412,7 +410,7 @@ static const SortableSpriteStruct RailCatenarySpriteData_Tunnel[] = { * Identifiers for Wires: *
      1. Direction of the wire
      2. *
      3. Slope of the tile for diagonals, placement inside the track for horiz/vertical pieces
      4. - *
      5. Place where a pylon shoule be
      + *
    • Place where a pylon should be
    • * Identifiers for Pylons: *
      1. Direction of the wire
      2. *
      3. Slope of the tile
      4. diff --git a/src/table/engines.h b/src/table/engines.h index 3b29a8dc17..85e0ad2b6f 100644 --- a/src/table/engines.h +++ b/src/table/engines.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. @@ -388,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 } +#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 } #define M RAILVEH_MULTIHEAD #define W RAILVEH_WAGON #define G RAILVEH_SINGLEHEAD @@ -669,7 +667,7 @@ static const AircraftVehicleInfo _orig_aircraft_vehicle_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 ROV(a, b, c, d, e, f, g, h) { a, b, c, PR_RUNNING_ROADVEH, d, e, f, g, h, 76, 0, VE_DEFAULT, 0 } +#define ROV(a, b, c, d, e, f, g, h) { a, b, c, PR_RUNNING_ROADVEH, d, e, f, g, h, 76, 0, VE_DEFAULT, 0, ROADTYPE_ROAD } static const RoadVehicleInfo _orig_road_vehicle_info[] = { /* image_index sfx max_speed power * | cost_factor | | capacity | diff --git a/src/table/gameopt_settings.ini b/src/table/gameopt_settings.ini index 6152dfb2f6..ebd76f74f3 100644 --- a/src/table/gameopt_settings.ini +++ b/src/table/gameopt_settings.ini @@ -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. ; 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. @@ -12,7 +10,7 @@ static uint16 _old_diff_custom[GAME_DIFFICULTY_NUM]; uint8 _old_diff_level; ///< Old difficulty level from old savegames uint8 _old_units; ///< Old units from old savegames -/* Most of these strings are used both for gameopt-backward compatability +/* Most of these strings are used both for gameopt-backward compatibility * and the settings tables. The rest is here for consistency. */ static const char *_locale_currencies = "GBP|USD|EUR|YEN|ATS|BEF|CHF|CZK|DEM|DKK|ESP|FIM|FRF|GRD|HUF|ISK|ITL|NLG|NOK|PLN|RON|RUR|SIT|SEK|YTL|SKK|BRL|EEK|custom"; static const char *_locale_units = "imperial|metric|si"; @@ -22,9 +20,7 @@ static const char *_autosave_interval = "off|monthly|quarterly|half year|yearly" static const char *_save_to_network = "disabled|enabled|ask"; static const char *_roadsides = "left|right"; static const char *_savegame_date = "long|short|iso"; -#ifdef ENABLE_NETWORK static const char *_server_langs = "ANY|ENGLISH|GERMAN|FRENCH|BRAZILIAN|BULGARIAN|CHINESE|CZECH|DANISH|DUTCH|ESPERANTO|FINNISH|HUNGARIAN|ICELANDIC|ITALIAN|JAPANESE|KOREAN|LITHUANIAN|NORWEGIAN|POLISH|PORTUGUESE|ROMANIAN|RUSSIAN|SLOVAK|SLOVENIAN|SPANISH|SWEDISH|TURKISH|UKRAINIAN|AFRIKAANS|CROATIAN|CATALAN|ESTONIAN|GALICIAN|GREEK|LATVIAN"; -#endif /* ENABLE_NETWORK */ static const char *_osk_activation = "disabled|double|single|immediately"; static const char *_settings_profiles = "easy|medium|hard"; static const char *_news_display = "off|summarized|full"; @@ -53,13 +49,13 @@ SDT_END = SDT_END() [defaults] flags = 0 -guiflags = 0 +guiflags = SGF_NONE interval = 0 str = STR_NULL strhelp = STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT strval = STR_NULL -proc = NULL -load = NULL +proc = nullptr +load = nullptr from = SL_MIN_VERSION to = SL_MAX_VERSION cat = SC_ADVANCED @@ -77,7 +73,7 @@ length = 17 def = 0 min = 0 max = 0 -full = NULL +full = nullptr to = SLV_4 [SDTG_GENERAL] @@ -91,7 +87,7 @@ length = 18 def = 0 min = 0 max = 0 -full = NULL +full = nullptr from = SLV_4 ## diff --git a/src/table/genland.h b/src/table/genland.h index fd2a07e7ab..53801e2f68 100644 --- a/src/table/genland.h +++ b/src/table/genland.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/heightmap_colours.h b/src/table/heightmap_colours.h index 42b99eeca1..9f4b7d4129 100644 --- a/src/table/heightmap_colours.h +++ b/src/table/heightmap_colours.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/industry_land.h b/src/table/industry_land.h index fe5dd5b6e5..c0c50fa7d5 100644 --- a/src/table/industry_land.h +++ b/src/table/industry_land.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/landscape_sprite.h b/src/table/landscape_sprite.h index ceadd3e584..57855a9607 100644 --- a/src/table/landscape_sprite.h +++ b/src/table/landscape_sprite.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/misc_settings.ini b/src/table/misc_settings.ini index 870c3ae367..6ca7b3e6ef 100644 --- a/src/table/misc_settings.ini +++ b/src/table/misc_settings.ini @@ -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. ; 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. @@ -25,13 +23,13 @@ SDTG_END = SDTG_END() [defaults] flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC -guiflags = 0 +guiflags = SGF_NONE interval = 0 str = STR_NULL strhelp = STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT strval = STR_NULL -proc = NULL -load = NULL +proc = nullptr +load = nullptr from = SL_MIN_VERSION to = SL_MAX_VERSION cat = SC_ADVANCED @@ -64,55 +62,55 @@ cat = SC_BASIC name = ""graphicsset"" type = SLE_STRQ var = BaseGraphics::ini_set -def = NULL +def = nullptr cat = SC_BASIC [SDTG_STR] name = ""soundsset"" type = SLE_STRQ var = BaseSounds::ini_set -def = NULL +def = nullptr cat = SC_BASIC [SDTG_STR] name = ""musicset"" type = SLE_STRQ var = BaseMusic::ini_set -def = NULL +def = nullptr cat = SC_BASIC [SDTG_STR] name = ""videodriver"" type = SLE_STRQ var = _ini_videodriver -def = NULL +def = nullptr cat = SC_EXPERT [SDTG_STR] name = ""musicdriver"" type = SLE_STRQ var = _ini_musicdriver -def = NULL +def = nullptr cat = SC_EXPERT [SDTG_STR] name = ""sounddriver"" type = SLE_STRQ var = _ini_sounddriver -def = NULL +def = nullptr cat = SC_EXPERT [SDTG_STR] name = ""blitter"" type = SLE_STRQ var = _ini_blitter -def = NULL +def = nullptr [SDTG_STR] name = ""language"" type = SLE_STRB var = _config_language_file -def = NULL +def = nullptr cat = SC_BASIC ; workaround for implicit lengthof() in SDTG_LIST @@ -128,14 +126,14 @@ cat = SC_BASIC name = ""screenshot_format"" type = SLE_STRB var = _screenshot_format_name -def = NULL +def = nullptr cat = SC_EXPERT [SDTG_STR] name = ""savegame_format"" type = SLE_STRB var = _savegame_format -def = NULL +def = nullptr cat = SC_EXPERT [SDTG_BOOL] @@ -144,35 +142,35 @@ var = _rightclick_emulate def = false [SDTG_STR] -ifdef = WITH_FREETYPE +ifdef = HAS_TRUETYPE_FONT name = ""small_font"" type = SLE_STRB var = _freetype.small.font -def = NULL +def = nullptr [SDTG_STR] -ifdef = WITH_FREETYPE +ifdef = HAS_TRUETYPE_FONT name = ""medium_font"" type = SLE_STRB var = _freetype.medium.font -def = NULL +def = nullptr [SDTG_STR] -ifdef = WITH_FREETYPE +ifdef = HAS_TRUETYPE_FONT name = ""large_font"" type = SLE_STRB var = _freetype.large.font -def = NULL +def = nullptr [SDTG_STR] -ifdef = WITH_FREETYPE +ifdef = HAS_TRUETYPE_FONT name = ""mono_font"" type = SLE_STRB var = _freetype.mono.font -def = NULL +def = nullptr [SDTG_VAR] -ifdef = WITH_FREETYPE +ifdef = HAS_TRUETYPE_FONT name = ""small_size"" type = SLE_UINT var = _freetype.small.size @@ -181,7 +179,7 @@ min = 0 max = 72 [SDTG_VAR] -ifdef = WITH_FREETYPE +ifdef = HAS_TRUETYPE_FONT name = ""medium_size"" type = SLE_UINT var = _freetype.medium.size @@ -190,7 +188,7 @@ min = 0 max = 72 [SDTG_VAR] -ifdef = WITH_FREETYPE +ifdef = HAS_TRUETYPE_FONT name = ""large_size"" type = SLE_UINT var = _freetype.large.size @@ -199,7 +197,7 @@ min = 0 max = 72 [SDTG_VAR] -ifdef = WITH_FREETYPE +ifdef = HAS_TRUETYPE_FONT name = ""mono_size"" type = SLE_UINT var = _freetype.mono.size @@ -208,25 +206,25 @@ min = 0 max = 72 [SDTG_BOOL] -ifdef = WITH_FREETYPE +ifdef = HAS_TRUETYPE_FONT name = ""small_aa"" var = _freetype.small.aa def = false [SDTG_BOOL] -ifdef = WITH_FREETYPE +ifdef = HAS_TRUETYPE_FONT name = ""medium_aa"" var = _freetype.medium.aa def = false [SDTG_BOOL] -ifdef = WITH_FREETYPE +ifdef = HAS_TRUETYPE_FONT name = ""large_aa"" var = _freetype.large.aa def = false [SDTG_BOOL] -ifdef = WITH_FREETYPE +ifdef = HAS_TRUETYPE_FONT name = ""mono_aa"" var = _freetype.mono.aa def = false @@ -299,14 +297,14 @@ cat = SC_BASIC name = ""keyboard"" type = SLE_STRB var = _keyboard_opt[0] -def = NULL +def = nullptr cat = SC_EXPERT [SDTG_STR] name = ""keyboard_caps"" type = SLE_STRB var = _keyboard_opt[1] -def = NULL +def = nullptr cat = SC_EXPERT [SDTG_VAR] diff --git a/src/table/newgrf_debug_data.h b/src/table/newgrf_debug_data.h index 19b411fed0..d14415051c 100644 --- a/src/table/newgrf_debug_data.h +++ b/src/table/newgrf_debug_data.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. @@ -11,18 +9,19 @@ #include "../newgrf_house.h" #include "../newgrf_engine.h" +#include "../newgrf_roadtype.h" /* Helper for filling property tables */ #define NIP(prop, base, variable, type, name) { name, (ptrdiff_t)cpp_offsetof(base, variable), cpp_sizeof(base, variable), prop, type } -#define NIP_END() { NULL, 0, 0, 0, 0 } +#define NIP_END() { nullptr, 0, 0, 0, 0 } /* Helper for filling callback tables */ #define NIC(cb_id, base, variable, bit) { #cb_id, (ptrdiff_t)cpp_offsetof(base, variable), cpp_sizeof(base, variable), bit, cb_id } -#define NIC_END() { NULL, 0, 0, 0, 0 } +#define NIC_END() { nullptr, 0, 0, 0, 0 } /* Helper for filling variable tables */ #define NIV(var, name) { name, var } -#define NIV_END() { NULL, 0 } +#define NIV_END() { nullptr, 0 } /*** NewGRF Vehicles ***/ @@ -58,7 +57,7 @@ static const NIVariable _niv_vehicles[] = { NIV(0x47, "vehicle cargo info"), NIV(0x48, "vehicle type info"), NIV(0x49, "year of construction"), - NIV(0x4A, "current rail type info"), + NIV(0x4A, "current rail/road type info"), NIV(0x4B, "long date of last service"), NIV(0x4C, "current max speed"), NIV(0x4D, "position in articulated vehicle"), @@ -69,14 +68,14 @@ static const NIVariable _niv_vehicles[] = { }; class NIHVehicle : public NIHelper { - bool IsInspectable(uint index) const { return Vehicle::Get(index)->GetGRF() != NULL; } - uint GetParent(uint index) const { const Vehicle *first = Vehicle::Get(index)->First(); return GetInspectWindowNumber(GetGrfSpecFeature(first->type), first->index); } - const void *GetInstance(uint index)const { return Vehicle::Get(index); } - const void *GetSpec(uint index) const { return Vehicle::Get(index)->GetEngine(); } - void SetStringParameters(uint index) const { this->SetSimpleStringParameters(STR_VEHICLE_NAME, index); } - uint32 GetGRFID(uint index) const { return Vehicle::Get(index)->GetGRFID(); } + bool IsInspectable(uint index) const override { return Vehicle::Get(index)->GetGRF() != nullptr; } + uint GetParent(uint index) const override { const Vehicle *first = Vehicle::Get(index)->First(); return GetInspectWindowNumber(GetGrfSpecFeature(first->type), first->index); } + const void *GetInstance(uint index)const override { return Vehicle::Get(index); } + const void *GetSpec(uint index) const override { return Vehicle::Get(index)->GetEngine(); } + void SetStringParameters(uint index) const override { this->SetSimpleStringParameters(STR_VEHICLE_NAME, index); } + uint32 GetGRFID(uint index) const override { return Vehicle::Get(index)->GetGRFID(); } - /* virtual */ uint Resolve(uint index, uint var, uint param, bool *avail) const + uint Resolve(uint index, uint var, uint param, bool *avail) const override { Vehicle *v = Vehicle::Get(index); VehicleResolverObject ro(v->engine_type, v, VehicleResolverObject::WO_CACHED); @@ -85,7 +84,7 @@ class NIHVehicle : public NIHelper { }; static const NIFeature _nif_vehicle = { - NULL, + nullptr, _nic_vehicles, _niv_vehicles, new NIHVehicle(), @@ -128,18 +127,19 @@ static const NIVariable _niv_stations[] = { NIV(0x67, "land info of nearby tiles"), NIV(0x68, "station info of nearby tiles"), NIV(0x69, "information about cargo accepted in the past"), + NIV(0x6A, "GRFID of nearby station tiles"), NIV_END() }; class NIHStation : public NIHelper { - bool IsInspectable(uint index) const { return GetStationSpec(index) != NULL; } - uint GetParent(uint index) const { return GetInspectWindowNumber(GSF_FAKE_TOWNS, Station::GetByTile(index)->town->index); } - const void *GetInstance(uint index)const { return NULL; } - const void *GetSpec(uint index) const { return GetStationSpec(index); } - void SetStringParameters(uint index) const { this->SetObjectAtStringParameters(STR_STATION_NAME, GetStationIndex(index), index); } - uint32 GetGRFID(uint index) const { return (this->IsInspectable(index)) ? GetStationSpec(index)->grf_prop.grffile->grfid : 0; } + bool IsInspectable(uint index) const override { return GetStationSpec(index) != nullptr; } + uint GetParent(uint index) const override { return GetInspectWindowNumber(GSF_FAKE_TOWNS, Station::GetByTile(index)->town->index); } + const void *GetInstance(uint index)const override { return nullptr; } + const void *GetSpec(uint index) const override { return GetStationSpec(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)) ? GetStationSpec(index)->grf_prop.grffile->grfid : 0; } - /* virtual */ uint Resolve(uint index, uint var, uint param, bool *avail) const + uint Resolve(uint index, uint var, uint param, bool *avail) const override { StationResolverObject ro(GetStationSpec(index), Station::GetByTile(index), index); return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, avail); @@ -147,7 +147,7 @@ class NIHStation : public NIHelper { }; static const NIFeature _nif_station = { - NULL, + nullptr, _nic_stations, _niv_stations, new NIHStation(), @@ -197,14 +197,14 @@ static const NIVariable _niv_house[] = { }; class NIHHouse : public NIHelper { - bool IsInspectable(uint index) const { return HouseSpec::Get(GetHouseType(index))->grf_prop.grffile != NULL; } - uint GetParent(uint index) const { return GetInspectWindowNumber(GSF_FAKE_TOWNS, GetTownIndex(index)); } - const void *GetInstance(uint index)const { return NULL; } - const void *GetSpec(uint index) const { return HouseSpec::Get(GetHouseType(index)); } - void SetStringParameters(uint index) const { this->SetObjectAtStringParameters(STR_TOWN_NAME, GetTownIndex(index), index); } - uint32 GetGRFID(uint index) const { return (this->IsInspectable(index)) ? HouseSpec::Get(GetHouseType(index))->grf_prop.grffile->grfid : 0; } + bool IsInspectable(uint index) const override { return HouseSpec::Get(GetHouseType(index))->grf_prop.grffile != nullptr; } + uint GetParent(uint index) const override { return GetInspectWindowNumber(GSF_FAKE_TOWNS, GetTownIndex(index)); } + const void *GetInstance(uint index)const override { return nullptr; } + const void *GetSpec(uint index) const override { return HouseSpec::Get(GetHouseType(index)); } + void SetStringParameters(uint index) const override { this->SetObjectAtStringParameters(STR_TOWN_NAME, GetTownIndex(index), index); } + uint32 GetGRFID(uint index) const override { return (this->IsInspectable(index)) ? HouseSpec::Get(GetHouseType(index))->grf_prop.grffile->grfid : 0; } - /* virtual */ uint Resolve(uint index, uint var, uint param, bool *avail) const + uint Resolve(uint index, uint var, uint param, bool *avail) const override { HouseResolverObject ro(GetHouseType(index), index, Town::GetByTile(index)); return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, avail); @@ -212,7 +212,7 @@ class NIHHouse : public NIHelper { }; static const NIFeature _nif_house = { - NULL, + nullptr, _nic_house, _niv_house, new NIHHouse(), @@ -247,14 +247,14 @@ static const NIVariable _niv_industrytiles[] = { }; class NIHIndustryTile : public NIHelper { - bool IsInspectable(uint index) const { return GetIndustryTileSpec(GetIndustryGfx(index))->grf_prop.grffile != NULL; } - uint GetParent(uint index) const { return GetInspectWindowNumber(GSF_INDUSTRIES, GetIndustryIndex(index)); } - const void *GetInstance(uint index)const { return NULL; } - const void *GetSpec(uint index) const { return GetIndustryTileSpec(GetIndustryGfx(index)); } - void SetStringParameters(uint index) const { this->SetObjectAtStringParameters(STR_INDUSTRY_NAME, GetIndustryIndex(index), index); } - uint32 GetGRFID(uint index) const { return (this->IsInspectable(index)) ? GetIndustryTileSpec(GetIndustryGfx(index))->grf_prop.grffile->grfid : 0; } + bool IsInspectable(uint index) const override { return GetIndustryTileSpec(GetIndustryGfx(index))->grf_prop.grffile != nullptr; } + uint GetParent(uint index) const override { return GetInspectWindowNumber(GSF_INDUSTRIES, GetIndustryIndex(index)); } + const void *GetInstance(uint index)const override { return nullptr; } + const void *GetSpec(uint index) const override { return GetIndustryTileSpec(GetIndustryGfx(index)); } + void SetStringParameters(uint index) const override { this->SetObjectAtStringParameters(STR_INDUSTRY_NAME, GetIndustryIndex(index), index); } + uint32 GetGRFID(uint index) const override { return (this->IsInspectable(index)) ? GetIndustryTileSpec(GetIndustryGfx(index))->grf_prop.grffile->grfid : 0; } - /* virtual */ uint Resolve(uint index, uint var, uint param, bool *avail) const + uint Resolve(uint index, uint var, uint param, bool *avail) const override { IndustryTileResolverObject ro(GetIndustryGfx(index), index, Industry::GetByTile(index)); return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, avail); @@ -262,7 +262,7 @@ class NIHIndustryTile : public NIHelper { }; static const NIFeature _nif_industrytile = { - NULL, + nullptr, _nic_industrytiles, _niv_industrytiles, new NIHIndustryTile(), @@ -346,26 +346,26 @@ static const NIVariable _niv_industries[] = { }; class NIHIndustry : public NIHelper { - bool IsInspectable(uint index) const { return GetIndustrySpec(Industry::Get(index)->type)->grf_prop.grffile != NULL; } - uint GetParent(uint index) const { return GetInspectWindowNumber(GSF_FAKE_TOWNS, Industry::Get(index)->town->index); } - const void *GetInstance(uint index)const { return Industry::Get(index); } - const void *GetSpec(uint index) const { return GetIndustrySpec(Industry::Get(index)->type); } - void SetStringParameters(uint index) const { this->SetSimpleStringParameters(STR_INDUSTRY_NAME, index); } - uint32 GetGRFID(uint index) const { return (this->IsInspectable(index)) ? GetIndustrySpec(Industry::Get(index)->type)->grf_prop.grffile->grfid : 0; } + bool IsInspectable(uint index) const override { return GetIndustrySpec(Industry::Get(index)->type)->grf_prop.grffile != nullptr; } + uint GetParent(uint index) const override { return GetInspectWindowNumber(GSF_FAKE_TOWNS, Industry::Get(index)->town->index); } + const void *GetInstance(uint index)const override { return Industry::Get(index); } + const void *GetSpec(uint index) const override { return GetIndustrySpec(Industry::Get(index)->type); } + void SetStringParameters(uint index) const override { this->SetSimpleStringParameters(STR_INDUSTRY_NAME, index); } + uint32 GetGRFID(uint index) const override { return (this->IsInspectable(index)) ? GetIndustrySpec(Industry::Get(index)->type)->grf_prop.grffile->grfid : 0; } - /* virtual */ uint Resolve(uint index, uint var, uint param, bool *avail) const + uint Resolve(uint index, uint var, uint param, bool *avail) const override { Industry *i = Industry::Get(index); IndustriesResolverObject ro(i->location.tile, i, i->type); return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, avail); } - uint GetPSASize(uint index, uint32 grfid) const { return cpp_lengthof(PersistentStorage, storage); } + uint GetPSASize(uint index, uint32 grfid) const override { return cpp_lengthof(PersistentStorage, storage); } - const int32 *GetPSAFirstPosition(uint index, uint32 grfid) const + const int32 *GetPSAFirstPosition(uint index, uint32 grfid) const override { const Industry *i = (const Industry *)this->GetInstance(index); - if (i->psa == NULL) return NULL; + if (i->psa == nullptr) return nullptr; return (int32 *)(&i->psa->storage); } }; @@ -411,14 +411,14 @@ static const NIVariable _niv_objects[] = { }; class NIHObject : public NIHelper { - bool IsInspectable(uint index) const { return ObjectSpec::GetByTile(index)->grf_prop.grffile != NULL; } - uint GetParent(uint index) const { return GetInspectWindowNumber(GSF_FAKE_TOWNS, Object::GetByTile(index)->town->index); } - const void *GetInstance(uint index)const { return Object::GetByTile(index); } - const void *GetSpec(uint index) const { return ObjectSpec::GetByTile(index); } - void SetStringParameters(uint index) const { this->SetObjectAtStringParameters(STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_OBJECT, INVALID_STRING_ID, index); } - uint32 GetGRFID(uint index) const { return (this->IsInspectable(index)) ? ObjectSpec::GetByTile(index)->grf_prop.grffile->grfid : 0; } + bool IsInspectable(uint index) const override { return ObjectSpec::GetByTile(index)->grf_prop.grffile != nullptr; } + uint GetParent(uint index) const override { return GetInspectWindowNumber(GSF_FAKE_TOWNS, Object::GetByTile(index)->town->index); } + const void *GetInstance(uint index)const override { return Object::GetByTile(index); } + const void *GetSpec(uint index) const override { return ObjectSpec::GetByTile(index); } + void SetStringParameters(uint index) const override { this->SetObjectAtStringParameters(STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_OBJECT, INVALID_STRING_ID, index); } + uint32 GetGRFID(uint index) const override { return (this->IsInspectable(index)) ? ObjectSpec::GetByTile(index)->grf_prop.grffile->grfid : 0; } - /* virtual */ uint Resolve(uint index, uint var, uint param, bool *avail) const + uint Resolve(uint index, uint var, uint param, bool *avail) const override { ObjectResolverObject ro(ObjectSpec::GetByTile(index), Object::GetByTile(index), index); return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, avail); @@ -426,7 +426,7 @@ class NIHObject : public NIHelper { }; static const NIFeature _nif_object = { - NULL, + nullptr, _nic_objects, _niv_objects, new NIHObject(), @@ -445,25 +445,25 @@ static const NIVariable _niv_railtypes[] = { }; class NIHRailType : public NIHelper { - bool IsInspectable(uint index) const { return true; } - uint GetParent(uint index) const { return UINT32_MAX; } - const void *GetInstance(uint index)const { return NULL; } - const void *GetSpec(uint index) const { return NULL; } - void SetStringParameters(uint index) const { this->SetObjectAtStringParameters(STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_RAIL_TYPE, INVALID_STRING_ID, index); } - uint32 GetGRFID(uint index) const { return 0; } + bool IsInspectable(uint index) const override { return true; } + uint GetParent(uint index) const override { return UINT32_MAX; } + const void *GetInstance(uint index)const override { return nullptr; } + const void *GetSpec(uint index) const override { return nullptr; } + void SetStringParameters(uint index) const override { this->SetObjectAtStringParameters(STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_RAIL_TYPE, INVALID_STRING_ID, index); } + uint32 GetGRFID(uint index) const override { return 0; } - /* virtual */ uint Resolve(uint index, uint var, uint param, bool *avail) const + uint Resolve(uint index, uint var, uint param, bool *avail) const override { /* There is no unique GRFFile for the tile. Multiple GRFs can define different parts of the railtype. * However, currently the NewGRF Debug GUI does not display variables depending on the GRF (like 0x7F) anyway. */ - RailTypeResolverObject ro(NULL, index, TCX_NORMAL, RTSG_END); + RailTypeResolverObject ro(nullptr, index, TCX_NORMAL, RTSG_END); return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, avail); } }; static const NIFeature _nif_railtype = { - NULL, - NULL, + nullptr, + nullptr, _niv_railtypes, new NIHRailType(), }; @@ -481,14 +481,14 @@ static const NICallback _nic_airporttiles[] = { }; class NIHAirportTile : public NIHelper { - bool IsInspectable(uint index) const { return AirportTileSpec::Get(GetAirportGfx(index))->grf_prop.grffile != NULL; } - uint GetParent(uint index) const { return GetInspectWindowNumber(GSF_FAKE_TOWNS, Station::GetByTile(index)->town->index); } - const void *GetInstance(uint index)const { return NULL; } - const void *GetSpec(uint index) const { return AirportTileSpec::Get(GetAirportGfx(index)); } - void SetStringParameters(uint index) const { this->SetObjectAtStringParameters(STR_STATION_NAME, GetStationIndex(index), index); } - uint32 GetGRFID(uint index) const { return (this->IsInspectable(index)) ? AirportTileSpec::Get(GetAirportGfx(index))->grf_prop.grffile->grfid : 0; } + bool IsInspectable(uint index) const override { return AirportTileSpec::Get(GetAirportGfx(index))->grf_prop.grffile != nullptr; } + uint GetParent(uint index) const override { return GetInspectWindowNumber(GSF_FAKE_TOWNS, Station::GetByTile(index)->town->index); } + const void *GetInstance(uint index)const override { return nullptr; } + const void *GetSpec(uint index) const override { return AirportTileSpec::Get(GetAirportGfx(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)) ? AirportTileSpec::Get(GetAirportGfx(index))->grf_prop.grffile->grfid : 0; } - /* virtual */ uint Resolve(uint index, uint var, uint param, bool *avail) const + uint Resolve(uint index, uint var, uint param, bool *avail) const override { AirportTileResolverObject ro(AirportTileSpec::GetByTile(index), index, Station::GetByTile(index)); return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, avail); @@ -496,7 +496,7 @@ class NIHAirportTile : public NIHelper { }; static const NIFeature _nif_airporttile = { - NULL, + nullptr, _nic_airporttiles, _niv_industrytiles, // Yes, they share this (at least now) new NIHAirportTile(), @@ -519,22 +519,22 @@ static const NIVariable _niv_towns[] = { }; class NIHTown : public NIHelper { - bool IsInspectable(uint index) const { return Town::IsValidID(index); } - uint GetParent(uint index) const { return UINT32_MAX; } - const void *GetInstance(uint index)const { return Town::Get(index); } - const void *GetSpec(uint index) const { return NULL; } - void SetStringParameters(uint index) const { this->SetSimpleStringParameters(STR_TOWN_NAME, index); } - uint32 GetGRFID(uint index) const { return 0; } - bool PSAWithParameter() const { return true; } - uint GetPSASize(uint index, uint32 grfid) const { return cpp_lengthof(PersistentStorage, storage); } + bool IsInspectable(uint index) const override { return Town::IsValidID(index); } + uint GetParent(uint index) const override { return UINT32_MAX; } + const void *GetInstance(uint index)const override { return Town::Get(index); } + const void *GetSpec(uint index) const override { return nullptr; } + void SetStringParameters(uint index) const override { this->SetSimpleStringParameters(STR_TOWN_NAME, index); } + uint32 GetGRFID(uint index) const override { return 0; } + bool PSAWithParameter() const override { return true; } + uint GetPSASize(uint index, uint32 grfid) const override { return cpp_lengthof(PersistentStorage, storage); } - /* virtual */ uint Resolve(uint index, uint var, uint param, bool *avail) const + uint Resolve(uint index, uint var, uint param, bool *avail) const override { - TownResolverObject ro(NULL, Town::Get(index), true); + TownResolverObject ro(nullptr, Town::Get(index), true); return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, avail); } - const int32 *GetPSAFirstPosition(uint index, uint32 grfid) const + const int32 *GetPSAFirstPosition(uint index, uint32 grfid) const override { Town *t = Town::Get(index); @@ -543,17 +543,59 @@ class NIHTown : public NIHelper { if ((*iter)->grfid == grfid) return (int32 *)(&(*iter)->storage[0]); } - return NULL; + return nullptr; } }; static const NIFeature _nif_town = { - NULL, - NULL, + nullptr, + nullptr, _niv_towns, new NIHTown(), }; +/*** NewGRF road types ***/ + +static const NIVariable _niv_roadtypes[] = { + NIV(0x40, "terrain type"), + NIV(0x41, "enhanced tunnels"), + NIV(0x42, "level crossing status"), + NIV(0x43, "construction date"), + NIV(0x44, "town zone"), + NIV_END() +}; + +class NIHRoadType : public NIHelper { + bool IsInspectable(uint index) const override { return true; } + uint GetParent(uint index) const override { return UINT32_MAX; } + const void *GetInstance(uint index) const override { return nullptr; } + const void *GetSpec(uint index) const override { return nullptr; } + void SetStringParameters(uint index) const override { this->SetObjectAtStringParameters(STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_RAIL_TYPE, INVALID_STRING_ID, index); } + uint32 GetGRFID(uint index) const override { return 0; } + + uint Resolve(uint index, uint var, uint param, bool *avail) const override + { + /* There is no unique GRFFile for the tile. Multiple GRFs can define different parts of the railtype. + * However, currently the NewGRF Debug GUI does not display variables depending on the GRF (like 0x7F) anyway. */ + RoadTypeResolverObject ro(nullptr, index, TCX_NORMAL, ROTSG_END); + return ro.GetScope(VSG_SCOPE_SELF)->GetVariable(var, param, avail); + } +}; + +static const NIFeature _nif_roadtype = { + nullptr, + nullptr, + _niv_roadtypes, + new NIHRoadType(), +}; + +static const NIFeature _nif_tramtype = { + nullptr, + nullptr, + _niv_roadtypes, + new NIHRoadType(), +}; + /** Table with all NIFeatures. */ static const NIFeature * const _nifeatures[] = { &_nif_vehicle, // GSF_TRAINS @@ -561,19 +603,21 @@ static const NIFeature * const _nifeatures[] = { &_nif_vehicle, // GSF_SHIPS &_nif_vehicle, // GSF_AIRCRAFT &_nif_station, // GSF_STATIONS - NULL, // GSF_CANALS (no callbacks/action2 implemented) - NULL, // GSF_BRIDGES (no callbacks/action2) + nullptr, // GSF_CANALS (no callbacks/action2 implemented) + nullptr, // GSF_BRIDGES (no callbacks/action2) &_nif_house, // GSF_HOUSES - NULL, // GSF_GLOBALVAR (has no "physical" objects) + nullptr, // GSF_GLOBALVAR (has no "physical" objects) &_nif_industrytile, // GSF_INDUSTRYTILES &_nif_industry, // GSF_INDUSTRIES - NULL, // GSF_CARGOES (has no "physical" objects) - NULL, // GSF_SOUNDFX (has no "physical" objects) - NULL, // GSF_AIRPORTS (feature not implemented) - NULL, // GSF_SIGNALS (feature not implemented) + nullptr, // GSF_CARGOES (has no "physical" objects) + nullptr, // GSF_SOUNDFX (has no "physical" objects) + nullptr, // GSF_AIRPORTS (feature not implemented) + nullptr, // GSF_SIGNALS (feature not implemented) &_nif_object, // GSF_OBJECTS &_nif_railtype, // GSF_RAILTYPES &_nif_airporttile, // GSF_AIRPORTTILES + &_nif_roadtype, // GSF_ROADTYPES + &_nif_tramtype, // GSF_TRAMTYPES &_nif_town, // GSF_FAKE_TOWNS }; assert_compile(lengthof(_nifeatures) == GSF_FAKE_END); diff --git a/src/table/object_land.h b/src/table/object_land.h index a19b2cb089..ed26a0f500 100644 --- a/src/table/object_land.h +++ b/src/table/object_land.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/palette_convert.h b/src/table/palette_convert.h index 58c190424f..0a3e3d4a4e 100644 --- a/src/table/palette_convert.h +++ b/src/table/palette_convert.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/palettes.h b/src/table/palettes.h index 93cb7385e1..e5d1684b3f 100644 --- a/src/table/palettes.h +++ b/src/table/palettes.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/pricebase.h b/src/table/pricebase.h index 9dc2ee2ba7..5051254a38 100644 --- a/src/table/pricebase.h +++ b/src/table/pricebase.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/railtypes.h b/src/table/railtypes.h index f52a1524bd..95285de5f0 100644 --- a/src/table/railtypes.h +++ b/src/table/railtypes.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. @@ -112,8 +110,8 @@ static const RailtypeInfo _original_railtypes[] = { /* sort order */ 0 << 4 | 7, - { NULL }, - { NULL }, + { nullptr }, + { nullptr }, }, /** Electrified railway */ @@ -156,7 +154,7 @@ static const RailtypeInfo _original_railtypes[] = { STR_RAIL_MENU_ELRAIL_CONSTRUCTION, STR_BUY_VEHICLE_TRAIN_ELRAIL_CAPTION, STR_REPLACE_ELRAIL_VEHICLES, - STR_ENGINE_PREVIEW_RAILROAD_LOCOMOTIVE, + STR_ENGINE_PREVIEW_ELRAIL_LOCOMOTIVE, }, /* Offset of snow tiles */ @@ -213,8 +211,8 @@ static const RailtypeInfo _original_railtypes[] = { /* sort order */ 1 << 4 | 7, - { NULL }, - { NULL }, + { nullptr }, + { nullptr }, }, /** Monorail */ @@ -310,8 +308,8 @@ static const RailtypeInfo _original_railtypes[] = { /* sort order */ 2 << 4 | 7, - { NULL }, - { NULL }, + { nullptr }, + { nullptr }, }, /** Maglev */ @@ -407,8 +405,8 @@ static const RailtypeInfo _original_railtypes[] = { /* sort order */ 3 << 4 | 7, - { NULL }, - { NULL }, + { nullptr }, + { nullptr }, }, }; diff --git a/src/table/road_land.h b/src/table/road_land.h index 19b8f57119..67423784a2 100644 --- a/src/table/road_land.h +++ b/src/table/road_land.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. @@ -41,35 +39,6 @@ static const DrawTileSprites _road_depot[] = { { {0xA4A, PAL_NONE}, _road_depot_NW } }; -static const DrawTileSeqStruct _tram_depot_NE[] = { - TILE_SEQ_LINE((SPR_TRAMWAY_BASE + 0x35) | (1 << PALETTE_MODIFIER_COLOUR), PAL_NONE, 0, 15, 16, 1) - TILE_SEQ_END() -}; - -static const DrawTileSeqStruct _tram_depot_SE[] = { - TILE_SEQ_LINE((SPR_TRAMWAY_BASE + 0x31) | (1 << PALETTE_MODIFIER_COLOUR), PAL_NONE, 0, 0, 1, 16) - TILE_SEQ_LINE((SPR_TRAMWAY_BASE + 0x32) | (1 << PALETTE_MODIFIER_COLOUR), PAL_NONE, 15, 0, 1, 16) - TILE_SEQ_END() -}; - -static const DrawTileSeqStruct _tram_depot_SW[] = { - TILE_SEQ_LINE((SPR_TRAMWAY_BASE + 0x33) | (1 << PALETTE_MODIFIER_COLOUR), PAL_NONE, 0, 0, 16, 1) - TILE_SEQ_LINE((SPR_TRAMWAY_BASE + 0x34) | (1 << PALETTE_MODIFIER_COLOUR), PAL_NONE, 0, 15, 16, 1) - TILE_SEQ_END() -}; - -static const DrawTileSeqStruct _tram_depot_NW[] = { - TILE_SEQ_LINE((SPR_TRAMWAY_BASE + 0x36) | (1 << PALETTE_MODIFIER_COLOUR), PAL_NONE, 15, 0, 1, 16) - TILE_SEQ_END() -}; - -static const DrawTileSprites _tram_depot[] = { - { {0xA4A, PAL_NONE}, _tram_depot_NE }, - { {0xA4A, PAL_NONE}, _tram_depot_SE }, - { {0xA4A, PAL_NONE}, _tram_depot_SW }, - { {0xA4A, PAL_NONE}, _tram_depot_NW } -}; - /* Sprite layout for level crossings. The SpriteIDs are actually offsets * from the base SpriteID returned from the NewGRF sprite resolver. */ static const DrawTileSeqStruct _crossing_layout_ALL[] = { diff --git a/src/table/roadtypes.h b/src/table/roadtypes.h new file mode 100644 index 0000000000..d11573d632 --- /dev/null +++ b/src/table/roadtypes.h @@ -0,0 +1,181 @@ +/* + * 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 roadtypes.h + * All the roadtype-specific information is stored here. + */ + +#ifndef ROADTYPES_H +#define ROADTYPES_H + +/** + * Global Roadtype definition + */ +static const RoadTypeInfo _original_roadtypes[] = { + /* Road */ + { + /* GUI sprites */ + { + SPR_IMG_ROAD_X_DIR, + SPR_IMG_ROAD_Y_DIR, + SPR_IMG_AUTOROAD, + SPR_IMG_ROAD_DEPOT, + SPR_IMG_ROAD_TUNNEL, + SPR_IMG_CONVERT_ROAD, + }, + + { + SPR_CURSOR_ROAD_NESW, + SPR_CURSOR_ROAD_NWSE, + SPR_CURSOR_AUTOROAD, + SPR_CURSOR_ROAD_DEPOT, + SPR_CURSOR_ROAD_TUNNEL, + SPR_CURSOR_CONVERT_ROAD, + }, + + /* strings */ + { + STR_ROAD_NAME_ROAD, + STR_ROAD_TOOLBAR_ROAD_CONSTRUCTION_CAPTION, + STR_ROAD_MENU_ROAD_CONSTRUCTION, + STR_BUY_VEHICLE_ROAD_VEHICLE_CAPTION, + STR_REPLACE_ROAD_VEHICLES, + STR_ENGINE_PREVIEW_ROAD_VEHICLE, + + STR_ERROR_CAN_T_BUILD_ROAD_HERE, + STR_ERROR_CAN_T_REMOVE_ROAD_FROM, + STR_ERROR_CAN_T_BUILD_ROAD_DEPOT, + { STR_ERROR_CAN_T_BUILD_BUS_STATION, STR_ERROR_CAN_T_BUILD_TRUCK_STATION }, + { STR_ERROR_CAN_T_REMOVE_BUS_STATION, STR_ERROR_CAN_T_REMOVE_TRUCK_STATION }, + STR_ERROR_CAN_T_CONVERT_ROAD, + { STR_STATION_BUILD_BUS_ORIENTATION, STR_STATION_BUILD_TRUCK_ORIENTATION }, + { STR_STATION_BUILD_BUS_ORIENTATION_TOOLTIP, STR_STATION_BUILD_TRUCK_ORIENTATION_TOOLTIP }, + }, + + /* Powered roadtypes */ + ROADTYPES_ROAD, + + /* flags */ + ROTFB_TOWN_BUILD, + + /* cost multiplier */ + 8, + + /* maintenance cost multiplier */ + 16, + + /* max speed */ + 0, + + /* road type label */ + 'ROAD', + + /* alternate labels */ + RoadTypeLabelList(), + + /* map colour */ + 0x01, + + /* introduction date */ + MIN_YEAR, + + /* roadtypes required for this to be introduced */ + ROADTYPES_NONE, + + /* introduction road types */ + ROADTYPES_ROAD, + + /* sort order */ + 0x07, + + { nullptr }, + { nullptr }, + }, + + /* Electrified Tram */ + { + /* GUI sprites */ + { + SPR_IMG_TRAMWAY_X_DIR, + SPR_IMG_TRAMWAY_Y_DIR, + SPR_IMG_AUTOTRAM, + SPR_IMG_ROAD_DEPOT, + SPR_IMG_ROAD_TUNNEL, + SPR_IMG_CONVERT_TRAM, + }, + + { + SPR_CURSOR_TRAMWAY_NESW, + SPR_CURSOR_TRAMWAY_NWSE, + SPR_CURSOR_AUTOTRAM, + SPR_CURSOR_ROAD_DEPOT, + SPR_CURSOR_ROAD_TUNNEL, + SPR_CURSOR_CONVERT_TRAM, + }, + + /* strings */ + { + STR_ROAD_NAME_TRAM, + STR_ROAD_TOOLBAR_TRAM_CONSTRUCTION_CAPTION, + STR_ROAD_MENU_TRAM_CONSTRUCTION, + STR_BUY_VEHICLE_TRAM_VEHICLE_CAPTION, + STR_REPLACE_TRAM_VEHICLES, + STR_ENGINE_PREVIEW_TRAM_VEHICLE, + + STR_ERROR_CAN_T_BUILD_TRAMWAY_HERE, + STR_ERROR_CAN_T_REMOVE_TRAMWAY_FROM, + STR_ERROR_CAN_T_BUILD_TRAM_DEPOT, + { STR_ERROR_CAN_T_BUILD_PASSENGER_TRAM_STATION, STR_ERROR_CAN_T_BUILD_CARGO_TRAM_STATION }, + { STR_ERROR_CAN_T_REMOVE_PASSENGER_TRAM_STATION, STR_ERROR_CAN_T_REMOVE_CARGO_TRAM_STATION }, + STR_ERROR_CAN_T_CONVERT_TRAMWAY, + { STR_STATION_BUILD_PASSENGER_TRAM_ORIENTATION, STR_STATION_BUILD_CARGO_TRAM_ORIENTATION }, + { STR_STATION_BUILD_PASSENGER_TRAM_ORIENTATION_TOOLTIP, STR_STATION_BUILD_CARGO_TRAM_ORIENTATION_TOOLTIP }, + }, + + /* Powered roadtypes */ + ROADTYPES_TRAM, + + /* flags */ + ROTFB_CATENARY | ROTFB_NO_HOUSES, + + /* cost multiplier */ + 16, + + /* maintenance cost multiplier */ + 24, + + /* max speed */ + 0, + + /* road type label */ + 'ELRL', + + /* alternate labels */ + RoadTypeLabelList(), + + /* map colour */ + 0x01, + + /* introduction date */ + INVALID_DATE, + + /* roadtypes required for this to be introduced */ + ROADTYPES_NONE, + + /* introduction road types */ + ROADTYPES_TRAM, + + /* sort order */ + 0x17, + + { nullptr }, + { nullptr }, + }, +}; + +#endif /* ROADTYPES_H */ diff --git a/src/table/roadveh_movement.h b/src/table/roadveh_movement.h index 5b202b2b59..bb4c5df3b2 100644 --- a/src/table/roadveh_movement.h +++ b/src/table/roadveh_movement.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. @@ -1445,39 +1443,39 @@ static const RoadDriveEntry * const _road_tram_drive_data[] = { _roadveh_drive_data_29, _roadveh_tram_turn_sw_1, _roadveh_tram_turn_nw_1, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, + nullptr, }; static const RoadDriveEntry * const * const _road_drive_data[2] = { diff --git a/src/table/settings.h.preamble b/src/table/settings.h.preamble index f475e305bc..2be8239a6c 100644 --- a/src/table/settings.h.preamble +++ b/src/table/settings.h.preamble @@ -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,7 +31,7 @@ static size_t ConvertLandscape(const char *value); * Thse are for members in the struct described by the current * #SettingDesc list / .ini file. Here, 'base' specifies type of the * struct while 'var' points out the member of the struct (the actual - * struct to store it in is implicitely defined by the #SettingDesc + * struct to store it in is implicitly defined by the #SettingDesc * list / .ini file preamble the entry is in). * * The something part defines the type of variable to store. There are a @@ -57,24 +55,24 @@ static size_t ConvertLandscape(const char *value); */ #define NSD_GENERAL(name, def, cmd, guiflags, min, max, interval, many, str, strhelp, strval, proc, load, cat)\ - {name, (const void*)(size_t)(def), {(byte)cmd}, {(uint16)guiflags}, min, max, interval, many, str, strhelp, strval, proc, load, cat} + {name, (const void*)(size_t)(def), cmd, guiflags, min, max, interval, many, str, strhelp, strval, proc, load, cat} /* Macros for various objects to go in the configuration file. * This section is for global variables */ #define SDTG_GENERAL(name, sdt_cmd, sle_cmd, type, flags, guiflags, var, length, def, min, max, interval, full, str, strhelp, strval, proc, from, to, cat)\ - {NSD_GENERAL(name, def, sdt_cmd, guiflags, min, max, interval, full, str, strhelp, strval, proc, NULL, cat), SLEG_GENERAL(sle_cmd, var, type | flags, length, from, to)} + {NSD_GENERAL(name, def, sdt_cmd, guiflags, min, max, interval, full, str, strhelp, strval, proc, nullptr, cat), SLEG_GENERAL(sle_cmd, var, type | flags, length, from, to)} #define SDTG_VAR(name, type, flags, guiflags, var, def, min, max, interval, str, strhelp, strval, proc, from, to, cat)\ - SDTG_GENERAL(name, SDT_NUMX, SL_VAR, type, flags, guiflags, var, 0, def, min, max, interval, NULL, str, strhelp, strval, proc, from, to, cat) + SDTG_GENERAL(name, SDT_NUMX, SL_VAR, type, flags, guiflags, var, 0, def, min, max, interval, nullptr, str, strhelp, strval, proc, from, to, cat) #define SDTG_BOOL(name, flags, guiflags, var, def, str, strhelp, strval, proc, from, to, cat)\ - SDTG_GENERAL(name, SDT_BOOLX, SL_VAR, SLE_BOOL, flags, guiflags, var, 0, def, 0, 1, 0, NULL, str, strhelp, strval, proc, from, to, cat) + SDTG_GENERAL(name, SDT_BOOLX, SL_VAR, SLE_BOOL, flags, guiflags, var, 0, def, 0, 1, 0, nullptr, str, strhelp, strval, proc, from, to, cat) #define SDTG_LIST(name, type, length, flags, guiflags, var, def, str, strhelp, strval, proc, from, to, cat)\ - SDTG_GENERAL(name, SDT_INTLIST, SL_ARR, type, flags, guiflags, var, length, def, 0, 0, 0, NULL, str, strhelp, strval, proc, from, to, cat) + SDTG_GENERAL(name, SDT_INTLIST, SL_ARR, type, flags, guiflags, var, length, def, 0, 0, 0, nullptr, str, strhelp, strval, proc, from, to, cat) #define SDTG_STR(name, type, flags, guiflags, var, def, str, strhelp, strval, proc, from, to, cat)\ - SDTG_GENERAL(name, SDT_STRING, SL_STR, type, flags, guiflags, var, sizeof(var), def, 0, 0, 0, NULL, str, strhelp, strval, proc, from, to, cat) + SDTG_GENERAL(name, SDT_STRING, SL_STR, type, flags, guiflags, var, sizeof(var), def, 0, 0, 0, nullptr, str, strhelp, strval, proc, from, to, cat) #define SDTG_OMANY(name, type, flags, guiflags, var, def, max, full, str, strhelp, strval, proc, from, to, cat)\ SDTG_GENERAL(name, SDT_ONEOFMANY, SL_VAR, type, flags, guiflags, var, 0, def, 0, max, 0, full, str, strhelp, strval, proc, from, to, cat) @@ -83,9 +81,9 @@ static size_t ConvertLandscape(const char *value); SDTG_GENERAL(name, SDT_MANYOFMANY, SL_VAR, type, flags, guiflags, var, 0, def, 0, 0, 0, full, str, strhelp, strval, proc, from, to, cat) #define SDTG_NULL(length, from, to)\ - {{"", NULL, {0}, {0}, 0, 0, 0, NULL, STR_NULL, STR_NULL, STR_NULL, NULL, NULL, SC_NONE}, SLEG_NULL(length, from, to)} + {{"", nullptr, SDT_NUMX, SGF_NONE, 0, 0, 0, nullptr, STR_NULL, STR_NULL, STR_NULL, nullptr, nullptr, SC_NONE}, SLEG_NULL(length, from, to)} -#define SDTG_END() {{NULL, NULL, {0}, {0}, 0, 0, 0, NULL, STR_NULL, STR_NULL, STR_NULL, NULL, NULL, SC_NONE}, SLEG_END()} +#define SDTG_END() {{nullptr, nullptr, SDT_NUMX, SGF_NONE, 0, 0, 0, nullptr, STR_NULL, STR_NULL, STR_NULL, nullptr, nullptr, SC_NONE}, SLEG_END()} /* Macros for various objects to go in the configuration file. * This section is for structures where their various members are saved */ @@ -93,44 +91,44 @@ static size_t ConvertLandscape(const char *value); {NSD_GENERAL(name, def, sdt_cmd, guiflags, min, max, interval, full, str, strhelp, strval, proc, load, cat), SLE_GENERAL(sle_cmd, base, var, type | flags, length, from, to)} #define SDT_VAR(base, var, type, flags, guiflags, def, min, max, interval, str, strhelp, strval, proc, from, to, cat)\ - SDT_GENERAL(#var, SDT_NUMX, SL_VAR, type, flags, guiflags, base, var, 1, def, min, max, interval, NULL, str, strhelp, strval, proc, NULL, from, to, cat) + SDT_GENERAL(#var, SDT_NUMX, SL_VAR, type, flags, guiflags, base, var, 1, def, min, max, interval, nullptr, str, strhelp, strval, proc, nullptr, from, to, cat) #define SDT_BOOL(base, var, flags, guiflags, def, str, strhelp, strval, proc, from, to, cat)\ - SDT_GENERAL(#var, SDT_BOOLX, SL_VAR, SLE_BOOL, flags, guiflags, base, var, 1, def, 0, 1, 0, NULL, str, strhelp, strval, proc, NULL, from, to, cat) + SDT_GENERAL(#var, SDT_BOOLX, SL_VAR, SLE_BOOL, flags, guiflags, base, var, 1, def, 0, 1, 0, nullptr, str, strhelp, strval, proc, nullptr, from, to, cat) #define SDT_LIST(base, var, type, flags, guiflags, def, str, strhelp, strval, proc, from, to, cat)\ - SDT_GENERAL(#var, SDT_INTLIST, SL_ARR, type, flags, guiflags, base, var, lengthof(((base*)8)->var), def, 0, 0, 0, NULL, str, strhelp, strval, proc, NULL, from, to, cat) + SDT_GENERAL(#var, SDT_INTLIST, SL_ARR, type, flags, guiflags, base, var, lengthof(((base*)8)->var), def, 0, 0, 0, nullptr, str, strhelp, strval, proc, nullptr, from, to, cat) #define SDT_STR(base, var, type, flags, guiflags, def, str, strhelp, strval, proc, from, to, cat)\ - SDT_GENERAL(#var, SDT_STRING, SL_STR, type, flags, guiflags, base, var, sizeof(((base*)8)->var), def, 0, 0, 0, NULL, str, strhelp, strval, proc, NULL, from, to, cat) + SDT_GENERAL(#var, SDT_STRING, SL_STR, type, flags, guiflags, base, var, sizeof(((base*)8)->var), def, 0, 0, 0, nullptr, str, strhelp, strval, proc, nullptr, from, to, cat) #define SDT_CHR(base, var, flags, guiflags, def, str, strhelp, strval, proc, from, to, cat)\ - SDT_GENERAL(#var, SDT_STRING, SL_VAR, SLE_CHAR, flags, guiflags, base, var, 1, def, 0, 0, 0, NULL, str, strhelp, strval, proc, NULL, from, to, cat) + SDT_GENERAL(#var, SDT_STRING, SL_VAR, SLE_CHAR, flags, guiflags, base, var, 1, def, 0, 0, 0, nullptr, str, strhelp, strval, proc, nullptr, from, to, cat) #define SDT_OMANY(base, var, type, flags, guiflags, def, max, full, str, strhelp, strval, proc, from, to, load, cat)\ SDT_GENERAL(#var, SDT_ONEOFMANY, SL_VAR, type, flags, guiflags, base, var, 1, def, 0, max, 0, full, str, strhelp, strval, proc, load, from, to, cat) #define SDT_MMANY(base, var, type, flags, guiflags, def, full, str, proc, strhelp, strval, from, to, cat)\ - SDT_GENERAL(#var, SDT_MANYOFMANY, SL_VAR, type, flags, guiflags, base, var, 1, def, 0, 0, 0, full, str, strhelp, strval, proc, NULL, from, to, cat) + SDT_GENERAL(#var, SDT_MANYOFMANY, SL_VAR, type, flags, guiflags, base, var, 1, def, 0, 0, 0, full, str, strhelp, strval, proc, nullptr, from, to, cat) #define SDT_NULL(length, from, to)\ - {{"", NULL, {0}, {0}, 0, 0, 0, NULL, STR_NULL, STR_NULL, STR_NULL, NULL, NULL, SC_NONE}, SLE_CONDNULL(length, from, to)} + {{"", nullptr, SDT_NUMX, SGF_NONE, 0, 0, 0, nullptr, STR_NULL, STR_NULL, STR_NULL, nullptr, nullptr, SC_NONE}, SLE_CONDNULL(length, from, to)} #define SDTC_VAR(var, type, flags, guiflags, def, min, max, interval, str, strhelp, strval, proc, from, to, cat)\ - SDTG_GENERAL(#var, SDT_NUMX, SL_VAR, type, flags, guiflags, _settings_client.var, 1, def, min, max, interval, NULL, str, strhelp, strval, proc, from, to, cat) + SDTG_GENERAL(#var, SDT_NUMX, SL_VAR, type, flags, guiflags, _settings_client.var, 1, def, min, max, interval, nullptr, str, strhelp, strval, proc, from, to, cat) #define SDTC_BOOL(var, flags, guiflags, def, str, strhelp, strval, proc, from, to, cat)\ - SDTG_GENERAL(#var, SDT_BOOLX, SL_VAR, SLE_BOOL, flags, guiflags, _settings_client.var, 1, def, 0, 1, 0, NULL, str, strhelp, strval, proc, from, to, cat) + SDTG_GENERAL(#var, SDT_BOOLX, SL_VAR, SLE_BOOL, flags, guiflags, _settings_client.var, 1, def, 0, 1, 0, nullptr, str, strhelp, strval, proc, from, to, cat) #define SDTC_LIST(var, type, flags, guiflags, def, str, strhelp, strval, proc, from, to, cat)\ - SDTG_GENERAL(#var, SDT_INTLIST, SL_ARR, type, flags, guiflags, _settings_client.var, lengthof(_settings_client.var), def, 0, 0, 0, NULL, str, strhelp, strval, proc, from, to, cat) + SDTG_GENERAL(#var, SDT_INTLIST, SL_ARR, type, flags, guiflags, _settings_client.var, lengthof(_settings_client.var), def, 0, 0, 0, nullptr, str, strhelp, strval, proc, from, to, cat) #define SDTC_STR(var, type, flags, guiflags, def, str, strhelp, strval, proc, from, to, cat)\ - SDTG_GENERAL(#var, SDT_STRING, SL_STR, type, flags, guiflags, _settings_client.var, sizeof(_settings_client.var), def, 0, 0, 0, NULL, str, strhelp, strval, proc, from, to, cat) + SDTG_GENERAL(#var, SDT_STRING, SL_STR, type, flags, guiflags, _settings_client.var, sizeof(_settings_client.var), def, 0, 0, 0, nullptr, str, strhelp, strval, proc, from, to, cat) #define SDTC_OMANY(var, type, flags, guiflags, def, max, full, str, strhelp, strval, proc, from, to, cat)\ SDTG_GENERAL(#var, SDT_ONEOFMANY, SL_VAR, type, flags, guiflags, _settings_client.var, 1, def, 0, max, 0, full, str, strhelp, strval, proc, from, to, cat) -#define SDT_END() {{NULL, NULL, {0}, {0}, 0, 0, 0, NULL, STR_NULL, STR_NULL, STR_NULL, NULL, NULL, SC_NONE}, SLE_END()} +#define SDT_END() {{nullptr, nullptr, SDT_NUMX, SGF_NONE, 0, 0, 0, nullptr, STR_NULL, STR_NULL, STR_NULL, nullptr, nullptr, SC_NONE}, SLE_END()} diff --git a/src/table/settings.ini b/src/table/settings.ini index 3493097551..1fe4b85d38 100644 --- a/src/table/settings.ini +++ b/src/table/settings.ini @@ -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. ; 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. @@ -45,12 +43,13 @@ static bool VerticalToolbarChanged(int32 p1); static bool MaxVehiclesChanged(int32 p1); static bool InvalidateShipPathCache(int32 p1); -#ifdef ENABLE_NETWORK static bool UpdateClientName(int32 p1); static bool UpdateServerPassword(int32 p1); static bool UpdateRconPassword(int32 p1); static bool UpdateClientConfigValues(int32 p1); -#endif /* ENABLE_NETWORK */ + +extern int32 _old_ending_year_slv_105; + /* End - Callback Functions for the various settings */ /* Some settings do not need to be synchronised when playing in multiplayer. @@ -83,13 +82,13 @@ SDT_END = SDT_END() [defaults] flags = 0 -guiflags = 0 +guiflags = SGF_NONE interval = 0 str = STR_NULL strhelp = STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT strval = STR_NULL -proc = NULL -load = NULL +proc = nullptr +load = nullptr from = SL_MIN_VERSION to = SL_MAX_VERSION cat = SC_ADVANCED @@ -97,7 +96,7 @@ cat = SC_ADVANCED ; Saved settings variables. -; Do not ADD or REMOVE something in this "difficulty.XXX" table or before it. It breaks savegame compatability. +; Do not ADD or REMOVE something in this "difficulty.XXX" table or before it. It breaks savegame compatibility. [SDT_VAR] base = GameSettings var = difficulty.max_no_competitors @@ -619,6 +618,21 @@ def = true str = STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS strhelp = STR_CONFIG_SETTING_ALLOW_TOWN_LEVEL_CROSSINGS_HELPTEXT +[SDT_VAR] +base = GameSettings +var = economy.town_cargogen_mode +type = SLE_UINT8 +from = SLV_TOWN_CARGOGEN +guiflags = SGF_MULTISTRING +def = TCGM_BITCOUNT +min = TCGM_BEGIN +max = TCGM_END - 1 +interval = 1 +str = STR_CONFIG_SETTING_TOWN_CARGOGENMODE +strhelp = STR_CONFIG_SETTING_TOWN_CARGOGENMODE_HELPTEXT +strval = STR_CONFIG_SETTING_TOWN_CARGOGENMODE_ORIGINAL +cat = SC_ADVANCED + ; link graph [SDT_VAR] @@ -939,12 +953,12 @@ type = SLE_UINT8 from = SLV_87 guiflags = SGF_MULTISTRING def = 2 -min = 0 +min = 1 max = 2 interval = 1 str = STR_CONFIG_SETTING_PATHFINDER_FOR_SHIPS strhelp = STR_CONFIG_SETTING_PATHFINDER_FOR_SHIPS_HELPTEXT -strval = STR_CONFIG_SETTING_PATHFINDER_OPF +strval = STR_CONFIG_SETTING_PATHFINDER_NPF proc = InvalidateShipPathCache cat = SC_EXPERT @@ -1009,14 +1023,14 @@ proc = MaxVehiclesChanged cat = SC_BASIC [SDTG_BOOL] -name = NULL +name = nullptr guiflags = SGF_NO_NETWORK var = _old_vds.servint_ispercent def = false to = SLV_120 [SDTG_VAR] -name = NULL +name = nullptr type = SLE_UINT16 guiflags = SGF_0ISDISABLED var = _old_vds.servint_trains @@ -1026,7 +1040,7 @@ max = 800 to = SLV_120 [SDTG_VAR] -name = NULL +name = nullptr type = SLE_UINT16 guiflags = SGF_0ISDISABLED var = _old_vds.servint_roadveh @@ -1036,7 +1050,7 @@ max = 800 to = SLV_120 [SDTG_VAR] -name = NULL +name = nullptr type = SLE_UINT16 guiflags = SGF_0ISDISABLED var = _old_vds.servint_ships @@ -1046,7 +1060,7 @@ max = 800 to = SLV_120 [SDTG_VAR] -name = NULL +name = nullptr type = SLE_UINT16 guiflags = SGF_0ISDISABLED var = _old_vds.servint_aircraft @@ -1205,6 +1219,15 @@ strhelp = STR_CONFIG_SETTING_CATCHMENT_HELPTEXT proc = StationCatchmentChanged cat = SC_EXPERT +[SDT_BOOL] +base = GameSettings +var = station.serve_neutral_industries +def = true +from = SLV_SERVE_NEUTRAL_INDUSTRIES +str = STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES +strhelp = STR_CONFIG_SETTING_SERVE_NEUTRAL_INDUSTRIES_HELPTEXT +proc = StationCatchmentChanged + [SDT_BOOL] base = GameSettings var = order.gradual_loading @@ -1360,6 +1383,7 @@ guiflags = SGF_NO_NETWORK def = DEF_SNOWLINE_HEIGHT min = MIN_SNOWLINE_HEIGHT max = MAX_SNOWLINE_HEIGHT +interval = 1 str = STR_CONFIG_SETTING_SNOWLINE_HEIGHT strhelp = STR_CONFIG_SETTING_SNOWLINE_HEIGHT_HELPTEXT strval = STR_JUST_COMMA @@ -1381,9 +1405,30 @@ str = STR_CONFIG_SETTING_STARTING_YEAR strval = STR_JUST_INT cat = SC_BASIC -[SDT_NULL] -length = 4 +[SDTG_VAR] +name = ""old_ending_year_slv_105"" +var = _old_ending_year_slv_105 +flags = SLF_NOT_IN_CONFIG +type = SLE_INT32 to = SLV_105 +def = DEF_END_YEAR +min = MIN_YEAR +max = MAX_YEAR + +[SDT_VAR] +base = GameSettings +var = game_creation.ending_year +type = SLE_INT32 +from = SLV_ENDING_YEAR +guiflags = SGF_0ISDISABLED +def = DEF_END_YEAR +min = MIN_YEAR +max = MAX_YEAR +interval = 1 +str = STR_CONFIG_SETTING_ENDING_YEAR +strhelp = STR_CONFIG_SETTING_ENDING_YEAR_HELPTEXT +strval = STR_CONFIG_SETTING_ENDING_YEAR_VALUE +cat = SC_ADVANCED [SDT_BOOL] base = GameSettings @@ -1402,6 +1447,20 @@ str = STR_CONFIG_SETTING_ALLOW_SHARES strhelp = STR_CONFIG_SETTING_ALLOW_SHARES_HELPTEXT proc = InvalidateCompanyWindow +[SDT_VAR] +base = GameSettings +var = economy.min_years_for_shares +type = SLE_UINT8 +from = SLV_TRADING_AGE +def = 6 +min = 0 +max = 255 +interval = 1 +str = STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES +strhelp = STR_CONFIG_SETTING_MIN_YEARS_FOR_SHARES_HELPTEXT +strval = STR_JUST_INT +cat = SC_EXPERT + [SDT_VAR] base = GameSettings var = economy.feeder_payment_share @@ -1533,6 +1592,21 @@ strhelp = STR_CONFIG_SETTING_SCRIPT_MAX_OPCODES_HELPTEXT strval = STR_JUST_COMMA cat = SC_EXPERT +[SDT_VAR] +base = GameSettings +var = script.script_max_memory_megabytes +type = SLE_UINT32 +from = SLV_SCRIPT_MEMLIMIT +guiflags = SGF_NEWGAME_ONLY +def = 1024 +min = 8 +max = 8192 +interval = 8 +str = STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY +strhelp = STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_HELPTEXT +strval = STR_CONFIG_SETTING_SCRIPT_MAX_MEMORY_VALUE +cat = SC_EXPERT + ## [SDT_VAR] base = GameSettings @@ -1647,23 +1721,10 @@ max = 255 cat = SC_EXPERT ## -[SDT_VAR] -base = GameSettings -var = pf.opf.pf_maxlength -type = SLE_UINT16 -def = 4096 -min = 64 -max = 65535 -cat = SC_EXPERT - -[SDT_VAR] -base = GameSettings -var = pf.opf.pf_maxdepth -type = SLE_UINT8 -def = 48 -min = 4 -max = 255 -cat = SC_EXPERT +; Used to be pf.opf.pf_maxlength & pf.opf.pf_maxdepth +[SDT_NULL] +length = 3 +to = SLV_REMOVE_OPF ## [SDT_VAR] @@ -2149,6 +2210,26 @@ min = 0 max = 1000000 cat = SC_EXPERT +[SDT_VAR] +base = GameSettings +var = pf.yapf.ship_curve45_penalty +type = SLE_UINT +from = SLV_SHIP_CURVE_PENALTY +def = 1 * YAPF_TILE_LENGTH +min = 0 +max = 1000000 +cat = SC_EXPERT + +[SDT_VAR] +base = GameSettings +var = pf.yapf.ship_curve90_penalty +type = SLE_UINT +from = SLV_SHIP_CURVE_PENALTY +def = 6 * YAPF_TILE_LENGTH +min = 0 +max = 1000000 +cat = SC_EXPERT + ## [SDT_VAR] base = GameSettings @@ -2317,9 +2398,9 @@ base = GameSettings var = game_creation.custom_sea_level type = SLE_UINT8 from = SLV_149 -def = 1 -min = 2 -max = 90 +def = CUSTOM_SEA_LEVEL_MIN_PERCENTAGE +min = CUSTOM_SEA_LEVEL_MIN_PERCENTAGE +max = CUSTOM_SEA_LEVEL_MAX_PERCENTAGE cat = SC_BASIC [SDT_VAR] @@ -2484,7 +2565,7 @@ var = locale.digit_group_separator type = SLE_STRQ from = SLV_118 flags = SLF_NO_NETWORK_SYNC -def = NULL +def = nullptr proc = RedrawScreen cat = SC_BASIC @@ -2494,7 +2575,7 @@ var = locale.digit_group_separator_currency type = SLE_STRQ from = SLV_118 flags = SLF_NO_NETWORK_SYNC -def = NULL +def = nullptr proc = RedrawScreen cat = SC_BASIC @@ -2504,7 +2585,7 @@ var = locale.digit_decimal_separator type = SLE_STRQ from = SLV_126 flags = SLF_NO_NETWORK_SYNC -def = NULL +def = nullptr proc = RedrawScreen cat = SC_BASIC @@ -2625,6 +2706,7 @@ max = 3 str = STR_CONFIG_SETTING_SCROLLMODE strhelp = STR_CONFIG_SETTING_SCROLLMODE_HELPTEXT strval = STR_CONFIG_SETTING_SCROLLMODE_DEFAULT +cat = SC_BASIC [SDTC_BOOL] var = gui.smooth_scroll @@ -3209,6 +3291,15 @@ strhelp = STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT strval = STR_JUST_COMMA proc = RedrawScreen +[SDTC_BOOL] +var = gui.show_newgrf_name +flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC +def = false +str = STR_CONFIG_SETTING_SHOW_NEWGRF_NAME +strhelp = STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT +proc = RedrawScreen +cat = SC_ADVANCED + ; For the dedicated build we'll enable dates in logs by default. [SDTC_BOOL] ifdef = DEDICATED @@ -3382,14 +3473,14 @@ cat = SC_BASIC var = music.custom_1 type = SLE_UINT8 flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC -def = NULL +def = nullptr cat = SC_BASIC [SDTC_LIST] var = music.custom_2 type = SLE_UINT8 flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC -def = NULL +def = nullptr cat = SC_BASIC [SDTC_BOOL] @@ -3585,7 +3676,6 @@ strhelp = STR_CONFIG_SETTING_NEWS_GENERAL_INFORMATION_HELPTEXT strval = STR_CONFIG_SETTING_NEWS_MESSAGES_OFF [SDTC_VAR] -ifdef = ENABLE_NETWORK var = gui.network_chat_box_width_pct type = SLE_UINT16 flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC @@ -3595,7 +3685,6 @@ max = 100 cat = SC_EXPERT [SDTC_VAR] -ifdef = ENABLE_NETWORK var = gui.network_chat_box_height type = SLE_UINT8 flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC @@ -3605,7 +3694,6 @@ max = 255 cat = SC_EXPERT [SDTC_VAR] -ifdef = ENABLE_NETWORK var = gui.network_chat_timeout type = SLE_UINT16 flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC @@ -3615,7 +3703,6 @@ max = 65535 cat = SC_EXPERT [SDTC_VAR] -ifdef = ENABLE_NETWORK var = network.sync_freq type = SLE_UINT16 flags = SLF_NOT_IN_SAVE | SLF_NOT_IN_CONFIG | SLF_NO_NETWORK_SYNC @@ -3626,7 +3713,6 @@ max = 100 cat = SC_EXPERT [SDTC_VAR] -ifdef = ENABLE_NETWORK var = network.frame_freq type = SLE_UINT8 flags = SLF_NOT_IN_SAVE | SLF_NOT_IN_CONFIG | SLF_NO_NETWORK_SYNC @@ -3637,7 +3723,6 @@ max = 100 cat = SC_EXPERT [SDTC_VAR] -ifdef = ENABLE_NETWORK var = network.commands_per_frame type = SLE_UINT16 flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC @@ -3648,7 +3733,6 @@ max = 65535 cat = SC_EXPERT [SDTC_VAR] -ifdef = ENABLE_NETWORK var = network.max_commands_in_queue type = SLE_UINT16 flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC @@ -3659,7 +3743,6 @@ max = 65535 cat = SC_EXPERT [SDTC_VAR] -ifdef = ENABLE_NETWORK var = network.bytes_per_frame type = SLE_UINT16 flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC @@ -3670,7 +3753,6 @@ max = 65535 cat = SC_EXPERT [SDTC_VAR] -ifdef = ENABLE_NETWORK var = network.bytes_per_frame_burst type = SLE_UINT16 flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC @@ -3681,7 +3763,6 @@ max = 65535 cat = SC_EXPERT [SDTC_VAR] -ifdef = ENABLE_NETWORK var = network.max_init_time type = SLE_UINT16 flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC @@ -3692,7 +3773,6 @@ max = 32000 cat = SC_EXPERT [SDTC_VAR] -ifdef = ENABLE_NETWORK var = network.max_join_time type = SLE_UINT16 flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC @@ -3702,7 +3782,6 @@ min = 0 max = 32000 [SDTC_VAR] -ifdef = ENABLE_NETWORK var = network.max_download_time type = SLE_UINT16 flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC @@ -3712,7 +3791,6 @@ min = 0 max = 32000 [SDTC_VAR] -ifdef = ENABLE_NETWORK var = network.max_password_time type = SLE_UINT16 flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC @@ -3722,7 +3800,6 @@ min = 0 max = 32000 [SDTC_VAR] -ifdef = ENABLE_NETWORK var = network.max_lag_time type = SLE_UINT16 flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC @@ -3732,14 +3809,12 @@ min = 0 max = 32000 [SDTC_BOOL] -ifdef = ENABLE_NETWORK var = network.pause_on_join flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC guiflags = SGF_NETWORK_ONLY def = true [SDTC_VAR] -ifdef = ENABLE_NETWORK var = network.server_port type = SLE_UINT16 flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC @@ -3750,7 +3825,6 @@ max = 65535 cat = SC_EXPERT [SDTC_VAR] -ifdef = ENABLE_NETWORK var = network.server_admin_port type = SLE_UINT16 flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC @@ -3761,7 +3835,6 @@ max = 65535 cat = SC_EXPERT [SDTC_BOOL] -ifdef = ENABLE_NETWORK var = network.server_admin_chat flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC guiflags = SGF_NETWORK_ONLY @@ -3769,100 +3842,88 @@ def = true cat = SC_EXPERT [SDTC_BOOL] -ifdef = ENABLE_NETWORK var = network.server_advertise flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC guiflags = SGF_NETWORK_ONLY def = true [SDTC_VAR] -ifdef = ENABLE_NETWORK var = network.lan_internet type = SLE_UINT8 flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC guiflags = SGF_NETWORK_ONLY -def = 0 +def = 1 min = 0 max = 1 [SDTC_STR] -ifdef = ENABLE_NETWORK var = network.client_name type = SLE_STRB flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC -def = NULL +def = nullptr proc = UpdateClientName cat = SC_BASIC [SDTC_STR] -ifdef = ENABLE_NETWORK var = network.server_password type = SLE_STRB flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC guiflags = SGF_NETWORK_ONLY -def = NULL +def = nullptr proc = UpdateServerPassword cat = SC_BASIC [SDTC_STR] -ifdef = ENABLE_NETWORK var = network.rcon_password type = SLE_STRB flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC guiflags = SGF_NETWORK_ONLY -def = NULL +def = nullptr proc = UpdateRconPassword cat = SC_BASIC [SDTC_STR] -ifdef = ENABLE_NETWORK var = network.admin_password type = SLE_STRB flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC guiflags = SGF_NETWORK_ONLY -def = NULL +def = nullptr cat = SC_BASIC [SDTC_STR] -ifdef = ENABLE_NETWORK var = network.default_company_pass type = SLE_STRB flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC -def = NULL +def = nullptr [SDTC_STR] -ifdef = ENABLE_NETWORK var = network.server_name type = SLE_STRB flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC guiflags = SGF_NETWORK_ONLY -def = NULL +def = nullptr cat = SC_BASIC [SDTC_STR] -ifdef = ENABLE_NETWORK var = network.connect_to_ip type = SLE_STRB flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC -def = NULL +def = nullptr [SDTC_STR] -ifdef = ENABLE_NETWORK var = network.network_id type = SLE_STRB flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC guiflags = SGF_NETWORK_ONLY -def = NULL +def = nullptr [SDTC_BOOL] -ifdef = ENABLE_NETWORK var = network.autoclean_companies flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC guiflags = SGF_NETWORK_ONLY def = false [SDTC_VAR] -ifdef = ENABLE_NETWORK var = network.autoclean_unprotected type = SLE_UINT8 flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC @@ -3872,7 +3933,6 @@ min = 0 max = 240 [SDTC_VAR] -ifdef = ENABLE_NETWORK var = network.autoclean_protected type = SLE_UINT8 flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC @@ -3882,7 +3942,6 @@ min = 0 max = 240 [SDTC_VAR] -ifdef = ENABLE_NETWORK var = network.autoclean_novehicles type = SLE_UINT8 flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC @@ -3892,7 +3951,6 @@ min = 0 max = 240 [SDTC_VAR] -ifdef = ENABLE_NETWORK var = network.max_companies type = SLE_UINT8 flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC @@ -3904,7 +3962,6 @@ proc = UpdateClientConfigValues cat = SC_BASIC [SDTC_VAR] -ifdef = ENABLE_NETWORK var = network.max_clients type = SLE_UINT8 flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC @@ -3915,7 +3972,6 @@ max = MAX_CLIENTS cat = SC_BASIC [SDTC_VAR] -ifdef = ENABLE_NETWORK var = network.max_spectators type = SLE_UINT8 flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC @@ -3927,7 +3983,6 @@ proc = UpdateClientConfigValues cat = SC_BASIC [SDTC_VAR] -ifdef = ENABLE_NETWORK var = network.restart_game_year type = SLE_INT32 flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC @@ -3938,7 +3993,6 @@ max = MAX_YEAR interval = 1 [SDTC_VAR] -ifdef = ENABLE_NETWORK var = network.min_active_clients type = SLE_UINT8 flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC @@ -3948,7 +4002,6 @@ min = 0 max = MAX_CLIENTS [SDTC_OMANY] -ifdef = ENABLE_NETWORK var = network.server_lang type = SLE_UINT8 flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC @@ -3959,7 +4012,6 @@ full = _server_langs cat = SC_BASIC [SDTC_BOOL] -ifdef = ENABLE_NETWORK var = network.reload_cfg flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC guiflags = SGF_NETWORK_ONLY @@ -3967,7 +4019,6 @@ def = false cat = SC_EXPERT [SDTC_STR] -ifdef = ENABLE_NETWORK var = network.last_host type = SLE_STRB flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC @@ -3975,7 +4026,6 @@ def = """" cat = SC_EXPERT [SDTC_VAR] -ifdef = ENABLE_NETWORK var = network.last_port type = SLE_UINT16 flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC @@ -3985,7 +4035,6 @@ max = UINT16_MAX cat = SC_EXPERT [SDTC_BOOL] -ifdef = ENABLE_NETWORK var = network.no_http_content_downloads flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC def = false @@ -3994,7 +4043,7 @@ cat = SC_EXPERT ; Since the network code (CmdChangeSetting and friends) use the index in this array to decide ; which setting the server is talking about all conditional compilation of this array must be at the ; end. This isn't really the best solution, the settings the server can tell the client about should -; either use a seperate array or some other form of identifier. +; either use a separate array or some other form of identifier. ; ; We might need to emulate a right mouse button on mac diff --git a/src/table/sprites.h b/src/table/sprites.h index da3bc76271..5df55b8ae4 100644 --- a/src/table/sprites.h +++ b/src/table/sprites.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. @@ -27,10 +25,10 @@ * All sprites which are described here are referenced only one to a handful of times * throughout the code. When introducing new sprite enums, use meaningful names. * Don't be lazy and typing, and only use abbreviations when their meaning is clear or - * the length of the enum would get out of hand. In that case EXPLAIN THE ABBREVATION + * the length of the enum would get out of hand. In that case EXPLAIN THE ABBREVIATION * IN THIS FILE, and perhaps add some comments in the code where it is used. * Now, don't whine about this being too much typing work if the enums are like - * 30 characters in length. If your editor doen't help you simplifying your work, + * 30 characters in length. If your editor doesn't help you simplifying your work, * get a proper editor. If your Operating Systems don't have any decent editors, * get a proper Operating System. * @@ -56,7 +54,7 @@ static const SpriteID SPR_LARGE_SMALL_WINDOW = 682; /** Extra graphic spritenumbers */ static const SpriteID SPR_OPENTTD_BASE = 4896; -static const uint16 OPENTTD_SPRITE_COUNT = 179; +static const uint16 OPENTTD_SPRITE_COUNT = 184; /* Halftile-selection sprites */ static const SpriteID SPR_HALFTILE_SELECTION_FLAT = SPR_OPENTTD_BASE; @@ -273,13 +271,15 @@ static const SpriteID SPR_TRAMWAY_BUS_STOP_DT_X_W = SPR_TRAMWAY_BASE + 24; static const SpriteID SPR_TRAMWAY_BUS_STOP_DT_X_E = SPR_TRAMWAY_BASE + 26; static const SpriteID SPR_TRAMWAY_PAVED_STRAIGHT_Y = SPR_TRAMWAY_BASE + 46; static const SpriteID SPR_TRAMWAY_PAVED_STRAIGHT_X = SPR_TRAMWAY_BASE + 47; +static const SpriteID SPR_TRAMWAY_DEPOT_WITH_TRACK = SPR_TRAMWAY_BASE + 49; static const SpriteID SPR_TRAMWAY_BACK_WIRES_STRAIGHT = SPR_TRAMWAY_BASE + 55; static const SpriteID SPR_TRAMWAY_FRONT_WIRES_STRAIGHT = SPR_TRAMWAY_BASE + 56; static const SpriteID SPR_TRAMWAY_BACK_WIRES_SLOPED = SPR_TRAMWAY_BASE + 72; static const SpriteID SPR_TRAMWAY_FRONT_WIRES_SLOPED = SPR_TRAMWAY_BASE + 68; static const SpriteID SPR_TRAMWAY_TUNNEL_WIRES = SPR_TRAMWAY_BASE + 80; static const SpriteID SPR_TRAMWAY_BRIDGE = SPR_TRAMWAY_BASE + 107; -static const uint16 TRAMWAY_SPRITE_COUNT = 113; +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; @@ -402,8 +402,11 @@ static const SpriteID SPR_MONO_SINGLE_SOUTH = 1090; static const SpriteID SPR_MONO_SINGLE_EAST = 1091; static const SpriteID SPR_MONO_SINGLE_WEST = 1092; static const SpriteID SPR_MONO_TRACK_Y = 1093; +static const SpriteID SPR_MONO_TRACK_X = 1094; static const SpriteID SPR_MONO_TRACK_BASE = 1100; static const SpriteID SPR_MONO_TRACK_N_S = 1117; +static const SpriteID SPR_MONO_TRACK_Y_SNOW = 1119; +static const SpriteID SPR_MONO_TRACK_X_SNOW = 1120; static const SpriteID SPR_MGLV_SINGLE_X = 1169; static const SpriteID SPR_MGLV_SINGLE_Y = 1170; static const SpriteID SPR_MGLV_SINGLE_NORTH = 1171; @@ -411,7 +414,10 @@ static const SpriteID SPR_MGLV_SINGLE_SOUTH = 1172; static const SpriteID SPR_MGLV_SINGLE_EAST = 1173; static const SpriteID SPR_MGLV_SINGLE_WEST = 1174; static const SpriteID SPR_MGLV_TRACK_Y = 1175; +static const SpriteID SPR_MGLV_TRACK_X = 1176; static const SpriteID SPR_MGLV_TRACK_BASE = 1182; +static const SpriteID SPR_MGLV_TRACK_Y_SNOW = 1184; +static const SpriteID SPR_MGLV_TRACK_X_SNOW = 1185; static const SpriteID SPR_MGLV_TRACK_N_S = 1199; static const SpriteID SPR_WAYPOINT_X_1 = SPR_OPENTTD_BASE + 78; static const SpriteID SPR_WAYPOINT_X_2 = SPR_OPENTTD_BASE + 79; @@ -557,6 +563,7 @@ static const SpriteID SPR_ROAD_SLOPE_START = 1343; static const SpriteID SPR_ROAD_Y_SNOW = 1351; static const SpriteID SPR_ROAD_X_SNOW = 1352; /* see _road_sloped_sprites_offset in road_cmd.cpp for offsets for sloped road tiles */ +static const SpriteID SPR_ROAD_DEPOT = 1408; static const SpriteID SPR_EXCAVATION_X = 1414; static const SpriteID SPR_EXCAVATION_Y = 1415; @@ -1093,6 +1100,7 @@ static const SpriteID SPR_IMG_ZOOMIN = 735; static const SpriteID SPR_IMG_ZOOMOUT = 736; static const SpriteID SPR_IMG_BUILDRAIL = 727; static const SpriteID SPR_IMG_BUILDROAD = 728; +static const SpriteID SPR_IMG_BUILDTRAMS = SPR_OPENTTD_BASE + 179; static const SpriteID SPR_IMG_BUILDWATER = 729; static const SpriteID SPR_IMG_BUILDAIR = 730; static const SpriteID SPR_IMG_LANDSCAPING = 4083; @@ -1337,6 +1345,11 @@ static const SpriteID SPR_IMG_GOAL = SPR_OPENTTD_BASE + 171; static const SpriteID SPR_IMG_GOAL_COMPLETED = SPR_OPENTTD_BASE + 172; static const SpriteID SPR_IMG_GOAL_BROKEN_REF= SPR_OPENTTD_BASE + 173; +static const SpriteID SPR_IMG_CONVERT_ROAD = SPR_OPENTTD_BASE + 180; +static const CursorID SPR_CURSOR_CONVERT_ROAD = SPR_OPENTTD_BASE + 181; +static const SpriteID SPR_IMG_CONVERT_TRAM = SPR_OPENTTD_BASE + 182; +static const CursorID SPR_CURSOR_CONVERT_TRAM = SPR_OPENTTD_BASE + 183; + /* intro_gui.cpp, genworld_gui.cpp */ static const SpriteID SPR_SELECT_TEMPERATE = 4882; static const SpriteID SPR_SELECT_TEMPERATE_PUSHED = 4883; diff --git a/src/table/station_land.h b/src/table/station_land.h index 3327dab5dd..6b4b2267ac 100644 --- a/src/table/station_land.h +++ b/src/table/station_land.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. @@ -789,7 +787,7 @@ static const DrawTileSeqStruct _station_display_datas_waypoint_Y[] = { * @param dtss Sequence child sprites of the tile */ #define TILE_SPRITE_LINE(img, dtss) { {img, PAL_NONE}, dtss }, -#define TILE_SPRITE_NULL() { {0, 0}, NULL }, +#define TILE_SPRITE_NULL() { {0, 0}, nullptr }, extern const DrawTileSprites _station_display_datas_rail[] = { TILE_SPRITE_LINE(SPR_RAIL_TRACK_X, _station_display_datas_0) diff --git a/src/table/strgen_tables.h b/src/table/strgen_tables.h index 6297eea3bc..1c565089ad 100644 --- a/src/table/strgen_tables.h +++ b/src/table/strgen_tables.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/string_colours.h b/src/table/string_colours.h index ae64705a57..3af980bae4 100644 --- a/src/table/string_colours.h +++ b/src/table/string_colours.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/town_land.h b/src/table/town_land.h index 6476015119..80a181baa3 100644 --- a/src/table/town_land.h +++ b/src/table/town_land.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/townname.h b/src/table/townname.h index 551a050697..4a7da93e9a 100644 --- a/src/table/townname.h +++ b/src/table/townname.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. @@ -1991,7 +1989,7 @@ static const char * const _name_romanian_real[] = { "Motru", "N\xC4\x83s\xC4\x83ud", "N\xC4\x83vodari", - "Odobe\xC8x99ti", + "Odobe\xC8\x99ti", "Olteni\xC8\x9B""a", "One\xC8\x99ti", "Oradea", diff --git a/src/table/track_land.h b/src/table/track_land.h index 1916a54f6b..33950a4389 100644 --- a/src/table/track_land.h +++ b/src/table/track_land.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/train_cmd.h b/src/table/train_cmd.h index 15ac6f2aab..cc53582f8d 100644 --- a/src/table/train_cmd.h +++ b/src/table/train_cmd.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/tree_land.h b/src/table/tree_land.h index 64757267ec..6c35cc3f07 100644 --- a/src/table/tree_land.h +++ b/src/table/tree_land.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/unicode.h b/src/table/unicode.h index a83a65861c..882fcb5696 100644 --- a/src/table/unicode.h +++ b/src/table/unicode.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/water_land.h b/src/table/water_land.h index d3cb0a3f98..c1d55de956 100644 --- a/src/table/water_land.h +++ b/src/table/water_land.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/win32_settings.ini b/src/table/win32_settings.ini index bb241f50cd..c7915e32bd 100644 --- a/src/table/win32_settings.ini +++ b/src/table/win32_settings.ini @@ -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. ; 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. @@ -23,13 +21,13 @@ SDTG_END = SDTG_END() [defaults] flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC -guiflags = 0 +guiflags = SGF_NONE interval = 0 str = STR_NULL strhelp = STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT strval = STR_NULL -proc = NULL -load = NULL +proc = nullptr +load = nullptr from = SL_MIN_VERSION to = SL_MAX_VERSION cat = SC_ADVANCED diff --git a/src/table/window_settings.ini b/src/table/window_settings.ini index 41223586a6..fc0c57b39e 100644 --- a/src/table/window_settings.ini +++ b/src/table/window_settings.ini @@ -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. ; 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. @@ -19,13 +17,13 @@ SDT_END = SDT_END() [defaults] base = WindowDesc flags = SLF_NOT_IN_SAVE | SLF_NO_NETWORK_SYNC -guiflags = 0 +guiflags = SGF_NONE interval = 0 str = STR_NULL strhelp = STR_CONFIG_SETTING_NO_EXPLANATION_AVAILABLE_HELPTEXT strval = STR_NULL -proc = NULL -load = NULL +proc = nullptr +load = nullptr from = SL_MIN_VERSION to = SL_MAX_VERSION cat = SC_ADVANCED diff --git a/src/tar_type.h b/src/tar_type.h index 6306fb6500..e428bc2496 100644 --- a/src/tar_type.h +++ b/src/tar_type.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. @@ -25,7 +23,7 @@ struct TarListEntry { /* MSVC goes copying around this struct after initialisation, so it tries * to free filename, which isn't set at that moment... but because it * initializes the variable with garbage, it's going to segfault. */ - TarListEntry() : filename(NULL), dirname(NULL) {} + TarListEntry() : filename(nullptr), dirname(nullptr) {} ~TarListEntry() { free(this->filename); free(this->dirname); } }; diff --git a/src/terraform_cmd.cpp b/src/terraform_cmd.cpp index 9839f5e34b..85edb73128 100644 --- a/src/terraform_cmd.cpp +++ b/src/terraform_cmd.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. @@ -278,7 +276,7 @@ CommandCost CmdTerraformLand(TileIndex tile, DoCommandFlag flags, uint32 p1, uin /* Is the tile already cleared? */ const ClearedObjectArea *coa = FindClearedObject(tile); - bool indirectly_cleared = coa != NULL && coa->first_tile != tile; + bool indirectly_cleared = coa != nullptr && coa->first_tile != tile; /* Check tiletype-specific things, and add extra-cost */ const bool curr_gen = _generating_world; @@ -304,7 +302,7 @@ CommandCost CmdTerraformLand(TileIndex tile, DoCommandFlag flags, uint32 p1, uin } Company *c = Company::GetIfValid(_current_company); - if (c != NULL && GB(c->terraform_limit, 16, 16) < ts.tile_to_new_height.size()) { + if (c != nullptr && GB(c->terraform_limit, 16, 16) < ts.tile_to_new_height.size()) { return_cmd_error(STR_ERROR_TERRAFORM_LIMIT_REACHED); } @@ -326,7 +324,7 @@ CommandCost CmdTerraformLand(TileIndex tile, DoCommandFlag flags, uint32 p1, uin SetTileHeight(tile, (uint)height); } - if (c != NULL) c->terraform_limit -= (uint32)ts.tile_to_new_height.size() << 16; + if (c != nullptr) c->terraform_limit -= (uint32)ts.tile_to_new_height.size() << 16; } return total_cost; } @@ -371,7 +369,7 @@ CommandCost CmdLevelLand(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 bool had_success = false; const Company *c = Company::GetIfValid(_current_company); - int limit = (c == NULL ? INT32_MAX : GB(c->terraform_limit, 16, 16)); + int limit = (c == nullptr ? INT32_MAX : GB(c->terraform_limit, 16, 16)); if (limit == 0) return_cmd_error(STR_ERROR_TERRAFORM_LIMIT_REACHED); TileIterator *iter = HasBit(p2, 0) ? (TileIterator *)new DiagonalTileIterator(tile, p1) : new OrthogonalTileIterator(tile, p1); diff --git a/src/terraform_gui.cpp b/src/terraform_gui.cpp index 122096ec05..6fad228dc6 100644 --- a/src/terraform_gui.cpp +++ b/src/terraform_gui.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. @@ -40,7 +38,7 @@ #include "safeguards.h" -void CcTerraform(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) +void CcTerraform(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) { if (result.Succeeded()) { if (_settings_client.sound.confirm) SndPlayTileFx(SND_1F_SPLAT_OTHER, tile); @@ -165,14 +163,14 @@ struct TerraformToolbarWindow : Window { { } - virtual void OnInit() + void OnInit() override { /* Don't show the place object button when there are no objects to place. */ NWidgetStacked *show_object = this->GetWidget(WID_TT_SHOW_PLACE_OBJECT); show_object->SetDisplayedPlane(ObjectClass::GetUIClassCount() != 0 ? 0 : SZSP_NONE); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { if (widget < WID_TT_BUTTONS_START) return; @@ -219,7 +217,7 @@ struct TerraformToolbarWindow : Window { } } - virtual void OnPlaceObject(Point pt, TileIndex tile) + void OnPlaceObject(Point pt, TileIndex tile) override { switch (this->last_user_action) { case WID_TT_LOWER_LAND: // Lower land button @@ -254,19 +252,19 @@ struct TerraformToolbarWindow : Window { } } - virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) + void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) override { VpSelectTilesWithMethod(pt.x, pt.y, select_method); } - virtual Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number) + Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number) override { Point pt = GetToolbarAlignedWindowPosition(sm_width); pt.y += sm_height; return pt; } - virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) + void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) override { if (pt.x != -1) { switch (select_proc) { @@ -282,7 +280,7 @@ struct TerraformToolbarWindow : Window { } } - virtual void OnPlaceObjectAbort() + void OnPlaceObjectAbort() override { MoveAllHiddenWindowsBackToScreen(); this->RaiseButtons(); @@ -309,8 +307,8 @@ struct TerraformToolbarWindow : Window { static EventState TerraformToolbarGlobalHotkeys(int hotkey) { if (_game_mode != GM_NORMAL) return ES_NOT_HANDLED; - Window *w = ShowTerraformToolbar(NULL); - if (w == NULL) return ES_NOT_HANDLED; + Window *w = ShowTerraformToolbar(nullptr); + if (w == nullptr) return ES_NOT_HANDLED; return w->OnHotkey(hotkey); } @@ -369,14 +367,14 @@ static WindowDesc _terraform_desc( /** * Show the toolbar for terraforming in the game. * @param link The toolbar we might want to link to. - * @return The allocated toolbar if the window was newly opened, else \c NULL. + * @return The allocated toolbar if the window was newly opened, else \c nullptr. */ Window *ShowTerraformToolbar(Window *link) { - if (!Company::IsValidID(_local_company)) return NULL; + if (!Company::IsValidID(_local_company)) return nullptr; Window *w; - if (link == NULL) { + if (link == nullptr) { w = AllocateWindowDescFront(&_terraform_desc, 0); return w; } @@ -518,8 +516,7 @@ static void ResetLandscapeConfirmationCallback(Window *w, bool confirmed) _generating_world = true; /* Delete all companies */ - Company *c; - FOR_ALL_COMPANIES(c) { + for (Company *c : Company::Iterate()) { ChangeOwnershipOfCompanyItems(c->index, INVALID_OWNER); delete c; } @@ -527,8 +524,7 @@ static void ResetLandscapeConfirmationCallback(Window *w, bool confirmed) _generating_world = false; /* Delete all station signs */ - BaseStation *st; - FOR_ALL_BASE_STATIONS(st) { + for (BaseStation *st : BaseStation::Iterate()) { /* There can be buoys, remove them */ if (IsBuoyTile(st->xy)) DoCommand(st->xy, 0, 0, DC_EXEC | DC_BANKRUPT, CMD_LANDSCAPE_CLEAR); if (!st->IsInUse()) delete st; @@ -554,7 +550,7 @@ struct ScenarioEditorLandscapeGenerationWindow : Window { this->last_user_action = WIDGET_LIST_END; } - virtual void OnPaint() + void OnPaint() override { this->DrawWidgets(); @@ -563,7 +559,7 @@ struct ScenarioEditorLandscapeGenerationWindow : Window { } } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { if (widget != WID_ETT_DOTS) return; @@ -571,7 +567,7 @@ struct ScenarioEditorLandscapeGenerationWindow : Window { size->height = max(size->height, ScaleGUITrad(31)); } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { if (widget != WID_ETT_DOTS) return; @@ -588,7 +584,7 @@ struct ScenarioEditorLandscapeGenerationWindow : Window { } while (--n); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { if (widget < WID_ETT_BUTTONS_START) return; @@ -647,14 +643,14 @@ struct ScenarioEditorLandscapeGenerationWindow : Window { break; case WID_ETT_RESET_LANDSCAPE: // Reset landscape - ShowQuery(STR_QUERY_RESET_LANDSCAPE_CAPTION, STR_RESET_LANDSCAPE_CONFIRMATION_TEXT, NULL, ResetLandscapeConfirmationCallback); + ShowQuery(STR_QUERY_RESET_LANDSCAPE_CAPTION, STR_RESET_LANDSCAPE_CONFIRMATION_TEXT, nullptr, ResetLandscapeConfirmationCallback); break; default: NOT_REACHED(); } } - virtual void OnTimeout() + void OnTimeout() override { for (uint i = WID_ETT_START; i < this->nested_array_size; i++) { if (i == WID_ETT_BUTTONS_START) i = WID_ETT_BUTTONS_END; // skip the buttons @@ -665,7 +661,7 @@ struct ScenarioEditorLandscapeGenerationWindow : Window { } } - virtual void OnPlaceObject(Point pt, TileIndex tile) + void OnPlaceObject(Point pt, TileIndex tile) override { switch (this->last_user_action) { case WID_ETT_DEMOLISH: // Demolish aka dynamite button @@ -696,12 +692,12 @@ struct ScenarioEditorLandscapeGenerationWindow : Window { } } - virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) + void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) override { VpSelectTilesWithMethod(pt.x, pt.y, select_method); } - virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) + void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) override { if (pt.x != -1) { switch (select_proc) { @@ -718,7 +714,7 @@ struct ScenarioEditorLandscapeGenerationWindow : Window { } } - virtual void OnPlaceObjectAbort() + void OnPlaceObjectAbort() override { this->RaiseButtons(); this->SetDirty(); @@ -736,7 +732,7 @@ static EventState TerraformToolbarEditorGlobalHotkeys(int hotkey) { if (_game_mode != GM_EDITOR) return ES_NOT_HANDLED; Window *w = ShowEditorTerraformToolbar(); - if (w == NULL) return ES_NOT_HANDLED; + if (w == nullptr) return ES_NOT_HANDLED; return w->OnHotkey(hotkey); } @@ -763,7 +759,7 @@ static WindowDesc _scen_edit_land_gen_desc( /** * Show the toolbar for terraforming in the scenario editor. - * @return The allocated toolbar if the window was newly opened, else \c NULL. + * @return The allocated toolbar if the window was newly opened, else \c nullptr. */ Window *ShowEditorTerraformToolbar() { diff --git a/src/terraform_gui.h b/src/terraform_gui.h index 26a1c5e9a1..79ffd86764 100644 --- a/src/terraform_gui.h +++ b/src/terraform_gui.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. @@ -14,7 +12,7 @@ #include "window_type.h" -Window *ShowTerraformToolbar(Window *link = NULL); +Window *ShowTerraformToolbar(Window *link = nullptr); Window *ShowEditorTerraformToolbar(); #endif /* TERRAFORM_GUI_H */ diff --git a/src/textbuf.cpp b/src/textbuf.cpp index 61e449d3ae..53d90e6c24 100644 --- a/src/textbuf.cpp +++ b/src/textbuf.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. @@ -164,18 +162,18 @@ bool Textbuf::InsertChar(WChar key) bool Textbuf::InsertString(const char *str, bool marked, const char *caret, const char *insert_location, const char *replacement_end) { uint16 insertpos = (marked && this->marklength != 0) ? this->markpos : this->caretpos; - if (insert_location != NULL) { + if (insert_location != nullptr) { insertpos = insert_location - this->buf; if (insertpos > this->bytes) return false; - if (replacement_end != NULL) { - this->DeleteText(insertpos, replacement_end - this->buf, str == NULL); + if (replacement_end != nullptr) { + this->DeleteText(insertpos, replacement_end - this->buf, str == nullptr); } } else { - if (marked) this->DiscardMarkedText(str == NULL); + if (marked) this->DiscardMarkedText(str == nullptr); } - if (str == NULL) return false; + if (str == nullptr) return false; uint16 bytes = 0, chars = 0; WChar c; @@ -205,7 +203,7 @@ bool Textbuf::InsertString(const char *str, bool marked, const char *caret, cons this->bytes += bytes; this->chars += chars; - if (!marked && caret == NULL) this->caretpos += bytes; + if (!marked && caret == nullptr) this->caretpos += bytes; assert(this->bytes <= this->max_bytes); assert(this->chars <= this->max_chars); this->buf[this->bytes - 1] = '\0'; // terminating zero diff --git a/src/textbuf_gui.h b/src/textbuf_gui.h index ec134c11c6..c96f4e2e06 100644 --- a/src/textbuf_gui.h +++ b/src/textbuf_gui.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. @@ -22,6 +20,7 @@ enum QueryStringFlags { QSF_ACCEPT_UNCHANGED = 0x01, ///< return success even when the text didn't change QSF_ENABLE_DEFAULT = 0x02, ///< enable the 'Default' button ("\0" is returned) QSF_LEN_IN_CHARS = 0x04, ///< the length of the string is counted in characters + QSF_PASSWORD = 0x08, ///< password entry box, show warning about password security }; DECLARE_ENUM_AS_BIT_SET(QueryStringFlags) diff --git a/src/textbuf_type.h b/src/textbuf_type.h index 1d927b72d9..a238aa74b5 100644 --- a/src/textbuf_type.h +++ b/src/textbuf_type.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. @@ -56,7 +54,7 @@ struct Textbuf { bool InsertClipboard(); bool InsertChar(uint32 key); - bool InsertString(const char *str, bool marked, const char *caret = NULL, const char *insert_location = NULL, const char *replacement_end = NULL); + bool InsertString(const char *str, bool marked, const char *caret = nullptr, const char *insert_location = nullptr, const char *replacement_end = nullptr); bool DeleteChar(uint16 keycode); bool MovePos(uint16 keycode); diff --git a/src/texteff.cpp b/src/texteff.cpp index ee5ce592b4..f08701939f 100644 --- a/src/texteff.cpp +++ b/src/texteff.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. @@ -37,7 +35,7 @@ struct TextEffect : public ViewportSign { } }; -static SmallVector _text_effects; ///< Text effects are stored there +static std::vector _text_effects; ///< Text effects are stored there /* Text Effects */ TextEffectID AddTextEffect(StringID msg, int center, int y, uint8 duration, TextEffectMode mode) @@ -45,23 +43,23 @@ TextEffectID AddTextEffect(StringID msg, int center, int y, uint8 duration, Text if (_game_mode == GM_MENU) return INVALID_TE_ID; TextEffectID i; - for (i = 0; i < _text_effects.Length(); i++) { + for (i = 0; i < _text_effects.size(); i++) { if (_text_effects[i].string_id == INVALID_STRING_ID) break; } - if (i == _text_effects.Length()) _text_effects.Append(); + if (i == _text_effects.size()) _text_effects.emplace_back(); - TextEffect *te = _text_effects.Get(i); + TextEffect &te = _text_effects[i]; /* Start defining this object */ - te->string_id = msg; - te->duration = duration; - te->params_1 = GetDParam(0); - te->params_2 = GetDParam(1); - te->mode = mode; + te.string_id = msg; + te.duration = duration; + te.params_1 = GetDParam(0); + te.params_2 = GetDParam(1); + te.mode = mode; /* Make sure we only dirty the new area */ - te->width_normal = 0; - te->UpdatePosition(center, y, msg); + te.width_normal = 0; + te.UpdatePosition(center, y, msg); return i; } @@ -69,7 +67,7 @@ TextEffectID AddTextEffect(StringID msg, int center, int y, uint8 duration, Text void UpdateTextEffect(TextEffectID te_id, StringID msg) { /* Update details */ - TextEffect *te = _text_effects.Get(te_id); + TextEffect *te = _text_effects.data() + te_id; if (msg == te->string_id && GetDParam(0) == te->params_1) return; te->string_id = msg; te->params_1 = GetDParam(0); @@ -89,26 +87,26 @@ void MoveAllTextEffects(uint delta_ms) uint count = texteffecttimer.CountElapsed(delta_ms); if (count == 0) return; - const TextEffect *end = _text_effects.End(); - for (TextEffect *te = _text_effects.Begin(); te != end; te++) { - if (te->string_id == INVALID_STRING_ID) continue; - if (te->mode != TE_RISING) continue; + for (TextEffect &te : _text_effects) { + if (te.string_id == INVALID_STRING_ID) continue; + if (te.mode != TE_RISING) continue; - if (te->duration < count) { - te->Reset(); + if (te.duration < count) { + te.Reset(); continue; } - te->MarkDirty(ZOOM_LVL_OUT_8X); - te->duration -= count; - te->top -= count * ZOOM_LVL_BASE; - te->MarkDirty(ZOOM_LVL_OUT_8X); + te.MarkDirty(ZOOM_LVL_OUT_8X); + te.duration -= count; + te.top -= count * ZOOM_LVL_BASE; + te.MarkDirty(ZOOM_LVL_OUT_8X); } } void InitTextEffects() { - _text_effects.Reset(); + _text_effects.clear(); + _text_effects.shrink_to_fit(); } void DrawTextEffects(DrawPixelInfo *dpi) @@ -116,11 +114,10 @@ void DrawTextEffects(DrawPixelInfo *dpi) /* Don't draw the text effects when zoomed out a lot */ if (dpi->zoom > ZOOM_LVL_OUT_8X) return; - const TextEffect *end = _text_effects.End(); - for (TextEffect *te = _text_effects.Begin(); te != end; te++) { - if (te->string_id == INVALID_STRING_ID) continue; - if (te->mode == TE_RISING || (_settings_client.gui.loading_indicators && !IsTransparencySet(TO_LOADING))) { - ViewportAddString(dpi, ZOOM_LVL_OUT_8X, te, te->string_id, te->string_id - 1, STR_NULL, te->params_1, te->params_2); + for (TextEffect &te : _text_effects) { + if (te.string_id == INVALID_STRING_ID) continue; + if (te.mode == TE_RISING || (_settings_client.gui.loading_indicators && !IsTransparencySet(TO_LOADING))) { + ViewportAddString(dpi, ZOOM_LVL_OUT_8X, &te, te.string_id, te.string_id - 1, STR_NULL, te.params_1, te.params_2); } } } diff --git a/src/texteff.hpp b/src/texteff.hpp index 114cebed02..789b12d540 100644 --- a/src/texteff.hpp +++ b/src/texteff.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/textfile_gui.cpp b/src/textfile_gui.cpp index 6a1d975c66..9276ddf896 100644 --- a/src/textfile_gui.cpp +++ b/src/textfile_gui.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. @@ -25,7 +23,7 @@ #include #endif -#if defined(WITH_LZMA) +#if defined(WITH_LIBLZMA) #include #endif @@ -86,7 +84,7 @@ uint TextfileWindow::GetContentHeight() int max_width = this->GetWidget(WID_TF_BACKGROUND)->current_x - WD_FRAMETEXT_LEFT - WD_FRAMERECT_RIGHT; uint height = 0; - for (uint i = 0; i < this->lines.Length(); i++) { + for (uint i = 0; i < this->lines.size(); i++) { height += GetStringHeight(this->lines[i], max_width, FS_MONO); } @@ -113,10 +111,10 @@ void TextfileWindow::SetupScrollbars() this->hscroll->SetCount(0); } else { uint max_length = 0; - for (uint i = 0; i < this->lines.Length(); i++) { + for (uint i = 0; i < this->lines.size(); i++) { max_length = max(max_length, GetStringBoundingBox(this->lines[i], FS_MONO).width); } - this->vscroll->SetCount(this->lines.Length() * FONT_HEIGHT_MONO); + this->vscroll->SetCount((uint)this->lines.size() * FONT_HEIGHT_MONO); this->hscroll->SetCount(max_length + WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT); } @@ -152,7 +150,7 @@ void TextfileWindow::SetupScrollbars() int line_height = FONT_HEIGHT_MONO; int y_offset = -this->vscroll->GetPosition(); - for (uint i = 0; i < this->lines.Length(); i++) { + for (uint i = 0; i < this->lines.size(); i++) { if (IsWidgetLowered(WID_TF_WRAPTEXT)) { y_offset = DrawStringMultiLine(0, right - x, y_offset, bottom - y, this->lines[i], TC_WHITE, SA_TOP | SA_LEFT, false, FS_MONO); } else { @@ -184,7 +182,7 @@ void TextfileWindow::SetupScrollbars() /* virtual */ const char *TextfileWindow::NextString() { - if (this->search_iterator >= this->lines.Length()) return NULL; + if (this->search_iterator >= this->lines.size()) return nullptr; return this->lines[this->search_iterator++]; } @@ -194,11 +192,13 @@ void TextfileWindow::SetupScrollbars() return true; } -/* virtual */ void TextfileWindow::SetFontNames(FreeTypeSettings *settings, const char *font_name) +/* virtual */ void TextfileWindow::SetFontNames(FreeTypeSettings *settings, const char *font_name, const void *os_data) { -#ifdef WITH_FREETYPE +#if defined(WITH_FREETYPE) || defined(_WIN32) strecpy(settings->mono.font, font_name, lastof(settings->mono.font)); -#endif /* WITH_FREETYPE */ + free(settings->mono.os_handle); + settings->mono.os_handle = os_data; +#endif } #if defined(WITH_ZLIB) @@ -214,13 +214,13 @@ void TextfileWindow::SetupScrollbars() * After the call, it contains the size of the uncompressed * data. * - * When decompressing fails, *bufp is set to NULL and *sizep to 0. The + * When decompressing fails, *bufp is set to nullptr and *sizep to 0. The * compressed buffer passed in is still freed in this case. */ static void Gunzip(byte **bufp, size_t *sizep) { static const int BLOCKSIZE = 8192; - byte *buf = NULL; + byte *buf = nullptr; size_t alloc_size = 0; z_stream z; int res; @@ -250,14 +250,14 @@ static void Gunzip(byte **bufp, size_t *sizep) *sizep = alloc_size - z.avail_out; } else { /* Something went wrong */ - *bufp = NULL; + *bufp = nullptr; *sizep = 0; free(buf); } } #endif -#if defined(WITH_LZMA) +#if defined(WITH_LIBLZMA) /** * Do an in-memory xunzip operation. This works on a .xz or (legacy) @@ -270,13 +270,13 @@ static void Gunzip(byte **bufp, size_t *sizep) * After the call, it contains the size of the uncompressed * data. * - * When decompressing fails, *bufp is set to NULL and *sizep to 0. The + * When decompressing fails, *bufp is set to nullptr and *sizep to 0. The * compressed buffer passed in is still freed in this case. */ static void Xunzip(byte **bufp, size_t *sizep) { static const int BLOCKSIZE = 8192; - byte *buf = NULL; + byte *buf = nullptr; size_t alloc_size = 0; lzma_stream z = LZMA_STREAM_INIT; int res; @@ -304,7 +304,7 @@ static void Xunzip(byte **bufp, size_t *sizep) *sizep = alloc_size - z.avail_out; } else { /* Something went wrong */ - *bufp = NULL; + *bufp = nullptr; *sizep = 0; free(buf); } @@ -317,14 +317,14 @@ static void Xunzip(byte **bufp, size_t *sizep) */ /* virtual */ void TextfileWindow::LoadTextfile(const char *textfile, Subdirectory dir) { - if (textfile == NULL) return; + if (textfile == nullptr) return; - this->lines.Clear(); + this->lines.clear(); /* Get text from file */ size_t filesize; FILE *handle = FioFOpenFile(textfile, "rb", dir, &filesize); - if (handle == NULL) return; + if (handle == nullptr) return; this->text = ReallocT(this->text, filesize); size_t read = fread(this->text, 1, filesize, handle); @@ -332,9 +332,9 @@ static void Xunzip(byte **bufp, size_t *sizep) if (read != filesize) return; -#if defined(WITH_ZLIB) || defined(WITH_LZMA) +#if defined(WITH_ZLIB) || defined(WITH_LIBLZMA) const char *suffix = strrchr(textfile, '.'); - if (suffix == NULL) return; + if (suffix == nullptr) return; #endif #if defined(WITH_ZLIB) @@ -342,7 +342,7 @@ static void Xunzip(byte **bufp, size_t *sizep) if (strcmp(suffix, ".gz") == 0) Gunzip((byte**)&this->text, &filesize); #endif -#if defined(WITH_LZMA) +#if defined(WITH_LIBLZMA) /* In-place xunzip */ if (strcmp(suffix, ".xz") == 0) Xunzip((byte**)&this->text, &filesize); #endif @@ -365,11 +365,11 @@ static void Xunzip(byte **bufp, size_t *sizep) str_validate(p, this->text + filesize, SVS_REPLACE_WITH_QUESTION_MARK | SVS_ALLOW_NEWLINE); /* Split the string on newlines. */ - *this->lines.Append() = p; + this->lines.push_back(p); for (; *p != '\0'; p++) { if (*p == '\n') { *p = '\0'; - *this->lines.Append() = p + 1; + this->lines.push_back(p + 1); } } @@ -381,7 +381,7 @@ static void Xunzip(byte **bufp, size_t *sizep) * @param type The type of the textfile to search for. * @param dir The subdirectory to search in. * @param filename The filename of the content to look for. - * @return The path to the textfile, \c NULL otherwise. + * @return The path to the textfile, \c nullptr otherwise. */ const char *GetTextfile(TextfileType type, Subdirectory dir, const char *filename) { @@ -394,20 +394,20 @@ const char *GetTextfile(TextfileType type, Subdirectory dir, const char *filenam const char *prefix = prefixes[type]; - if (filename == NULL) return NULL; + if (filename == nullptr) return nullptr; static char file_path[MAX_PATH]; strecpy(file_path, filename, lastof(file_path)); char *slash = strrchr(file_path, PATHSEPCHAR); - if (slash == NULL) return NULL; + if (slash == nullptr) return nullptr; static const char * const exts[] = { "txt", #if defined(WITH_ZLIB) "txt.gz", #endif -#if defined(WITH_LZMA) +#if defined(WITH_LIBLZMA) "txt.xz", #endif }; @@ -422,5 +422,5 @@ const char *GetTextfile(TextfileType type, Subdirectory dir, const char *filenam seprintf(slash + 1, lastof(file_path), "%s.%s", prefix, exts[i]); if (FioCheckFileExists(file_path, dir)) return file_path; } - return NULL; + return nullptr; } diff --git a/src/textfile_gui.h b/src/textfile_gui.h index 9495fa3f08..d67435c015 100644 --- a/src/textfile_gui.h +++ b/src/textfile_gui.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. @@ -21,28 +19,32 @@ const char *GetTextfile(TextfileType type, Subdirectory dir, const char *filenam /** Window for displaying a textfile */ struct TextfileWindow : public Window, MissingGlyphSearcher { - TextfileType file_type; ///< Type of textfile to view. - Scrollbar *vscroll; ///< Vertical scrollbar. - Scrollbar *hscroll; ///< Horizontal scrollbar. - char *text; ///< Lines of text from the NewGRF's textfile. - SmallVector lines; ///< #text, split into lines in a table with lines. - uint search_iterator; ///< Iterator for the font check search. + TextfileType file_type; ///< Type of textfile to view. + Scrollbar *vscroll; ///< Vertical scrollbar. + Scrollbar *hscroll; ///< Horizontal scrollbar. + char *text; ///< Lines of text from the NewGRF's textfile. + std::vector lines; ///< #text, split into lines in a table with lines. + uint search_iterator; ///< Iterator for the font check search. 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); - virtual ~TextfileWindow(); - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize); - virtual void OnClick(Point pt, int widget, int click_count); - virtual void DrawWidget(const Rect &r, int widget) const; - virtual void OnResize(); - virtual void Reset(); - virtual FontSize DefaultSize(); - virtual const char *NextString(); - virtual bool Monospace(); - virtual void SetFontNames(FreeTypeSettings *settings, const char *font_name); + ~TextfileWindow(); + + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override; + void OnClick(Point pt, int widget, int click_count) override; + void DrawWidget(const Rect &r, int widget) const override; + void OnResize() override; + + void Reset() override; + FontSize DefaultSize() override; + const char *NextString() override; + bool Monospace() override; + void SetFontNames(FreeTypeSettings *settings, const char *font_name, const void *os_data) override; + virtual void LoadTextfile(const char *textfile, Subdirectory dir); + private: uint GetContentHeight(); void SetupScrollbars(); diff --git a/src/textfile_type.h b/src/textfile_type.h index 374b4641a3..ddb26f6a65 100644 --- a/src/textfile_type.h +++ b/src/textfile_type.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/tgp.cpp b/src/tgp.cpp index 4dbb79aa82..fb5c69cf75 100644 --- a/src/tgp.cpp +++ b/src/tgp.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. @@ -184,7 +182,7 @@ struct HeightMap }; /** Global height map instance */ -static HeightMap _height_map = {NULL, 0, 0, 0, 0}; +static HeightMap _height_map = {nullptr, 0, 0, 0, 0}; /** Conversion: int to height_t */ #define I2H(i) ((i) << height_decimal_bits) @@ -325,7 +323,7 @@ static inline bool AllocHeightMap() static inline void FreeHeightMap() { free(_height_map.h); - _height_map.h = NULL; + _height_map.h = nullptr; } /** @@ -349,7 +347,7 @@ static inline height_t RandomHeight(amplitude_t rMax) static void HeightMapGenerate() { /* Trying to apply noise to uninitialized height map */ - assert(_height_map.h != NULL); + assert(_height_map.h != nullptr); int start = max(MAX_TGP_FREQUENCIES - (int)min(MapLogX(), MapLogY()), 0); bool first = true; @@ -423,9 +421,9 @@ static void HeightMapGetMinMaxAvg(height_t *min_ptr, height_t *max_ptr, height_t h_avg = (height_t)(h_accu / (_height_map.size_x * _height_map.size_y)); /* Return required results */ - if (min_ptr != NULL) *min_ptr = h_min; - if (max_ptr != NULL) *max_ptr = h_max; - if (avg_ptr != NULL) *avg_ptr = h_avg; + if (min_ptr != nullptr) *min_ptr = h_min; + if (max_ptr != nullptr) *max_ptr = h_max; + if (avg_ptr != nullptr) *avg_ptr = h_avg; } /** Dill histogram and return pointer to its base point - to the count of zero heights */ @@ -1011,5 +1009,5 @@ void GenerateTerrainPerlin() IncreaseGeneratingWorldProgress(GWP_LANDSCAPE); FreeHeightMap(); - GenerateWorldSetAbortCallback(NULL); + GenerateWorldSetAbortCallback(nullptr); } diff --git a/src/tgp.h b/src/tgp.h index 42f991e91d..8d8d974892 100644 --- a/src/tgp.h +++ b/src/tgp.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/thread.h b/src/thread.h new file mode 100644 index 0000000000..f4a16d4e0d --- /dev/null +++ b/src/thread.h @@ -0,0 +1,79 @@ +/* + * 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 thread.h Base of all threads. */ + +#ifndef THREAD_H +#define THREAD_H + +#include "debug.h" +#include +#include + +/** Signal used for signalling we knowingly want to end the thread. */ +class OTTDThreadExitSignal { }; + + +/** + * Sleep on the current thread for a defined time. + * @param milliseconds Time to sleep for in milliseconds. + */ +inline void CSleep(int milliseconds) +{ + std::this_thread::sleep_for(std::chrono::milliseconds(milliseconds)); +} + +/** + * Name the thread this function is called on for the debugger. + * @param name Name to set for the thread.. + */ +void SetCurrentThreadName(const char *name); + + +/** + * Start a new thread. + * @tparam TFn Type of the function to call on the thread. + * @tparam TArgs Type of the parameters of the thread function. + * @param thr Pointer to a thread object; may be \c nullptr if a detached thread is wanted. + * @param name Name of the thread. + * @param _Fx Function to call on the thread. + * @param _Ax Arguments for the thread function. + * @return True if the thread was successfully started, false otherwise. + */ +template +inline bool StartNewThread(std::thread *thr, const char *name, TFn&& _Fx, TArgs&&... _Ax) +{ +#ifndef NO_THREADS + try { + std::thread t([] (const char *name, TFn&& F, TArgs&&... A) { + SetCurrentThreadName(name); + try { + /* Call user function with the given arguments. */ + F(A...); + } catch (OTTDThreadExitSignal&) { + } catch (...) { + NOT_REACHED(); + } + }, name, std::forward(_Fx), std::forward(_Ax)...); + + if (thr != nullptr) { + *thr = std::move(t); + } else { + t.detach(); + } + + return true; + } catch (const std::system_error& e) { + /* Something went wrong, the system we are running on might not support threads. */ + DEBUG(misc, 1, "Can't create thread '%s': %s", name, e.what()); + } +#endif + + return false; +} + +#endif /* THREAD_H */ diff --git a/src/thread/thread.h b/src/thread/thread.h deleted file mode 100644 index 07831bb4ba..0000000000 --- a/src/thread/thread.h +++ /dev/null @@ -1,126 +0,0 @@ -/* $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. - * 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 thread.h Base of all threads. */ - -#ifndef THREAD_H -#define THREAD_H - -/** Definition of all thread entry functions. */ -typedef void (*OTTDThreadFunc)(void *); - -/** Signal used for signalling we knowingly want to end the thread. */ -class OTTDThreadExitSignal { }; - -/** - * A Thread Object which works on all our supported OSes. - */ -class ThreadObject { -public: - /** - * Virtual destructor to allow 'delete' operator to work properly. - */ - virtual ~ThreadObject() {}; - - /** - * Exit this thread. - */ - virtual bool Exit() = 0; - - /** - * Join this thread. - */ - virtual void Join() = 0; - - /** - * Create a thread; proc will be called as first function inside the thread, - * with optional params. - * @param proc The procedure to call inside the thread. - * @param param The params to give with 'proc'. - * @param thread Place to store a pointer to the thread in. May be NULL. - * @param name A name for the thread. May be NULL. - * @return True if the thread was started correctly. - */ - static bool New(OTTDThreadFunc proc, void *param, ThreadObject **thread = NULL, const char *name = NULL); -}; - -/** - * Cross-platform Mutex - */ -class ThreadMutex { -public: - /** - * Create a new mutex. - */ - static ThreadMutex *New(); - - /** - * Virtual Destructor to avoid compiler warnings. - */ - virtual ~ThreadMutex() {}; - - /** - * Begin the critical section - * @param allow_recursive Whether recursive locking is intentional. - * If false, NOT_REACHED() will be called when the mutex is already locked - * by the current thread. - */ - virtual void BeginCritical(bool allow_recursive = false) = 0; - - /** - * End of the critical section - * @param allow_recursive Whether recursive unlocking is intentional. - * If false, NOT_REACHED() will be called when the mutex was locked more - * than once by the current thread. - */ - virtual void EndCritical(bool allow_recursive = false) = 0; - - /** - * Wait for a signal to be send. - * @pre You must be in the critical section. - * @note While waiting the critical section is left. - * @post You will be in the critical section. - */ - virtual void WaitForSignal() = 0; - - /** - * Send a signal and wake the 'thread' that was waiting for it. - */ - virtual void SendSignal() = 0; -}; - -/** - * Simple mutex locker to keep a mutex locked until the locker goes out of scope. - */ -class ThreadMutexLocker { -public: - /** - * Lock the mutex and keep it locked for the life time of this object. - * @param mutex Mutex to be locked. - */ - ThreadMutexLocker(ThreadMutex *mutex) : mutex(mutex) { mutex->BeginCritical(); } - - /** - * Unlock the mutex. - */ - ~ThreadMutexLocker() { this->mutex->EndCritical(); } - -private: - ThreadMutexLocker(const ThreadMutexLocker &) { NOT_REACHED(); } - ThreadMutexLocker &operator=(const ThreadMutexLocker &) { NOT_REACHED(); return *this; } - ThreadMutex *mutex; -}; - -/** - * Get number of processor cores in the system, including HyperThreading or similar. - * @return Total number of processor cores. - */ -uint GetCPUCoreCount(); - -#endif /* THREAD_H */ diff --git a/src/thread/thread_morphos.cpp b/src/thread/thread_morphos.cpp deleted file mode 100644 index e368663f79..0000000000 --- a/src/thread/thread_morphos.cpp +++ /dev/null @@ -1,197 +0,0 @@ -/* $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. - * 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 thread_morphos.cpp MorphOS implementation of Threads. */ - -#include "../stdafx.h" -#include "thread.h" -#include "../debug.h" -#include "../core/alloc_func.hpp" -#include -#include - -#include -#include -#include - -#include -#include - -#include "../safeguards.h" - -/** - * avoid name clashes with MorphOS API functions - */ -#undef Exit -#undef Wait - - -/** - * NOTE: this code heavily depends on latest libnix updates. So make - * sure you link with new stuff which supports semaphore locking of - * the IO resources, else it will just go foobar. - */ - - -struct OTTDThreadStartupMessage { - struct Message msg; ///< standard exec.library message (MUST be the first thing in the message struct!) - OTTDThreadFunc func; ///< function the thread will execute - void *arg; ///< functions arguments for the thread function -}; - - -/** - * Default OpenTTD STDIO/ERR debug output is not very useful for this, so we - * utilize serial/ramdebug instead. - */ -void KPutStr(CONST_STRPTR format) -{ - RawDoFmt(format, NULL, (void (*)())RAWFMTFUNC_SERIAL, NULL); -} - - -/** - * MorphOS version for ThreadObject. - */ -class ThreadObject_MorphOS : public ThreadObject { -private: - APTR m_thr; ///< System thread identifier. - struct MsgPort *m_replyport; - struct OTTDThreadStartupMessage m_msg; - bool self_destruct; - -public: - /** - * Create a sub process and start it, calling proc(param). - */ - ThreadObject_MorphOS(OTTDThreadFunc proc, void *param, self_destruct) : - m_thr(0), self_destruct(self_destruct) - { - struct Task *parent; - - KPutStr("[OpenTTD] Create thread...\n"); - - parent = FindTask(NULL); - - /* Make sure main thread runs with sane priority */ - SetTaskPri(parent, 0); - - /* Things we'll pass down to the child by utilizing NP_StartupMsg */ - m_msg.func = proc; - m_msg.arg = param; - - m_replyport = CreateMsgPort(); - - if (m_replyport != NULL) { - struct Process *child; - - m_msg.msg.mn_Node.ln_Type = NT_MESSAGE; - m_msg.msg.mn_ReplyPort = m_replyport; - m_msg.msg.mn_Length = sizeof(struct OTTDThreadStartupMessage); - - child = CreateNewProcTags( - NP_CodeType, CODETYPE_PPC, - NP_Entry, ThreadObject_MorphOS::Proxy, - NP_StartupMsg, (IPTR)&m_msg, - NP_Priority, 5UL, - NP_Name, (IPTR)"OpenTTD Thread", - NP_PPCStackSize, 131072UL, - TAG_DONE); - - m_thr = (APTR) child; - - if (child != NULL) { - KPutStr("[OpenTTD] Child process launched.\n"); - } else { - KPutStr("[OpenTTD] Couldn't create child process. (constructors never fail, yeah!)\n"); - DeleteMsgPort(m_replyport); - } - } - } - - /* virtual */ ~ThreadObject_MorphOS() - { - } - - /* virtual */ bool Exit() - { - struct OTTDThreadStartupMessage *msg; - - /* You can only exit yourself */ - assert(IsCurrent()); - - KPutStr("[Child] Aborting...\n"); - - if (NewGetTaskAttrs(NULL, &msg, sizeof(struct OTTDThreadStartupMessage *), TASKINFOTYPE_STARTUPMSG, TAG_DONE) && msg != NULL) { - /* For now we terminate by throwing an error, gives much cleaner cleanup */ - throw OTTDThreadExitSignal(); - } - - return true; - } - - /* virtual */ void Join() - { - struct OTTDThreadStartupMessage *reply; - - /* You cannot join yourself */ - assert(!IsCurrent()); - - KPutStr("[OpenTTD] Join threads...\n"); - KPutStr("[OpenTTD] Wait for child to quit...\n"); - WaitPort(m_replyport); - - GetMsg(m_replyport); - DeleteMsgPort(m_replyport); - m_thr = 0; - } - - /* virtual */ bool IsCurrent() - { - return FindTask(NULL) == m_thr; - } - -private: - /** - * On thread creation, this function is called, which calls the real startup - * function. This to get back into the correct instance again. - */ - static void Proxy() - { - struct Task *child = FindTask(NULL); - struct OTTDThreadStartupMessage *msg; - - /* Make sure, we don't block the parent. */ - SetTaskPri(child, -5); - - KPutStr("[Child] Progressing...\n"); - - if (NewGetTaskAttrs(NULL, &msg, sizeof(struct OTTDThreadStartupMessage *), TASKINFOTYPE_STARTUPMSG, TAG_DONE) && msg != NULL) { - try { - msg->func(msg->arg); - } catch(OTTDThreadExitSignal e) { - KPutStr("[Child] Returned to main()\n"); - } catch(...) { - NOT_REACHED(); - } - } - - /* Quit the child, exec.library will reply the startup msg internally. */ - KPutStr("[Child] Done.\n"); - - if (self_destruct) delete this; - } -}; - -/* static */ bool ThreadObject::New(OTTDThreadFunc proc, void *param, ThreadObject **thread, const char *name) -{ - ThreadObject *to = new ThreadObject_MorphOS(proc, param, thread == NULL); - if (thread != NULL) *thread = to; - return true; -} diff --git a/src/thread/thread_none.cpp b/src/thread/thread_none.cpp deleted file mode 100644 index 91eb50b113..0000000000 --- a/src/thread/thread_none.cpp +++ /dev/null @@ -1,35 +0,0 @@ -/* $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. - * 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 thread_none.cpp No-Threads-Available implementation of Threads */ - -#include "../stdafx.h" -#include "thread.h" - -#include "../safeguards.h" - -/* static */ bool ThreadObject::New(OTTDThreadFunc proc, void *param, ThreadObject **thread, const char *name) -{ - if (thread != NULL) *thread = NULL; - return false; -} - -/** Mutex that doesn't do locking because it ain't needed when there're no threads */ -class ThreadMutex_None : public ThreadMutex { -public: - virtual void BeginCritical(bool allow_recursive = false) {} - virtual void EndCritical(bool allow_recursive = false) {} - virtual void WaitForSignal() {} - virtual void SendSignal() {} -}; - -/* static */ ThreadMutex *ThreadMutex::New() -{ - return new ThreadMutex_None(); -} diff --git a/src/thread/thread_os2.cpp b/src/thread/thread_os2.cpp deleted file mode 100644 index c66e2ad643..0000000000 --- a/src/thread/thread_os2.cpp +++ /dev/null @@ -1,147 +0,0 @@ -/* $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. - * 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 thread_os2.cpp OS/2 implementation of Threads. */ - -#include "../stdafx.h" -#include "thread.h" - -#define INCL_DOS -#include -#include - -#include "../safeguards.h" - -/** - * OS/2 version for ThreadObject. - */ -class ThreadObject_OS2 : public ThreadObject { -private: - TID thread; ///< System thread identifier. - OTTDThreadFunc proc; ///< External thread procedure. - void *param; ///< Parameter for the external thread procedure. - bool self_destruct; ///< Free ourselves when done? - -public: - /** - * Create a thread and start it, calling proc(param). - */ - ThreadObject_OS2(OTTDThreadFunc proc, void *param, bool self_destruct) : - thread(0), - proc(proc), - param(param), - self_destruct(self_destruct) - { - thread = _beginthread(stThreadProc, NULL, 1048576, this); - } - - /* virtual */ bool Exit() - { - _endthread(); - return true; - } - - /* virtual */ void Join() - { - DosWaitThread(&this->thread, DCWW_WAIT); - this->thread = 0; - } -private: - /** - * On thread creation, this function is called, which calls the real startup - * function. This to get back into the correct instance again. - */ - static void stThreadProc(void *thr) - { - ((ThreadObject_OS2 *)thr)->ThreadProc(); - } - - /** - * A new thread is created, and this function is called. Call the custom - * function of the creator of the thread. - */ - void ThreadProc() - { - /* Call the proc of the creator to continue this thread */ - try { - this->proc(this->param); - } catch (OTTDThreadExitSignal e) { - } catch (...) { - NOT_REACHED(); - } - - if (self_destruct) { - this->Exit(); - delete this; - } - } -}; - -/* static */ bool ThreadObject::New(OTTDThreadFunc proc, void *param, ThreadObject **thread, const char *name) -{ - ThreadObject *to = new ThreadObject_OS2(proc, param, thread == NULL); - if (thread != NULL) *thread = to; - return true; -} - -/** - * OS/2 version of ThreadMutex. - */ -class ThreadMutex_OS2 : public ThreadMutex { -private: - HMTX mutex; ///< The mutex. - HEV event; ///< Event for waiting. - uint recursive_count; ///< Recursive lock count. - -public: - ThreadMutex_OS2() : recursive_count(0) - { - DosCreateMutexSem(NULL, &mutex, 0, FALSE); - DosCreateEventSem(NULL, &event, 0, FALSE); - } - - /* virtual */ ~ThreadMutex_OS2() - { - DosCloseMutexSem(mutex); - DosCloseEventSem(event); - } - - /* virtual */ void BeginCritical(bool allow_recursive = false) - { - /* os2 mutex is recursive by itself */ - DosRequestMutexSem(mutex, (unsigned long) SEM_INDEFINITE_WAIT); - this->recursive_count++; - if (!allow_recursive && this->recursive_count != 1) NOT_REACHED(); - } - - /* virtual */ void EndCritical(bool allow_recursive = false) - { - if (!allow_recursive && this->recursive_count != 1) NOT_REACHED(); - this->recursive_count--; - DosReleaseMutexSem(mutex); - } - - /* virtual */ void WaitForSignal() - { - assert(this->recursive_count == 1); // Do we need to call Begin/EndCritical multiple times otherwise? - this->EndCritical(); - DosWaitEventSem(event, SEM_INDEFINITE_WAIT); - this->BeginCritical(); - } - - /* virtual */ void SendSignal() - { - DosPostEventSem(event); - } -}; - -/* static */ ThreadMutex *ThreadMutex::New() -{ - return new ThreadMutex_OS2(); -} diff --git a/src/thread/thread_pthread.cpp b/src/thread/thread_pthread.cpp deleted file mode 100644 index 8aed5ee136..0000000000 --- a/src/thread/thread_pthread.cpp +++ /dev/null @@ -1,191 +0,0 @@ -/* $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. - * 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 thread_pthread.cpp POSIX pthread implementation of Threads. */ - -#include "../stdafx.h" -#include "thread.h" -#include -#include - -#if defined(__APPLE__) -#include "../os/macosx/macos.h" -#endif - -#include "../safeguards.h" - -/** - * POSIX pthread version for ThreadObject. - */ -class ThreadObject_pthread : public ThreadObject { -private: - pthread_t thread; ///< System thread identifier. - OTTDThreadFunc proc; ///< External thread procedure. - void *param; ///< Parameter for the external thread procedure. - bool self_destruct; ///< Free ourselves when done? - const char *name; ///< Name for the thread - -public: - /** - * Create a pthread and start it, calling proc(param). - */ - ThreadObject_pthread(OTTDThreadFunc proc, void *param, bool self_destruct, const char *name) : - thread(0), - proc(proc), - param(param), - self_destruct(self_destruct), - name(name) - { - pthread_create(&this->thread, NULL, &stThreadProc, this); - } - - /* virtual */ bool Exit() - { - assert(pthread_self() == this->thread); - /* For now we terminate by throwing an error, gives much cleaner cleanup */ - throw OTTDThreadExitSignal(); - } - - /* virtual */ void Join() - { - /* You cannot join yourself */ - assert(pthread_self() != this->thread); - pthread_join(this->thread, NULL); - this->thread = 0; - } -private: - /** - * On thread creation, this function is called, which calls the real startup - * function. This to get back into the correct instance again. - */ - static void *stThreadProc(void *thr) - { - ThreadObject_pthread *self = (ThreadObject_pthread *) thr; -#if defined(__GLIBC__) -#if __GLIBC_PREREQ(2, 12) - if (self->name) { - pthread_setname_np(pthread_self(), self->name); - } -#endif -#endif -#if defined(__APPLE__) - MacOSSetThreadName(self->name); -#endif - self->ThreadProc(); - pthread_exit(NULL); - } - - /** - * A new thread is created, and this function is called. Call the custom - * function of the creator of the thread. - */ - void ThreadProc() - { - /* Call the proc of the creator to continue this thread */ - try { - this->proc(this->param); - } catch (OTTDThreadExitSignal) { - } catch (...) { - NOT_REACHED(); - } - - if (self_destruct) { - pthread_detach(pthread_self()); - delete this; - } - } -}; - -/* static */ bool ThreadObject::New(OTTDThreadFunc proc, void *param, ThreadObject **thread, const char *name) -{ - ThreadObject *to = new ThreadObject_pthread(proc, param, thread == NULL, name); - if (thread != NULL) *thread = to; - return true; -} - -/** - * POSIX pthread version of ThreadMutex. - */ -class ThreadMutex_pthread : public ThreadMutex { -private: - pthread_mutex_t mutex; ///< The actual mutex. - pthread_cond_t condition; ///< Data for conditional waiting. - pthread_mutexattr_t attr; ///< Attributes set for the mutex. - pthread_t owner; ///< Owning thread of the mutex. - uint recursive_count; ///< Recursive lock count. - -public: - ThreadMutex_pthread() : owner(0), recursive_count(0) - { - pthread_mutexattr_init(&this->attr); - pthread_mutexattr_settype(&this->attr, PTHREAD_MUTEX_ERRORCHECK); - pthread_mutex_init(&this->mutex, &this->attr); - pthread_cond_init(&this->condition, NULL); - } - - /* virtual */ ~ThreadMutex_pthread() - { - int err = pthread_cond_destroy(&this->condition); - assert(err != EBUSY); - err = pthread_mutex_destroy(&this->mutex); - assert(err != EBUSY); - } - - bool IsOwnedByCurrentThread() const - { - return this->owner == pthread_self(); - } - - /* virtual */ void BeginCritical(bool allow_recursive = false) - { - /* pthread mutex is not recursive by itself */ - if (this->IsOwnedByCurrentThread()) { - if (!allow_recursive) NOT_REACHED(); - } else { - int err = pthread_mutex_lock(&this->mutex); - assert(err == 0); - assert(this->recursive_count == 0); - this->owner = pthread_self(); - } - this->recursive_count++; - } - - /* virtual */ void EndCritical(bool allow_recursive = false) - { - assert(this->IsOwnedByCurrentThread()); - if (!allow_recursive && this->recursive_count != 1) NOT_REACHED(); - this->recursive_count--; - if (this->recursive_count != 0) return; - this->owner = 0; - int err = pthread_mutex_unlock(&this->mutex); - assert(err == 0); - } - - /* virtual */ void WaitForSignal() - { - uint old_recursive_count = this->recursive_count; - this->recursive_count = 0; - this->owner = 0; - int err = pthread_cond_wait(&this->condition, &this->mutex); - assert(err == 0); - this->owner = pthread_self(); - this->recursive_count = old_recursive_count; - } - - /* virtual */ void SendSignal() - { - int err = pthread_cond_signal(&this->condition); - assert(err == 0); - } -}; - -/* static */ ThreadMutex *ThreadMutex::New() -{ - return new ThreadMutex_pthread(); -} diff --git a/src/thread/thread_win32.cpp b/src/thread/thread_win32.cpp deleted file mode 100644 index a01ea8e108..0000000000 --- a/src/thread/thread_win32.cpp +++ /dev/null @@ -1,167 +0,0 @@ -/* $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. - * 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 thread_win32.cpp Win32 thread implementation of Threads. */ - -#include "../stdafx.h" -#include "thread.h" -#include "../debug.h" -#include "../core/alloc_func.hpp" -#include -#include -#include -#include "../os/windows/win32.h" - -#include "../safeguards.h" - -/** - * Win32 thread version for ThreadObject. - */ -class ThreadObject_Win32 : public ThreadObject { -private: - HANDLE thread; ///< System thread identifier. - uint id; ///< Thread identifier. - OTTDThreadFunc proc; ///< External thread procedure. - void *param; ///< Parameter for the external thread procedure. - bool self_destruct; ///< Free ourselves when done? - const char *name; ///< Thread name. - -public: - /** - * Create a win32 thread and start it, calling proc(param). - */ - ThreadObject_Win32(OTTDThreadFunc proc, void *param, bool self_destruct, const char *name) : - thread(NULL), - id(0), - proc(proc), - param(param), - self_destruct(self_destruct), - name(name) - { - this->thread = (HANDLE)_beginthreadex(NULL, 0, &stThreadProc, this, CREATE_SUSPENDED, &this->id); - if (this->thread == NULL) return; - ResumeThread(this->thread); - } - - /* virtual */ ~ThreadObject_Win32() - { - if (this->thread != NULL) { - CloseHandle(this->thread); - this->thread = NULL; - } - } - - /* virtual */ bool Exit() - { - assert(GetCurrentThreadId() == this->id); - /* For now we terminate by throwing an error, gives much cleaner cleanup */ - throw OTTDThreadExitSignal(); - } - - /* virtual */ void Join() - { - /* You cannot join yourself */ - assert(GetCurrentThreadId() != this->id); - WaitForSingleObject(this->thread, INFINITE); - } - -private: - /** - * On thread creation, this function is called, which calls the real startup - * function. This to get back into the correct instance again. - */ - static uint CALLBACK stThreadProc(void *thr) - { - ((ThreadObject_Win32 *)thr)->ThreadProc(); - return 0; - } - - /** - * A new thread is created, and this function is called. Call the custom - * function of the creator of the thread. - */ - void ThreadProc() - { -#ifdef _MSC_VER - /* Set thread name for debuggers. Has to be done from the thread due to a race condition in older MS debuggers. */ - SetWin32ThreadName(-1, this->name); -#endif - try { - this->proc(this->param); - } catch (OTTDThreadExitSignal) { - } catch (...) { - NOT_REACHED(); - } - - if (self_destruct) delete this; - } -}; - -/* static */ bool ThreadObject::New(OTTDThreadFunc proc, void *param, ThreadObject **thread, const char *name) -{ - ThreadObject *to = new ThreadObject_Win32(proc, param, thread == NULL, name); - if (thread != NULL) *thread = to; - return true; -} - -/** - * Win32 thread version of ThreadMutex. - */ -class ThreadMutex_Win32 : public ThreadMutex { -private: - CRITICAL_SECTION critical_section; ///< The critical section we would enter. - HANDLE event; ///< Event for signalling. - uint recursive_count; ///< Recursive lock count. - -public: - ThreadMutex_Win32() : recursive_count(0) - { - InitializeCriticalSection(&this->critical_section); - this->event = CreateEvent(NULL, FALSE, FALSE, NULL); - } - - /* virtual */ ~ThreadMutex_Win32() - { - DeleteCriticalSection(&this->critical_section); - CloseHandle(this->event); - } - - /* virtual */ void BeginCritical(bool allow_recursive = false) - { - /* windows mutex is recursive by itself */ - EnterCriticalSection(&this->critical_section); - this->recursive_count++; - if (!allow_recursive && this->recursive_count != 1) NOT_REACHED(); - } - - /* virtual */ void EndCritical(bool allow_recursive = false) - { - if (!allow_recursive && this->recursive_count != 1) NOT_REACHED(); - this->recursive_count--; - LeaveCriticalSection(&this->critical_section); - } - - /* virtual */ void WaitForSignal() - { - assert(this->recursive_count == 1); // Do we need to call Begin/EndCritical multiple times otherwise? - this->EndCritical(); - WaitForSingleObject(this->event, INFINITE); - this->BeginCritical(); - } - - /* virtual */ void SendSignal() - { - SetEvent(this->event); - } -}; - -/* static */ ThreadMutex *ThreadMutex::New() -{ - return new ThreadMutex_Win32(); -} diff --git a/src/tile_cmd.h b/src/tile_cmd.h index ce70232a02..75964abad5 100644 --- a/src/tile_cmd.h +++ b/src/tile_cmd.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. @@ -64,7 +62,10 @@ struct TileDesc { uint64 dparam[2]; ///< Parameters of the \a str string StringID railtype; ///< Type of rail on the tile. uint16 rail_speed; ///< Speed limit of rail (bridges and track) - uint16 road_speed; ///< Speed limit of road (bridges) + StringID roadtype; ///< Type of road on the tile. + uint16 road_speed; ///< Speed limit of road (bridges and track) + StringID tramtype; ///< Type of tram on the tile. + uint16 tram_speed; ///< Speed limit of tram (bridges and track) }; /** @@ -168,29 +169,29 @@ void GetTileDesc(TileIndex tile, TileDesc *td); static inline void AddAcceptedCargo(TileIndex tile, CargoArray &acceptance, CargoTypes *always_accepted) { AddAcceptedCargoProc *proc = _tile_type_procs[GetTileType(tile)]->add_accepted_cargo_proc; - if (proc == NULL) return; - CargoTypes dummy = 0; // use dummy bitmask so there don't need to be several 'always_accepted != NULL' checks - proc(tile, acceptance, always_accepted == NULL ? &dummy : always_accepted); + if (proc == nullptr) return; + CargoTypes dummy = 0; // use dummy bitmask so there don't need to be several 'always_accepted != nullptr' checks + proc(tile, acceptance, always_accepted == nullptr ? &dummy : always_accepted); } static inline void AddProducedCargo(TileIndex tile, CargoArray &produced) { AddProducedCargoProc *proc = _tile_type_procs[GetTileType(tile)]->add_produced_cargo_proc; - if (proc == NULL) return; + if (proc == nullptr) return; proc(tile, produced); } static inline void AnimateTile(TileIndex tile) { AnimateTileProc *proc = _tile_type_procs[GetTileType(tile)]->animate_tile_proc; - assert(proc != NULL); + assert(proc != nullptr); proc(tile); } static inline bool ClickTile(TileIndex tile) { ClickTileProc *proc = _tile_type_procs[GetTileType(tile)]->click_tile_proc; - if (proc == NULL) return false; + if (proc == nullptr) return false; return proc(tile); } diff --git a/src/tile_map.cpp b/src/tile_map.cpp index 200a203089..0b5c8e070b 100644 --- a/src/tile_map.cpp +++ b/src/tile_map.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. @@ -34,7 +32,7 @@ static Slope GetTileSlopeGivenHeight(int hnorth, int hwest, int heast, int hsout int hmines = min(heast, hsouth); int hmin = min(hminnw, hmines); - if (h != NULL) *h = hmin; + if (h != nullptr) *h = hmin; int hmaxnw = max(hnorth, hwest); int hmaxes = max(heast, hsouth); @@ -55,7 +53,7 @@ static Slope GetTileSlopeGivenHeight(int hnorth, int hwest, int heast, int hsout /** * Return the slope of a given tile inside the map. * @param tile Tile to compute slope of - * @param h If not \c NULL, pointer to storage of z height + * @param h If not \c nullptr, pointer to storage of z height * @return Slope of the tile, except for the HALFTILE part */ Slope GetTileSlope(TileIndex tile, int *h) @@ -76,9 +74,9 @@ Slope GetTileSlope(TileIndex tile, int *h) /** * Return the slope of a given tile, also for tiles outside the map (virtual "black" tiles). * - * @param x X coordinate of the tile to compute slope of, may be ouside the map. - * @param y Y coordinate of the tile to compute slope of, may be ouside the map. - * @param h If not \c NULL, pointer to storage of z height. + * @param x X coordinate of the tile to compute slope of, may be outside the map. + * @param y Y coordinate of the tile to compute slope of, may be outside the map. + * @param h If not \c nullptr, pointer to storage of z height. * @return Slope of the tile, except for the HALFTILE part. */ Slope GetTilePixelSlopeOutsideMap(int x, int y, int *h) @@ -89,14 +87,14 @@ Slope GetTilePixelSlopeOutsideMap(int x, int y, int *h) int hsouth = TileHeightOutsideMap(x + 1, y + 1); // S corner. Slope s = GetTileSlopeGivenHeight(hnorth, hwest, heast, hsouth, h); - if (h != NULL) *h *= TILE_HEIGHT; + if (h != nullptr) *h *= TILE_HEIGHT; return s; } /** * Check if a given tile is flat * @param tile Tile to check - * @param h If not \c NULL, pointer to storage of z height (only if tile is flat) + * @param h If not \c nullptr, pointer to storage of z height (only if tile is flat) * @return Whether the tile is flat */ bool IsTileFlat(TileIndex tile, int *h) @@ -111,7 +109,7 @@ bool IsTileFlat(TileIndex tile, int *h) if (TileHeight(TileXY(x1, y2)) != z) return false; if (TileHeight(TileXY(x2, y2)) != z) return false; - if (h != NULL) *h = z; + if (h != nullptr) *h = z; return true; } diff --git a/src/tile_map.h b/src/tile_map.h index 7a76f2b974..b6c715e8a8 100644 --- a/src/tile_map.h +++ b/src/tile_map.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. @@ -37,8 +35,8 @@ static inline uint TileHeight(TileIndex tile) /** * Returns the height of a tile, also for tiles outside the map (virtual "black" tiles). * - * @param x X coordinate of the tile, may be ouside the map. - * @param y Y coordinate of the tile, may be ouside the map. + * @param x X coordinate of the tile, may be outside the map. + * @param y Y coordinate of the tile, may be outside the map. * @return The height in the same unit as TileHeight. */ static inline uint TileHeightOutsideMap(int x, int y) @@ -79,8 +77,8 @@ static inline uint TilePixelHeight(TileIndex tile) /** * Returns the height of a tile in pixels, also for tiles outside the map (virtual "black" tiles). * - * @param x X coordinate of the tile, may be ouside the map. - * @param y Y coordinate of the tile, may be ouside the map. + * @param x X coordinate of the tile, may be outside the map. + * @param y Y coordinate of the tile, may be outside the map. * @return The height in pixels in the same unit as TilePixelHeight. */ static inline uint TilePixelHeightOutsideMap(int x, int y) @@ -267,22 +265,22 @@ static inline void SetAnimationFrame(TileIndex t, byte frame) _me[t].m7 = frame; } -Slope GetTileSlope(TileIndex tile, int *h = NULL); +Slope GetTileSlope(TileIndex tile, int *h = nullptr); int GetTileZ(TileIndex tile); int GetTileMaxZ(TileIndex tile); -bool IsTileFlat(TileIndex tile, int *h = NULL); +bool IsTileFlat(TileIndex tile, int *h = nullptr); /** * Return the slope of a given tile * @param tile Tile to compute slope of - * @param h If not \c NULL, pointer to storage of z height + * @param h If not \c nullptr, pointer to storage of z height * @return Slope of the tile, except for the HALFTILE part */ static inline Slope GetTilePixelSlope(TileIndex tile, int *h) { Slope s = GetTileSlope(tile, h); - if (h != NULL) *h *= TILE_HEIGHT; + if (h != nullptr) *h *= TILE_HEIGHT; return s; } diff --git a/src/tile_type.h b/src/tile_type.h index c02ba4fc45..132b566f0f 100644 --- a/src/tile_type.h +++ b/src/tile_type.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/tilearea.cpp b/src/tilearea.cpp index ec3b9aafbb..3f240feb40 100644 --- a/src/tilearea.cpp +++ b/src/tilearea.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. @@ -117,6 +115,27 @@ bool OrthogonalTileArea::Contains(TileIndex tile) const return IsInsideBS(tile_x, left, this->w) && IsInsideBS(tile_y, top, this->h); } +/** + * Expand a tile area by rad tiles in each direction, keeping within map bounds. + * @param rad Number of tiles to expand + * @return The OrthogonalTileArea. + */ +OrthogonalTileArea &OrthogonalTileArea::Expand(int rad) +{ + int x = TileX(this->tile); + int y = TileY(this->tile); + + int sx = max(x - rad, 0); + int sy = max(y - rad, 0); + int ex = min(x + this->w + rad, MapSizeX()); + int ey = min(y + this->h + rad, MapSizeY()); + + this->tile = TileXY(sx, sy); + this->w = ex - sx; + this->h = ey - sy; + return *this; +} + /** * Clamp the tile area to map borders. */ diff --git a/src/tilearea_type.h b/src/tilearea_type.h index 45bfb3d4c0..2648219853 100644 --- a/src/tilearea_type.h +++ b/src/tilearea_type.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. @@ -48,6 +46,8 @@ struct OrthogonalTileArea { bool Contains(TileIndex tile) const; + OrthogonalTileArea &Expand(int rad); + void ClampToMap(); /** diff --git a/src/tilehighlight_func.h b/src/tilehighlight_func.h index c9c7ea809f..bb56cae617 100644 --- a/src/tilehighlight_func.h +++ b/src/tilehighlight_func.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/tilehighlight_type.h b/src/tilehighlight_type.h index 207f865a35..d6b9fe89d1 100644 --- a/src/tilehighlight_type.h +++ b/src/tilehighlight_type.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. @@ -53,6 +51,8 @@ struct TileHighlightData { Point outersize; ///< Size, in tile "units", of the blue coverage area excluding the side of the selected area. bool diagonal; ///< Whether the dragged area is a 45 degrees rotated rectangle. + bool freeze; ///< Freeze highlight in place. + Point new_pos; ///< New value for \a pos; used to determine whether to redraw the selection. Point new_size; ///< New value for \a size; used to determine whether to redraw the selection. Point new_outersize; ///< New value for \a outersize; used to determine whether to redraw the selection. diff --git a/src/tilematrix_type.hpp b/src/tilematrix_type.hpp index f9c7392b24..118c994cd5 100644 --- a/src/tilematrix_type.hpp +++ b/src/tilematrix_type.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. @@ -69,7 +67,7 @@ public: T *data; ///< Pointer to data array. - TileMatrix() : area(INVALID_TILE, 0, 0), data(NULL) {} + TileMatrix() : area(INVALID_TILE, 0, 0), data(nullptr) {} ~TileMatrix() { diff --git a/src/timetable.h b/src/timetable.h index fe0848b564..0eba8a7b62 100644 --- a/src/timetable.h +++ b/src/timetable.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/timetable_cmd.cpp b/src/timetable_cmd.cpp index 29986c353d..58cf8d46b7 100644 --- a/src/timetable_cmd.cpp +++ b/src/timetable_cmd.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. @@ -16,7 +14,6 @@ #include "window_func.h" #include "vehicle_base.h" #include "cmd_helper.h" -#include "core/sort_func.hpp" #include "table/strings.h" @@ -61,7 +58,7 @@ static void ChangeTimetable(Vehicle *v, VehicleOrderID order_number, uint16 val, v->orders.list->UpdateTotalDuration(total_delta); v->orders.list->UpdateTimetableDuration(timetable_delta); - for (v = v->FirstShared(); v != NULL; v = v->NextShared()) { + for (v = v->FirstShared(); v != nullptr; v = v->NextShared()) { if (v->cur_real_order_index == order_number && v->current_order.Equals(*order)) { switch (mtf) { case MTF_WAIT_TIME: @@ -105,14 +102,14 @@ CommandCost CmdChangeTimetable(TileIndex tile, DoCommandFlag flags, uint32 p1, u VehicleID veh = GB(p1, 0, 20); Vehicle *v = Vehicle::GetIfValid(veh); - if (v == NULL || !v->IsPrimaryVehicle()) return CMD_ERROR; + if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR; CommandCost ret = CheckOwnership(v->owner); if (ret.Failed()) return ret; VehicleOrderID order_number = GB(p1, 20, 8); Order *order = v->GetOrder(order_number); - if (order == NULL || order->IsType(OT_IMPLICIT)) return CMD_ERROR; + if (order == nullptr || order->IsType(OT_IMPLICIT)) return CMD_ERROR; ModifyTimetableFlags mtf = Extract(p1); if (mtf >= MTF_END) return CMD_ERROR; @@ -199,7 +196,7 @@ CommandCost CmdSetVehicleOnTime(TileIndex tile, DoCommandFlag flags, uint32 p1, VehicleID veh = GB(p1, 0, 20); Vehicle *v = Vehicle::GetIfValid(veh); - if (v == NULL || !v->IsPrimaryVehicle() || v->orders.list == NULL) return CMD_ERROR; + if (v == nullptr || !v->IsPrimaryVehicle() || v->orders.list == nullptr) return CMD_ERROR; CommandCost ret = CheckOwnership(v->owner); if (ret.Failed()) return ret; @@ -216,15 +213,12 @@ CommandCost CmdSetVehicleOnTime(TileIndex tile, DoCommandFlag flags, uint32 p1, * Order vehicles based on their timetable. The vehicles will be sorted in order * they would reach the first station. * - * @param ap First Vehicle pointer. - * @param bp Second Vehicle pointer. + * @param a First Vehicle pointer. + * @param b Second Vehicle pointer. * @return Comparison value. */ -static int CDECL VehicleTimetableSorter(Vehicle * const *ap, Vehicle * const *bp) +static bool VehicleTimetableSorter(Vehicle * const &a, Vehicle * const &b) { - const Vehicle *a = *ap; - const Vehicle *b = *bp; - VehicleOrderID a_order = a->cur_real_order_index; VehicleOrderID b_order = b->cur_real_order_index; int j = (int)b_order - (int)a_order; @@ -242,15 +236,15 @@ static int CDECL VehicleTimetableSorter(Vehicle * const *ap, Vehicle * const *bp /* First check the order index that accounted for loading, then just the raw one. */ int i = (int)b_order - (int)a_order; - if (i != 0) return i; - if (j != 0) return j; + if (i != 0) return i < 0; + if (j != 0) return j < 0; /* Look at the time we spent in this order; the higher, the closer to its destination. */ i = b->current_order_time - a->current_order_time; - if (i != 0) return i; + if (i != 0) return i < 0; /* If all else is equal, use some unique index to sort it the same way. */ - return b->unitnumber - a->unitnumber; + return b->unitnumber < a->unitnumber; } /** @@ -268,7 +262,7 @@ CommandCost CmdSetTimetableStart(TileIndex tile, DoCommandFlag flags, uint32 p1, { bool timetable_all = HasBit(p1, 20); Vehicle *v = Vehicle::GetIfValid(GB(p1, 0, 20)); - if (v == NULL || !v->IsPrimaryVehicle() || v->orders.list == NULL) return CMD_ERROR; + if (v == nullptr || !v->IsPrimaryVehicle() || v->orders.list == nullptr) return CMD_ERROR; CommandCost ret = CheckOwnership(v->owner); if (ret.Failed()) return ret; @@ -281,34 +275,33 @@ CommandCost CmdSetTimetableStart(TileIndex tile, DoCommandFlag flags, uint32 p1, if (timetable_all && !v->orders.list->IsCompleteTimetable()) return CMD_ERROR; if (flags & DC_EXEC) { - SmallVector vehs; + std::vector vehs; if (timetable_all) { - for (Vehicle *w = v->orders.list->GetFirstSharedVehicle(); w != NULL; w = w->NextShared()) { - *vehs.Append() = w; + for (Vehicle *w = v->orders.list->GetFirstSharedVehicle(); w != nullptr; w = w->NextShared()) { + vehs.push_back(w); } } else { - *vehs.Append() = v; + vehs.push_back(v); } int total_duration = v->orders.list->GetTimetableTotalDuration(); - int num_vehs = vehs.Length(); + int num_vehs = (uint)vehs.size(); if (num_vehs >= 2) { - QSortT(vehs.Begin(), vehs.Length(), &VehicleTimetableSorter); + std::sort(vehs.begin(), vehs.end(), &VehicleTimetableSorter); } - int base = vehs.FindIndex(v); + int idx = vehs.begin() - std::find(vehs.begin(), vehs.end(), v); - for (Vehicle **viter = vehs.Begin(); viter != vehs.End(); viter++) { - int idx = (viter - vehs.Begin()) - base; - Vehicle *w = *viter; + for (Vehicle *w : vehs) { w->lateness_counter = 0; ClrBit(w->vehicle_flags, VF_TIMETABLE_STARTED); /* Do multiplication, then division to reduce rounding errors. */ w->timetable_start = start_date + idx * total_duration / num_vehs / DAY_TICKS; SetWindowDirty(WC_VEHICLE_TIMETABLE, w->index); + ++idx; } } @@ -335,7 +328,7 @@ CommandCost CmdAutofillTimetable(TileIndex tile, DoCommandFlag flags, uint32 p1, VehicleID veh = GB(p1, 0, 20); Vehicle *v = Vehicle::GetIfValid(veh); - if (v == NULL || !v->IsPrimaryVehicle() || v->orders.list == NULL) return CMD_ERROR; + if (v == nullptr || !v->IsPrimaryVehicle() || v->orders.list == nullptr) return CMD_ERROR; CommandCost ret = CheckOwnership(v->owner); if (ret.Failed()) return ret; @@ -358,7 +351,7 @@ CommandCost CmdAutofillTimetable(TileIndex tile, DoCommandFlag flags, uint32 p1, ClrBit(v->vehicle_flags, VF_AUTOFILL_PRES_WAIT_TIME); } - for (Vehicle *v2 = v->FirstShared(); v2 != NULL; v2 = v2->NextShared()) { + for (Vehicle *v2 = v->FirstShared(); v2 != nullptr; v2 = v2->NextShared()) { if (v2 != v) { /* Stop autofilling; only one vehicle at a time can perform autofill */ ClrBit(v2->vehicle_flags, VF_AUTOFILL_TIMETABLE); @@ -388,7 +381,7 @@ void UpdateVehicleTimetable(Vehicle *v, bool travelling) Order *real_current_order = v->GetOrder(v->cur_real_order_index); VehicleOrderID first_manual_order = 0; - for (Order *o = v->GetFirstOrder(); o != NULL && o->IsType(OT_IMPLICIT); o = o->next) { + for (Order *o = v->GetFirstOrder(); o != nullptr && o->IsType(OT_IMPLICIT); o = o->next) { ++first_manual_order; } @@ -478,7 +471,7 @@ void UpdateVehicleTimetable(Vehicle *v, bool travelling) } } - for (v = v->FirstShared(); v != NULL; v = v->NextShared()) { + for (v = v->FirstShared(); v != nullptr; v = v->NextShared()) { SetWindowDirty(WC_VEHICLE_TIMETABLE, v->index); } } diff --git a/src/timetable_gui.cpp b/src/timetable_gui.cpp index e3e9660d19..84f661f335 100644 --- a/src/timetable_gui.cpp +++ b/src/timetable_gui.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. @@ -87,7 +85,7 @@ static bool CanDetermineTimeTaken(const Order *order, bool travelling) */ static void FillTimetableArrivalDepartureTable(const Vehicle *v, VehicleOrderID start, bool travelling, TimetableArrivalDeparture *table, Ticks offset) { - assert(table != NULL); + assert(table != nullptr); assert(v->GetNumOrders() >= 2); assert(start < v->GetNumOrders()); @@ -122,7 +120,7 @@ static void FillTimetableArrivalDepartureTable(const Vehicle *v, VehicleOrderID order = order->next; if (i >= v->GetNumOrders()) { i = 0; - assert(order == NULL); + assert(order == nullptr); order = v->orders.list->GetFirstOrder(); } } while (i != start); @@ -189,7 +187,7 @@ struct TimetableWindow : Window { return (travelling && v->lateness_counter < 0); } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_VT_ARRIVAL_DEPARTURE_PANEL: @@ -228,7 +226,7 @@ struct TimetableWindow : Window { * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { switch (data) { case VIWD_AUTOREPLACE: @@ -298,7 +296,7 @@ struct TimetableWindow : Window { } - virtual void OnPaint() + void OnPaint() override { const Vehicle *v = this->vehicle; int selected = this->sel_index; @@ -310,9 +308,9 @@ struct TimetableWindow : Window { if (selected != -1) { const Order *order = v->GetOrder(((selected + 1) / 2) % v->GetNumOrders()); if (selected % 2 == 1) { - disable = order != NULL && (order->IsType(OT_CONDITIONAL) || order->IsType(OT_IMPLICIT)); + disable = order != nullptr && (order->IsType(OT_CONDITIONAL) || order->IsType(OT_IMPLICIT)); } else { - disable = order == NULL || ((!order->IsType(OT_GOTO_STATION) || (order->GetNonStopType() & ONSF_NO_STOP_AT_DESTINATION_STATION)) && !order->IsType(OT_CONDITIONAL)); + 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; @@ -323,9 +321,9 @@ struct TimetableWindow : Window { this->SetWidgetDisabledState(WID_VT_CLEAR_SPEED, disable_speed); this->SetWidgetDisabledState(WID_VT_SHARED_ORDER_LIST, !v->IsOrderListShared()); - this->SetWidgetDisabledState(WID_VT_START_DATE, v->orders.list == NULL); - this->SetWidgetDisabledState(WID_VT_RESET_LATENESS, v->orders.list == NULL); - this->SetWidgetDisabledState(WID_VT_AUTOFILL, v->orders.list == NULL); + this->SetWidgetDisabledState(WID_VT_START_DATE, v->orders.list == nullptr); + this->SetWidgetDisabledState(WID_VT_RESET_LATENESS, v->orders.list == nullptr); + this->SetWidgetDisabledState(WID_VT_AUTOFILL, v->orders.list == nullptr); } else { this->DisableWidget(WID_VT_START_DATE); this->DisableWidget(WID_VT_CHANGE_TIME); @@ -342,7 +340,7 @@ struct TimetableWindow : Window { this->DrawWidgets(); } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { switch (widget) { case WID_VT_CAPTION: SetDParam(0, this->vehicle->index); break; @@ -350,7 +348,7 @@ struct TimetableWindow : Window { } } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { const Vehicle *v = this->vehicle; int selected = this->sel_index; @@ -369,7 +367,7 @@ struct TimetableWindow : Window { int middle = rtl ? r.right - WD_FRAMERECT_RIGHT - index_column_width : r.left + WD_FRAMERECT_LEFT + index_column_width; const Order *order = v->GetOrder(order_id); - while (order != NULL) { + while (order != nullptr) { /* Don't draw anything if it extends past the end of the window. */ if (!this->vscroll->IsVisible(i)) break; @@ -426,7 +424,7 @@ struct TimetableWindow : Window { * i.e. are only shown if we can calculate all times. * Excluding order lists with only one order makes some things easier. */ - Ticks total_time = v->orders.list != NULL ? v->orders.list->GetTimetableDurationIncomplete() : 0; + Ticks total_time = v->orders.list != nullptr ? v->orders.list->GetTimetableDurationIncomplete() : 0; if (total_time <= 0 || v->GetNumOrders() <= 1 || !HasBit(v->vehicle_flags, VF_TIMETABLE_STARTED)) break; TimetableArrivalDeparture *arr_dep = AllocaM(TimetableArrivalDeparture, v->GetNumOrders()); @@ -478,7 +476,7 @@ struct TimetableWindow : Window { case WID_VT_SUMMARY_PANEL: { int y = r.top + WD_FRAMERECT_TOP; - Ticks total_time = v->orders.list != NULL ? v->orders.list->GetTimetableDurationIncomplete() : 0; + Ticks total_time = v->orders.list != nullptr ? v->orders.list->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.list->IsCompleteTimetable() ? STR_TIMETABLE_TOTAL_TIME : STR_TIMETABLE_TOTAL_TIME_INCOMPLETE); @@ -516,7 +514,7 @@ struct TimetableWindow : Window { return v->index | (order_number << 20) | (mtf << 28); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { const Vehicle *v = this->vehicle; @@ -546,7 +544,7 @@ struct TimetableWindow : Window { const Order *order = v->GetOrder(real); StringID current = STR_EMPTY; - if (order != NULL) { + if (order != nullptr) { uint time = (selected % 2 == 1) ? order->GetTravelTime() : order->GetWaitTime(); if (!_settings_client.gui.timetable_in_ticks) time /= DAY_TICKS; @@ -569,7 +567,7 @@ struct TimetableWindow : Window { StringID current = STR_EMPTY; const Order *order = v->GetOrder(real); - if (order != NULL) { + if (order != nullptr) { if (order->GetMaxSpeed() != UINT16_MAX) { SetDParam(0, ConvertKmhishSpeedToDisplaySpeed(order->GetMaxSpeed())); current = STR_JUST_INT; @@ -617,15 +615,15 @@ struct TimetableWindow : Window { this->SetDirty(); } - virtual void OnQueryTextFinished(char *str) + void OnQueryTextFinished(char *str) override { - if (str == NULL) return; + if (str == nullptr) return; const Vehicle *v = this->vehicle; uint32 p1 = PackTimetableArgs(v, this->sel_index, this->query_is_speed_query); - uint64 val = StrEmpty(str) ? 0 : strtoul(str, NULL, 10); + uint64 val = StrEmpty(str) ? 0 : strtoul(str, nullptr, 10); if (this->query_is_speed_query) { val = ConvertDisplaySpeedToKmhishSpeed(val); } else { @@ -637,7 +635,7 @@ struct TimetableWindow : Window { DoCommandP(0, p1, p2, CMD_CHANGE_TIMETABLE | CMD_MSG(STR_ERROR_CAN_T_TIMETABLE_VEHICLE)); } - virtual void OnResize() + void OnResize() override { /* Update the scroll bar */ this->vscroll->SetCapacityFromWidget(this, WID_VT_TIMETABLE_PANEL, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM); diff --git a/src/toolbar_gui.cpp b/src/toolbar_gui.cpp index 82a3f80ea6..15bfc1b166 100644 --- a/src/toolbar_gui.cpp +++ b/src/toolbar_gui.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. @@ -17,6 +15,7 @@ #include "command_func.h" #include "vehicle_gui.h" #include "rail_gui.h" +#include "road.h" #include "road_gui.h" #include "date_func.h" #include "vehicle_func.h" @@ -50,6 +49,7 @@ #include "toolbar_gui.h" #include "framerate_type.h" #include "guitimer_func.h" +#include "screenshot_gui.h" #include "widgets/toolbar_widget.h" @@ -65,6 +65,7 @@ uint _toolbar_width = 0; RailType _last_built_railtype; RoadType _last_built_roadtype; +RoadType _last_built_tramtype; static ScreenshotType _confirmed_screenshot_type; ///< Screenshot type the current query is about to confirm. int _last_clicked_toolbar_idx = 0; @@ -99,14 +100,12 @@ public: this->checkmark_width = GetStringBoundingBox(STR_JUST_CHECKMARK).width + 3; } - virtual ~DropDownListCheckedItem() {} - uint Width() const { return DropDownListStringItem::Width() + this->checkmark_width; } - void Draw(int left, int right, int top, int bottom, bool sel, int bg_colour) const + void Draw(int left, int right, int top, int bottom, bool sel, Colours bg_colour) const { bool rtl = _current_text_dir == TD_RTL; if (this->checked) { @@ -131,14 +130,12 @@ public: this->lock_size = GetSpriteSize(SPR_LOCK); } - virtual ~DropDownListCompanyItem() {} - - bool Selectable() const + bool Selectable() const override { return true; } - uint Width() const + uint Width() const override { CompanyID company = (CompanyID)this->result; SetDParam(0, company); @@ -146,12 +143,12 @@ public: return GetStringBoundingBox(STR_COMPANY_NAME_COMPANY_NUM).width + this->icon_size.width + this->lock_size.width + 6; } - uint Height(uint width) const + uint Height(uint width) const override { return GetMinSizing(NWST_STEP, max(max(this->icon_size.height, this->lock_size.height) + 2U, (uint)FONT_HEIGHT_NORMAL)); } - void Draw(int left, int right, int top, int bottom, bool sel, int bg_colour) const + void Draw(int left, int right, int top, int bottom, bool sel, Colours bg_colour) const override { CompanyID company = (CompanyID)this->result; bool rtl = _current_text_dir == TD_RTL; @@ -164,11 +161,9 @@ public: int lock_offset = (bottom - top - lock_size.height) / 2; DrawCompanyIcon(company, rtl ? right - this->icon_size.width - WD_FRAMERECT_RIGHT : left + WD_FRAMERECT_LEFT, top + icon_offset); -#ifdef ENABLE_NETWORK if (NetworkCompanyIsPassworded(company)) { DrawSprite(SPR_LOCK, PAL_NONE, rtl ? left + WD_FRAMERECT_LEFT : right - this->lock_size.width - WD_FRAMERECT_RIGHT, top + lock_offset); } -#endif SetDParam(0, company); SetDParam(1, company); @@ -189,10 +184,10 @@ public: * @param list List of items * @param def Default item */ -static void PopupMainToolbMenu(Window *w, int widget, DropDownList *list, int def) +static void PopupMainToolbMenu(Window *w, int widget, DropDownList &&list, int def) { if (!_settings_client.gui.vertical_toolbar) { - ShowDropDownList(w, list, def, widget, 0, true, list->Length() <= 1); + ShowDropDownList(w, std::move(list), def, widget, 0, true, list->Length() <= 1); } else { Rect wi_rect; NWidgetCore *nwi = w->GetWidget(widget); @@ -200,7 +195,7 @@ static void PopupMainToolbMenu(Window *w, int widget, DropDownList *list, int de wi_rect.right = nwi->pos_x + nwi->current_x; wi_rect.top = nwi->pos_y; wi_rect.bottom = nwi->pos_y + nwi->current_y; - ShowDropDownListAt(w, list, def, widget, wi_rect, nwi->colour, true, list->Length() <= 1); + ShowDropDownListAt(w, std::move(list), def, widget, wi_rect, nwi->colour, true, list->Length() <= 1); } if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); } @@ -214,11 +209,11 @@ static void PopupMainToolbMenu(Window *w, int widget, DropDownList *list, int de */ static void PopupMainToolbMenu(Window *w, int widget, StringID string, int count) { - DropDownList *list = new DropDownList(); + DropDownList list; for (int i = 0; i < count; i++) { - *list->Append() = new DropDownListStringItem(string + i, i, false); + list.emplace_back(new DropDownListStringItem(string + i, i, false)); } - PopupMainToolbMenu(w, widget, list, 0); + PopupMainToolbMenu(w, widget, std::move(list), 0); } /** Enum for the Company Toolbar's network related buttons */ @@ -236,40 +231,38 @@ static const int CTMN_SPEAK_ALL = -5; ///< Send message to public chat */ static void PopupMainCompanyToolbMenu(Window *w, int widget, int grey = 0) { - DropDownList *list = new DropDownList(); + DropDownList list; switch (widget) { case WID_TN_COMPANIES: -#ifdef ENABLE_NETWORK if (!_networking) break; /* Add the client list button for the companies menu */ - *list->Append() = new DropDownListStringItem(STR_NETWORK_COMPANY_LIST_CLIENT_LIST, CTMN_CLIENT_LIST, false); - *list->Append() = new DropDownListStringItem(STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL, CTMN_SPEAK_ALL, false); + list.emplace_back(new DropDownListStringItem(STR_NETWORK_COMPANY_LIST_CLIENT_LIST, CTMN_CLIENT_LIST, false)); + list.emplace_back(new DropDownListStringItem(STR_NETWORK_CLIENTLIST_SPEAK_TO_ALL, CTMN_SPEAK_ALL, false)); if (_local_company == COMPANY_SPECTATOR) { - *list->Append() = new DropDownListStringItem(STR_NETWORK_COMPANY_LIST_NEW_COMPANY, CTMN_NEW_COMPANY, NetworkMaxCompaniesReached()); + list.emplace_back(new DropDownListStringItem(STR_NETWORK_COMPANY_LIST_NEW_COMPANY, CTMN_NEW_COMPANY, NetworkMaxCompaniesReached())); } else { - *list->Append() = new DropDownListStringItem(STR_NETWORK_COMPANY_LIST_SPECTATE, CTMN_SPECTATE, NetworkMaxSpectatorsReached()); + list.emplace_back(new DropDownListStringItem(STR_NETWORK_COMPANY_LIST_SPECTATE, CTMN_SPECTATE, NetworkMaxSpectatorsReached())); } -#endif /* ENABLE_NETWORK */ break; case WID_TN_STORY: - *list->Append() = new DropDownListStringItem(STR_STORY_BOOK_SPECTATOR, CTMN_SPECTATOR, false); + list.emplace_back(new DropDownListStringItem(STR_STORY_BOOK_SPECTATOR, CTMN_SPECTATOR, false)); break; case WID_TN_GOAL: - *list->Append() = new DropDownListStringItem(STR_GOALS_SPECTATOR, CTMN_SPECTATOR, false); + list.emplace_back(new DropDownListStringItem(STR_GOALS_SPECTATOR, CTMN_SPECTATOR, false)); break; } for (CompanyID c = COMPANY_FIRST; c < MAX_COMPANIES; c++) { if (!Company::IsValidID(c)) continue; - *list->Append() = new DropDownListCompanyItem(c, false, HasBit(grey, c)); + list.emplace_back(new DropDownListCompanyItem(c, false, HasBit(grey, c))); } - PopupMainToolbMenu(w, widget, list, _local_company == COMPANY_SPECTATOR ? (widget == WID_TN_COMPANIES ? CTMN_CLIENT_LIST : CTMN_SPECTATOR) : (int)_local_company); + PopupMainToolbMenu(w, widget, std::move(list), _local_company == COMPANY_SPECTATOR ? (widget == WID_TN_COMPANIES ? CTMN_CLIENT_LIST : CTMN_SPECTATOR) : (int)_local_company); } @@ -339,27 +332,27 @@ enum OptionMenuEntries { */ static CallBackFunction ToolbarOptionsClick(Window *w) { - DropDownList *list = new DropDownList(); - *list->Append() = new DropDownListStringItem(STR_SETTINGS_MENU_GAME_OPTIONS, OME_GAMEOPTIONS, false); - *list->Append() = new DropDownListStringItem(STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE, OME_SETTINGS, false); + DropDownList list; + list.emplace_back(new DropDownListStringItem(STR_SETTINGS_MENU_GAME_OPTIONS, OME_GAMEOPTIONS, false)); + list.emplace_back(new DropDownListStringItem(STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE, OME_SETTINGS, false)); /* 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->Append() = new DropDownListStringItem(STR_SETTINGS_MENU_SCRIPT_SETTINGS, OME_SCRIPT_SETTINGS, false); - *list->Append() = new DropDownListStringItem(STR_SETTINGS_MENU_NEWGRF_SETTINGS, OME_NEWGRFSETTINGS, false); - *list->Append() = new DropDownListStringItem(STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS, OME_TRANSPARENCIES, false); - *list->Append() = new DropDownListItem(-1, false); - *list->Append() = new DropDownListCheckedItem(STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED, OME_SHOW_TOWNNAMES, false, HasBit(_display_opt, DO_SHOW_TOWN_NAMES)); - *list->Append() = new DropDownListCheckedItem(STR_SETTINGS_MENU_STATION_NAMES_DISPLAYED, OME_SHOW_STATIONNAMES, false, HasBit(_display_opt, DO_SHOW_STATION_NAMES)); - *list->Append() = new DropDownListCheckedItem(STR_SETTINGS_MENU_WAYPOINTS_DISPLAYED, OME_SHOW_WAYPOINTNAMES, false, HasBit(_display_opt, DO_SHOW_WAYPOINT_NAMES)); - *list->Append() = new DropDownListCheckedItem(STR_SETTINGS_MENU_SIGNS_DISPLAYED, OME_SHOW_SIGNS, false, HasBit(_display_opt, DO_SHOW_SIGNS)); - *list->Append() = new DropDownListCheckedItem(STR_SETTINGS_MENU_SHOW_COMPETITOR_SIGNS, OME_SHOW_COMPETITOR_SIGNS, false, HasBit(_display_opt, DO_SHOW_COMPETITOR_SIGNS)); - *list->Append() = new DropDownListCheckedItem(STR_SETTINGS_MENU_FULL_ANIMATION, OME_FULL_ANIMATION, false, HasBit(_display_opt, DO_FULL_ANIMATION)); - *list->Append() = new DropDownListCheckedItem(STR_SETTINGS_MENU_FULL_DETAIL, OME_FULL_DETAILS, false, HasBit(_display_opt, DO_FULL_DETAIL)); - *list->Append() = new DropDownListCheckedItem(STR_SETTINGS_MENU_TRANSPARENT_BUILDINGS, OME_TRANSPARENTBUILDINGS, false, IsTransparencySet(TO_HOUSES)); - *list->Append() = new DropDownListCheckedItem(STR_SETTINGS_MENU_TRANSPARENT_SIGNS, OME_SHOW_STATIONSIGNS, false, IsTransparencySet(TO_SIGNS)); + if (!_networking || _network_server) list.emplace_back(new DropDownListStringItem(STR_SETTINGS_MENU_SCRIPT_SETTINGS, OME_SCRIPT_SETTINGS, false)); + list.emplace_back(new DropDownListStringItem(STR_SETTINGS_MENU_NEWGRF_SETTINGS, OME_NEWGRFSETTINGS, false)); + list.emplace_back(new DropDownListStringItem(STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS, OME_TRANSPARENCIES, false)); + list.emplace_back(new DropDownListItem(-1, false)); + list.emplace_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED, OME_SHOW_TOWNNAMES, false, HasBit(_display_opt, DO_SHOW_TOWN_NAMES))); + list.emplace_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_STATION_NAMES_DISPLAYED, OME_SHOW_STATIONNAMES, false, HasBit(_display_opt, DO_SHOW_STATION_NAMES))); + list.emplace_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_WAYPOINTS_DISPLAYED, OME_SHOW_WAYPOINTNAMES, false, HasBit(_display_opt, DO_SHOW_WAYPOINT_NAMES))); + list.emplace_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_SIGNS_DISPLAYED, OME_SHOW_SIGNS, false, HasBit(_display_opt, DO_SHOW_SIGNS))); + list.emplace_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_SHOW_COMPETITOR_SIGNS, OME_SHOW_COMPETITOR_SIGNS, false, HasBit(_display_opt, DO_SHOW_COMPETITOR_SIGNS))); + list.emplace_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_FULL_ANIMATION, OME_FULL_ANIMATION, false, HasBit(_display_opt, DO_FULL_ANIMATION))); + list.emplace_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_FULL_DETAIL, OME_FULL_DETAILS, false, HasBit(_display_opt, DO_FULL_DETAIL))); + list.emplace_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_TRANSPARENT_BUILDINGS, OME_TRANSPARENTBUILDINGS, false, IsTransparencySet(TO_HOUSES))); + list.emplace_back(new DropDownListCheckedItem(STR_SETTINGS_MENU_TRANSPARENT_SIGNS, OME_SHOW_STATIONSIGNS, false, IsTransparencySet(TO_SIGNS))); - ShowDropDownList(w, list, 0, WID_TN_SETTINGS, 140, true); + ShowDropDownList(w, std::move(list), 0, WID_TN_SETTINGS, 140, true, false); if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); return CBF_NONE; } @@ -485,24 +478,24 @@ enum MapMenuEntries { static CallBackFunction ToolbarMapClick(Window *w) { - DropDownList *list = new DropDownList(); - *list->Append() = new DropDownListStringItem(STR_MAP_MENU_MAP_OF_WORLD, MME_SHOW_SMALLMAP, false); - *list->Append() = new DropDownListStringItem(STR_MAP_MENU_EXTRA_VIEW_PORT, MME_SHOW_EXTRAVIEWPORTS, false); - *list->Append() = new DropDownListStringItem(STR_MAP_MENU_LINGRAPH_LEGEND, MME_SHOW_LINKGRAPH, false); - *list->Append() = new DropDownListStringItem(STR_MAP_MENU_SIGN_LIST, MME_SHOW_SIGNLISTS, false); - PopupMainToolbMenu(w, WID_TN_SMALL_MAP, list, 0); + DropDownList list; + list.emplace_back(new DropDownListStringItem(STR_MAP_MENU_MAP_OF_WORLD, MME_SHOW_SMALLMAP, false)); + list.emplace_back(new DropDownListStringItem(STR_MAP_MENU_EXTRA_VIEW_PORT, MME_SHOW_EXTRAVIEWPORTS, false)); + list.emplace_back(new DropDownListStringItem(STR_MAP_MENU_LINGRAPH_LEGEND, MME_SHOW_LINKGRAPH, false)); + list.emplace_back(new DropDownListStringItem(STR_MAP_MENU_SIGN_LIST, MME_SHOW_SIGNLISTS, false)); + PopupMainToolbMenu(w, WID_TN_SMALL_MAP, std::move(list), 0); return CBF_NONE; } static CallBackFunction ToolbarScenMapTownDir(Window *w) { - DropDownList *list = new DropDownList(); - *list->Append() = new DropDownListStringItem(STR_MAP_MENU_MAP_OF_WORLD, MME_SHOW_SMALLMAP, false); - *list->Append() = new DropDownListStringItem(STR_MAP_MENU_EXTRA_VIEW_PORT, MME_SHOW_EXTRAVIEWPORTS, false); - *list->Append() = new DropDownListStringItem(STR_MAP_MENU_SIGN_LIST, MME_SHOW_SIGNLISTS, false); - *list->Append() = new DropDownListStringItem(STR_TOWN_MENU_TOWN_DIRECTORY, MME_SHOW_TOWNDIRECTORY, false); - *list->Append() = new DropDownListStringItem(STR_INDUSTRY_MENU_INDUSTRY_DIRECTORY, MME_SHOW_INDUSTRYDIRECTORY, false); - PopupMainToolbMenu(w, WID_TE_SMALL_MAP, list, 0); + DropDownList list; + list.emplace_back(new DropDownListStringItem(STR_MAP_MENU_MAP_OF_WORLD, MME_SHOW_SMALLMAP, false)); + list.emplace_back(new DropDownListStringItem(STR_MAP_MENU_EXTRA_VIEW_PORT, MME_SHOW_EXTRAVIEWPORTS, false)); + list.emplace_back(new DropDownListStringItem(STR_MAP_MENU_SIGN_LIST, MME_SHOW_SIGNLISTS, false)); + list.emplace_back(new DropDownListStringItem(STR_TOWN_MENU_TOWN_DIRECTORY, MME_SHOW_TOWNDIRECTORY, false)); + list.emplace_back(new DropDownListStringItem(STR_INDUSTRY_MENU_INDUSTRY_DIRECTORY, MME_SHOW_INDUSTRYDIRECTORY, false)); + PopupMainToolbMenu(w, WID_TE_SMALL_MAP, std::move(list), 0); return CBF_NONE; } @@ -632,7 +625,6 @@ static CallBackFunction ToolbarCompaniesClick(Window *w) */ static CallBackFunction MenuClickCompany(int index) { -#ifdef ENABLE_NETWORK if (_networking) { switch (index) { case CTMN_CLIENT_LIST: @@ -643,7 +635,7 @@ static CallBackFunction MenuClickCompany(int index) if (_network_server) { DoCommandP(0, CCA_NEW, _network_own_client_id, CMD_COMPANY_CTRL); } else { - NetworkSendCommand(0, CCA_NEW, 0, CMD_COMPANY_CTRL, NULL, NULL, _local_company); + NetworkSendCommand(0, CCA_NEW, 0, CMD_COMPANY_CTRL, nullptr, nullptr, _local_company); } return CBF_NONE; @@ -661,7 +653,6 @@ static CallBackFunction MenuClickCompany(int index) return CBF_NONE; } } -#endif /* ENABLE_NETWORK */ ShowCompany((CompanyID)index); return CBF_NONE; } @@ -791,10 +782,9 @@ static CallBackFunction MenuClickIndustry(int index) static void ToolbarVehicleClick(Window *w, VehicleType veh) { - const Vehicle *v; int dis = ~0; - FOR_ALL_VEHICLES(v) { + for (const Vehicle *v : Vehicle::Iterate()) { if (v->type == veh && v->IsPrimaryVehicle()) ClrBit(dis, v->owner); } PopupMainCompanyToolbMenu(w, WID_TN_VEHICLE_START + veh, dis); @@ -949,22 +939,8 @@ static CallBackFunction MenuClickBuildRail(int index) static CallBackFunction ToolbarBuildRoadClick(Window *w) { - const Company *c = Company::Get(_local_company); - DropDownList *list = new DropDownList(); - - /* Road is always visible and available. */ - *list->Append() = new DropDownListStringItem(STR_ROAD_MENU_ROAD_CONSTRUCTION, ROADTYPE_ROAD, false); - - /* Tram is only visible when there will be a tram, and available when that has been introduced. */ - Engine *e; - FOR_ALL_ENGINES_OF_TYPE(e, VEH_ROAD) { - if (!HasBit(e->info.climates, _settings_game.game_creation.landscape)) continue; - if (!HasBit(e->info.misc_flags, EF_ROAD_TRAM)) continue; - - *list->Append() = new DropDownListStringItem(STR_ROAD_MENU_TRAM_CONSTRUCTION, ROADTYPE_TRAM, !HasBit(c->avail_roadtypes, ROADTYPE_TRAM)); - break; - } - ShowDropDownList(w, list, _last_built_roadtype, WID_TN_ROADS, 140, true, list->Length() <= 1); + DropDownList list = GetRoadTypeDropDownList(RTTB_ROAD); + ShowDropDownList(w, list, _last_built_roadtype, WID_TN_ROADS, 140, true, list->size() <= 1); if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); return CBF_NONE; } @@ -982,11 +958,36 @@ static CallBackFunction MenuClickBuildRoad(int index) return CBF_NONE; } +/* --- Tram button menu --- */ + +static CallBackFunction ToolbarBuildTramClick(Window *w) +{ + ShowDropDownList(w, GetRoadTypeDropDownList(RTTB_TRAM), _last_built_tramtype, WID_TN_TRAMS, 140, true, true); + if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); + return CBF_NONE; +} + +/** + * Handle click on the entry in the Build Tram menu. + * + * @param index RoadType to show the build toolbar for. + * @return #CBF_NONE + */ +static CallBackFunction MenuClickBuildTram(int index) +{ + _last_built_tramtype = (RoadType)index; + ShowBuildRoadToolbar(_last_built_tramtype); + return CBF_NONE; +} + /* --- Water button menu --- */ static CallBackFunction ToolbarBuildWaterClick(Window *w) { - PopupMainToolbMenu(w, WID_TN_WATER, STR_WATERWAYS_MENU_WATERWAYS_CONSTRUCTION, 1); + DropDownList list; + list.emplace_back(new DropDownListIconItem(SPR_IMG_BUILD_CANAL, PAL_NONE, STR_WATERWAYS_MENU_WATERWAYS_CONSTRUCTION, 0, false)); + ShowDropDownList(w, std::move(list), 0, WID_TN_WATER, 140, true, true); + if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); return CBF_NONE; } @@ -1006,7 +1007,10 @@ static CallBackFunction MenuClickBuildWater(int index) static CallBackFunction ToolbarBuildAirClick(Window *w) { - PopupMainToolbMenu(w, WID_TN_AIR, STR_AIRCRAFT_MENU_AIRPORT_CONSTRUCTION, 1); + DropDownList list; + list.emplace_back(new DropDownListIconItem(SPR_IMG_AIRPORT, PAL_NONE, STR_AIRCRAFT_MENU_AIRPORT_CONSTRUCTION, 0, false)); + ShowDropDownList(w, std::move(list), 0, WID_TN_AIR, 140, true, true); + if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); return CBF_NONE; } @@ -1026,7 +1030,12 @@ static CallBackFunction MenuClickBuildAir(int index) static CallBackFunction ToolbarForestClick(Window *w) { - PopupMainToolbMenu(w, WID_TN_LANDSCAPE, STR_LANDSCAPING_MENU_LANDSCAPING, 3); + DropDownList list; + list.emplace_back(new DropDownListIconItem(SPR_IMG_LANDSCAPING, PAL_NONE, STR_LANDSCAPING_MENU_LANDSCAPING, 0, false)); + list.emplace_back(new DropDownListIconItem(SPR_IMG_PLANTTREES, PAL_NONE, STR_LANDSCAPING_MENU_PLANT_TREES, 1, false)); + list.emplace_back(new DropDownListIconItem(SPR_IMG_SIGN, PAL_NONE, STR_LANDSCAPING_MENU_PLACE_SIGN, 2, false)); + ShowDropDownList(w, std::move(list), 0, WID_TN_LANDSCAPE, 100, true, true); + if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); return CBF_NONE; } @@ -1050,7 +1059,7 @@ static CallBackFunction MenuClickForest(int index) static CallBackFunction ToolbarMusicClick(Window *w) { - PopupMainToolbMenu(w, WID_TN_MUSIC_SOUND, STR_TOOLBAR_SOUND_MUSIC, 1); + PopupMainToolbMenu(w, _game_mode == GM_EDITOR ? (int)WID_TE_MUSIC_SOUND : (int)WID_TN_MUSIC_SOUND, STR_TOOLBAR_SOUND_MUSIC, 1); return CBF_NONE; } @@ -1105,35 +1114,10 @@ static CallBackFunction PlaceLandBlockInfo() static CallBackFunction ToolbarHelpClick(Window *w) { - DropDownList *list = new DropDownList(); - *list->Append() = new DropDownListStringItem(STR_ABOUT_MENU_LAND_BLOCK_INFO, 0, false); - *list->Append() = new DropDownListStringItem(STR_NEWS_MENU_LAST_MESSAGE_NEWS_REPORT, 1, false); - *list->Append() = new DropDownListStringItem(STR_NEWS_MENU_MESSAGE_HISTORY_MENU, 2, false); - *list->Append() = new DropDownListStringItem(STR_TOOLBAR_SOUND_MUSIC, 3, false); - *list->Append() = new DropDownListStringItem(STR_ABOUT_MENU_TUTORIAL, 4, false); - *list->Append() = new DropDownListStringItem(STR_ABOUT_MENU_TOGGLE_CONSOLE, 5, false); - *list->Append() = new DropDownListStringItem(STR_ABOUT_MENU_AI_DEBUG, 6, false); - *list->Append() = new DropDownListStringItem(STR_ABOUT_MENU_SCREENSHOT, 7, false); - *list->Append() = new DropDownListStringItem(STR_ABOUT_MENU_ZOOMIN_SCREENSHOT, 8, false); - *list->Append() = new DropDownListStringItem(STR_ABOUT_MENU_DEFAULTZOOM_SCREENSHOT, 9, false); - *list->Append() = new DropDownListStringItem(STR_ABOUT_MENU_GIANT_SCREENSHOT, 10, false); - *list->Append() = new DropDownListStringItem(STR_ABOUT_MENU_SHOW_FRAMERATE, 11, false); - *list->Append() = new DropDownListStringItem(STR_ABOUT_MENU_ABOUT_OPENTTD, 12, false); - if (_settings_client.gui.newgrf_developer_tools) { - *list->Append() = new DropDownListStringItem(STR_ABOUT_MENU_SPRITE_ALIGNER, 13, false); - *list->Append() = new DropDownListStringItem(STR_ABOUT_MENU_TOGGLE_BOUNDING_BOXES, 14, false); - *list->Append() = new DropDownListStringItem(STR_ABOUT_MENU_TOGGLE_DIRTY_BLOCKS, 15, false); - } - ShowDropDownList(w, list, 0, WID_TN_HELP, 140, true); - if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); + PopupMainToolbMenu(w, _game_mode == GM_EDITOR ? (int)WID_TE_HELP : (int)WID_TN_HELP, STR_ABOUT_MENU_LAND_BLOCK_INFO, _settings_client.gui.newgrf_developer_tools ? 11 : 8); return CBF_NONE; } -static void MenuClickSmallScreenshot() -{ - MakeScreenshot(SC_VIEWPORT, NULL); -} - /** * Callback on the confirmation window for huge screenshots. * @param w Window with viewport @@ -1141,7 +1125,7 @@ static void MenuClickSmallScreenshot() */ static void ScreenshotConfirmCallback(Window *w, bool confirmed) { - if (confirmed) MakeScreenshot(_confirmed_screenshot_type, NULL); + if (confirmed) MakeScreenshot(_confirmed_screenshot_type, nullptr); } /** @@ -1149,7 +1133,7 @@ static void ScreenshotConfirmCallback(Window *w, bool confirmed) * Ask for confirmation if the screenshot will be huge. * @param t Screenshot type: World or viewport screenshot */ -static void MenuClickLargeWorldScreenshot(ScreenshotType t) +static void MenuClickScreenshot(ScreenshotType t) { ViewPort vp; SetupScreenshotViewport(t, &vp); @@ -1158,10 +1142,10 @@ static void MenuClickLargeWorldScreenshot(ScreenshotType t) SetDParam(0, vp.width); SetDParam(1, vp.height); _confirmed_screenshot_type = t; - ShowQuery(STR_WARNING_SCREENSHOT_SIZE_CAPTION, STR_WARNING_SCREENSHOT_SIZE_MESSAGE, NULL, ScreenshotConfirmCallback); + ShowQuery(STR_WARNING_SCREENSHOT_SIZE_CAPTION, STR_WARNING_SCREENSHOT_SIZE_MESSAGE, nullptr, ScreenshotConfirmCallback); } else { /* Less than 64M pixels, just do it */ - MakeScreenshot(t, NULL); + MakeScreenshot(t, nullptr); } } @@ -1221,21 +1205,15 @@ static CallBackFunction MenuClickHelp(int index) { switch (index) { case 0: return PlaceLandBlockInfo(); - case 1: ShowLastNewsMessage(); break; - case 2: ShowMessageHistory(); break; - case 3: ShowMusicWindow(); break; - case 4: ShowTutorialWindow(); break; - case 5: IConsoleSwitch(); break; - case 6: ShowAIDebugWindow(); break; - case 7: MenuClickSmallScreenshot(); break; - case 8: MenuClickLargeWorldScreenshot(SC_ZOOMEDIN); break; - case 9: MenuClickLargeWorldScreenshot(SC_DEFAULTZOOM); break; - case 10: MenuClickLargeWorldScreenshot(SC_WORLD); break; - case 11: ShowFramerateWindow(); break; - case 12: ShowAboutWindow(); break; - case 13: ShowSpriteAlignerWindow(); break; - case 14: ToggleBoundingBoxes(); break; - case 15: ToggleDirtyBlocks(); break; + case 2: ShowTutorialWindow(); break; + case 3: IConsoleSwitch(); break; + case 4: ShowAIDebugWindow(); break; + case 5: ShowScreenshotWindow(); break; + case 6: ShowFramerateWindow(); break; + case 7: ShowAboutWindow(); break; + case 8: ShowSpriteAlignerWindow(); break; + case 9: ToggleBoundingBoxes(); break; + case 10: ToggleDirtyBlocks(); break; } return CBF_NONE; } @@ -1251,7 +1229,7 @@ static CallBackFunction ToolbarSwitchClick(Window *w) } w->ReInit(); - w->SetWidgetLoweredState(WID_TN_SWITCH_BAR, _toolbar_mode == TB_LOWER); + w->SetWidgetLoweredState(_game_mode == GM_EDITOR ? (uint)WID_TE_SWITCH_BAR : (uint)WID_TN_SWITCH_BAR, _toolbar_mode == TB_LOWER); if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); return CBF_NONE; } @@ -1355,11 +1333,43 @@ static CallBackFunction ToolbarScenGenIndustry(Window *w) return CBF_NONE; } -static CallBackFunction ToolbarScenBuildRoad(Window *w) +static CallBackFunction ToolbarScenBuildRoadClick(Window *w) { - w->HandleButtonClick(WID_TE_ROADS); + ShowDropDownList(w, GetScenRoadTypeDropDownList(RTTB_ROAD), _last_built_roadtype, WID_TE_ROADS, 140, true, true); if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); - ShowBuildRoadScenToolbar(); + return CBF_NONE; +} + +/** + * Handle click on the entry in the Build Road menu. + * + * @param index RoadType to show the build toolbar for. + * @return #CBF_NONE + */ +static CallBackFunction ToolbarScenBuildRoad(int index) +{ + _last_built_roadtype = (RoadType)index; + ShowBuildRoadScenToolbar(_last_built_roadtype); + return CBF_NONE; +} + +static CallBackFunction ToolbarScenBuildTramClick(Window *w) +{ + ShowDropDownList(w, GetScenRoadTypeDropDownList(RTTB_TRAM), _last_built_tramtype, WID_TE_TRAMS, 140, true, true); + if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); + return CBF_NONE; +} + +/** + * Handle click on the entry in the Build Tram menu. + * + * @param index RoadType to show the build toolbar for. + * @return #CBF_NONE + */ +static CallBackFunction ToolbarScenBuildTram(int index) +{ + _last_built_tramtype = (RoadType)index; + ShowBuildRoadScenToolbar(_last_built_tramtype); return CBF_NONE; } @@ -1394,8 +1404,8 @@ static CallBackFunction ToolbarBtn_NULL(Window *w) typedef CallBackFunction MenuClickedProc(int index); static MenuClickedProc * const _menu_clicked_procs[] = { - NULL, // 0 - NULL, // 1 + nullptr, // 0 + nullptr, // 1 MenuClickSettings, // 2 MenuClickSaveLoad, // 3 MenuClickMap, // 4 @@ -1414,15 +1424,16 @@ static MenuClickedProc * const _menu_clicked_procs[] = { MenuClickShowShips, // 17 MenuClickShowAir, // 18 MenuClickMap, // 19 - NULL, // 20 + nullptr, // 20 MenuClickBuildRail, // 21 MenuClickBuildRoad, // 22 - MenuClickBuildWater, // 23 - MenuClickBuildAir, // 24 - MenuClickForest, // 25 - MenuClickMusicWindow, // 26 - MenuClickNewspaper, // 27 - MenuClickHelp, // 28 + MenuClickBuildTram, // 23 + MenuClickBuildWater, // 24 + MenuClickBuildAir, // 25 + MenuClickForest, // 26 + MenuClickMusicWindow, // 27 + MenuClickNewspaper, // 28 + MenuClickHelp, // 29 }; /** Full blown container to make it behave exactly as we want :) */ @@ -1446,7 +1457,7 @@ public: return type == WWT_IMGBTN || type == WWT_IMGBTN_2 || type == WWT_PUSHIMGBTN || type == WWT_PUSHTXTBTN || type == WWT_TEXTBTN; } - void SetupSmallestSize(Window *w, bool init_array) + void SetupSmallestSize(Window *w, bool init_array) override { this->smallest_x = 0; // Biggest child this->smallest_y = 0; // Biggest child @@ -1458,7 +1469,7 @@ public: uint nbuttons = 0; /* First initialise some variables... */ - for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) { + for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { child_wid->SetupSmallestSize(w, init_array); if (type == NWID_HORIZONTAL) { this->smallest_y = max(this->smallest_y, child_wid->smallest_y + child_wid->padding_top + child_wid->padding_bottom); @@ -1478,7 +1489,7 @@ public: } /* ... then in a second pass make sure the 'current' heights are set. Won't change ever. */ - for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) { + for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { if (type == NWID_HORIZONTAL) { child_wid->current_y = this->smallest_y; if (!this->IsButton(child_wid->type)) { @@ -1501,7 +1512,7 @@ public: _toolbar_width = nbuttons * this->smallest_x; } - void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl) + void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl) override { assert(given_width >= this->smallest_x && given_height >= this->smallest_y); @@ -1520,7 +1531,7 @@ public: /* Create us ourselves a quick lookup table */ NWidgetBase *widgets[WID_TN_END]; - for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) { + for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { if (child_wid->type == NWID_SPACER) continue; widgets[((NWidgetCore*)child_wid)->index] = child_wid; } @@ -1543,7 +1554,7 @@ public: /* If we have to give space to the spacers, do that */ if (spacer_space != 0) { NWidgetBase *possible_spacer = rtl ? child_wid->next : child_wid->prev; - if (possible_spacer != NULL && possible_spacer->type == NWID_SPACER) { + if (possible_spacer != nullptr && possible_spacer->type == NWID_SPACER) { uint add = spacer_space / (spacer_count - spacer_i); position += add; spacer_space -= add; @@ -1578,14 +1589,14 @@ public: } } - /* virtual */ void Draw(const Window *w) + void Draw(const Window *w) override { /* Draw brown-red toolbar bg. */ GfxFillRect(this->pos_x, this->pos_y, this->pos_x + this->current_x - 1, this->pos_y + this->current_y - 1, PC_VERY_DARK_RED); GfxFillRect(this->pos_x, this->pos_y, this->pos_x + this->current_x - 1, this->pos_y + this->current_y - 1, PC_DARK_RED, FILLRECT_CHECKER); bool rtl = _current_text_dir == TD_RTL; - for (NWidgetBase *child_wid = rtl ? this->tail : this->head; child_wid != NULL; child_wid = rtl ? child_wid->prev : child_wid->next) { + for (NWidgetBase *child_wid = rtl ? this->tail : this->head; child_wid != nullptr; child_wid = rtl ? child_wid->prev : child_wid->next) { if (child_wid->type == NWID_SPACER) continue; if (!this->visible[((NWidgetCore*)child_wid)->index]) continue; @@ -1593,18 +1604,18 @@ public: } } - /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y) + NWidgetCore *GetWidgetFromPos(int x, int y) override { - if (!IsInsideBS(x, this->pos_x, this->current_x) || !IsInsideBS(y, this->pos_y, this->current_y)) return NULL; + if (!IsInsideBS(x, this->pos_x, this->current_x) || !IsInsideBS(y, this->pos_y, this->current_y)) return nullptr; - for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) { + for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { if (child_wid->type == NWID_SPACER) continue; if (!this->visible[((NWidgetCore*)child_wid)->index]) continue; NWidgetCore *nwid = child_wid->GetWidgetFromPos(x, y); - if (nwid != NULL) return nwid; + if (nwid != nullptr) return nwid; } - return NULL; + return nullptr; } /** @@ -1620,7 +1631,7 @@ public: /** Container for the 'normal' main toolbar */ class NWidgetMainToolbarContainer : public NWidgetToolbarContainer { - /* virtual */ const byte *GetButtonArrangement(uint &width, uint &arrangable_count, uint &button_count, uint &spacer_count) const + const byte *GetButtonArrangement(uint &width, uint &arrangable_count, uint &button_count, uint &spacer_count) const override { uint SMALLEST_ARRANGEMENT = 14 + (_settings_client.gui.build_confirmation ? 1 : 2); uint BIGGEST_ARRANGEMENT = 20 + (_settings_client.gui.build_confirmation ? 1 : 2); @@ -1928,6 +1939,7 @@ class NWidgetMainToolbarContainer : public NWidgetToolbarContainer { WID_TN_ZOOM_OUT, WID_TN_RAILS, WID_TN_ROADS, + WID_TN_TRAMS, WID_TN_WATER, WID_TN_AIR, WID_TN_LANDSCAPE, @@ -2501,17 +2513,18 @@ class NWidgetVerticalToolbarContainer : public NWidgetToolbarContainer { } }; + /** Container for the scenario editor's toolbar */ class NWidgetScenarioToolbarContainer : public NWidgetToolbarContainer { uint panel_widths[2]; ///< The width of the two panels (the text panel and date panel) - void SetupSmallestSize(Window *w, bool init_array) + void SetupSmallestSize(Window *w, bool init_array) override { this->NWidgetToolbarContainer::SetupSmallestSize(w, init_array); /* Find the size of panel_widths */ uint i = 0; - for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) { + for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { if (child_wid->type == NWID_SPACER || this->IsButton(child_wid->type)) continue; assert(i < lengthof(this->panel_widths)); @@ -2520,7 +2533,7 @@ class NWidgetScenarioToolbarContainer : public NWidgetToolbarContainer { } } - /* virtual */ const byte *GetButtonArrangement(uint &width, uint &arrangable_count, uint &button_count, uint &spacer_count) const + const byte *GetButtonArrangement(uint &width, uint &arrangable_count, uint &button_count, uint &spacer_count) const override { static const byte arrange_all[] = { WID_TE_PAUSE, @@ -2536,6 +2549,7 @@ class NWidgetScenarioToolbarContainer : public NWidgetToolbarContainer { WID_TE_TOWN_GENERATE, WID_TE_INDUSTRY, WID_TE_ROADS, + WID_TE_TRAMS, WID_TE_WATER, WID_TE_TREES, WID_TE_SIGNS, @@ -2555,6 +2569,7 @@ class NWidgetScenarioToolbarContainer : public NWidgetToolbarContainer { WID_TE_TOWN_GENERATE, WID_TE_INDUSTRY, WID_TE_ROADS, + WID_TE_TRAMS, WID_TE_WATER, WID_TE_TREES, WID_TE_SIGNS, @@ -2568,6 +2583,7 @@ class NWidgetScenarioToolbarContainer : public NWidgetToolbarContainer { WID_TE_TOWN_GENERATE, WID_TE_INDUSTRY, WID_TE_ROADS, + WID_TE_TRAMS, WID_TE_WATER, WID_TE_TREES, WID_TE_SIGNS, @@ -2578,10 +2594,12 @@ class NWidgetScenarioToolbarContainer : public NWidgetToolbarContainer { WID_TE_SETTINGS, WID_TE_SAVE, WID_TE_DATE_PANEL, + WID_TE_SMALL_MAP, WID_TE_ZOOM_IN, WID_TE_ZOOM_OUT, WID_TE_MUSIC_SOUND, - WID_TE_HELP, WID_TE_SWITCH_BAR, + WID_TE_HELP, + WID_TE_SWITCH_BAR, }; /* If we can place all buttons *and* the panels, show them. */ @@ -2641,6 +2659,7 @@ static ToolbarButtonProc * const _toolbar_button_procs[] = { ToolbarZoomOutClick, ToolbarBuildRailClick, ToolbarBuildRoadClick, + ToolbarBuildTramClick, ToolbarBuildWaterClick, ToolbarBuildAirClick, ToolbarForestClick, @@ -2678,6 +2697,7 @@ enum MainToolbarHotkeys { MTHK_ZOOM_OUT, MTHK_BUILD_RAIL, MTHK_BUILD_ROAD, + MTHK_BUILD_TRAM, MTHK_BUILD_DOCKS, MTHK_BUILD_AIRPORT, MTHK_BUILD_TREES, @@ -2714,17 +2734,17 @@ struct MainToolbarWindow : Window { this->timer.SetInterval(MILLISECONDS_PER_TICK); } - virtual void FindWindowPlacementAndResize(int def_width, int def_height) + void FindWindowPlacementAndResize(int def_width, int def_height) override { Window::FindWindowPlacementAndResize(_toolbar_width, def_height); } - virtual void OnPaint() + void OnPaint() override { /* If spectator, disable all construction buttons * ie : Build road, rail, ships, airports and landscaping * Since enabled state is the default, just disable when needed */ - this->SetWidgetsDisabledState(_local_company == COMPANY_SPECTATOR, WID_TN_RAILS, WID_TN_ROADS, WID_TN_WATER, WID_TN_AIR, WID_TN_LANDSCAPE, WIDGET_LIST_END); + this->SetWidgetsDisabledState(_local_company == COMPANY_SPECTATOR, WID_TN_RAILS, WID_TN_ROADS, WID_TN_TRAMS, WID_TN_WATER, WID_TN_AIR, WID_TN_LANDSCAPE, WIDGET_LIST_END); /* disable company list drop downs, if there are no companies */ this->SetWidgetsDisabledState(Company::GetNumItems() == 0, WID_TN_STATIONS, WID_TN_FINANCES, WID_TN_TRAINS, WID_TN_ROADVEHS, WID_TN_SHIPS, WID_TN_AIRCRAFT, WIDGET_LIST_END); @@ -2732,19 +2752,21 @@ struct MainToolbarWindow : Window { this->SetWidgetDisabledState(WID_TN_STORY, StoryPage::GetNumItems() == 0); this->SetWidgetDisabledState(WID_TN_RAILS, !CanBuildVehicleInfrastructure(VEH_TRAIN)); + this->SetWidgetDisabledState(WID_TN_ROADS, !CanBuildVehicleInfrastructure(VEH_ROAD, RTT_ROAD)); + this->SetWidgetDisabledState(WID_TN_TRAMS, !CanBuildVehicleInfrastructure(VEH_ROAD, RTT_TRAM)); this->SetWidgetDisabledState(WID_TN_AIR, !CanBuildVehicleInfrastructure(VEH_AIRCRAFT)); this->DrawWidgets(); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { if (clickedFlag) *clickedFlag = clickedValue; if (_game_mode != GM_MENU && !this->IsWidgetDisabled(widget)) _toolbar_button_procs[widget](this); } - virtual void OnDropdownSelect(int widget, int index) + void OnDropdownSelect(int widget, int index) override { if (clickedFlag) *clickedFlag = clickedValue; @@ -2752,7 +2774,7 @@ struct MainToolbarWindow : Window { if (cbf != CBF_NONE) _last_started_action = cbf; } - virtual EventState OnHotkey(int hotkey) + EventState OnHotkey(int hotkey) override { switch (hotkey) { case MTHK_PAUSE: ToolbarPauseClick(this); break; @@ -2779,28 +2801,27 @@ struct MainToolbarWindow : Window { case MTHK_ZOOM_OUT: ToolbarZoomOutClick(this); break; case MTHK_BUILD_RAIL: if (CanBuildVehicleInfrastructure(VEH_TRAIN)) ShowBuildRailToolbar(_last_built_railtype); break; case MTHK_BUILD_ROAD: ShowBuildRoadToolbar(_last_built_roadtype); break; + case MTHK_BUILD_TRAM: if (CanBuildVehicleInfrastructure(VEH_ROAD, RTT_TRAM)) ShowBuildRoadToolbar(_last_built_tramtype); break; case MTHK_BUILD_DOCKS: ShowBuildDocksToolbar(); break; case MTHK_BUILD_AIRPORT: if (CanBuildVehicleInfrastructure(VEH_AIRCRAFT)) ShowBuildAirToolbar(); break; case MTHK_BUILD_TREES: ShowBuildTreesToolbar(); break; case MTHK_MUSIC: ShowMusicWindow(); break; case MTHK_AI_DEBUG: ShowAIDebugWindow(); break; - case MTHK_SMALL_SCREENSHOT: MenuClickSmallScreenshot(); break; - case MTHK_ZOOMEDIN_SCREENSHOT: MenuClickLargeWorldScreenshot(SC_ZOOMEDIN); break; - case MTHK_DEFAULTZOOM_SCREENSHOT: MenuClickLargeWorldScreenshot(SC_DEFAULTZOOM); break; - case MTHK_GIANT_SCREENSHOT: MenuClickLargeWorldScreenshot(SC_WORLD); break; + case MTHK_SMALL_SCREENSHOT: MenuClickScreenshot(SC_VIEWPORT); break; + case MTHK_ZOOMEDIN_SCREENSHOT: MenuClickScreenshot(SC_ZOOMEDIN); break; + case MTHK_DEFAULTZOOM_SCREENSHOT: MenuClickScreenshot(SC_DEFAULTZOOM); break; + case MTHK_GIANT_SCREENSHOT: MenuClickScreenshot(SC_WORLD); break; case MTHK_CHEATS: if (!_networking) ShowCheatWindow(); break; case MTHK_TERRAFORM: ShowTerraformToolbar(); break; case MTHK_EXTRA_VIEWPORT: ShowExtraViewPortWindowForTileUnderCursor(); break; -#ifdef ENABLE_NETWORK case MTHK_CLIENT_LIST: if (_networking) ShowClientList(); break; -#endif case MTHK_SIGN_LIST: ShowSignList(); break; default: return ES_NOT_HANDLED; } return ES_HANDLED; } - virtual void OnPlaceObject(Point pt, TileIndex tile) + void OnPlaceObject(Point pt, TileIndex tile) override { switch (_last_started_action) { case CBF_PLACE_SIGN: @@ -2815,12 +2836,12 @@ struct MainToolbarWindow : Window { } } - virtual void OnPlaceObjectAbort() + void OnPlaceObjectAbort() override { _last_started_action = CBF_NONE; } - virtual void OnRealtimeTick(uint delta_ms) + void OnRealtimeTick(uint delta_ms) override { if (!this->timer.Elapsed(delta_ms)) return; this->timer.SetInterval(MILLISECONDS_PER_TICK); @@ -2836,7 +2857,7 @@ struct MainToolbarWindow : Window { } } - virtual void OnTimeout() + void OnTimeout() override { /* We do not want to automatically raise the pause, fast forward and * switchbar buttons; they have to stay down when pressed etc. */ @@ -2853,10 +2874,10 @@ struct MainToolbarWindow : Window { * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; - if (FindWindowById(WC_MAIN_WINDOW, 0) != NULL) HandleZoomMessage(this, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, WID_TN_ZOOM_IN, WID_TN_ZOOM_OUT); + if (FindWindowById(WC_MAIN_WINDOW, 0) != nullptr) HandleZoomMessage(this, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, WID_TN_ZOOM_IN, WID_TN_ZOOM_OUT); } static HotkeyList hotkeys; @@ -2892,6 +2913,7 @@ static Hotkey maintoolbar_hotkeys[] = { Hotkey(_maintoolbar_zoomout_keys, "zoomout", MTHK_ZOOM_OUT), Hotkey(WKC_SHIFT | WKC_F7, "build_rail", MTHK_BUILD_RAIL), Hotkey(WKC_SHIFT | WKC_F8, "build_road", MTHK_BUILD_ROAD), + Hotkey((uint16)0, "build_tram", MTHK_BUILD_TRAM), Hotkey(WKC_SHIFT | WKC_F9, "build_docks", MTHK_BUILD_DOCKS), Hotkey(WKC_SHIFT | WKC_F10, "build_airport", MTHK_BUILD_AIRPORT), Hotkey(WKC_SHIFT | WKC_F11, "build_trees", MTHK_BUILD_TREES), @@ -2904,50 +2926,49 @@ static Hotkey maintoolbar_hotkeys[] = { Hotkey(WKC_CTRL | WKC_ALT | 'C', "cheats", MTHK_CHEATS), Hotkey('L', "terraform", MTHK_TERRAFORM), Hotkey('V', "extra_viewport", MTHK_EXTRA_VIEWPORT), -#ifdef ENABLE_NETWORK Hotkey((uint16)0, "client_list", MTHK_CLIENT_LIST), -#endif Hotkey((uint16)0, "sign_list", MTHK_SIGN_LIST), HOTKEY_LIST_END }; HotkeyList MainToolbarWindow::hotkeys("maintoolbar", maintoolbar_hotkeys); -/** Sprites to use for the different toolbar buttons */ -static const SpriteID _toolbar_button_sprites[] = { - SPR_IMG_PAUSE, // WID_TN_PAUSE - SPR_IMG_FASTFORWARD, // WID_TN_FAST_FORWARD - SPR_IMG_SETTINGS, // WID_TN_SETTINGS - SPR_IMG_SAVE, // WID_TN_SAVE - SPR_IMG_SMALLMAP, // WID_TN_SMALL_MAP - SPR_IMG_TOWN, // WID_TN_TOWNS - SPR_IMG_SUBSIDIES, // WID_TN_SUBSIDIES - SPR_IMG_COMPANY_LIST, // WID_TN_STATIONS - SPR_IMG_COMPANY_FINANCE, // WID_TN_FINANCES - SPR_IMG_COMPANY_GENERAL, // WID_TN_COMPANIES - SPR_IMG_STORY_BOOK, // WID_TN_STORY - SPR_IMG_GOAL, // WID_TN_GOAL - SPR_IMG_GRAPHS, // WID_TN_GRAPHS - SPR_IMG_COMPANY_LEAGUE, // WID_TN_LEAGUE - SPR_IMG_INDUSTRY, // WID_TN_INDUSTRIES - SPR_IMG_TRAINLIST, // WID_TN_TRAINS - SPR_IMG_TRUCKLIST, // WID_TN_ROADVEHS - SPR_IMG_SHIPLIST, // WID_TN_SHIPS - SPR_IMG_AIRPLANESLIST, // WID_TN_AIRCRAFT - SPR_IMG_ZOOMIN, // WID_TN_ZOOMIN - SPR_IMG_ZOOMOUT, // WID_TN_ZOOMOUT - SPR_IMG_BUILDRAIL, // WID_TN_RAILS - SPR_IMG_BUILDROAD, // WID_TN_ROADS - SPR_IMG_BUILDWATER, // WID_TN_WATER - SPR_IMG_BUILDAIR, // WID_TN_AIR - SPR_IMG_LANDSCAPING, // WID_TN_LANDSCAPE - SPR_IMG_MUSIC, // WID_TN_MUSIC_SOUND - SPR_IMG_MESSAGES, // WID_TN_MESSAGES - SPR_IMG_QUERY, // WID_TN_HELP - SPR_IMG_SWITCH_TOOLBAR, // WID_TN_SWITCH_BAR -}; - static NWidgetBase *MakeMainToolbar(int *biggest_index) { + /** Sprites to use for the different toolbar buttons */ + static const SpriteID toolbar_button_sprites[] = { + SPR_IMG_PAUSE, // WID_TN_PAUSE + SPR_IMG_FASTFORWARD, // WID_TN_FAST_FORWARD + SPR_IMG_SETTINGS, // WID_TN_SETTINGS + SPR_IMG_SAVE, // WID_TN_SAVE + SPR_IMG_SMALLMAP, // WID_TN_SMALL_MAP + SPR_IMG_TOWN, // WID_TN_TOWNS + SPR_IMG_SUBSIDIES, // WID_TN_SUBSIDIES + SPR_IMG_COMPANY_LIST, // WID_TN_STATIONS + SPR_IMG_COMPANY_FINANCE, // WID_TN_FINANCES + SPR_IMG_COMPANY_GENERAL, // WID_TN_COMPANIES + SPR_IMG_STORY_BOOK, // WID_TN_STORY + SPR_IMG_GOAL, // WID_TN_GOAL + SPR_IMG_GRAPHS, // WID_TN_GRAPHS + SPR_IMG_COMPANY_LEAGUE, // WID_TN_LEAGUE + SPR_IMG_INDUSTRY, // WID_TN_INDUSTRIES + SPR_IMG_TRAINLIST, // WID_TN_TRAINS + SPR_IMG_TRUCKLIST, // WID_TN_ROADVEHS + SPR_IMG_SHIPLIST, // WID_TN_SHIPS + SPR_IMG_AIRPLANESLIST, // WID_TN_AIRCRAFT + SPR_IMG_ZOOMIN, // WID_TN_ZOOMIN + SPR_IMG_ZOOMOUT, // WID_TN_ZOOMOUT + SPR_IMG_BUILDRAIL, // WID_TN_RAILS + SPR_IMG_BUILDROAD, // WID_TN_ROADS + SPR_IMG_BUILDTRAMS, // WID_TN_TRAMS + SPR_IMG_BUILDWATER, // WID_TN_WATER + SPR_IMG_BUILDAIR, // WID_TN_AIR + SPR_IMG_LANDSCAPING, // WID_TN_LANDSCAPE + SPR_IMG_MUSIC, // WID_TN_MUSIC_SOUND + SPR_IMG_MESSAGES, // WID_TN_MESSAGES + SPR_IMG_QUERY, // WID_TN_HELP + SPR_IMG_SWITCH_TOOLBAR, // WID_TN_SWITCH_BAR + }; + NWidgetMainToolbarContainer *hor = new NWidgetMainToolbarContainer(); for (uint i = 0; i <= WID_TN_SWITCH_BAR; i++) { switch (i) { @@ -2977,7 +2998,7 @@ static const NWidgetPart _nested_toolbar_normal_widgets[] = { }; static WindowDesc _toolb_normal_desc( - WDP_MANUAL, NULL, 0, 0, + WDP_MANUAL, nullptr, 0, 0, WC_MAIN_TOOLBAR, WC_NONE, WDF_NO_FOCUS, _nested_toolbar_normal_widgets, lengthof(_nested_toolbar_normal_widgets), @@ -3040,6 +3061,32 @@ static WindowDesc _toolb_vertical_right_desc( /* --- Toolbar handling for the scenario editor */ +static MenuClickedProc * const _scen_toolbar_dropdown_procs[] = { + nullptr, // 0 + nullptr, // 1 + MenuClickSettings, // 2 + MenuClickSaveLoad, // 3 + nullptr, // 4 + nullptr, // 5 + nullptr, // 6 + nullptr, // 7 + MenuClickMap, // 8 + nullptr, // 9 + nullptr, // 10 + nullptr, // 11 + nullptr, // 12 + nullptr, // 13 + ToolbarScenBuildRoad, // 14 + ToolbarScenBuildTram, // 15 + nullptr, // 16 + nullptr, // 17 + nullptr, // 18 + nullptr, // 19 + MenuClickMusicWindow, // 20 + MenuClickHelp, // 21 + nullptr, // 22 +}; + static ToolbarButtonProc * const _scen_toolbar_button_procs[] = { ToolbarPauseClick, ToolbarFastForwardClick, @@ -3055,20 +3102,13 @@ static ToolbarButtonProc * const _scen_toolbar_button_procs[] = { ToolbarScenGenLand, ToolbarScenGenTown, ToolbarScenGenIndustry, - ToolbarScenBuildRoad, + ToolbarScenBuildRoadClick, + ToolbarScenBuildTramClick, ToolbarScenBuildDocks, ToolbarScenPlantTrees, ToolbarScenPlaceSign, ToolbarBtn_NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL, ToolbarMusicClick, - NULL, ToolbarHelpClick, ToolbarSwitchClick, }; @@ -3082,6 +3122,7 @@ enum MainToolbarEditorHotkeys { MTEHK_GENTOWN, MTEHK_GENINDUSTRY, MTEHK_BUILD_ROAD, + MTEHK_BUILD_TRAM, MTEHK_BUILD_DOCKS, MTEHK_BUILD_TREES, MTEHK_SIGN, @@ -3113,20 +3154,22 @@ struct ScenarioEditorToolbarWindow : Window { this->timer.SetInterval(MILLISECONDS_PER_TICK); } - virtual void FindWindowPlacementAndResize(int def_width, int def_height) + void FindWindowPlacementAndResize(int def_width, int def_height) override { Window::FindWindowPlacementAndResize(_toolbar_width, def_height); } - virtual void OnPaint() + void OnPaint() override { this->SetWidgetDisabledState(WID_TE_DATE_BACKWARD, _settings_game.game_creation.starting_year <= MIN_YEAR); this->SetWidgetDisabledState(WID_TE_DATE_FORWARD, _settings_game.game_creation.starting_year >= MAX_YEAR); + this->SetWidgetDisabledState(WID_TE_ROADS, (GetRoadTypes(true) & ~_roadtypes_type) == ROADTYPES_NONE); + this->SetWidgetDisabledState(WID_TE_TRAMS, (GetRoadTypes(true) & _roadtypes_type) == ROADTYPES_NONE); this->DrawWidgets(); } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { switch (widget) { case WID_TE_DATE: @@ -3147,7 +3190,7 @@ struct ScenarioEditorToolbarWindow : Window { } } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_TE_SPACER: @@ -3162,24 +3205,21 @@ struct ScenarioEditorToolbarWindow : Window { } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { if (_game_mode == GM_MENU) return; CallBackFunction cbf = _scen_toolbar_button_procs[widget](this); if (cbf != CBF_NONE) _last_started_action = cbf; } - virtual void OnDropdownSelect(int widget, int index) + void OnDropdownSelect(int widget, int index) override { - /* The map button is in a different location on the scenario - * editor toolbar, so we need to adjust for it. */ - if (widget == WID_TE_SMALL_MAP) widget = WID_TN_SMALL_MAP; - CallBackFunction cbf = _menu_clicked_procs[widget](index); + CallBackFunction cbf = _scen_toolbar_dropdown_procs[widget](index); if (cbf != CBF_NONE) _last_started_action = cbf; if (_settings_client.sound.click_beep) SndPlayFx(SND_15_BEEP); } - virtual EventState OnHotkey(int hotkey) + EventState OnHotkey(int hotkey) override { CallBackFunction cbf = CBF_NONE; switch (hotkey) { @@ -3190,16 +3230,17 @@ struct ScenarioEditorToolbarWindow : Window { case MTEHK_GENLAND: ToolbarScenGenLand(this); break; case MTEHK_GENTOWN: ToolbarScenGenTown(this); break; case MTEHK_GENINDUSTRY: ToolbarScenGenIndustry(this); break; - case MTEHK_BUILD_ROAD: ToolbarScenBuildRoad(this); break; + case MTEHK_BUILD_ROAD: ToolbarScenBuildRoadClick(this); break; + case MTEHK_BUILD_TRAM: ToolbarScenBuildTramClick(this); break; case MTEHK_BUILD_DOCKS: ToolbarScenBuildDocks(this); break; case MTEHK_BUILD_TREES: ToolbarScenPlantTrees(this); break; case MTEHK_SIGN: cbf = ToolbarScenPlaceSign(this); break; case MTEHK_MUSIC: ShowMusicWindow(); break; case MTEHK_LANDINFO: cbf = PlaceLandBlockInfo(); break; - case MTEHK_SMALL_SCREENSHOT: MenuClickSmallScreenshot(); break; - case MTEHK_ZOOMEDIN_SCREENSHOT: MenuClickLargeWorldScreenshot(SC_ZOOMEDIN); break; - case MTEHK_DEFAULTZOOM_SCREENSHOT: MenuClickLargeWorldScreenshot(SC_DEFAULTZOOM); break; - case MTEHK_GIANT_SCREENSHOT: MenuClickLargeWorldScreenshot(SC_WORLD); break; + case MTEHK_SMALL_SCREENSHOT: MenuClickScreenshot(SC_VIEWPORT); break; + case MTEHK_ZOOMEDIN_SCREENSHOT: MenuClickScreenshot(SC_ZOOMEDIN); break; + case MTEHK_DEFAULTZOOM_SCREENSHOT: MenuClickScreenshot(SC_DEFAULTZOOM); break; + case MTEHK_GIANT_SCREENSHOT: MenuClickScreenshot(SC_WORLD); break; case MTEHK_ZOOM_IN: ToolbarZoomInClick(this); break; case MTEHK_ZOOM_OUT: ToolbarZoomOutClick(this); break; case MTEHK_TERRAFORM: ShowEditorTerraformToolbar(); break; @@ -3211,7 +3252,7 @@ struct ScenarioEditorToolbarWindow : Window { return ES_HANDLED; } - virtual void OnPlaceObject(Point pt, TileIndex tile) + void OnPlaceObject(Point pt, TileIndex tile) override { switch (_last_started_action) { case CBF_PLACE_SIGN: @@ -3226,19 +3267,19 @@ struct ScenarioEditorToolbarWindow : Window { } } - virtual void OnPlaceObjectAbort() + void OnPlaceObjectAbort() override { _last_started_action = CBF_NONE; } - virtual void OnTimeout() + void OnTimeout() override { this->SetWidgetsLoweredState(false, WID_TE_DATE_BACKWARD, WID_TE_DATE_FORWARD, WIDGET_LIST_END); this->SetWidgetDirty(WID_TE_DATE_BACKWARD); this->SetWidgetDirty(WID_TE_DATE_FORWARD); } - virtual void OnRealtimeTick(uint delta_ms) + void OnRealtimeTick(uint delta_ms) override { if (!this->timer.Elapsed(delta_ms)) return; this->timer.SetInterval(MILLISECONDS_PER_TICK); @@ -3259,16 +3300,16 @@ struct ScenarioEditorToolbarWindow : Window { * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; - if (FindWindowById(WC_MAIN_WINDOW, 0) != NULL) HandleZoomMessage(this, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, WID_TE_ZOOM_IN, WID_TE_ZOOM_OUT); + if (FindWindowById(WC_MAIN_WINDOW, 0) != nullptr) HandleZoomMessage(this, FindWindowById(WC_MAIN_WINDOW, 0)->viewport, WID_TE_ZOOM_IN, WID_TE_ZOOM_OUT); } - virtual void OnQueryTextFinished(char *str) + void OnQueryTextFinished(char *str) override { /* Was 'cancel' pressed? */ - if (str == NULL) return; + if (str == nullptr) return; int32 value; if (!StrEmpty(str)) { @@ -3294,6 +3335,7 @@ static Hotkey scenedit_maintoolbar_hotkeys[] = { Hotkey(WKC_F5, "gen_town", MTEHK_GENTOWN), Hotkey(WKC_F6, "gen_industry", MTEHK_GENINDUSTRY), Hotkey(WKC_F7, "build_road", MTEHK_BUILD_ROAD), + Hotkey((uint16)0, "build_tram", MTEHK_BUILD_TRAM), Hotkey(WKC_F8, "build_docks", MTEHK_BUILD_DOCKS), Hotkey(WKC_F9, "build_trees", MTEHK_BUILD_TREES), Hotkey(WKC_F10, "build_sign", MTEHK_SIGN), @@ -3337,6 +3379,7 @@ static const NWidgetPart _nested_toolb_scen_inner_widgets[] = { NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_TOWN_GENERATE), SetDataTip(SPR_IMG_TOWN, STR_SCENEDIT_TOOLBAR_TOWN_GENERATION), NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_INDUSTRY), SetDataTip(SPR_IMG_INDUSTRY, STR_SCENEDIT_TOOLBAR_INDUSTRY_GENERATION), NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_ROADS), SetDataTip(SPR_IMG_BUILDROAD, STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION), + NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_TRAMS), SetDataTip(SPR_IMG_BUILDTRAMS, STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION), NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_WATER), SetDataTip(SPR_IMG_BUILDWATER, STR_TOOLBAR_TOOLTIP_BUILD_SHIP_DOCKS), NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_TREES), SetDataTip(SPR_IMG_PLANTTREES, STR_SCENEDIT_TOOLBAR_PLANT_TREES), NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_TE_SIGNS), SetDataTip(SPR_IMG_SIGN, STR_SCENEDIT_TOOLBAR_PLACE_SIGN), @@ -3356,7 +3399,7 @@ static const NWidgetPart _nested_toolb_scen_widgets[] = { }; static WindowDesc _toolb_scen_desc( - WDP_MANUAL, NULL, 0, 0, + WDP_MANUAL, nullptr, 0, 0, WC_MAIN_TOOLBAR, WC_NONE, WDF_NO_FOCUS, _nested_toolb_scen_widgets, lengthof(_nested_toolb_scen_widgets), @@ -3368,6 +3411,7 @@ void AllocateToolbar() { /* Clean old GUI values; railtype is (re)set by rail_gui.cpp */ _last_built_roadtype = ROADTYPE_ROAD; + _last_built_tramtype = ROADTYPE_TRAM; if (_game_mode == GM_EDITOR) { new ScenarioEditorToolbarWindow(&_toolb_scen_desc); diff --git a/src/toolbar_gui.h b/src/toolbar_gui.h index 69cb3bba6d..039d89debb 100644 --- a/src/toolbar_gui.h +++ b/src/toolbar_gui.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/town.h b/src/town.h index a905ea837b..8399fa63f3 100644 --- a/src/town.h +++ b/src/town.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. @@ -36,7 +34,7 @@ static const TownID INVALID_TOWN = 0xFFFF; static const uint TOWN_GROWTH_WINTER = 0xFFFFFFFE; ///< The town only needs this cargo in the winter (any amount) static const uint TOWN_GROWTH_DESERT = 0xFFFFFFFF; ///< The town needs the cargo for growth when on desert (any amount) static const uint16 TOWN_GROWTH_RATE_NONE = 0xFFFF; ///< Special value for Town::growth_rate to disable town growth. -static const uint16 MAX_TOWN_GROWTH_TICKS = 930; ///< Max amount of original town ticks that still fit into uint16, about equal to UINT16_MAX / TOWN_GROWTH_TICKS but sligtly less to simplify calculations +static const uint16 MAX_TOWN_GROWTH_TICKS = 930; ///< Max amount of original town ticks that still fit into uint16, about equal to UINT16_MAX / TOWN_GROWTH_TICKS but slightly less to simplify calculations typedef Pool TownPool; extern TownPool _town_pool; @@ -45,8 +43,8 @@ extern TownPool _town_pool; struct TownCache { uint32 num_houses; ///< Amount of houses uint32 population; ///< Current population of people - ViewportSign sign; ///< Location of name sign, UpdateVirtCoord updates this - PartOfSubsidyByte part_of_subsidy; ///< Is this town a source/destination of a subsidy? + TrackedViewportSign sign; ///< Location of name sign, UpdateVirtCoord updates this + PartOfSubsidy part_of_subsidy; ///< Is this town a source/destination of a subsidy? uint32 squared_town_zone_radius[HZB_END]; ///< UpdateTownRadius updates this given the house count BuildingCounts building_counts; ///< The number of each type of building in the town }; @@ -61,7 +59,8 @@ struct Town : TownPool::PoolItem<&_town_pool> { uint32 townnamegrfid; uint16 townnametype; uint32 townnameparts; - char *name; ///< Custom town name. If NULL, the town was not renamed and uses the generated name. + char *name; ///< Custom town name. If nullptr, the town was not renamed and uses the generated name. + mutable std::string cached_name; ///< NOSAVE: Cache of the resolved name of the town, if not using a custom town name byte flags; ///< See #TownFlags. @@ -72,7 +71,7 @@ struct Town : TownPool::PoolItem<&_town_pool> { /* Company ratings. */ CompanyMask have_ratings; ///< which companies have a rating uint8 unwanted[MAX_COMPANIES]; ///< how many months companies aren't wanted by towns (bribe) - CompanyByte exclusivity; ///< which company has exclusivity + CompanyID exclusivity; ///< which company has exclusivity uint8 exclusive_counter; ///< months till the exclusivity expires int16 ratings[MAX_COMPANIES]; ///< ratings of each company for this town @@ -88,17 +87,20 @@ struct Town : TownPool::PoolItem<&_town_pool> { CargoTypes cargo_produced; ///< Bitmap of all cargoes produced by houses in this town. AcceptanceMatrix cargo_accepted; ///< Bitmap of cargoes accepted by houses for each 4*4 map square of the town. CargoTypes cargo_accepted_total; ///< NOSAVE: Bitmap of all cargoes accepted by houses in this town. + StationList stations_near; ///< NOSAVE: List of nearby stations. - uint16 time_until_rebuild; ///< time until we rebuild a house + uint16 time_until_rebuild; ///< time until we rebuild a house - uint16 grow_counter; ///< counter to count when to grow, value is smaller than or equal to growth_rate - uint16 growth_rate; ///< town growth rate + uint16 grow_counter; ///< counter to count when to grow, value is smaller than or equal to growth_rate + uint16 growth_rate; ///< town growth rate - byte fund_buildings_months; ///< fund buildings program in action? - byte road_build_months; ///< fund road reconstruction in action? + byte fund_buildings_months; ///< fund buildings program in action? + byte road_build_months; ///< fund road reconstruction in action? - bool larger_town; ///< if this is a larger town and should grow more quickly - TownLayoutByte layout; ///< town specific road layout + bool larger_town; ///< if this is a larger town and should grow more quickly + TownLayout layout; ///< town specific road layout + + bool show_zone; ///< NOSAVE: mark town to show the local authority zone in the viewports std::list psa_list; @@ -129,6 +131,13 @@ struct Town : TownPool::PoolItem<&_town_pool> { void UpdateVirtCoord(); + inline const char *GetCachedName() const + { + if (this->name != nullptr) return this->name; + if (this->cached_name.empty()) this->FillCachedName(); + return this->cached_name.c_str(); + } + static inline Town *GetByTile(TileIndex tile) { return Town::Get(GetTownIndex(tile)); @@ -136,14 +145,21 @@ struct Town : TownPool::PoolItem<&_town_pool> { static Town *GetRandom(); static void PostDestructor(size_t index); + +private: + void FillCachedName() const; }; uint32 GetWorldPopulation(); void UpdateAllTownVirtCoords(); +void ClearAllTownCachedNames(); void ShowTownViewWindow(TownID town); void ExpandTown(Town *t); +void RebuildTownKdtree(); + + /** * Action types that a company must ask permission for to a town authority. * @see CheckforTownRating @@ -154,6 +170,13 @@ enum TownRatingCheckType { TOWN_RATING_CHECK_TYPE_COUNT, ///< Number of town checking action types. }; +/** Special values for town list window for the data parameter of #InvalidateWindowData. */ +enum TownDirectoryInvalidateWindowData { + TDIWD_FORCE_REBUILD, + TDIWD_POPULATION_CHANGE, + TDIWD_FORCE_RESORT, +}; + /** * This enum is used in conjunction with town->flags. * IT simply states what bit is used for. @@ -175,9 +198,6 @@ TileIndexDiff GetHouseNorthPart(HouseID &house); Town *CalcClosestTownFromTile(TileIndex tile, uint threshold = UINT_MAX); -#define FOR_ALL_TOWNS_FROM(var, start) FOR_ALL_ITEMS_FROM(Town, town_index, var, start) -#define FOR_ALL_TOWNS(var) FOR_ALL_TOWNS_FROM(var, 0) - void ResetHouses(); void ClearTownHouse(Town *t, TileIndex tile); @@ -229,7 +249,7 @@ template void MakeDefaultName(T *obj) { /* We only want to set names if it hasn't been set before, or when we're calling from afterload. */ - assert(obj->name == NULL || obj->town_cn == UINT16_MAX); + assert(obj->name == nullptr || obj->town_cn == UINT16_MAX); obj->town = ClosestTownFromTile(obj->xy, UINT_MAX); @@ -253,7 +273,7 @@ void MakeDefaultName(T *obj) T *lobj = T::GetIfValid(cid); /* check only valid waypoints... */ - if (lobj != NULL && obj != lobj) { + if (lobj != nullptr && obj != lobj) { /* only objects within the same city and with the same type */ if (lobj->town == obj->town && lobj->IsOfType(obj)) { /* if lobj->town_cn < next, uint will overflow to '+inf' */ @@ -295,4 +315,6 @@ static inline uint16 TownTicksToGameTicks(uint16 ticks) { extern CargoTypes _town_cargoes_accepted; +RoadType GetTownRoadType(const Town *t); + #endif /* TOWN_H */ diff --git a/src/town_cmd.cpp b/src/town_cmd.cpp index 84c7d44f3a..0a582eee7f 100644 --- a/src/town_cmd.cpp +++ b/src/town_cmd.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. @@ -10,14 +8,17 @@ /** @file town_cmd.cpp Handling of town tiles. */ #include "stdafx.h" +#include "road.h" #include "road_internal.h" /* Cleaning up road bits */ #include "road_cmd.h" #include "landscape.h" #include "viewport_func.h" +#include "viewport_kdtree.h" #include "cmd_helper.h" #include "command_func.h" #include "industry.h" #include "station_base.h" +#include "station_kdtree.h" #include "company_base.h" #include "news_func.h" #include "error.h" @@ -38,6 +39,7 @@ #include "subsidy_func.h" #include "core/pool_func.hpp" #include "town.h" +#include "town_kdtree.h" #include "townname_func.h" #include "core/random_func.hpp" #include "core/backup_type.hpp" @@ -59,6 +61,44 @@ CargoTypes _town_cargoes_accepted; ///< Bitmap of all cargoes accepted by houses TownPool _town_pool("Town"); INSTANTIATE_POOL_METHODS(Town) + +TownKdtree _town_kdtree(&Kdtree_TownXYFunc); + +void RebuildTownKdtree() +{ + std::vector townids; + for (const Town *town : Town::Iterate()) { + townids.push_back(town->index); + } + _town_kdtree.Build(townids.begin(), townids.end()); +} + + +/** + * Check if a town 'owns' a bridge. + * Bridges to not directly have an owner, so we check the tiles adjacent to the bridge ends. + * If either adjacent tile belongs to the town then it will be assumed that the town built + * the bridge. + * @param tile Bridge tile to test + * @param t Town we are interested in + * @return true if town 'owns' a bridge. + */ +static bool TestTownOwnsBridge(TileIndex tile, const Town *t) +{ + if (!IsTileOwner(tile, OWNER_TOWN)) return false; + + TileIndex adjacent = tile + TileOffsByDiagDir(ReverseDiagDir(GetTunnelBridgeDirection(tile))); + bool town_owned = IsTileType(adjacent, MP_ROAD) && IsTileOwner(adjacent, OWNER_TOWN) && GetTownIndex(adjacent) == t->index; + + if (!town_owned) { + /* Or other adjacent road */ + TileIndex adjacent = tile + TileOffsByDiagDir(ReverseDiagDir(GetTunnelBridgeDirection(GetOtherTunnelBridgeEnd(tile)))); + town_owned = IsTileType(adjacent, MP_ROAD) && IsTileOwner(adjacent, OWNER_TOWN) && GetTownIndex(adjacent) == t->index; + } + + return town_owned; +} + Town::~Town() { free(this->name); @@ -71,12 +111,10 @@ Town::~Town() DeleteWindowById(WC_TOWN_VIEW, this->index); /* Check no industry is related to us. */ - const Industry *i; - FOR_ALL_INDUSTRIES(i) assert(i->town != this); + for (const Industry *i : Industry::Iterate()) assert(i->town != this); /* ... and no object is related to us. */ - const Object *o; - FOR_ALL_OBJECTS(o) assert(o->town != this); + for (const Object *o : Object::Iterate()) assert(o->town != this); /* Check no tile is related to us. */ for (TileIndex tile = 0; tile < MapSize(); ++tile) { @@ -90,7 +128,7 @@ Town::~Town() break; case MP_TUNNELBRIDGE: - assert(!IsTileOwner(tile, OWNER_TOWN) || ClosestTownFromTile(tile, UINT_MAX) != this); + assert(!TestTownOwnsBridge(tile, this)); break; default: @@ -115,13 +153,12 @@ Town::~Town() */ void Town::PostDestructor(size_t index) { - InvalidateWindowData(WC_TOWN_DIRECTORY, 0, 0); + InvalidateWindowData(WC_TOWN_DIRECTORY, 0, TDIWD_FORCE_REBUILD); UpdateNearestTownForRoadTiles(false); /* Give objects a new home! */ - Object *o; - FOR_ALL_OBJECTS(o) { - if (o->town == NULL) o->town = CalcClosestTownFromTile(o->location.tile, UINT_MAX); + for (Object *o : Object::Iterate()) { + if (o->town == nullptr) o->town = CalcClosestTownFromTile(o->location.tile, UINT_MAX); } } @@ -135,16 +172,16 @@ void Town::InitializeLayout(TownLayout layout) return; } - this->layout = TileHash(TileX(this->xy), TileY(this->xy)) % (NUM_TLS - 1); + this->layout = static_cast(TileHash(TileX(this->xy), TileY(this->xy)) % (NUM_TLS - 1)); } /** * Return a random valid town. - * @return random town, NULL if there are no towns + * @return random town, nullptr if there are no towns */ /* static */ Town *Town::GetRandom() { - if (Town::GetNumItems() == 0) return NULL; + if (Town::GetNumItems() == 0) return nullptr; int num = RandomRange((uint16)Town::GetNumItems()); size_t index = MAX_UVALUE(size_t); @@ -162,6 +199,13 @@ void Town::InitializeLayout(TownLayout layout) return Town::Get(index); } +void Town::FillCachedName() const +{ + char buf[MAX_LENGTH_TOWN_NAME_CHARS * MAX_CHAR_LENGTH]; + char *end = GetTownName(buf, this, lastof(buf)); + this->cached_name.assign(buf, end); +} + /** * Get the cost for removing this house * @return the cost (inflation corrected etc) @@ -217,7 +261,7 @@ static void DrawTile_Town(TileInfo *ti) /* Houses don't necessarily need new graphics. If they don't have a * spritegroup associated with them, then the sprite for the substitute * house id is drawn instead. */ - if (HouseSpec::Get(house_id)->grf_prop.spritegroup[0] != NULL) { + if (HouseSpec::Get(house_id)->grf_prop.spritegroup[0] != nullptr) { DrawNewHouseTile(ti, house_id); return; } else { @@ -274,7 +318,7 @@ static Foundation GetFoundation_Town(TileIndex tile, Slope tileh) */ if (hid >= NEW_HOUSE_OFFSET) { const HouseSpec *hs = HouseSpec::Get(hid); - if (hs->grf_prop.spritegroup[0] != NULL && HasBit(hs->callback_mask, CBM_HOUSE_DRAW_FOUNDATIONS)) { + if (hs->grf_prop.spritegroup[0] != nullptr && HasBit(hs->callback_mask, CBM_HOUSE_DRAW_FOUNDATIONS)) { uint32 callback_res = GetHouseCallback(CBID_HOUSE_DRAW_FOUNDATIONS, 0, 0, hid, Town::GetByTile(tile), tile); if (callback_res != CALLBACK_FAILED && !ConvertBooleanCallback(hs->grf_prop.grffile, CBID_HOUSE_DRAW_FOUNDATIONS, callback_res)) return FOUNDATION_NONE; } @@ -341,30 +385,9 @@ static void AnimateTile_Town(TileIndex tile) */ static bool IsCloseToTown(TileIndex tile, uint dist) { - /* On a large map with many towns, it may be faster to check the surroundings of the tile. - * An iteration in TILE_AREA_LOOP() is generally 2 times faster than one in FOR_ALL_TOWNS(). */ - if (Town::GetNumItems() > (size_t) (dist * dist * 2)) { - const int tx = TileX(tile); - const int ty = TileY(tile); - TileArea tile_area = TileArea( - TileXY(max(0, tx - (int) dist), max(0, ty - (int) dist)), - TileXY(min(MapMaxX(), tx + (int) dist), min(MapMaxY(), ty + (int) dist)) - ); - TILE_AREA_LOOP(atile, tile_area) { - if (GetTileType(atile) == MP_HOUSE) { - Town *t = Town::GetByTile(atile); - if (DistanceManhattan(tile, t->xy) < dist) return true; - } - } - return false; - } - - const Town *t; - - FOR_ALL_TOWNS(t) { - if (DistanceManhattan(tile, t->xy) < dist) return true; - } - return false; + if (_town_kdtree.Count() == 0) return false; + Town *t = Town::Get(_town_kdtree.FindNearest(TileX(tile), TileY(tile))); + return DistanceManhattan(tile, t->xy) < dist; } /** @@ -374,25 +397,35 @@ static bool IsCloseToTown(TileIndex tile, uint dist) void Town::UpdateVirtCoord() { Point pt = RemapCoords2(TileX(this->xy) * TILE_SIZE, TileY(this->xy) * TILE_SIZE); + + if (this->cache.sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeTown(this->index)); + SetDParam(0, this->index); 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); + _viewport_sign_kdtree.Insert(ViewportSignKdtreeItem::MakeTown(this->index)); + SetWindowDirty(WC_TOWN_VIEW, this->index); } /** Update the virtual coords needed to draw the town sign for all towns. */ void UpdateAllTownVirtCoords() { - Town *t; - - FOR_ALL_TOWNS(t) { + for (Town *t : Town::Iterate()) { t->UpdateVirtCoord(); } } +void ClearAllTownCachedNames() +{ + for (Town *t : Town::Iterate()) { + t->cached_name.clear(); + } +} + /** * Change the towns population * @param t Town which population has changed @@ -402,9 +435,9 @@ static void ChangePopulation(Town *t, int mod) { t->cache.population += mod; InvalidateWindowData(WC_TOWN_VIEW, t->index); // Cargo requirements may appear/vanish for small populations - t->UpdateVirtCoord(); + if (_settings_client.gui.population_in_label) t->UpdateVirtCoord(); - InvalidateWindowData(WC_TOWN_DIRECTORY, 0, 1); + InvalidateWindowData(WC_TOWN_DIRECTORY, 0, TDIWD_POPULATION_CHANGE); } /** @@ -415,12 +448,26 @@ static void ChangePopulation(Town *t, int mod) uint32 GetWorldPopulation() { uint32 pop = 0; - const Town *t; - - FOR_ALL_TOWNS(t) pop += t->cache.population; + for (const Town *t : Town::Iterate()) pop += t->cache.population; return pop; } +/** + * Remove stations from nearby station list if a town is no longer in the catchment area of each. + * @param t Town to work on + */ +static void RemoveNearbyStations(Town *t) +{ + for (StationList::iterator it = t->stations_near.begin(); it != t->stations_near.end(); /* incremented inside loop */) { + const Station *st = *it; + if (!st->CatchmentCoversTown(t->index)) { + it = t->stations_near.erase(it); + } else { + ++it; + } + } +} + /** * Helper function for house completion stages progression * @param tile TileIndex of the house (or parts of it) to "grow" @@ -511,24 +558,58 @@ static void TileLoop_Town(TileIndex tile) t->supplied[cs->Index()].new_act += moved; } } else { - if (GB(r, 0, 8) < hs->population) { - uint amt = GB(r, 0, 8) / 8 + 1; + switch (_settings_game.economy.town_cargogen_mode) { + case TCGM_ORIGINAL: + /* Original (quadratic) cargo generation algorithm */ + if (GB(r, 0, 8) < hs->population) { + uint amt = GB(r, 0, 8) / 8 + 1; - if (EconomyIsInRecession()) amt = (amt + 1) >> 1; - t->supplied[CT_PASSENGERS].new_max += amt; - t->supplied[CT_PASSENGERS].new_act += MoveGoodsToStation(CT_PASSENGERS, amt, ST_TOWN, t->index, stations.GetStations()); - } + if (EconomyIsInRecession()) amt = (amt + 1) >> 1; + t->supplied[CT_PASSENGERS].new_max += amt; + t->supplied[CT_PASSENGERS].new_act += MoveGoodsToStation(CT_PASSENGERS, amt, ST_TOWN, t->index, stations.GetStations()); + } - if (GB(r, 8, 8) < hs->mail_generation) { - uint amt = GB(r, 8, 8) / 8 + 1; + if (GB(r, 8, 8) < hs->mail_generation) { + uint amt = GB(r, 8, 8) / 8 + 1; - if (EconomyIsInRecession()) amt = (amt + 1) >> 1; - t->supplied[CT_MAIL].new_max += amt; - t->supplied[CT_MAIL].new_act += MoveGoodsToStation(CT_MAIL, amt, ST_TOWN, t->index, stations.GetStations()); + if (EconomyIsInRecession()) amt = (amt + 1) >> 1; + t->supplied[CT_MAIL].new_max += amt; + t->supplied[CT_MAIL].new_act += MoveGoodsToStation(CT_MAIL, amt, ST_TOWN, t->index, stations.GetStations()); + } + break; + + case TCGM_BITCOUNT: + /* Binomial distribution per tick, by a series of coin flips */ + /* Reduce generation rate to a 1/4, using tile bits to spread out distribution. + * As tick counter is incremented by 256 between each call, we ignore the lower 8 bits. */ + if (GB(_tick_counter, 8, 2) == GB(tile, 0, 2)) { + /* Make a bitmask with up to 32 bits set, one for each potential pax */ + int genmax = (hs->population + 7) / 8; + uint32 genmask = (genmax >= 32) ? 0xFFFFFFFF : ((1 << genmax) - 1); + /* Mask random value by potential pax and count number of actual pax */ + uint amt = CountBits(r & genmask); + /* Adjust and apply */ + if (EconomyIsInRecession()) amt = (amt + 1) >> 1; + t->supplied[CT_PASSENGERS].new_max += amt; + t->supplied[CT_PASSENGERS].new_act += MoveGoodsToStation(CT_PASSENGERS, amt, ST_TOWN, t->index, stations.GetStations()); + + /* Do the same for mail, with a fresh random */ + r = Random(); + genmax = (hs->mail_generation + 7) / 8; + genmask = (genmax >= 32) ? 0xFFFFFFFF : ((1 << genmax) - 1); + amt = CountBits(r & genmask); + if (EconomyIsInRecession()) amt = (amt + 1) >> 1; + t->supplied[CT_MAIL].new_max += amt; + t->supplied[CT_MAIL].new_act += MoveGoodsToStation(CT_MAIL, amt, ST_TOWN, t->index, stations.GetStations()); + } + break; + + default: + NOT_REACHED(); } } - Backup cur_company(_current_company, OWNER_TOWN, FILE_LINE); + Backup cur_company(_current_company, OWNER_TOWN, FILE_LINE); if ((hs->building_flags & BUILDING_HAS_1_TILE) && HasBit(t->flags, TOWN_IS_GROWING) && @@ -540,7 +621,11 @@ static void TileLoop_Town(TileIndex tile) ClearTownHouse(t, tile); /* Rebuild with another house? */ - if (GB(r, 24, 8) >= 12) BuildTownHouse(t, tile); + if (GB(r, 24, 8) < 12 || !BuildTownHouse(t, tile)) + { + /* House wasn't replaced, so remove it */ + if (!_generating_world) RemoveNearbyStations(t); + } } cur_company.Restore(); @@ -569,6 +654,7 @@ static CommandCost ClearTile_Town(TileIndex tile, DoCommandFlag flags) ChangeTownRating(t, -rating, RATING_HOUSE_MINIMUM, flags); if (flags & DC_EXEC) { ClearTownHouse(t, tile); + RemoveNearbyStations(t); } return cost; @@ -676,7 +762,7 @@ static void GetTileDesc_Town(TileIndex tile, TileDesc *td) td->str = STR_LAI_TOWN_INDUSTRY_DESCRIPTION_UNDER_CONSTRUCTION; } - if (hs->grf_prop.grffile != NULL) { + if (hs->grf_prop.grffile != nullptr) { const GRFConfig *gc = GetGRFConfig(hs->grf_prop.grffile->grfid); td->grf = gc->GetName(); } @@ -767,10 +853,9 @@ void UpdateTownCargoes(Town *t) /** Updates the bitmap of all cargoes accepted by houses. */ void UpdateTownCargoBitmap() { - Town *town; _town_cargoes_accepted = 0; - FOR_ALL_TOWNS(town) { + for (const Town *town : Town::Iterate()) { _town_cargoes_accepted |= town->cargo_accepted_total; } } @@ -797,8 +882,7 @@ void OnTick_Town() { if (_game_mode == GM_EDITOR) return; - Town *t; - FOR_ALL_TOWNS(t) { + for (Town *t : Town::Iterate()) { TownTickHandler(t); } } @@ -815,7 +899,38 @@ static RoadBits GetTownRoadBits(TileIndex tile) { if (IsRoadDepotTile(tile) || IsStandardRoadStopTile(tile)) return ROAD_NONE; - return GetAnyRoadBits(tile, ROADTYPE_ROAD, true); + return GetAnyRoadBits(tile, RTT_ROAD, true); +} + +RoadType GetTownRoadType(const Town *t) +{ + RoadType best_rt = ROADTYPE_ROAD; + const RoadTypeInfo *best = nullptr; + const uint16 assume_max_speed = 50; + + for (RoadType rt = ROADTYPE_BEGIN; rt != ROADTYPE_END; rt++) { + if (RoadTypeIsTram(rt)) continue; + + const RoadTypeInfo *rti = GetRoadTypeInfo(rt); + + /* Unused road type. */ + if (rti->label == 0) continue; + + /* Can town build this road. */ + if (!HasBit(rti->flags, ROTF_TOWN_BUILD)) continue; + + /* Not yet introduced at this date. */ + if (IsInsideMM(rti->introduction_date, 0, MAX_DAY) && rti->introduction_date > _date) continue; + + if (best != nullptr) { + if ((rti->max_speed == 0 ? assume_max_speed : rti->max_speed) < (best->max_speed == 0 ? assume_max_speed : best->max_speed)) continue; + } + + best_rt = rt; + best = rti; + } + + return best_rt; } /** @@ -874,7 +989,8 @@ static bool IsRoadAllowedHere(Town *t, TileIndex tile, DiagDirection dir) /* No, try if we are able to build a road piece there. * If that fails clear the land, and if that fails exit. * This is to make sure that we can build a road here later. */ - if (DoCommand(tile, ((dir == DIAGDIR_NW || dir == DIAGDIR_SE) ? ROAD_Y : ROAD_X), 0, DC_AUTO, CMD_BUILD_ROAD).Failed() && + RoadType rt = GetTownRoadType(t); + if (DoCommand(tile, ((dir == DIAGDIR_NW || dir == DIAGDIR_SE) ? ROAD_Y : ROAD_X) | (rt << 4), 0, DC_AUTO, CMD_BUILD_ROAD).Failed() && DoCommand(tile, 0, 0, DC_AUTO, CMD_LANDSCAPE_CLEAR).Failed()) { return false; } @@ -1042,7 +1158,8 @@ static bool GrowTownWithExtraHouse(Town *t, TileIndex tile) */ static bool GrowTownWithRoad(const Town *t, TileIndex tile, RoadBits rcmd) { - if (DoCommand(tile, rcmd, t->index, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD).Succeeded()) { + RoadType rt = GetTownRoadType(t); + if (DoCommand(tile, rcmd | (rt << 4), t->index, DC_EXEC | DC_AUTO | DC_NO_WATER, CMD_BUILD_ROAD).Succeeded()) { _grow_town_result = GROWTH_SUCCEED; return true; } @@ -1105,8 +1222,9 @@ static bool GrowTownWithBridge(const Town *t, const TileIndex tile, const DiagDi byte bridge_type = RandomRange(MAX_BRIDGES - 1); /* Can we actually build the bridge? */ - if (DoCommand(tile, bridge_tile, bridge_type | ROADTYPES_ROAD << 8 | TRANSPORT_ROAD << 15, CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_BRIDGE)), CMD_BUILD_BRIDGE).Succeeded()) { - DoCommand(tile, bridge_tile, bridge_type | ROADTYPES_ROAD << 8 | TRANSPORT_ROAD << 15, DC_EXEC | CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_BRIDGE)), CMD_BUILD_BRIDGE); + RoadType rt = GetTownRoadType(t); + if (DoCommand(tile, bridge_tile, bridge_type | rt << 8 | TRANSPORT_ROAD << 15, CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_BRIDGE)), CMD_BUILD_BRIDGE).Succeeded()) { + DoCommand(tile, bridge_tile, bridge_type | rt << 8 | TRANSPORT_ROAD << 15, DC_EXEC | CommandFlagsToDCFlags(GetCommandFlags(CMD_BUILD_BRIDGE)), CMD_BUILD_BRIDGE); _grow_town_result = GROWTH_SUCCEED; return true; } @@ -1115,6 +1233,37 @@ static bool GrowTownWithBridge(const Town *t, const TileIndex tile, const DiagDi return false; } + +/** + * Checks whether at least one surrounding roads allows to build a house here + * + * @param t the tile where the house will be built + * @return true if at least one surrounding roadtype allows building houses here + */ +static inline bool RoadTypesAllowHouseHere(TileIndex t) +{ + static const TileIndexDiffC tiles[] = { {-1, -1}, {-1, 0}, {-1, 1}, {0, -1}, {0, 1}, {1, -1}, {1, 0}, {1, 1} }; + bool allow = false; + + for (const TileIndexDiffC *ptr = tiles; ptr != endof(tiles); ++ptr) { + TileIndex cur_tile = t + ToTileIndexDiff(*ptr); + if (!IsValidTile(cur_tile)) continue; + + if (!(IsTileType(cur_tile, MP_ROAD) || IsTileType(cur_tile, MP_STATION))) continue; + allow = true; + + RoadType road_rt = GetRoadTypeRoad(cur_tile); + RoadType tram_rt = GetRoadTypeTram(cur_tile); + if (road_rt != INVALID_ROADTYPE && !HasBit(GetRoadTypeInfo(road_rt)->flags, ROTF_NO_HOUSES)) return true; + if (tram_rt != INVALID_ROADTYPE && !HasBit(GetRoadTypeInfo(tram_rt)->flags, ROTF_NO_HOUSES)) return true; + } + + /* If no road was found surrounding the tile we can allow building the house since there is + * nothing which forbids it, if a road was found but the execution reached this point, then + * all the found roads don't allow houses to be built */ + return !allow; +} + /** * Grows the given town. * There are at the moment 3 possible way's for @@ -1293,6 +1442,8 @@ static void GrowTownInTile(TileIndex *tile_ptr, RoadBits cur_rb, DiagDirection t } } + allow_house &= RoadTypesAllowHouseHere(house_tile); + if (allow_house) { /* Build a house, but not if there already is a house there. */ if (!IsTileType(house_tile, MP_HOUSE)) { @@ -1432,14 +1583,14 @@ static bool GrowTownAtRoad(Town *t, TileIndex tile) } tile = TileAddByDiagDir(tile, target_dir); - if (IsTileType(tile, MP_ROAD) && !IsRoadDepot(tile) && HasTileRoadType(tile, ROADTYPE_ROAD)) { + if (IsTileType(tile, MP_ROAD) && !IsRoadDepot(tile) && HasTileRoadType(tile, RTT_ROAD)) { /* Don't allow building over roads of other cities */ - if (IsRoadOwner(tile, ROADTYPE_ROAD, OWNER_TOWN) && Town::GetByTile(tile) != t) { + if (IsRoadOwner(tile, RTT_ROAD, OWNER_TOWN) && Town::GetByTile(tile) != t) { return false; - } else if (IsRoadOwner(tile, ROADTYPE_ROAD, OWNER_NONE) && _game_mode == GM_EDITOR) { + } else if (IsRoadOwner(tile, RTT_ROAD, OWNER_NONE) && _game_mode == GM_EDITOR) { /* If we are in the SE, and this road-piece has no town owner yet, it just found an * owner :) (happy happy happy road now) */ - SetRoadOwner(tile, ROADTYPE_ROAD, OWNER_TOWN); + SetRoadOwner(tile, RTT_ROAD, OWNER_TOWN); SetTownIndex(tile, t->index); } } @@ -1490,7 +1641,7 @@ static bool GrowTown(Town *t) }; /* Current "company" is a town */ - Backup cur_company(_current_company, OWNER_TOWN, FILE_LINE); + Backup cur_company(_current_company, OWNER_TOWN, FILE_LINE); TileIndex tile = t->xy; // The tile we are working with ATM @@ -1513,7 +1664,8 @@ static bool GrowTown(Town *t) /* Only work with plain land that not already has a house */ if (!IsTileType(tile, MP_HOUSE) && IsTileFlat(tile)) { if (DoCommand(tile, 0, 0, DC_AUTO | DC_NO_WATER, CMD_LANDSCAPE_CLEAR).Succeeded()) { - DoCommand(tile, GenRandomRoadBits(), t->index, DC_EXEC | DC_AUTO, CMD_BUILD_ROAD); + RoadType rt = GetTownRoadType(t); + DoCommand(tile, GenRandomRoadBits() | (rt << 4), t->index, DC_EXEC | DC_AUTO, CMD_BUILD_ROAD); cur_company.Restore(); return true; } @@ -1601,16 +1753,19 @@ static void DoCreateTown(Town *t, TileIndex tile, uint32 townnameparts, TownSize * similar towns they're unlikely to grow all in one tick */ t->grow_counter = t->index % TOWN_GROWTH_TICKS; t->growth_rate = TownTicksToGameTicks(250); + t->show_zone = false; + + _town_kdtree.Insert(t->index); /* Set the default cargo requirement for town growth */ switch (_settings_game.game_creation.landscape) { case LT_ARCTIC: - if (FindFirstCargoWithTownEffect(TE_FOOD) != NULL) t->goal[TE_FOOD] = TOWN_GROWTH_WINTER; + if (FindFirstCargoWithTownEffect(TE_FOOD) != nullptr) t->goal[TE_FOOD] = TOWN_GROWTH_WINTER; break; case LT_TROPIC: - if (FindFirstCargoWithTownEffect(TE_FOOD) != NULL) t->goal[TE_FOOD] = TOWN_GROWTH_DESERT; - if (FindFirstCargoWithTownEffect(TE_WATER) != NULL) t->goal[TE_WATER] = TOWN_GROWTH_DESERT; + if (FindFirstCargoWithTownEffect(TE_FOOD) != nullptr) t->goal[TE_FOOD] = TOWN_GROWTH_DESERT; + if (FindFirstCargoWithTownEffect(TE_WATER) != nullptr) t->goal[TE_WATER] = TOWN_GROWTH_DESERT; break; } @@ -1636,7 +1791,7 @@ static void DoCreateTown(Town *t, TileIndex tile, uint32 townnameparts, TownSize t->townnameparts = townnameparts; t->UpdateVirtCoord(); - InvalidateWindowData(WC_TOWN_DIRECTORY, 0, 0); + InvalidateWindowData(WC_TOWN_DIRECTORY, 0, TDIWD_FORCE_REBUILD); t->InitializeLayout(layout); @@ -1694,10 +1849,8 @@ static CommandCost TownCanBePlacedHere(TileIndex tile) */ static bool IsUniqueTownName(const char *name) { - const Town *t; - - FOR_ALL_TOWNS(t) { - if (t->name != NULL && strcmp(t->name, name) == 0) return false; + for (const Town *t : Town::Iterate()) { + if (t->name != nullptr && strcmp(t->name, name) == 0) return false; } return true; @@ -1778,7 +1931,7 @@ CommandCost CmdFoundTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 Town *t; if (random) { t = CreateRandomTown(20, townnameparts, size, city, layout); - if (t == NULL) { + if (t == nullptr) { cost = CommandCost(STR_ERROR_NO_SPACE_FOR_TOWN); } else { _new_town_id = t->index; @@ -1790,13 +1943,13 @@ CommandCost CmdFoundTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 UpdateNearestTownForRoadTiles(false); old_generating_world.Restore(); - if (t != NULL && !StrEmpty(text)) { + if (t != nullptr && !StrEmpty(text)) { t->name = stredup(text); t->UpdateVirtCoord(); } if (_game_mode != GM_EDITOR) { - /* 't' can't be NULL since 'random' is false outside scenedit */ + /* 't' can't be nullptr since 'random' is false outside scenedit */ assert(!random); if (_current_company == OWNER_DEITY) { @@ -1925,7 +2078,7 @@ static TileIndex FindNearestGoodCoastalTownSpot(TileIndex tile, TownLayout layou SpotData sp = { INVALID_TILE, 0, layout }; TileIndex coast = tile; - if (CircularTileSearch(&coast, 40, FindNearestEmptyLand, NULL)) { + if (CircularTileSearch(&coast, 40, FindNearestEmptyLand, nullptr)) { CircularTileSearch(&coast, 10, FindFurthestFromWater, &sp); return sp.tile; } @@ -1938,7 +2091,7 @@ static Town *CreateRandomTown(uint attempts, uint32 townnameparts, TownSize size { assert(_game_mode == GM_EDITOR || _generating_world); // These are the preconditions for CMD_DELETE_TOWN - if (!Town::CanAllocateItem()) return NULL; + if (!Town::CanAllocateItem()) return nullptr; do { /* Generate a tile index not too close from the edge */ @@ -1963,7 +2116,7 @@ static Town *CreateRandomTown(uint attempts, uint32 townnameparts, TownSize size * placement is so bad it couldn't grow at all */ if (t->cache.population > 0) return t; - Backup cur_company(_current_company, OWNER_TOWN, FILE_LINE); + Backup cur_company(_current_company, OWNER_TOWN, FILE_LINE); CommandCost rc = DoCommand(t->xy, t->index, 0, DC_EXEC, CMD_DELETE_TOWN); cur_company.Restore(); assert(rc.Succeeded()); @@ -1975,7 +2128,7 @@ static Town *CreateRandomTown(uint attempts, uint32 townnameparts, TownSize size assert(Town::CanAllocateItem()); } while (--attempts != 0); - return NULL; + return nullptr; } static const byte _num_initial_towns[4] = {5, 11, 23, 46}; // very low, low, normal, high @@ -2007,17 +2160,20 @@ bool GenerateTowns(TownLayout layout) /* Get a unique name for the town. */ if (!GenerateTownName(&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) != NULL) current_number++; // If creation was successful, raise a flag. + if (CreateRandomTown(20, townnameparts, TSZ_RANDOM, city, layout) != nullptr) current_number++; // If creation was successful, raise a flag. } while (--total); town_names.clear(); + /* Build the town k-d tree again to make sure it's well balanced */ + RebuildTownKdtree(); + if (current_number != 0) return true; /* 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) && - CreateRandomTown(10000, townnameparts, TSZ_RANDOM, _settings_game.economy.larger_towns != 0, layout) != NULL) { + CreateRandomTown(10000, townnameparts, TSZ_RANDOM, _settings_game.economy.larger_towns != 0, layout) != nullptr) { return true; } @@ -2092,6 +2248,8 @@ static void MakeTownHouse(TileIndex t, Town *town, byte counter, byte stage, Hou if (size & BUILDING_2_TILES_Y) ClearMakeHouseTile(t + TileDiffXY(0, 1), town, counter, stage, ++type, random_bits); if (size & BUILDING_2_TILES_X) ClearMakeHouseTile(t + TileDiffXY(1, 0), town, counter, stage, ++type, random_bits); if (size & BUILDING_HAS_4_TILES) ClearMakeHouseTile(t + TileDiffXY(1, 1), town, counter, stage, ++type, random_bits); + + if (!_generating_world) FindStationsAroundTiles(TileArea(t, (size & BUILDING_2_TILES_X) ? 2 : 1, (size & BUILDING_2_TILES_Y) ? 2 : 1), &town->stations_near, false); } @@ -2108,6 +2266,9 @@ static inline bool CanBuildHouseHere(TileIndex tile, bool noslope) Slope slope = GetTileSlope(tile); if ((noslope && slope != SLOPE_FLAT) || IsSteepSlope(slope)) return false; + /* at least one RoadTypes allow building the house here? */ + if (!RoadTypesAllowHouseHere(tile)) return false; + /* building under a bridge? */ if (IsBridgeAbove(tile)) return false; @@ -2524,7 +2685,7 @@ void ClearTownHouse(Town *t, TileIndex tile) CommandCost CmdRenameTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { Town *t = Town::GetIfValid(p1); - if (t == NULL) return CMD_ERROR; + if (t == nullptr) return CMD_ERROR; bool reset = StrEmpty(text); @@ -2534,11 +2695,14 @@ CommandCost CmdRenameTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 } if (flags & DC_EXEC) { + t->cached_name.clear(); free(t->name); - t->name = reset ? NULL : stredup(text); + t->name = reset ? nullptr : stredup(text); t->UpdateVirtCoord(); - InvalidateWindowData(WC_TOWN_DIRECTORY, 0, 1); + InvalidateWindowData(WC_TOWN_DIRECTORY, 0, TDIWD_FORCE_RESORT); + ClearAllStationCachedNames(); + ClearAllIndustryCachedNames(); UpdateAllStationVirtCoords(); } return CommandCost(); @@ -2555,7 +2719,7 @@ const CargoSpec *FindFirstCargoWithTownEffect(TownEffect effect) FOR_ALL_CARGOSPECS(cs) { if (cs->town_effect == effect) return cs; } - return NULL; + return nullptr; } /** @@ -2578,11 +2742,11 @@ CommandCost CmdTownCargoGoal(TileIndex tile, DoCommandFlag flags, uint32 p1, uin uint16 index = GB(p1, 0, 16); Town *t = Town::GetIfValid(index); - if (t == NULL) return CMD_ERROR; + if (t == nullptr) return CMD_ERROR; /* Validate if there is a cargo which is the requested TownEffect */ const CargoSpec *cargo = FindFirstCargoWithTownEffect(te); - if (cargo == NULL) return CMD_ERROR; + if (cargo == nullptr) return CMD_ERROR; if (flags & DC_EXEC) { t->goal[te] = p2; @@ -2606,11 +2770,11 @@ CommandCost CmdTownSetText(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 { if (_current_company != OWNER_DEITY) return CMD_ERROR; Town *t = Town::GetIfValid(p1); - if (t == NULL) return CMD_ERROR; + if (t == nullptr) return CMD_ERROR; if (flags & DC_EXEC) { free(t->text); - t->text = StrEmpty(text) ? NULL : stredup(text); + t->text = StrEmpty(text) ? nullptr : stredup(text); InvalidateWindowData(WC_TOWN_VIEW, p1); } @@ -2632,7 +2796,7 @@ CommandCost CmdTownGrowthRate(TileIndex tile, DoCommandFlag flags, uint32 p1, ui if (GB(p2, 16, 16) != 0) return CMD_ERROR; Town *t = Town::GetIfValid(p1); - if (t == NULL) return CMD_ERROR; + if (t == nullptr) return CMD_ERROR; if (flags & DC_EXEC) { if (p2 == 0) { @@ -2657,6 +2821,35 @@ CommandCost CmdTownGrowthRate(TileIndex tile, DoCommandFlag flags, uint32 p1, ui return CommandCost(); } +/** + * Change the rating of a company in a town + * @param tile Unused. + * @param flags Type of operation. + * @param p1 Bit 0..15 = Town ID to change, bit 16..23 = Company ID to change. + * @param p2 Bit 0..15 = New rating of company (signed int16). + * @param text Unused. + * @return Empty cost or an error. + */ +CommandCost CmdTownRating(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) +{ + if (_current_company != OWNER_DEITY) return CMD_ERROR; + + TownID town_id = (TownID)GB(p1, 0, 16); + Town *t = Town::GetIfValid(town_id); + if (t == nullptr) return CMD_ERROR; + + CompanyID company_id = (CompanyID)GB(p1, 16, 8); + if (!Company::IsValidID(company_id)) return CMD_ERROR; + + int16 new_rating = Clamp((int16)GB(p2, 0, 16), RATING_MINIMUM, RATING_MAXIMUM); + if (flags & DC_EXEC) { + t->ratings[company_id] = new_rating; + InvalidateWindowData(WC_TOWN_AUTHORITY, town_id); + } + + return CommandCost(); +} + /** * Expand a town (scenario editor only). * @param tile Unused. @@ -2670,7 +2863,7 @@ CommandCost CmdExpandTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 { if (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY) return CMD_ERROR; Town *t = Town::GetIfValid(p1); - if (t == NULL) return CMD_ERROR; + if (t == nullptr) return CMD_ERROR; if (flags & DC_EXEC) { /* The more houses, the faster we grow */ @@ -2710,11 +2903,10 @@ CommandCost CmdDeleteTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 { if (_game_mode != GM_EDITOR && !_generating_world) return CMD_ERROR; Town *t = Town::GetIfValid(p1); - if (t == NULL) return CMD_ERROR; + if (t == nullptr) return CMD_ERROR; /* Stations refer to towns. */ - const Station *st; - FOR_ALL_STATIONS(st) { + for (const Station *st : Station::Iterate()) { if (st->town == t) { /* Non-oil rig stations are always a problem. */ if (!(st->facilities & FACIL_AIRPORT) || st->airport.type != AT_OILRIG) return CMD_ERROR; @@ -2725,12 +2917,22 @@ CommandCost CmdDeleteTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 } /* Depots refer to towns. */ - const Depot *d; - FOR_ALL_DEPOTS(d) { + for (const Depot *d : Depot::Iterate()) { if (d->town == t) return CMD_ERROR; } - /* Check all tiles for town ownership. */ + /* Check all tiles for town ownership. First check for bridge tiles, as + * these do not directly have an owner so we need to check adjacent + * tiles. This won't work correctly in the same loop if the adjacent + * tile was already deleted earlier in the loop. */ + for (TileIndex tile = 0; tile < MapSize(); ++tile) { + if (IsTileType(tile, MP_TUNNELBRIDGE) && TestTownOwnsBridge(tile, t)) { + CommandCost ret = DoCommand(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR); + if (ret.Failed()) return ret; + } + } + + /* Check all remaining tiles for town ownership. */ for (TileIndex tile = 0; tile < MapSize(); ++tile) { bool try_clear = false; switch (GetTileType(tile)) { @@ -2738,10 +2940,6 @@ CommandCost CmdDeleteTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 try_clear = HasTownOwnedRoad(tile) && GetTownIndex(tile) == t->index; break; - case MP_TUNNELBRIDGE: - try_clear = IsTileOwner(tile, OWNER_TOWN) && ClosestTownFromTile(tile, UINT_MAX) == t; - break; - case MP_HOUSE: try_clear = GetTownIndex(tile) == t->index; break; @@ -2762,7 +2960,7 @@ CommandCost CmdDeleteTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 try_clear = true; } else { /* Tell to find a new town. */ - if (flags & DC_EXEC) o->town = NULL; + if (flags & DC_EXEC) o->town = nullptr; } } } @@ -2778,7 +2976,11 @@ CommandCost CmdDeleteTown(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 } /* The town destructor will delete the other things related to the town. */ - if (flags & DC_EXEC) delete t; + if (flags & DC_EXEC) { + _town_kdtree.Remove(t->index); + if (t->cache.sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeTown(t->index)); + delete t; + } return CommandCost(); } @@ -2845,7 +3047,7 @@ static CommandCost TownActionRoadRebuild(Town *t, DoCommandFlag flags) */ static bool TryClearTile(TileIndex tile) { - Backup cur_company(_current_company, OWNER_NONE, FILE_LINE); + Backup cur_company(_current_company, OWNER_NONE, FILE_LINE); CommandCost r = DoCommand(tile, 0, 0, DC_NONE, CMD_LANDSCAPE_CLEAR); cur_company.Restore(); return r.Succeeded(); @@ -2917,7 +3119,7 @@ static CommandCost TownActionBuildStatue(Town *t, DoCommandFlag flags) if (!CircularTileSearch(&tile, 9, SearchTileForStatue, &statue_data)) return_cmd_error(STR_ERROR_STATUE_NO_SUITABLE_PLACE); if (flags & DC_EXEC) { - Backup cur_company(_current_company, OWNER_NONE, FILE_LINE); + Backup cur_company(_current_company, OWNER_NONE, FILE_LINE); DoCommand(statue_data.best_position, 0, 0, DC_EXEC, CMD_LANDSCAPE_CLEAR); cur_company.Restore(); BuildObject(OBJECT_STATUE, statue_data.best_position, _current_company, t); @@ -2989,8 +3191,7 @@ static CommandCost TownActionBribe(Town *t, DoCommandFlag flags) t->unwanted[_current_company] = 6; /* set all close by station ratings to 0 */ - Station *st; - FOR_ALL_STATIONS(st) { + for (Station *st : Station::Iterate()) { if (st->town == t && st->owner == _current_company) { for (CargoID i = 0; i < NUM_CARGO; i++) st->goods[i].rating = 0; } @@ -3029,7 +3230,7 @@ static TownActionProc * const _town_action_proc[] = { /** * Get a list of available actions to do at a town. - * @param nump if not NULL add put the number of available actions in it + * @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 @@ -3072,7 +3273,7 @@ uint GetMaskOfTownActions(int *nump, CompanyID cid, const Town *t) } } - if (nump != NULL) *nump = num; + if (nump != nullptr) *nump = num; return buttons; } @@ -3090,9 +3291,9 @@ uint GetMaskOfTownActions(int *nump, CompanyID cid, const Town *t) CommandCost CmdDoTownAction(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { Town *t = Town::GetIfValid(p1); - if (t == NULL || p2 >= lengthof(_town_action_proc)) return CMD_ERROR; + if (t == nullptr || p2 >= lengthof(_town_action_proc)) return CMD_ERROR; - if (!HasBit(GetMaskOfTownActions(NULL, _current_company, t), p2)) return CMD_ERROR; + if (!HasBit(GetMaskOfTownActions(nullptr, _current_company, t), p2)) return CMD_ERROR; CommandCost cost(EXPENSES_OTHER, _price[PR_TOWN_ACTION] * _town_action_costs[p2] >> 8); @@ -3106,32 +3307,43 @@ CommandCost CmdDoTownAction(TileIndex tile, DoCommandFlag flags, uint32 p1, uint return cost; } +template +static void ForAllStationsNearTown(Town *t, Func func) +{ + /* Ideally the search radius should be close to the actual town zone 0 radius. + * The true radius is not stored or calculated anywhere, only the squared radius. */ + /* The efficiency of this search might be improved for large towns and many stations on the map, + * by using an integer square root approximation giving a value not less than the true square root. */ + uint search_radius = t->cache.squared_town_zone_radius[0] / 2; + ForAllStationsRadius(t->xy, search_radius, [&](const Station * st) { + if (DistanceSquare(st->xy, t->xy) <= t->cache.squared_town_zone_radius[0]) { + func(st); + } + }); +} + static void UpdateTownRating(Town *t) { /* Increase company ratings if they're low */ - const Company *c; - FOR_ALL_COMPANIES(c) { + for (const Company *c : Company::Iterate()) { if (t->ratings[c->index] < RATING_GROWTH_MAXIMUM) { t->ratings[c->index] = min((int)RATING_GROWTH_MAXIMUM, t->ratings[c->index] + RATING_GROWTH_UP_STEP); } } - const Station *st; - FOR_ALL_STATIONS(st) { - if (DistanceSquare(st->xy, t->xy) <= t->cache.squared_town_zone_radius[0]) { - if (st->time_since_load <= 20 || st->time_since_unload <= 20) { - if (Company::IsValidID(st->owner)) { - int new_rating = t->ratings[st->owner] + RATING_STATION_UP_STEP; - t->ratings[st->owner] = min(new_rating, INT16_MAX); // do not let it overflow - } - } else { - if (Company::IsValidID(st->owner)) { - int new_rating = t->ratings[st->owner] + RATING_STATION_DOWN_STEP; - t->ratings[st->owner] = max(new_rating, INT16_MIN); - } + ForAllStationsNearTown(t, [&](const Station *st) { + if (st->time_since_load <= 20 || st->time_since_unload <= 20) { + if (Company::IsValidID(st->owner)) { + int new_rating = t->ratings[st->owner] + RATING_STATION_UP_STEP; + t->ratings[st->owner] = min(new_rating, INT16_MAX); // do not let it overflow + } + } else { + if (Company::IsValidID(st->owner)) { + int new_rating = t->ratings[st->owner] + RATING_STATION_DOWN_STEP; + t->ratings[st->owner] = max(new_rating, INT16_MIN); } } - } + }); /* clamp all ratings to valid values */ for (uint i = 0; i < MAX_COMPANIES; i++) { @@ -3166,14 +3378,11 @@ static void UpdateTownGrowCounter(Town *t, uint16 prev_growth_rate) static int CountActiveStations(Town *t) { int n = 0; - const Station *st; - FOR_ALL_STATIONS(st) { - if (DistanceSquare(st->xy, t->xy) <= t->cache.squared_town_zone_radius[0]) { - if (st->time_since_load <= 20 || st->time_since_unload <= 20) { - n++; - } + ForAllStationsNearTown(t, [&](const Station * st) { + if (st->time_since_load <= 20 || st->time_since_unload <= 20) { + n++; } - } + }); return n; } @@ -3185,6 +3394,11 @@ static int CountActiveStations(Town *t) */ static uint GetNormalGrowthRate(Town *t) { + /** + * Note: + * Unserviced+unfunded towns get an additional malus in UpdateTownGrowth(), + * so the "320" is actually not better than the "420". + */ static const uint16 _grow_count_values[2][6] = { { 120, 120, 120, 100, 80, 60 }, // Fund new buildings has been activated { 320, 420, 300, 220, 160, 100 } // Normal values @@ -3267,9 +3481,7 @@ static void UpdateTownAmounts(Town *t) static void UpdateTownUnwanted(Town *t) { - const Company *c; - - FOR_ALL_COMPANIES(c) { + for (const Company *c : Company::Iterate()) { if (t->unwanted[c->index] > 0) t->unwanted[c->index]--; } } @@ -3285,7 +3497,7 @@ CommandCost CheckIfAuthorityAllowsNewStation(TileIndex tile, DoCommandFlag flags if (!Company::IsValidID(_current_company) || (flags & DC_NO_TEST_TOWN_RATING)) return CommandCost(); Town *t = ClosestTownFromTile(tile, _settings_game.economy.dist_local_authority); - if (t == NULL) return CommandCost(); + if (t == nullptr) return CommandCost(); if (t->ratings[_current_company] > RATING_VERYPOOR) return CommandCost(); @@ -3297,32 +3509,25 @@ CommandCost CheckIfAuthorityAllowsNewStation(TileIndex tile, DoCommandFlag flags * Return the town closest to the given tile within \a threshold. * @param tile Starting point of the search. * @param threshold Biggest allowed distance to the town. - * @return Closest town to \a tile within \a threshold, or \c NULL if there is no such town. + * @return Closest town to \a tile within \a threshold, or \c nullptr if there is no such town. * * @note This function only uses distance, the #ClosestTownFromTile function also takes town ownership into account. */ Town *CalcClosestTownFromTile(TileIndex tile, uint threshold) { - Town *t; - uint best = threshold; - Town *best_town = NULL; + if (Town::GetNumItems() == 0) return nullptr; - FOR_ALL_TOWNS(t) { - uint dist = DistanceManhattan(tile, t->xy); - if (dist < best) { - best = dist; - best_town = t; - } - } - - return best_town; + TownID tid = _town_kdtree.FindNearest(TileX(tile), TileY(tile)); + Town *town = Town::Get(tid); + if (DistanceManhattan(tile, town->xy) < threshold) return town; + return nullptr; } /** * Return the town closest (in distance or ownership) to a given tile, within a given threshold. * @param tile Starting point of the search. * @param threshold Biggest allowed distance to the town. - * @return Closest town to \a tile within \a threshold, or \c NULL if there is no such town. + * @return Closest town to \a tile within \a threshold, or \c nullptr if there is no such town. * * @note If you only care about distance, you can use the #CalcClosestTownFromTile function. */ @@ -3339,13 +3544,13 @@ Town *ClosestTownFromTile(TileIndex tile, uint threshold) /* in the case we are generating "many random towns", this value may be INVALID_TOWN */ if (_generating_world) return CalcClosestTownFromTile(tile, threshold); assert(Town::GetNumItems() == 0); - return NULL; + return nullptr; } assert(Town::IsValidID(tid)); Town *town = Town::Get(tid); - if (DistanceManhattan(tile, town->xy) >= threshold) town = NULL; + if (DistanceManhattan(tile, town->xy) >= threshold) town = nullptr; return town; } @@ -3360,7 +3565,7 @@ Town *ClosestTownFromTile(TileIndex tile, uint threshold) } static bool _town_rating_test = false; ///< If \c true, town rating is in test-mode. -static SmallMap _town_test_ratings; ///< Map of towns to modified ratings, while in town rating test-mode. +static SmallMap _town_test_ratings; ///< Map of towns to modified ratings, while in town rating test-mode. /** * Switch the town rating to test-mode, to allow commands to be tested without affecting current ratings. @@ -3372,7 +3577,7 @@ void SetTownRatingTestMode(bool mode) static int ref_count = 0; // Number of times test-mode is switched on. if (mode) { if (ref_count == 0) { - _town_test_ratings.Clear(); + _town_test_ratings.clear(); } ref_count++; } else { @@ -3408,7 +3613,7 @@ static int GetRating(const Town *t) void ChangeTownRating(Town *t, int add, int max, DoCommandFlag flags) { /* if magic_bulldozer cheat is active, town doesn't penalize for removing stuff */ - if (t == NULL || (flags & DC_NO_MODIFY_TOWN_RATING) || + if (t == nullptr || (flags & DC_NO_MODIFY_TOWN_RATING) || !Company::IsValidID(_current_company) || (_cheats.magic_bulldozer.value && add < 0)) { return; @@ -3445,7 +3650,7 @@ void ChangeTownRating(Town *t, int add, int max, DoCommandFlag flags) CommandCost CheckforTownRating(DoCommandFlag flags, Town *t, TownRatingCheckType type) { /* if magic_bulldozer cheat is active, town doesn't restrict your destructive actions */ - if (t == NULL || !Company::IsValidID(_current_company) || + if (t == nullptr || !Company::IsValidID(_current_company) || _cheats.magic_bulldozer.value || (flags & DC_NO_TEST_TOWN_RATING)) { return CommandCost(); } @@ -3474,9 +3679,7 @@ CommandCost CheckforTownRating(DoCommandFlag flags, Town *t, TownRatingCheckType void TownsMonthlyLoop() { - Town *t; - - FOR_ALL_TOWNS(t) { + for (Town *t : Town::Iterate()) { if (t->road_build_months != 0) t->road_build_months--; if (t->exclusive_counter != 0) { @@ -3538,12 +3741,12 @@ extern const TileTypeProcs _tile_type_town_procs = { AddAcceptedCargo_Town, // add_accepted_cargo_proc GetTileDesc_Town, // get_tile_desc_proc GetTileTrackStatus_Town, // get_tile_track_status_proc - NULL, // click_tile_proc + nullptr, // click_tile_proc AnimateTile_Town, // animate_tile_proc TileLoop_Town, // tile_loop_proc ChangeTileOwner_Town, // change_tile_owner_proc AddProducedCargo_Town, // add_produced_cargo_proc - NULL, // vehicle_enter_tile_proc + nullptr, // vehicle_enter_tile_proc GetFoundation_Town, // get_foundation_proc TerraformTile_Town, // terraform_tile_proc }; diff --git a/src/town_gui.cpp b/src/town_gui.cpp index dae8696a72..363d84cbd6 100644 --- a/src/town_gui.cpp +++ b/src/town_gui.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. @@ -31,7 +29,9 @@ #include "townname_func.h" #include "core/geometry_func.hpp" #include "genworld.h" +#include "stringfilter_type.h" #include "widgets/dropdown_func.h" +#include "town_kdtree.h" #include "widgets/town_widget.h" @@ -39,12 +39,15 @@ #include "safeguards.h" +TownKdtree _town_local_authority_kdtree(&Kdtree_TownXYFunc); + typedef GUIList GUITownList; 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_SHADEBOX, COLOUR_BROWN), NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN), NWidget(WWT_STICKYBOX, COLOUR_BROWN), @@ -101,7 +104,7 @@ public: this->vscroll->SetCapacity((this->GetWidget(WID_TA_COMMAND_LIST)->current_y - WD_FRAMERECT_TOP - WD_FRAMERECT_BOTTOM) / this->actions_step); } - virtual void OnPaint() + void OnPaint() override { int numact; uint buttons = GetMaskOfTownActions(&numact, _local_company, this->town); @@ -114,6 +117,7 @@ public: this->sel_index = -1; } + this->SetWidgetLoweredState(WID_TA_ZONE_BUTTON, this->town->show_zone); this->SetWidgetDisabledState(WID_TA_EXECUTE, this->sel_index == -1); this->DrawWidgets(); @@ -147,8 +151,7 @@ public: uint exclusive_left = rtl ? right - icon_width - exclusive_width - 2 : left + icon_width + 2; /* Draw list of companies */ - const Company *c; - FOR_ALL_COMPANIES(c) { + 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); @@ -156,15 +159,14 @@ public: SetDParam(1, c->index); int r = this->town->ratings[c->index]; - StringID str; - (str = STR_CARGO_RATING_APPALLING, r <= RATING_APPALLING) || // Apalling - (str++, r <= RATING_VERYPOOR) || // Very Poor - (str++, r <= RATING_POOR) || // Poor - (str++, r <= RATING_MEDIOCRE) || // Mediocore - (str++, r <= RATING_GOOD) || // Good - (str++, r <= RATING_VERYGOOD) || // Very Good - (str++, r <= RATING_EXCELLENT) || // Excellent - (str++, true); // Outstanding + 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++; SetDParam(2, str); if (this->town->exclusivity == c->index) { @@ -183,12 +185,12 @@ public: } } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { if (widget == WID_TA_CAPTION) SetDParam(0, this->window_number); } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { switch (widget) { case WID_TA_ACTION_INFO: @@ -223,7 +225,7 @@ public: } } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_TA_ACTION_INFO: { @@ -258,14 +260,26 @@ public: } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { + case WID_TA_ZONE_BUTTON: { + bool new_show_state = !this->town->show_zone; + TownID index = this->town->index; + + new_show_state ? _town_local_authority_kdtree.Insert(index) : _town_local_authority_kdtree.Remove(index); + + this->town->show_zone = new_show_state; + this->SetWidgetLoweredState(widget, new_show_state); + MarkWholeScreenDirty(); + break; + } + case WID_TA_COMMAND_LIST: { int y = this->GetRowFromWidget(pt.y, WID_TA_COMMAND_LIST, 1, this->actions_step); if (!IsInsideMM(y, 0, 5)) return; - y = GetNthSetBit(GetMaskOfTownActions(NULL, _local_company, this->town), y + this->vscroll->GetPosition() - 1); + y = GetNthSetBit(GetMaskOfTownActions(nullptr, _local_company, this->town), y + this->vscroll->GetPosition() - 1); if (y >= 0) { this->sel_index = y; this->SetDirty(); @@ -281,7 +295,7 @@ public: } } - virtual void OnHundredthTick() + void OnHundredthTick() override { this->SetDirty(); } @@ -325,12 +339,25 @@ public: this->SetWidgetDisabledState(WID_TV_CHANGE_NAME, _networking && !_network_server); } - virtual void SetStringParameters(int widget) const + ~TownViewWindow() + { + SetViewportCatchmentTown(Town::Get(this->window_number), false); + } + + void SetStringParameters(int widget) const override { if (widget == WID_TV_CAPTION) SetDParam(0, this->town->index); } - virtual void DrawWidget(const Rect &r, int widget) const + void OnPaint() override + { + extern const Town *_viewport_highlight_town; + this->SetWidgetLoweredState(WID_TV_CATCHMENT, _viewport_highlight_town == this->town); + + this->DrawWidgets(); + } + + void DrawWidget(const Rect &r, int widget) const override { if (widget != WID_TV_INFO) return; @@ -366,7 +393,7 @@ public: uint cargo_text_right = r.right - WD_FRAMERECT_RIGHT - (rtl ? 20 : 0); const CargoSpec *cargo = FindFirstCargoWithTownEffect((TownEffect)i); - assert(cargo != NULL); + assert(cargo != nullptr); StringID string; @@ -410,13 +437,13 @@ public: DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_LEFT, y += FONT_HEIGHT_NORMAL, STR_TOWN_VIEW_NOISE_IN_TOWN); } - if (this->town->text != NULL) { + if (this->town->text != nullptr) { 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); } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_TV_CENTER_VIEW: // scroll to location @@ -436,6 +463,10 @@ public: ShowQueryString(STR_TOWN_NAME, STR_TOWN_VIEW_RENAME_TOWN_BUTTON, MAX_LENGTH_TOWN_NAME_CHARS, this, CS_ALPHANUMERAL, QSF_ENABLE_DEFAULT | QSF_LEN_IN_CHARS); break; + case WID_TV_CATCHMENT: + SetViewportCatchmentTown(Town::Get(this->window_number), !this->IsWidgetLowered(WID_TV_CATCHMENT)); + break; + case WID_TV_EXPAND: { // expand town - only available on Scenario editor /* Warn the user if towns are not allowed to build roads, but do this only once per OpenTTD run. */ static bool _warn_town_no_roads = false; @@ -455,7 +486,7 @@ public: } } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_TV_INFO: @@ -488,7 +519,7 @@ public: if (_settings_game.economy.station_noise_level) aimed_height += FONT_HEIGHT_NORMAL; - if (this->town->text != NULL) { + if (this->town->text != nullptr) { SetDParamStr(0, this->town->text); aimed_height += GetStringHeight(STR_JUST_RAW_STRING, width - WD_FRAMERECT_LEFT - WD_FRAMERECT_RIGHT); } @@ -505,9 +536,9 @@ public: } } - virtual void OnResize() + void OnResize() override { - if (this->viewport != NULL) { + if (this->viewport != nullptr) { NWidgetViewport *nvp = this->GetWidget(WID_TV_VIEWPORT); nvp->UpdateViewportCoordinates(this); @@ -520,7 +551,7 @@ public: * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; /* Called when setting station noise or required cargoes have changed, in order to resize the window */ @@ -528,11 +559,11 @@ public: this->ResizeWindowAsNeeded(); } - virtual void OnQueryTextFinished(char *str) + void OnQueryTextFinished(char *str) override { - if (str == NULL) return; + if (str == nullptr) return; - DoCommandP(0, this->window_number, 0, CMD_RENAME_TOWN | CMD_MSG(STR_ERROR_CAN_T_RENAME_TOWN), NULL, str); + DoCommandP(0, this->window_number, 0, CMD_RENAME_TOWN | CMD_MSG(STR_ERROR_CAN_T_RENAME_TOWN), nullptr, str); } }; @@ -556,6 +587,7 @@ static const NWidgetPart _nested_town_game_view_widgets[] = { NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TV_SHOW_AUTHORITY), SetMinimalSize(80, 12), SetFill(1, 1), SetResize(1, 0), SetDataTip(STR_TOWN_VIEW_LOCAL_AUTHORITY_BUTTON, STR_TOWN_VIEW_LOCAL_AUTHORITY_TOOLTIP), NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TV_CHANGE_NAME), SetMinimalSize(80, 12), SetFill(1, 1), SetResize(1, 0), SetDataTip(STR_BUTTON_RENAME, STR_TOWN_VIEW_RENAME_TOOLTIP), EndContainer(), + NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_TV_CATCHMENT), SetMinimalSize(14, 12), SetFill(0, 1), SetDataTip(STR_BUTTON_CATCHMENT, STR_TOOLTIP_CATCHMENT), NWidget(WWT_RESIZEBOX, COLOUR_BROWN), EndContainer(), }; @@ -588,6 +620,7 @@ static const NWidgetPart _nested_town_editor_view_widgets[] = { NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TV_EXPAND), SetMinimalSize(80, 12), SetFill(1, 1), SetResize(1, 0), SetDataTip(STR_TOWN_VIEW_EXPAND_BUTTON, STR_TOWN_VIEW_EXPAND_TOOLTIP), NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_TV_DELETE), SetMinimalSize(80, 12), SetFill(1, 1), SetResize(1, 0), SetDataTip(STR_TOWN_VIEW_DELETE_BUTTON, STR_TOWN_VIEW_DELETE_TOOLTIP), EndContainer(), + NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_TV_CATCHMENT), SetMinimalSize(14, 12), SetFill(0, 1), SetDataTip(STR_BUTTON_CATCHMENT, STR_TOOLTIP_CATCHMENT), NWidget(WWT_RESIZEBOX, COLOUR_BROWN), EndContainer(), }; @@ -621,7 +654,7 @@ static const NWidgetPart _nested_town_directory_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_TEXTBTN, COLOUR_BROWN, WID_TD_SORT_ORDER), SetSizingType(NWST_STEP), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER), NWidget(WWT_DROPDOWN, COLOUR_BROWN, WID_TD_SORT_CRITERIA), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_SORT_CRITERIA), - NWidget(WWT_PANEL, COLOUR_BROWN), SetResize(1, 0), EndContainer(), + NWidget(WWT_EDITBOX, COLOUR_BROWN, WID_TD_FILTER), SetFill(35, 12), SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP), EndContainer(), NWidget(WWT_PANEL, COLOUR_BROWN, WID_TD_LIST), SetMinimalSize(196, 0), SetDataTip(0x0, STR_TOWN_DIRECTORY_LIST_TOOLTIP), SetFill(1, 0), SetResize(0, 10), SetScrollbar(WID_TD_SCROLLBAR), EndContainer(), @@ -641,12 +674,14 @@ struct TownDirectoryWindow : public Window { private: /* Runtime saved values */ static Listing last_sorting; - static const Town *last_town; /* Constants for sorting towns */ static const StringID sorter_names[]; static GUITownList::SortFunction * const sorter_funcs[]; + StringFilter string_filter; ///< Filter for towns + QueryString townname_editbox; ///< Filter editbox + GUITownList towns; Scrollbar *vscroll; @@ -654,76 +689,66 @@ private: void BuildSortTownList() { if (this->towns.NeedRebuild()) { - this->towns.Clear(); + this->towns.clear(); - const Town *t; - FOR_ALL_TOWNS(t) { - *this->towns.Append() = t; + for (const Town *t : Town::Iterate()) { + if (this->string_filter.IsEmpty()) { + this->towns.push_back(t); + continue; + } + this->string_filter.ResetState(); + this->string_filter.AddLine(t->GetCachedName()); + if (this->string_filter.GetState()) this->towns.push_back(t); } - this->towns.Compact(); + this->towns.shrink_to_fit(); this->towns.RebuildDone(); - this->vscroll->SetCount(this->towns.Length()); // Update scrollbar as well. + this->vscroll->SetCount((uint)this->towns.size()); // Update scrollbar as well. } /* Always sort the towns. */ - this->last_town = NULL; this->towns.Sort(); this->SetWidgetDirty(WID_TD_LIST); // Force repaint of the displayed towns. } /** Sort by town name */ - static int CDECL TownNameSorter(const Town * const *a, const Town * const *b) + static bool TownNameSorter(const Town * const &a, const Town * const &b) { - static char buf_cache[64]; - const Town *ta = *a; - const Town *tb = *b; - char buf[64]; - - SetDParam(0, ta->index); - GetString(buf, STR_TOWN_NAME, lastof(buf)); - - /* If 'b' is the same town as in the last round, use the cached value - * We do this to speed stuff up ('b' is called with the same value a lot of - * times after each other) */ - if (tb != last_town) { - last_town = tb; - SetDParam(0, tb->index); - GetString(buf_cache, STR_TOWN_NAME, lastof(buf_cache)); - } - - return strnatcmp(buf, buf_cache); // Sort by name (natural sorting). + return strnatcmp(a->GetCachedName(), b->GetCachedName()) < 0; // Sort by name (natural sorting). } /** Sort by population (default descending, as big towns are of the most interest). */ - static int CDECL TownPopulationSorter(const Town * const *a, const Town * const *b) + static bool TownPopulationSorter(const Town * const &a, const Town * const &b) { - uint32 a_population = (*a)->cache.population; - uint32 b_population = (*b)->cache.population; + uint32 a_population = a->cache.population; + uint32 b_population = b->cache.population; if (a_population == b_population) return TownDirectoryWindow::TownNameSorter(a, b); - return (a_population < b_population) ? -1 : 1; + return a_population < b_population; } /** Sort by town rating */ - static int CDECL TownRatingSorter(const Town * const *a, const Town * const *b) + static bool TownRatingSorter(const Town * const &a, const Town * const &b) { - int before = TownDirectoryWindow::last_sorting.order ? 1 : -1; // Value to get 'a' before 'b'. + bool before = !TownDirectoryWindow::last_sorting.order; // Value to get 'a' before 'b'. /* Towns without rating are always after towns with rating. */ - if (HasBit((*a)->have_ratings, _local_company)) { - if (HasBit((*b)->have_ratings, _local_company)) { - int16 a_rating = (*a)->ratings[_local_company]; - int16 b_rating = (*b)->ratings[_local_company]; + if (HasBit(a->have_ratings, _local_company)) { + if (HasBit(b->have_ratings, _local_company)) { + int16 a_rating = a->ratings[_local_company]; + int16 b_rating = b->ratings[_local_company]; if (a_rating == b_rating) return TownDirectoryWindow::TownNameSorter(a, b); - return (a_rating < b_rating) ? -1 : 1; + return a_rating < b_rating; } return before; } - if (HasBit((*b)->have_ratings, _local_company)) return -before; - return -before * TownDirectoryWindow::TownNameSorter(a, b); // Sort unrated towns always on ascending town name. + if (HasBit(b->have_ratings, _local_company)) return !before; + + /* Sort unrated towns always on ascending town name. */ + if (before) return TownDirectoryWindow::TownNameSorter(a, b); + return !TownDirectoryWindow::TownNameSorter(a, b); } public: - TownDirectoryWindow(WindowDesc *desc) : Window(desc) + TownDirectoryWindow(WindowDesc *desc) : Window(desc), townname_editbox(MAX_LENGTH_TOWN_NAME_CHARS * MAX_CHAR_LENGTH, MAX_LENGTH_TOWN_NAME_CHARS) { this->CreateNestedTree(); @@ -735,9 +760,12 @@ public: this->BuildSortTownList(); this->FinishInitNested(0); + + this->querystrings[WID_TD_FILTER] = &this->townname_editbox; + this->townname_editbox.cancel_button = QueryString::ACTION_CLEAR; } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { switch (widget) { case WID_TD_WORLD_POPULATION: @@ -760,7 +788,7 @@ public: return t->larger_town ? STR_TOWN_DIRECTORY_CITY : STR_TOWN_DIRECTORY_TOWN; } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { switch (widget) { case WID_TD_SORT_ORDER: @@ -770,7 +798,7 @@ public: case WID_TD_LIST: { int n = 0; int y = r.top + WD_FRAMERECT_TOP; - if (this->towns.Length() == 0) { // No towns available. + if (this->towns.size() == 0) { // No towns available. DrawString(r.left + WD_FRAMERECT_LEFT, r.right, y, STR_TOWN_DIRECTORY_NONE); break; } @@ -782,7 +810,7 @@ public: 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; - for (uint i = this->vscroll->GetPosition(); i < this->towns.Length(); i++) { + for (uint i = this->vscroll->GetPosition(); i < this->towns.size(); i++) { const Town *t = this->towns[i]; assert(t->xy != INVALID_TILE); @@ -808,7 +836,7 @@ public: } } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_TD_SORT_ORDER: { @@ -830,10 +858,10 @@ public: } case WID_TD_LIST: { Dimension d = GetStringBoundingBox(STR_TOWN_DIRECTORY_NONE); - for (uint i = 0; i < this->towns.Length(); i++) { + for (uint i = 0; i < this->towns.size(); i++) { const Town *t = this->towns[i]; - assert(t != NULL); + assert(t != nullptr); SetDParam(0, t->index); SetDParamMaxDigits(1, 8); @@ -860,7 +888,7 @@ public: } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_TD_SORT_ORDER: // Click on sort order button @@ -883,10 +911,10 @@ public: case WID_TD_LIST: { // Click on Town Matrix uint id_v = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_TD_LIST, WD_FRAMERECT_TOP); - if (id_v >= this->towns.Length()) return; // click out of town bounds + if (id_v >= this->towns.size()) return; // click out of town bounds const Town *t = this->towns[id_v]; - assert(t != NULL); + assert(t != nullptr); if (_ctrl_pressed) { ShowExtraViewPortWindow(t->xy); } else { @@ -897,7 +925,7 @@ public: } } - virtual void OnDropdownSelect(int widget, int index) + void OnDropdownSelect(int widget, int index) override { if (widget != WID_TD_SORT_CRITERIA) return; @@ -908,41 +936,55 @@ public: } } - virtual void OnPaint() + void OnPaint() override { if (this->towns.NeedRebuild()) this->BuildSortTownList(); this->DrawWidgets(); } - virtual void OnHundredthTick() + void OnHundredthTick() override { this->BuildSortTownList(); this->SetDirty(); } - virtual void OnResize() + void OnResize() override { this->vscroll->SetCapacityFromWidget(this, WID_TD_LIST); } + void OnEditboxChanged(int wid) override + { + if (wid == WID_TD_FILTER) { + this->string_filter.SetFilterTerm(this->townname_editbox.text.buf); + this->InvalidateData(TDIWD_FORCE_REBUILD); + } + } + /** * 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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + 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->towns.ForceRebuild(); - } else { - this->towns.ForceResort(); + switch (data) { + case TDIWD_FORCE_REBUILD: + /* This needs to be done in command-scope to enforce rebuilding before resorting invalid data */ + this->towns.ForceRebuild(); + break; + + case TDIWD_POPULATION_CHANGE: + if (this->towns.SortType() == 1) this->towns.ForceResort(); + break; + + default: + this->towns.ForceResort(); } } }; Listing TownDirectoryWindow::last_sorting = {false, 0}; -const Town *TownDirectoryWindow::last_town = NULL; /** Names of the sorting functions. */ const StringID TownDirectoryWindow::sorter_names[] = { @@ -972,7 +1014,7 @@ void ShowTownDirectory() new TownDirectoryWindow(&_town_directory_desc); } -void CcFoundTown(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) +void CcFoundTown(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) { if (result.Failed()) return; @@ -980,7 +1022,7 @@ void CcFoundTown(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2 if (!_settings_client.gui.persistent_buildingtools) ResetObjectToPlace(); } -void CcFoundRandomTown(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) +void CcFoundRandomTown(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) { if (result.Succeeded()) ScrollMainWindowToTile(Town::Get(_new_town_id)->xy); } @@ -1123,7 +1165,7 @@ public: void ExecuteFoundTownCommand(TileIndex tile, bool random, StringID errstr, CommandCallback cc) { - const char *name = NULL; + const char *name = nullptr; if (!this->townnamevalid) { name = this->townname_editbox.text.buf; @@ -1141,7 +1183,7 @@ public: if (success && !_shift_pressed) this->RandomTownName(); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_TF_NEW_TOWN: @@ -1186,7 +1228,7 @@ public: } } - virtual void OnPlaceObject(Point pt, TileIndex tile) + void OnPlaceObject(Point pt, TileIndex tile) override { VpStartPlaceSizing(tile, VPM_SINGLE_TILE, DDSP_SINGLE_TILE); MoveAllWindowsOffScreen(); @@ -1204,7 +1246,7 @@ public: MoveAllHiddenWindowsBackToScreen(); } - virtual void OnPlaceObjectAbort() + void OnPlaceObjectAbort() override { MoveAllHiddenWindowsBackToScreen(); this->RaiseButtons(); @@ -1216,7 +1258,7 @@ public: * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; this->UpdateButtons(true); @@ -1236,3 +1278,8 @@ void ShowFoundTownWindow() DeleteToolbarLinkedWindows(); AllocateWindowDescFront(&_found_town_desc, 0); } + +void InitializeTownGui() +{ + _town_local_authority_kdtree.Clear(); +} diff --git a/src/town_kdtree.h b/src/town_kdtree.h new file mode 100644 index 0000000000..9241655854 --- /dev/null +++ b/src/town_kdtree.h @@ -0,0 +1,22 @@ +/* + * 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 town_kdtree.h Declarations for accessing the k-d tree of towns */ + +#ifndef TOWN_KDTREE_H +#define TOWN_KDTREE_H + +#include "core/kdtree.hpp" +#include "town.h" + +inline uint16 Kdtree_TownXYFunc(TownID tid, int dim) { return (dim == 0) ? TileX(Town::Get(tid)->xy) : TileY(Town::Get(tid)->xy); } +typedef Kdtree TownKdtree; + +extern TownKdtree _town_kdtree; +extern TownKdtree _town_local_authority_kdtree; + +#endif diff --git a/src/town_map.h b/src/town_map.h index 016ff9a6d2..248b1bd323 100644 --- a/src/town_map.h +++ b/src/town_map.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/town_type.h b/src/town_type.h index 0c93c8df85..f373a3c043 100644 --- a/src/town_type.h +++ b/src/town_type.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. @@ -76,10 +74,8 @@ enum Ratings { RATING_BRIBE_DOWN_TO = -50 // XXX SHOULD BE SOMETHING LOWER? }; -/** - * Town Layouts - */ -enum TownLayout { +/** Town Layouts. It needs to be 8bits, because we save and load it as such */ +enum TownLayout : byte { TL_BEGIN = 0, TL_ORIGINAL = 0, ///< Original algorithm (min. 1 distance between roads) TL_BETTER_ROADS, ///< Extended original algorithm (min. 2 distance between roads) @@ -91,19 +87,23 @@ enum TownLayout { NUM_TLS, ///< Number of town layouts }; template <> struct EnumPropsT : MakeEnumPropsT {}; -/** It needs to be 8bits, because we save and load it as such */ -typedef SimpleTinyEnumT TownLayoutByte; // typedefing-enumification of TownLayout -/** Town founding setting values */ -enum TownFounding { +/** Town founding setting values. It needs to be 8bits, because we save and load it as such */ +enum TownFounding : byte { TF_BEGIN = 0, ///< Used for iterations and limit testing TF_FORBIDDEN = 0, ///< Forbidden TF_ALLOWED, ///< Allowed TF_CUSTOM_LAYOUT, ///< Allowed, with custom town layout TF_END, ///< Used for iterations and limit testing }; -/** It needs to be 8bits, because we save and load it as such */ -typedef SimpleTinyEnumT TownFoundingByte; + +/** Town cargo generation modes */ +enum TownCargoGenMode : byte { + TCGM_BEGIN = 0, + TCGM_ORIGINAL = 0, ///< Original algorithm (quadratic cargo by population) + TCGM_BITCOUNT, ///< Bit-counted algorithm (normal distribution from individual house population) + TCGM_END, +}; static const uint MAX_LENGTH_TOWN_NAME_CHARS = 32; ///< The maximum length of a town name in characters including '\0' diff --git a/src/townname.cpp b/src/townname.cpp index b6d55f1ef4..5cc414794a 100644 --- a/src/townname.cpp +++ b/src/townname.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. @@ -31,7 +29,7 @@ TownNameParams::TownNameParams(const Town *t) : grfid(t->townnamegrfid), // by default, use supplied data type(t->townnametype) { - if (t->townnamegrfid != 0 && GetGRFTownName(t->townnamegrfid) == NULL) { + if (t->townnamegrfid != 0 && GetGRFTownName(t->townnamegrfid) == nullptr) { /* Fallback to english original */ this->grfid = 0; this->type = SPECSTR_TOWNNAME_ENGLISH; @@ -92,16 +90,15 @@ bool VerifyTownName(uint32 r, const TownNameParams *par, TownNames *town_names) /* Check size and width */ if (Utf8StringLength(buf1) >= MAX_LENGTH_TOWN_NAME_CHARS) return false; - if (town_names != NULL) { + if (town_names != nullptr) { if (town_names->find(buf1) != town_names->end()) return false; town_names->insert(buf1); } else { - const Town *t; - FOR_ALL_TOWNS(t) { + for (const Town *t : Town::Iterate()) { /* We can't just compare the numbers since * several numbers may map to a single name. */ const char *buf = t->name; - if (buf == NULL) { + if (buf == nullptr) { GetTownName(buf2, t, lastof(buf2)); buf = buf2; } @@ -124,7 +121,7 @@ bool GenerateTownName(uint32 *townnameparts, TownNames *town_names) TownNameParams par(_settings_game.game_creation.town_name); /* This function is called very often without entering the gameloop - * inbetween. So reset layout cache to prevent it from growing too big. */ + * in between. So reset layout cache to prevent it from growing too big. */ Layouter::ReduceLineCache(); /* Do not set i too low, since when we run out of names, we loop @@ -504,8 +501,8 @@ static char *MakeFinnishTownName(char *buf, const char *last, uint32 seed) char *end = buf - 1; assert(end >= orig); if (*end == 'i') *end = 'e'; - if (strstr(orig, "a") != NULL || strstr(orig, "o") != NULL || strstr(orig, "u") != NULL || - strstr(orig, "A") != NULL || strstr(orig, "O") != NULL || strstr(orig, "U") != NULL) { + if (strstr(orig, "a") != nullptr || strstr(orig, "o") != nullptr || strstr(orig, "u") != nullptr || + strstr(orig, "A") != nullptr || strstr(orig, "O") != nullptr || strstr(orig, "U") != nullptr) { buf = strecpy(buf, "la", last); } else { buf = strecpy(buf, "l\xC3\xA4", last); diff --git a/src/townname_func.h b/src/townname_func.h index 409993e42a..6438d2b283 100644 --- a/src/townname_func.h +++ b/src/townname_func.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. @@ -17,7 +15,7 @@ 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 = NULL); -bool GenerateTownName(uint32 *townnameparts, TownNames *town_names = NULL); +bool VerifyTownName(uint32 r, const TownNameParams *par, TownNames *town_names = nullptr); +bool GenerateTownName(uint32 *townnameparts, TownNames *town_names = nullptr); #endif /* TOWNNAME_FUNC_H */ diff --git a/src/townname_type.h b/src/townname_type.h index ba8f926861..dd95f8f70a 100644 --- a/src/townname_type.h +++ b/src/townname_type.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/track_func.h b/src/track_func.h index a55d6d8f20..1b56668780 100644 --- a/src/track_func.h +++ b/src/track_func.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. @@ -19,7 +17,7 @@ /** * Iterate through each set Track in a TrackBits value. - * For more informations see FOR_EACH_SET_BIT_EX. + * For more information see FOR_EACH_SET_BIT_EX. * * @param var Loop index variable that stores fallowing set track. Must be of type Track. * @param track_bits The value to iterate through (any expression). @@ -127,7 +125,7 @@ static inline TrackdirBits TrackdirToTrackdirBits(Trackdir trackdir) /** * Removes first Track from TrackBits and returns it * - * This function searchs for the first bit in the TrackBits, + * This function searches for the first bit in the TrackBits, * remove this bit from the parameter and returns the found * bit as Track value. It returns INVALID_TRACK if the * parameter was TRACK_BIT_NONE or INVALID_TRACK_BIT. This @@ -647,7 +645,7 @@ static inline bool IsDiagonalTrackdir(Trackdir trackdir) /** * Checks if the given tracks overlap, ie form a crossing. Basically this - * means when there is more than one track on the tile, exept when there are + * means when there is more than one track on the tile, except when there are * two parallel tracks. * @param bits The tracks present. * @return Whether the tracks present overlap in any way. diff --git a/src/track_type.h b/src/track_type.h index 2982288bba..70278c58d9 100644 --- a/src/track_type.h +++ b/src/track_type.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. @@ -18,7 +16,7 @@ * These are used to specify a single track. * Can be translated to a trackbit with TrackToTrackbit */ -enum Track { +enum Track : byte { TRACK_BEGIN = 0, ///< Used for iterations TRACK_X = 0, ///< Track along the x-axis (north-east to south-west) TRACK_Y = 1, ///< Track along the y-axis (north-west to south-east) @@ -34,11 +32,10 @@ enum Track { DECLARE_POSTFIX_INCREMENT(Track) /** Define basic enum properties */ template <> struct EnumPropsT : MakeEnumPropsT {}; -typedef TinyEnumT TrackByte; /** Bitfield corresponding to Track */ -enum TrackBits { +enum TrackBits : byte { TRACK_BIT_NONE = 0U, ///< No track TRACK_BIT_X = 1U << TRACK_X, ///< X-axis track TRACK_BIT_Y = 1U << TRACK_Y, ///< Y-axis track @@ -60,7 +57,6 @@ enum TrackBits { INVALID_TRACK_BIT = 0xFF, ///< Flag for an invalid trackbits value }; DECLARE_ENUM_AS_BIT_SET(TrackBits) -typedef SimpleTinyEnumT TrackBitsByte; /** * Enumeration for tracks and directions. @@ -71,7 +67,7 @@ typedef SimpleTinyEnumT TrackBitsByte; * reversing track dirs are not considered to be 'valid' except in a small * corner in the road vehicle controller. */ -enum Trackdir { +enum Trackdir : byte { TRACKDIR_BEGIN = 0, ///< Used for iterations TRACKDIR_X_NE = 0, ///< X-axis and direction to north-east TRACKDIR_Y_SE = 1, ///< Y-axis and direction to south-east @@ -95,7 +91,6 @@ enum Trackdir { /** Define basic enum properties */ template <> struct EnumPropsT : MakeEnumPropsT {}; -typedef TinyEnumT TrackdirByte; /** * Enumeration of bitmasks for the TrackDirs @@ -103,7 +98,7 @@ typedef TinyEnumT TrackdirByte; * These are a combination of tracks and directions. Values are 0-5 in one * direction (corresponding to the Track enum) and 8-13 in the other direction. */ -enum TrackdirBits { +enum TrackdirBits : uint16 { TRACKDIR_BIT_NONE = 0U, ///< No track build TRACKDIR_BIT_X_NE = 1U << TRACKDIR_X_NE, ///< Track x-axis, direction north-east TRACKDIR_BIT_Y_SE = 1U << TRACKDIR_Y_SE, ///< Track y-axis, direction south-east @@ -122,7 +117,6 @@ enum TrackdirBits { INVALID_TRACKDIR_BIT = 0xFFFF, ///< Flag for an invalid trackdirbit value }; DECLARE_ENUM_AS_BIT_SET(TrackdirBits) -typedef SimpleTinyEnumT TrackdirBitsShort; typedef uint32 TrackStatus; diff --git a/src/train.h b/src/train.h index 5958cde1a0..af638c283d 100644 --- a/src/train.h +++ b/src/train.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. @@ -36,12 +34,11 @@ enum VehicleRailFlags { }; /** Modes for ignoring signals. */ -enum TrainForceProceeding { +enum TrainForceProceeding : byte { TFP_NONE = 0, ///< Normal operation. TFP_STUCK = 1, ///< Proceed till next signal, but ignore being stuck till then. This includes force leaving depots. TFP_SIGNAL = 2, ///< Ignore next signal, after the signal ignore being stuck. }; -typedef SimpleTinyEnumT TrainForceProceedingByte; /** Flags for Train::ConsistChanged */ enum ConsistChangeFlags { @@ -94,9 +91,9 @@ struct Train FINAL : public GroundVehicle { uint16 crash_anim_pos; ///< Crash animation counter. uint16 flags; - TrackBitsByte track; - TrainForceProceedingByte force_proceed; - RailTypeByte railtype; + TrackBits track; + TrainForceProceeding force_proceed; + RailType railtype; RailTypes compatible_railtypes; /** Ticks waiting in front of a signal, ticks being stuck or a counter for forced proceeding through signals. */ @@ -118,7 +115,7 @@ struct Train FINAL : public GroundVehicle { int GetDisplaySpeed() const { return this->gcache.last_speed; } int GetDisplayMaxSpeed() const { return this->vcache.cached_max_speed; } Money GetRunningCost() const; - int GetDisplayImageWidth(Point *offset = NULL) const; + int GetDisplayImageWidth(Point *offset = nullptr) const; bool IsInDepot() const { return this->track == TRACK_BIT_DEPOT; } bool Tick(); void OnNewDay(); @@ -146,7 +143,7 @@ struct Train FINAL : public GroundVehicle { inline Train *GetNextUnit() const { Train *v = this->GetNextVehicle(); - if (v != NULL && v->IsRearDualheaded()) v = v->GetNextVehicle(); + if (v != nullptr && v->IsRearDualheaded()) v = v->GetNextVehicle(); return v; } @@ -158,7 +155,7 @@ struct Train FINAL : public GroundVehicle { inline Train *GetPrevUnit() { Train *v = this->GetPrevVehicle(); - if (v != NULL && v->IsRearDualheaded()) v = v->GetPrevVehicle(); + if (v != nullptr && v->IsRearDualheaded()) v = v->GetPrevVehicle(); return v; } @@ -173,7 +170,7 @@ struct Train FINAL : public GroundVehicle { * longer than the part after the center. This means we have to round up the * length of the next vehicle but may not round the length of the current * vehicle. */ - return this->gcache.cached_veh_length / 2 + (this->Next() != NULL ? this->Next()->gcache.cached_veh_length + 1 : 0) / 2; + return this->gcache.cached_veh_length / 2 + (this->Next() != nullptr ? this->Next()->gcache.cached_veh_length + 1 : 0) / 2; } protected: // These functions should not be called outside acceleration code. @@ -336,6 +333,4 @@ protected: // These functions should not be called outside acceleration code. } }; -#define FOR_ALL_TRAINS(var) FOR_ALL_VEHICLES_OF_TYPE(Train, var) - #endif /* TRAIN_H */ diff --git a/src/train_cmd.cpp b/src/train_cmd.cpp index 29b2e543e0..5d02764b55 100644 --- a/src/train_cmd.cpp +++ b/src/train_cmd.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. @@ -73,12 +71,11 @@ byte FreightWagonMult(CargoID cargo) /** Checks if lengths of all rail vehicles are valid. If not, shows an error message. */ void CheckTrainsLengths() { - const Train *v; bool first = true; - FOR_ALL_TRAINS(v) { + for (const Train *v : Train::Iterate()) { if (v->First() == v && !(v->vehstatus & VS_CRASHED)) { - for (const Train *u = v, *w = v->Next(); w != NULL; u = w, w = w->Next()) { + for (const Train *u = v, *w = v->Next(); w != nullptr; u = w, w = w->Next()) { if (u->track != TRACK_BIT_DEPOT) { if ((w->track != TRACK_BIT_DEPOT && max(abs(u->x_pos - w->x_pos), abs(u->y_pos - w->y_pos)) != u->CalcNextVehicleOffset()) || @@ -119,7 +116,7 @@ void Train::ConsistChanged(ConsistChangeFlags allowed_changes) bool train_can_tilt = true; - for (Train *u = this; u != NULL; u = u->Next()) { + for (Train *u = this; u != nullptr; u = u->Next()) { const RailVehicleInfo *rvi_u = RailVehInfo(u->engine_type); /* Check the this->first cache. */ @@ -137,20 +134,20 @@ void Train::ConsistChanged(ConsistChangeFlags allowed_changes) u->InvalidateNewGRFCache(); } - for (Train *u = this; u != NULL; u = u->Next()) { + for (Train *u = this; u != nullptr; u = u->Next()) { /* Update user defined data (must be done before other properties) */ u->tcache.user_def_data = GetVehicleProperty(u, PROP_TRAIN_USER_DATA, u->tcache.user_def_data); this->InvalidateNewGRFCache(); u->InvalidateNewGRFCache(); } - for (Train *u = this; u != NULL; u = u->Next()) { + for (Train *u = this; u != nullptr; u = u->Next()) { const Engine *e_u = u->GetEngine(); const RailVehicleInfo *rvi_u = &e_u->u.rail; if (!HasBit(e_u->info.misc_flags, EF_RAIL_TILTS)) train_can_tilt = false; - /* Cache wagon override sprite group. NULL is returned if there is none */ + /* Cache wagon override sprite group. nullptr is returned if there is none */ u->tcache.cached_override = GetWagonOverrideSpriteSet(u->engine_type, u->cargo_type, u->gcache.first_engine); /* Reset colour map */ @@ -202,7 +199,7 @@ void Train::ConsistChanged(ConsistChangeFlags allowed_changes) /* check the vehicle length (callback) */ uint16 veh_len = CALLBACK_FAILED; - if (e_u->GetGRF() != NULL && e_u->GetGRF()->grf_version >= 8) { + if (e_u->GetGRF() != nullptr && e_u->GetGRF()->grf_version >= 8) { /* Use callback 36 */ veh_len = GetVehicleProperty(u, PROP_TRAIN_SHORTEN_FACTOR, CALLBACK_FAILED); @@ -316,7 +313,7 @@ int Train::GetCurveSpeedLimit() const int sum = 0; int pos = 0; int lastpos = -1; - for (const Vehicle *u = this; u->Next() != NULL; u = u->Next(), pos++) { + for (const Vehicle *u = this; u->Next() != nullptr; u = u->Next(), pos++) { Direction this_dir = u->direction; Direction next_dir = u->Next()->direction; @@ -400,7 +397,7 @@ int Train::GetCurrentMaxSpeed() const } } - for (const Train *u = this; u != NULL; u = u->Next()) { + for (const Train *u = this; u != nullptr; u = u->Next()) { if (_settings_game.vehicle.train_acceleration_model == AM_REALISTIC && u->track == TRACK_BIT_DEPOT) { max_speed = min(max_speed, 61); break; @@ -429,7 +426,7 @@ void Train::UpdateAcceleration() /** * Get the width of a train vehicle image in the GUI. - * @param offset Additional offset for positioning the sprite; set to NULL if not needed + * @param offset Additional offset for positioning the sprite; set to nullptr if not needed * @return Width in pixels */ int Train::GetDisplayImageWidth(Point *offset) const @@ -438,12 +435,12 @@ int Train::GetDisplayImageWidth(Point *offset) const int vehicle_pitch = 0; const Engine *e = this->GetEngine(); - if (e->GetGRF() != NULL && is_custom_sprite(e->u.rail.image_index)) { + if (e->GetGRF() != nullptr && is_custom_sprite(e->u.rail.image_index)) { reference_width = e->GetGRF()->traininfo_vehicle_width; vehicle_pitch = e->GetGRF()->traininfo_vehicle_pitch; } - if (offset != NULL) { + if (offset != nullptr) { offset->x = ScaleGUITrad(reference_width) / 2; offset->y = ScaleGUITrad(vehicle_pitch); } @@ -492,7 +489,7 @@ static void GetRailIcon(EngineID engine, bool rear_head, int &y, EngineImageType if (is_custom_sprite(spritenum)) { GetCustomVehicleIcon(engine, dir, image_type, result); if (result->IsValid()) { - if (e->GetGRF() != NULL) { + if (e->GetGRF() != nullptr) { y += ScaleGUITrad(e->GetGRF()->traininfo_vehicle_pitch); } return; @@ -643,8 +640,7 @@ static CommandCost CmdBuildRailWagon(TileIndex tile, DoCommandFlag flags, const CheckConsistencyOfArticulatedVehicle(v); /* Try to connect the vehicle to one of free chains of wagons. */ - Train *w; - FOR_ALL_TRAINS(w) { + for (Train *w : Train::Iterate()) { if (w->tile == tile && ///< Same depot w->IsFreeWagon() && ///< A free wagon chain w->engine_type == e->index && ///< Same type @@ -662,8 +658,7 @@ static CommandCost CmdBuildRailWagon(TileIndex tile, DoCommandFlag flags, const /** Move all free vehicles in the depot to the train */ static void NormalizeTrainVehInDepot(const Train *u) { - const Train *v; - FOR_ALL_TRAINS(v) { + for (const Train *v : Train::Iterate()) { if (v->IsFreeWagon() && v->tile == u->tile && v->track == TRACK_BIT_DEPOT) { if (DoCommand(0, v->index | 1 << 20, u->index, DC_EXEC, @@ -798,23 +793,22 @@ static Train *FindGoodVehiclePos(const Train *src) EngineID eng = src->engine_type; TileIndex tile = src->tile; - Train *dst; - FOR_ALL_TRAINS(dst) { + for (Train *dst : Train::Iterate()) { if (dst->IsFreeWagon() && dst->tile == tile && !(dst->vehstatus & VS_CRASHED)) { /* check so all vehicles in the line have the same engine. */ Train *t = dst; while (t->engine_type == eng) { t = t->Next(); - if (t == NULL) return dst; + if (t == nullptr) return dst; } } } - return NULL; + return nullptr; } /** Helper type for lists/vectors of trains */ -typedef SmallVector TrainList; +typedef std::vector TrainList; /** * Make a backup of a train into a train list. @@ -823,7 +817,7 @@ typedef SmallVector TrainList; */ static void MakeTrainBackup(TrainList &list, Train *t) { - for (; t != NULL; t = t->Next()) *list.Append() = t; + for (; t != nullptr; t = t->Next()) list.push_back(t); } /** @@ -833,17 +827,16 @@ static void MakeTrainBackup(TrainList &list, Train *t) static void RestoreTrainBackup(TrainList &list) { /* No train, nothing to do. */ - if (list.Length() == 0) return; + if (list.size() == 0) return; - Train *prev = NULL; + Train *prev = nullptr; /* Iterate over the list and rebuild it. */ - for (Train **iter = list.Begin(); iter != list.End(); iter++) { - Train *t = *iter; - if (prev != NULL) { + for (Train *t : list) { + if (prev != nullptr) { prev->SetNext(t); - } else if (t->Previous() != NULL) { + } else if (t->Previous() != nullptr) { /* Make sure the head of the train is always the first in the chain. */ - t->Previous()->SetNext(NULL); + t->Previous()->SetNext(nullptr); } prev = t; } @@ -860,10 +853,10 @@ static void RemoveFromConsist(Train *part, bool chain = false) /* Unlink at the front, but make it point to the next * vehicle after the to be remove part. */ - if (part->Previous() != NULL) part->Previous()->SetNext(tail->Next()); + if (part->Previous() != nullptr) part->Previous()->SetNext(tail->Next()); /* Unlink at the back */ - tail->SetNext(NULL); + tail->SetNext(nullptr); } /** @@ -874,7 +867,7 @@ static void RemoveFromConsist(Train *part, bool chain = false) static void InsertInConsist(Train *dst, Train *chain) { /* We do not want to add something in the middle of an articulated part. */ - assert(dst != NULL && (dst->Next() == NULL || !dst->Next()->IsArticulatedPart())); + assert(dst != nullptr && (dst->Next() == nullptr || !dst->Next()->IsArticulatedPart())); chain->Last()->SetNext(dst->Next()); dst->SetNext(chain); @@ -887,12 +880,12 @@ static void InsertInConsist(Train *dst, Train *chain) */ static void NormaliseDualHeads(Train *t) { - for (; t != NULL; t = t->GetNextVehicle()) { + for (; t != nullptr; t = t->GetNextVehicle()) { if (!t->IsMultiheaded() || !t->IsEngine()) continue; /* Make sure that there are no free cars before next engine */ Train *u; - for (u = t; u->Next() != NULL && !u->Next()->IsEngine(); u = u->Next()) {} + for (u = t; u->Next() != nullptr && !u->Next()->IsEngine(); u = u->Next()) {} if (u == t->other_multiheaded_part) continue; @@ -910,10 +903,10 @@ static void NormaliseDualHeads(Train *t) static void NormaliseSubtypes(Train *chain) { /* Nothing to do */ - if (chain == NULL) return; + if (chain == nullptr) return; /* We must be the first in the chain. */ - assert(chain->Previous() == NULL); + assert(chain->Previous() == nullptr); /* Set the appropriate bits for the first in the chain. */ if (chain->IsWagon()) { @@ -924,7 +917,7 @@ static void NormaliseSubtypes(Train *chain) } /* Now clear the bits for the rest of the chain */ - for (Train *t = chain->Next(); t != NULL; t = t->Next()) { + for (Train *t = chain->Next(); t != nullptr; t = t->Next()) { t->ClearFreeWagon(); t->ClearFrontEngine(); } @@ -944,10 +937,10 @@ static CommandCost CheckNewTrain(Train *original_dst, Train *dst, Train *origina /* Just add 'new' engines and subtract the original ones. * If that's less than or equal to 0 we can be sure we did * not add any engines (read: trains) along the way. */ - if ((src != NULL && src->IsEngine() ? 1 : 0) + - (dst != NULL && dst->IsEngine() ? 1 : 0) - - (original_src != NULL && original_src->IsEngine() ? 1 : 0) - - (original_dst != NULL && original_dst->IsEngine() ? 1 : 0) <= 0) { + if ((src != nullptr && src->IsEngine() ? 1 : 0) + + (dst != nullptr && dst->IsEngine() ? 1 : 0) - + (original_src != nullptr && original_src->IsEngine() ? 1 : 0) - + (original_dst != nullptr && original_dst->IsEngine() ? 1 : 0) <= 0) { return CommandCost(); } @@ -966,7 +959,7 @@ static CommandCost CheckNewTrain(Train *original_dst, Train *dst, Train *origina static CommandCost CheckTrainAttachment(Train *t) { /* No multi-part train, no need to check. */ - if (t == NULL || t->Next() == NULL || !t->IsEngine()) return CommandCost(); + if (t == nullptr || t->Next() == nullptr || !t->IsEngine()) return CommandCost(); /* The maximum length for a train. For each part we decrease this by one * and if the result is negative the train is simply too long. */ @@ -977,19 +970,19 @@ static CommandCost CheckTrainAttachment(Train *t) /* Break the prev -> t link so it always holds within the loop. */ t = t->Next(); - prev->SetNext(NULL); + prev->SetNext(nullptr); /* Make sure the cache is cleared. */ head->InvalidateNewGRFCache(); - while (t != NULL) { + while (t != nullptr) { allowed_len -= t->gcache.cached_veh_length; Train *next = t->Next(); /* Unlink the to-be-added piece; it is already unlinked from the previous * part due to the fact that the prev -> t link is broken. */ - t->SetNext(NULL); + t->SetNext(nullptr); /* Don't check callback for articulated or rear dual headed parts */ if (!t->IsArticulatedPart() && !t->IsRearDualheaded()) { @@ -1085,8 +1078,8 @@ static void ArrangeTrains(Train **dst_head, Train *dst, Train **src_head, Train if (*src_head == *dst_head) { /* If we aren't moving part(s) to a new train, we are just moving the * front back and there is not destination head. */ - *dst_head = NULL; - } else if (*dst_head == NULL) { + *dst_head = nullptr; + } else if (*dst_head == nullptr) { /* If we are moving to a new train the head of the move train would become * the head of the new vehicle. */ *dst_head = src; @@ -1099,7 +1092,7 @@ static void ArrangeTrains(Train **dst_head, Train *dst, Train **src_head, Train * In case we are a multiheaded part we want the complete thing to come * with us, so src->GetNextUnit(), however... when we are e.g. a wagon * that is followed by a rear multihead we do not want to include that. */ - *src_head = move_chain ? NULL : + *src_head = move_chain ? nullptr : (src->IsMultiheaded() ? src->GetNextUnit() : src->GetNextVehicle()); } @@ -1123,7 +1116,7 @@ static void ArrangeTrains(Train **dst_head, Train *dst, Train **src_head, Train static void NormaliseTrainHead(Train *head) { /* Not much to do! */ - if (head == NULL) return; + if (head == nullptr) return; /* Tell the 'world' the train changed. */ head->ConsistChanged(CCF_ARRANGE); @@ -1160,7 +1153,7 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u bool move_chain = HasBit(p1, 20); Train *src = Train::GetIfValid(s); - if (src == NULL) return CMD_ERROR; + if (src == nullptr) return CMD_ERROR; CommandCost ret = CheckOwnership(src->owner); if (ret.Failed()) return ret; @@ -1171,10 +1164,10 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u /* if nothing is selected as destination, try and find a matching vehicle to drag to. */ Train *dst; if (d == INVALID_VEHICLE) { - dst = src->IsEngine() ? NULL : FindGoodVehiclePos(src); + dst = src->IsEngine() ? nullptr : FindGoodVehiclePos(src); } else { dst = Train::GetIfValid(d); - if (dst == NULL) return CMD_ERROR; + if (dst == nullptr) return CMD_ERROR; CommandCost ret = CheckOwnership(dst->owner); if (ret.Failed()) return ret; @@ -1185,7 +1178,7 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u /* if an articulated part is being handled, deal with its parent vehicle */ src = src->GetFirstEnginePart(); - if (dst != NULL) { + if (dst != nullptr) { dst = dst->GetFirstEnginePart(); } @@ -1195,13 +1188,13 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u /* locate the head of the two chains */ Train *src_head = src->First(); Train *dst_head; - if (dst != NULL) { + if (dst != nullptr) { dst_head = dst->First(); if (dst_head->tile != src_head->tile) return CMD_ERROR; /* Now deal with articulated part of destination wagon */ dst = dst->GetLastEnginePart(); } else { - dst_head = NULL; + dst_head = nullptr; } if (src->IsRearDualheaded()) return_cmd_error(STR_ERROR_REAR_ENGINE_FOLLOW_FRONT); @@ -1210,13 +1203,13 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u if (move_chain && src_head == dst_head) return CommandCost(); /* When moving a multiheaded part to be place after itself, bail out. */ - if (!move_chain && dst != NULL && dst->IsRearDualheaded() && src == dst->other_multiheaded_part) return CommandCost(); + if (!move_chain && dst != nullptr && dst->IsRearDualheaded() && src == dst->other_multiheaded_part) return CommandCost(); /* Check if all vehicles in the source train are stopped inside a depot. */ if (!src_head->IsStoppedInDepot()) return_cmd_error(STR_ERROR_TRAINS_CAN_ONLY_BE_ALTERED_INSIDE_A_DEPOT); /* Check if all vehicles in the destination train are stopped inside a depot. */ - if (dst_head != NULL && !dst_head->IsStoppedInDepot()) return_cmd_error(STR_ERROR_TRAINS_CAN_ONLY_BE_ALTERED_INSIDE_A_DEPOT); + if (dst_head != nullptr && !dst_head->IsStoppedInDepot()) return_cmd_error(STR_ERROR_TRAINS_CAN_ONLY_BE_ALTERED_INSIDE_A_DEPOT); /* First make a backup of the order of the trains. That way we can do * whatever we want with the order and later on easily revert. */ @@ -1230,13 +1223,13 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u * For the destination head we do not care if it is the same as the source * head because in that case it's just a copy. */ Train *original_src_head = src_head; - Train *original_dst_head = (dst_head == src_head ? NULL : dst_head); + Train *original_dst_head = (dst_head == src_head ? nullptr : dst_head); /* We want this information from before the rearrangement, but execute this after the validation. - * original_src_head can't be NULL; src is by definition != NULL, so src_head can't be NULL as - * src->GetFirst() always yields non-NULL, so eventually original_src_head != NULL as well. */ + * original_src_head can't be nullptr; src is by definition != nullptr, so src_head can't be nullptr as + * src->GetFirst() always yields non-nullptr, so eventually original_src_head != nullptr as well. */ bool original_src_head_front_engine = original_src_head->IsFrontEngine(); - bool original_dst_head_front_engine = original_dst_head != NULL && original_dst_head->IsFrontEngine(); + bool original_dst_head_front_engine = original_dst_head != nullptr && original_dst_head->IsFrontEngine(); /* (Re)arrange the trains in the wanted arrangement. */ ArrangeTrains(&dst_head, dst, &src_head, src, move_chain); @@ -1281,7 +1274,7 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u * b) the 'next' part is an engine that becomes a front engine. * c) there is no 'next' part, nothing else happens * 5) non front engine gets moved and becomes a new train, nothing else happens - * 6) non front engine gets moved within a train / to another train, nothing hapens + * 6) non front engine gets moved within a train / to another train, nothing happens * 7) wagon gets moved, nothing happens */ if (src == original_src_head && src->IsEngine() && !src->IsFrontEngine()) { @@ -1309,8 +1302,8 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u } /* Add new heads to statistics */ - if (src_head != NULL && src_head->IsFrontEngine()) GroupStatistics::CountVehicle(src_head, 1); - if (dst_head != NULL && dst_head->IsFrontEngine()) GroupStatistics::CountVehicle(dst_head, 1); + if (src_head != nullptr && src_head->IsFrontEngine()) GroupStatistics::CountVehicle(src_head, 1); + if (dst_head != nullptr && dst_head->IsFrontEngine()) GroupStatistics::CountVehicle(dst_head, 1); /* Handle 'new engine' part of cases #1b, #2b, #3b, #4b and #5 in NormaliseTrainHead. */ NormaliseTrainHead(src_head); @@ -1321,8 +1314,8 @@ CommandCost CmdMoveRailVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, u CheckCargoCapacity(dst_head); } - if (src_head != NULL) src_head->First()->MarkDirty(); - if (dst_head != NULL) dst_head->First()->MarkDirty(); + if (src_head != nullptr) src_head->First()->MarkDirty(); + if (dst_head != nullptr) dst_head->First()->MarkDirty(); /* We are undoubtedly changing something in the depot and train list. */ InvalidateWindowData(WC_VEHICLE_DEPOT, src->tile); @@ -1364,34 +1357,34 @@ CommandCost CmdSellRailWagon(DoCommandFlag flags, Vehicle *t, uint16 data, uint3 /* We need to keep track of the new head and the head of what we're going to sell. */ Train *new_head = first; - Train *sell_head = NULL; + Train *sell_head = nullptr; /* Split the train in the wanted way. */ - ArrangeTrains(&sell_head, NULL, &new_head, v, sell_chain); + ArrangeTrains(&sell_head, nullptr, &new_head, v, sell_chain); /* We don't need to validate the second train; it's going to be sold. */ - CommandCost ret = ValidateTrains(NULL, NULL, first, new_head, (flags & DC_AUTOREPLACE) == 0); + CommandCost ret = ValidateTrains(nullptr, nullptr, first, new_head, (flags & DC_AUTOREPLACE) == 0); if (ret.Failed()) { /* Restore the train we had. */ RestoreTrainBackup(original); return ret; } - if (first->orders.list == NULL && !OrderList::CanAllocateItem()) { + if (first->orders.list == nullptr && !OrderList::CanAllocateItem()) { /* Restore the train we had. */ RestoreTrainBackup(original); return_cmd_error(STR_ERROR_NO_MORE_SPACE_FOR_ORDERS); } CommandCost cost(EXPENSES_NEW_VEHICLES); - for (Train *t = sell_head; t != NULL; t = t->Next()) cost.AddCost(-t->value); + for (Train *t = sell_head; t != nullptr; t = t->Next()) cost.AddCost(-t->value); /* do it? */ if (flags & DC_EXEC) { /* First normalise the sub types of the chain. */ NormaliseSubtypes(new_head); - if (v == first && v->IsEngine() && !sell_chain && new_head != NULL && new_head->IsFrontEngine()) { + if (v == first && v->IsEngine() && !sell_chain && new_head != nullptr && new_head->IsFrontEngine()) { /* We are selling the front engine. In this case we want to * 'give' the order, unit number and such to the new head. */ new_head->orders.list = first->orders.list; @@ -1619,11 +1612,11 @@ void ReverseTrainSwapVeh(Train *v, int l, int r) /** * Check if the vehicle is a train * @param v vehicle on tile - * @return v if it is a train, NULL otherwise + * @return v if it is a train, nullptr otherwise */ static Vehicle *TrainOnTileEnum(Vehicle *v, void *) { - return (v->type == VEH_TRAIN) ? v : NULL; + return (v->type == VEH_TRAIN) ? v : nullptr; } @@ -1631,18 +1624,18 @@ static Vehicle *TrainOnTileEnum(Vehicle *v, void *) * Checks if a train is approaching a rail-road crossing * @param v vehicle on tile * @param data tile with crossing we are testing - * @return v if it is approaching a crossing, NULL otherwise + * @return v if it is approaching a crossing, nullptr otherwise */ static Vehicle *TrainApproachingCrossingEnum(Vehicle *v, void *data) { - if (v->type != VEH_TRAIN || (v->vehstatus & VS_CRASHED)) return NULL; + if (v->type != VEH_TRAIN || (v->vehstatus & VS_CRASHED)) return nullptr; Train *t = Train::From(v); - if (!t->IsFrontEngine()) return NULL; + if (!t->IsFrontEngine()) return nullptr; TileIndex tile = *(TileIndex *)data; - if (TrainApproachingCrossingTile(t) != tile) return NULL; + if (TrainApproachingCrossingTile(t) != tile) return nullptr; return t; } @@ -1681,7 +1674,7 @@ void UpdateLevelCrossing(TileIndex tile, bool sound) assert(IsLevelCrossingTile(tile)); /* reserved || train on crossing || train approaching crossing */ - bool new_state = HasCrossingReservation(tile) || HasVehicleOnPos(tile, NULL, &TrainOnTileEnum) || TrainApproachingCrossing(tile); + bool new_state = HasCrossingReservation(tile) || HasVehicleOnPos(tile, nullptr, &TrainOnTileEnum) || TrainApproachingCrossing(tile); if (new_state != IsCrossingBarred(tile)) { if (new_state && sound) { @@ -1745,23 +1738,23 @@ static void AdvanceWagonsAfterSwap(Train *v) { /* first of all, fix the situation when the train was entering a depot */ Train *dep = v; // last vehicle in front of just left depot - while (dep->Next() != NULL && (dep->track == TRACK_BIT_DEPOT || dep->Next()->track != TRACK_BIT_DEPOT)) { + while (dep->Next() != nullptr && (dep->track == TRACK_BIT_DEPOT || dep->Next()->track != TRACK_BIT_DEPOT)) { dep = dep->Next(); // find first vehicle outside of a depot, with next vehicle inside a depot } Train *leave = dep->Next(); // first vehicle in a depot we are leaving now - if (leave != NULL) { + if (leave != nullptr) { /* 'pull' next wagon out of the depot, so we won't miss it (it could stay in depot forever) */ int d = TicksToLeaveDepot(dep); if (d <= 0) { leave->vehstatus &= ~VS_HIDDEN; // move it out of the depot leave->track = TrackToTrackBits(GetRailDepotTrack(leave->tile)); - for (int i = 0; i >= d; i--) TrainController(leave, NULL); // maybe move it, and maybe let another wagon leave + for (int i = 0; i >= d; i--) TrainController(leave, nullptr); // maybe move it, and maybe let another wagon leave } } else { - dep = NULL; // no vehicle in a depot, so no vehicle leaving a depot + dep = nullptr; // no vehicle in a depot, so no vehicle leaving a depot } Train *base = v; @@ -1771,7 +1764,7 @@ static void AdvanceWagonsAfterSwap(Train *v) /* We have to make sure all wagons that leave a depot because of train reversing are moved correctly * they have already correct spacing, so we have to make sure they are moved how they should */ - bool nomove = (dep == NULL); // If there is no vehicle leaving a depot, limit the number of wagons moved immediately. + bool nomove = (dep == nullptr); // If there is no vehicle leaving a depot, limit the number of wagons moved immediately. while (length > 2) { /* we reached vehicle (originally) in front of a depot, stop now @@ -1787,7 +1780,7 @@ static void AdvanceWagonsAfterSwap(Train *v) int differential = last->CalcNextVehicleOffset() - base->CalcNextVehicleOffset(); /* do not update images now */ - for (int i = 0; i < differential; i++) TrainController(first, (nomove ? last->Next() : NULL)); + for (int i = 0; i < differential; i++) TrainController(first, (nomove ? last->Next() : nullptr)); base = first; // == base->Next() length -= 2; @@ -1835,7 +1828,7 @@ void ReverseTrainDirection(Train *v) v->ConsistChanged(CCF_TRACK); /* update all images */ - for (Train *u = v; u != NULL; u = u->Next()) u->UpdateViewport(false, false); + for (Train *u = v; u != nullptr; u = u->Next()) u->UpdateViewport(false, false); /* update crossing we were approaching */ if (crossing != INVALID_TILE) UpdateLevelCrossing(crossing); @@ -1894,7 +1887,7 @@ void ReverseTrainDirection(Train *v) CommandCost CmdReverseTrainDirection(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { Train *v = Train::GetIfValid(p1); - if (v == NULL) return CMD_ERROR; + if (v == nullptr) return CMD_ERROR; CommandCost ret = CheckOwnership(v->owner); if (ret.Failed()) return ret; @@ -1930,7 +1923,7 @@ CommandCost CmdReverseTrainDirection(TileIndex tile, DoCommandFlag flags, uint32 /* Properly leave the station if we are loading and won't be loading anymore */ if (v->current_order.IsType(OT_LOADING)) { const Vehicle *last = v; - while (last->Next() != NULL) last = last->Next(); + while (last->Next() != nullptr) last = last->Next(); /* not a station || different station --> leave the station */ if (!IsTileType(last->tile, MP_STATION) || GetStationIndex(last->tile) != GetStationIndex(v->tile)) { @@ -1967,7 +1960,7 @@ CommandCost CmdReverseTrainDirection(TileIndex tile, DoCommandFlag flags, uint32 CommandCost CmdForceTrainProceed(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { Train *t = Train::GetIfValid(p1); - if (t == NULL) return CMD_ERROR; + if (t == nullptr) return CMD_ERROR; if (!t->IsPrimaryVehicle()) return CMD_ERROR; @@ -2014,9 +2007,9 @@ 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 NULL and a depot is found, store its location in the given address. - * @param[out] destination If not \c NULL and a depot is found, store its index in the given address. - * @param[out] reverse If not \c NULL and a depot is found, store reversal information in the given address. + * @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) @@ -2024,9 +2017,9 @@ bool Train::FindClosestDepot(TileIndex *location, DestinationID *destination, bo FindDepotData tfdd = FindClosestTrainDepot(this, 0); if (tfdd.best_length == UINT_MAX) return false; - if (location != NULL) *location = tfdd.tile; - if (destination != NULL) *destination = GetDepotIndex(tfdd.tile); - if (reverse != NULL) *reverse = tfdd.reverse; + if (location != nullptr) *location = tfdd.tile; + if (destination != nullptr) *destination = GetDepotIndex(tfdd.tile); + if (reverse != nullptr) *reverse = tfdd.reverse; return true; } @@ -2100,10 +2093,10 @@ static void CheckNextTrainTile(Train *v) if (HasPbsSignalOnTrackdir(ft.m_new_tile, FindFirstTrackdir(ft.m_new_td_bits))) { /* If the next tile is a PBS signal, try to make a reservation. */ TrackBits tracks = TrackdirBitsToTrackBits(ft.m_new_td_bits); - if (_settings_game.pf.forbid_90_deg) { + if (Rail90DegTurnDisallowed(GetTileRailType(ft.m_old_tile), GetTileRailType(ft.m_new_tile))) { tracks &= ~TrackCrossesTracks(TrackdirToTrack(ft.m_old_td)); } - ChooseTrainTrack(v, ft.m_new_tile, ft.m_exitdir, tracks, false, NULL, false); + ChooseTrainTrack(v, ft.m_new_tile, ft.m_exitdir, tracks, false, nullptr, false); } } } @@ -2117,7 +2110,7 @@ static void CheckNextTrainTile(Train *v) static bool CheckTrainStayInDepot(Train *v) { /* bail out if not all wagons are in the same depot or not in a depot at all */ - for (const Train *u = v; u != NULL; u = u->Next()) { + for (const Train *u = v; u != nullptr; u = u->Next()) { if (u->track != TRACK_BIT_DEPOT || u->tile != v->tile) return false; } @@ -2246,7 +2239,7 @@ void FreeTrainTrackReservation(const Train *v) if (IsRailDepotTile(tile) && TrackdirToExitdir(td) != GetRailDepotDirection(tile)) return; if (v->track == TRACK_BIT_DEPOT) { /* Front engine is in a depot. We enter if some part is not in the depot. */ - for (const Train *u = v; u != NULL; u = u->Next()) { + for (const Train *u = v; u != nullptr; u = u->Next()) { if (u->track != TRACK_BIT_DEPOT || u->tile != v->tile) return; } } @@ -2339,7 +2332,7 @@ static PBSTileInfo ExtendTrainReservation(const Train *v, TrackBits *new_tracks, if (HasOnewaySignalBlockingTrackdir(ft.m_new_tile, FindFirstTrackdir(ft.m_new_td_bits))) break; } - if (_settings_game.pf.forbid_90_deg) { + if (Rail90DegTurnDisallowed(GetTileRailType(ft.m_old_tile), GetTileRailType(ft.m_new_tile))) { ft.m_new_td_bits &= ~TrackdirCrossesTrackdirs(ft.m_old_td); if (ft.m_new_td_bits == TRACKDIR_BIT_NONE) break; } @@ -2360,8 +2353,8 @@ static PBSTileInfo ExtendTrainReservation(const Train *v, TrackBits *new_tracks, if (ft.m_tiles_skipped != 0) ft.m_new_tile -= TileOffsByDiagDir(ft.m_exitdir) * ft.m_tiles_skipped; /* Choice found, path valid but not okay. Save info about the choice tile as well. */ - if (new_tracks != NULL) *new_tracks = TrackdirBitsToTrackBits(ft.m_new_td_bits); - if (enterdir != NULL) *enterdir = ft.m_exitdir; + if (new_tracks != nullptr) *new_tracks = TrackdirBitsToTrackBits(ft.m_new_td_bits); + if (enterdir != nullptr) *enterdir = ft.m_exitdir; return PBSTileInfo(ft.m_new_tile, ft.m_old_td, false); } @@ -2391,7 +2384,7 @@ static PBSTileInfo ExtendTrainReservation(const Train *v, TrackBits *new_tracks, while (tile != stopped || cur_td != stopped_td) { if (!ft.Follow(tile, cur_td)) break; - if (_settings_game.pf.forbid_90_deg) { + if (Rail90DegTurnDisallowed(GetTileRailType(ft.m_old_tile), GetTileRailType(ft.m_new_tile))) { ft.m_new_td_bits &= ~TrackdirCrossesTrackdirs(ft.m_old_td); assert(ft.m_new_td_bits != TRACKDIR_BIT_NONE); } @@ -2474,7 +2467,7 @@ public: if (this->index >= this->v->GetNumOrders()) this->index = 0; Order *order = this->v->GetOrder(this->index); - assert(order != NULL); + assert(order != nullptr); switch (order->GetType()) { case OT_GOTO_DEPOT: @@ -2517,7 +2510,7 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir, assert((tracks & ~TRACK_BIT_MASK) == 0); - if (got_reservation != NULL) *got_reservation = false; + if (got_reservation != nullptr) *got_reservation = false; /* Don't use tracks here as the setting to forbid 90 deg turns might have been switched between reservation and now. */ TrackBits res_tracks = (TrackBits)(GetReservedTrackbits(tile) & DiagdirReachesTracks(enterdir)); @@ -2550,7 +2543,7 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir, } if (res_dest.okay) { /* Got a valid reservation that ends at a safe target, quick exit. */ - if (got_reservation != NULL) *got_reservation = true; + if (got_reservation != nullptr) *got_reservation = true; if (changed_signal) MarkTileDirtyByTile(tile); TryReserveRailTrack(v->tile, TrackdirToTrack(v->GetVehicleTrackdir())); return best_track; @@ -2609,7 +2602,7 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir, TrackBits res = GetReservedTrackbits(tile) & DiagdirReachesTracks(enterdir); best_track = FindFirstTrack(res); TryReserveRailTrack(v->tile, TrackdirToTrack(v->GetVehicleTrackdir())); - if (got_reservation != NULL) *got_reservation = true; + if (got_reservation != nullptr) *got_reservation = true; if (changed_signal) MarkTileDirtyByTile(tile); } else { FreeTrainTrackReservation(v); @@ -2618,7 +2611,7 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir, return best_track; } - if (got_reservation != NULL) *got_reservation = true; + if (got_reservation != nullptr) *got_reservation = true; /* Reservation target found and free, check if it is safe. */ while (!IsSafeWaitingPosition(v, res_dest.tile, res_dest.trackdir, true, _settings_game.pf.forbid_90_deg)) { @@ -2626,7 +2619,7 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir, DiagDirection exitdir = TrackdirToExitdir(res_dest.trackdir); TileIndex next_tile = TileAddByDiagDir(res_dest.tile, exitdir); TrackBits reachable = TrackdirBitsToTrackBits((TrackdirBits)(GetTileTrackStatus(next_tile, TRANSPORT_RAIL, 0))) & DiagdirReachesTracks(exitdir); - if (_settings_game.pf.forbid_90_deg) { + if (Rail90DegTurnDisallowed(GetTileRailType(res_dest.tile), GetTileRailType(next_tile))) { reachable &= ~TrackCrossesTracks(TrackdirToTrack(res_dest.trackdir)); } @@ -2641,7 +2634,7 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir, /* Path found, but could not be reserved. */ FreeTrainTrackReservation(v); if (mark_stuck) MarkTrainAsStuck(v); - if (got_reservation != NULL) *got_reservation = false; + if (got_reservation != nullptr) *got_reservation = false; changed_signal = false; break; } @@ -2650,7 +2643,7 @@ static Track ChooseTrainTrack(Train *v, TileIndex tile, DiagDirection enterdir, if (!TryReserveSafeTrack(v, res_dest.tile, res_dest.trackdir, true)) { FreeTrainTrackReservation(v); if (mark_stuck) MarkTrainAsStuck(v); - if (got_reservation != NULL) *got_reservation = false; + if (got_reservation != nullptr) *got_reservation = false; changed_signal = false; } break; @@ -2689,14 +2682,14 @@ bool TryPathReserve(Train *v, bool mark_as_stuck, bool first_tile_okay) } } - Vehicle *other_train = NULL; + Vehicle *other_train = nullptr; PBSTileInfo origin = FollowTrainReservation(v, &other_train); /* The path we are driving on is already blocked by some other train. * This can only happen in certain situations when mixing path and * block signals or when changing tracks and/or signals. * Exit here as doing any further reservations will probably just * make matters worse. */ - if (other_train != NULL && other_train->index != v->index) { + if (other_train != nullptr && other_train->index != v->index) { if (mark_as_stuck) MarkTrainAsStuck(v); return false; } @@ -2718,7 +2711,7 @@ bool TryPathReserve(Train *v, bool mark_as_stuck, bool first_tile_okay) TileIndex new_tile = TileAddByDiagDir(origin.tile, exitdir); TrackBits reachable = TrackdirBitsToTrackBits(TrackStatusToTrackdirBits(GetTileTrackStatus(new_tile, TRANSPORT_RAIL, 0)) & DiagdirReachesTrackdirs(exitdir)); - if (_settings_game.pf.forbid_90_deg) reachable &= ~TrackCrossesTracks(TrackdirToTrack(origin.trackdir)); + if (Rail90DegTurnDisallowed(GetTileRailType(origin.tile), GetTileRailType(new_tile))) reachable &= ~TrackCrossesTracks(TrackdirToTrack(origin.trackdir)); bool res_made = false; ChooseTrainTrack(v, new_tile, exitdir, reachable, true, &res_made, mark_as_stuck); @@ -2782,7 +2775,7 @@ void Train::MarkDirty() do { v->colourmap = PAL_NONE; v->UpdateViewport(true, false); - } while ((v = v->Next()) != NULL); + } while ((v = v->Next()) != nullptr); /* need to update acceleration and cached values since the goods on the train changed. */ this->CargoChanged(); @@ -2900,7 +2893,7 @@ static bool TrainMovedChangeSignals(TileIndex tile, DiagDirection dir) /** Tries to reserve track under whole train consist. */ void Train::ReserveTrackUnderConsist() const { - for (const Train *u = this; u != NULL; u = u->Next()) { + for (const Train *u = this; u != nullptr; u = u->Next()) { switch (u->track) { case TRACK_BIT_WORMHOLE: TryReserveRailTrack(u->tile, DiagDirToDiagTrack(GetTunnelBridgeDirection(u->tile))); @@ -2929,7 +2922,7 @@ uint Train::Crash(bool flooded) /* Remove the reserved path in front of the train if it is not stuck. * Also clear all reserved tracks the train is currently on. */ if (!HasBit(this->flags, VRF_TRAIN_STUCK)) FreeTrainTrackReservation(this); - for (const Train *v = this; v != NULL; v = v->Next()) { + for (const Train *v = this; v != nullptr; v = v->Next()) { ClearPathReservation(v, v->tile, v->GetVehicleTrackdir()); if (IsTileType(v->tile, MP_TUNNELBRIDGE)) { /* ClearPathReservation will not free the wormhole exit @@ -2987,23 +2980,23 @@ struct TrainCollideChecker { * Collision test function. * @param v %Train vehicle to test collision with. * @param data %Train being examined. - * @return \c NULL (always continue search) + * @return \c nullptr (always continue search) */ static Vehicle *FindTrainCollideEnum(Vehicle *v, void *data) { TrainCollideChecker *tcc = (TrainCollideChecker*)data; /* not a train or in depot */ - if (v->type != VEH_TRAIN || Train::From(v)->track == TRACK_BIT_DEPOT) return NULL; + if (v->type != VEH_TRAIN || Train::From(v)->track == TRACK_BIT_DEPOT) return nullptr; /* do not crash into trains of another company. */ - if (v->owner != tcc->v->owner) return NULL; + if (v->owner != tcc->v->owner) return nullptr; /* get first vehicle now to make most usual checks faster */ Train *coll = Train::From(v)->First(); /* can't collide with own wagons */ - if (coll == tcc->v) return NULL; + if (coll == tcc->v) return nullptr; int x_diff = v->x_pos - tcc->v->x_pos; int y_diff = v->y_pos - tcc->v->y_pos; @@ -3013,20 +3006,20 @@ static Vehicle *FindTrainCollideEnum(Vehicle *v, void *data) * Differences are shifted by 7, mapping range [-7 .. 8] into [0 .. 15] * Differences are then ORed and then we check for any higher bits */ uint hash = (y_diff + 7) | (x_diff + 7); - if (hash & ~15) return NULL; + if (hash & ~15) return nullptr; /* Slower check using multiplication */ int min_diff = (Train::From(v)->gcache.cached_veh_length + 1) / 2 + (tcc->v->gcache.cached_veh_length + 1) / 2 - 1; - if (x_diff * x_diff + y_diff * y_diff > min_diff * min_diff) return NULL; + if (x_diff * x_diff + y_diff * y_diff > min_diff * min_diff) return nullptr; /* Happens when there is a train under bridge next to bridge head */ - if (abs(v->z_pos - tcc->v->z_pos) > 5) return NULL; + if (abs(v->z_pos - tcc->v->z_pos) > 5) return nullptr; /* crash both trains */ tcc->num += TrainCrashed(tcc->v); tcc->num += TrainCrashed(coll); - return NULL; // continue searching + return nullptr; // continue searching } /** @@ -3068,15 +3061,15 @@ static bool CheckTrainCollision(Train *v) static Vehicle *CheckTrainAtSignal(Vehicle *v, void *data) { - if (v->type != VEH_TRAIN || (v->vehstatus & VS_CRASHED)) return NULL; + if (v->type != VEH_TRAIN || (v->vehstatus & VS_CRASHED)) return nullptr; Train *t = Train::From(v); DiagDirection exitdir = *(DiagDirection *)data; /* not front engine of a train, inside wormhole or depot, crashed */ - if (!t->IsFrontEngine() || !(t->track & TRACK_BIT_MASK)) return NULL; + if (!t->IsFrontEngine() || !(t->track & TRACK_BIT_MASK)) return nullptr; - if (t->cur_speed > 5 || VehicleExitDir(t->direction, t->track) != exitdir) return NULL; + if (t->cur_speed > 5 || VehicleExitDir(t->direction, t->track) != exitdir) return nullptr; return t; } @@ -3139,7 +3132,7 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse) TrackBits red_signals = TrackdirBitsToTrackBits(TrackStatusToRedSignals(ts) & reachable_trackdirs); TrackBits bits = TrackdirBitsToTrackBits(trackdirbits); - if (_settings_game.pf.forbid_90_deg && prev == NULL) { + if (Rail90DegTurnDisallowed(GetTileRailType(gp.old_tile), GetTileRailType(gp.new_tile)) && prev == nullptr) { /* We allow wagons to make 90 deg turns, because forbid_90_deg * can be switched on halfway a turn */ bits &= ~TrackCrossesTracks(FindFirstTrack(v->track)); @@ -3152,10 +3145,10 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse) if (!CheckCompatibleRail(v, gp.new_tile)) goto invalid_rail; TrackBits chosen_track; - if (prev == NULL) { + if (prev == nullptr) { /* Currently the locomotive is active. Determine which one of the * available tracks to choose */ - chosen_track = TrackToTrackBits(ChooseTrainTrack(v, gp.new_tile, enterdir, bits, false, NULL, true)); + chosen_track = TrackToTrackBits(ChooseTrainTrack(v, gp.new_tile, enterdir, bits, false, nullptr, true)); assert(chosen_track & (bits | GetReservedTrackbits(gp.new_tile))); if (v->force_proceed != TFP_NONE && IsPlainRailTile(gp.new_tile) && HasSignals(gp.new_tile)) { @@ -3275,7 +3268,7 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse) } /* Clear any track reservation when the last vehicle leaves the tile */ - if (v->Next() == NULL) ClearPathReservation(v, v->tile, v->GetVehicleTrackdir()); + if (v->Next() == nullptr) ClearPathReservation(v, v->tile, v->GetVehicleTrackdir()); v->tile = gp.new_tile; @@ -3292,7 +3285,7 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse) update_signals_crossing = true; if (chosen_dir != v->direction) { - if (prev == NULL && _settings_game.vehicle.train_acceleration_model == AM_ORIGINAL) { + if (prev == nullptr && _settings_game.vehicle.train_acceleration_model == AM_ORIGINAL) { const AccelerationSlowdownParams *asp = &_accel_slowdown[GetRailTypeInfo(v->railtype)->acceleration_type]; DirDiff diff = DirDifference(v->direction, chosen_dir); v->cur_speed -= (diff == DIRDIFF_45RIGHT || diff == DIRDIFF_45LEFT ? asp->small_turn : asp->large_turn) * v->cur_speed >> 8; @@ -3348,7 +3341,7 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse) /* update the Z position of the vehicle */ int old_z = v->UpdateInclination(gp.new_tile != gp.old_tile, false); - if (prev == NULL) { + if (prev == nullptr) { /* This is the first vehicle in the train */ AffectSpeedByZChange(v, old_z); } @@ -3374,7 +3367,7 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse) /* Signals can only change when the first * (above) or the last vehicle moves. */ - if (v->Next() == NULL) { + if (v->Next() == nullptr) { TrainMovedChangeSignals(gp.old_tile, ReverseDiagDir(enterdir)); if (IsLevelCrossingTile(gp.old_tile)) UpdateLevelCrossing(gp.old_tile); } @@ -3390,7 +3383,7 @@ bool TrainController(Train *v, Vehicle *nomove, bool reverse) invalid_rail: /* We've reached end of line?? */ - if (prev != NULL) error("Disconnecting train"); + if (prev != nullptr) error("Disconnecting train"); reverse_train_direction: if (reverse) { @@ -3407,7 +3400,7 @@ reverse_train_direction: * Collect trackbits of all crashed train vehicles on a tile * @param v Vehicle passed from Find/HasVehicleOnPos() * @param data trackdirbits for the result - * @return NULL to iterate over all vehicles on the tile. + * @return nullptr to iterate over all vehicles on the tile. */ static Vehicle *CollectTrackbitsFromCrashedVehiclesEnum(Vehicle *v, void *data) { @@ -3423,7 +3416,7 @@ static Vehicle *CollectTrackbitsFromCrashedVehiclesEnum(Vehicle *v, void *data) } } - return NULL; + return nullptr; } /** @@ -3441,8 +3434,8 @@ static void DeleteLastWagon(Train *v) * *u is then the one-before-last wagon, and *v the last * one which will physically be removed */ Train *u = v; - for (; v->Next() != NULL; v = v->Next()) u = v; - u->SetNext(NULL); + for (; v->Next() != nullptr; v = v->Next()) u = v; + u->SetNext(nullptr); if (first != v) { /* Recalculate cached train properties */ @@ -3461,7 +3454,7 @@ static void DeleteLastWagon(Train *v) Owner owner = v->owner; delete v; - v = NULL; // make sure nobody will try to read 'v' anymore + v = nullptr; // make sure nobody will try to read 'v' anymore if (trackbits == TRACK_BIT_WORMHOLE) { /* Vehicle is inside a wormhole, v->track contains no useful value then. */ @@ -3517,7 +3510,7 @@ static void ChangeTrainDirRandomly(Train *v) v->UpdateViewport(false, true); } } - } while ((v = v->Next()) != NULL); + } while ((v = v->Next()) != nullptr); } /** @@ -3549,13 +3542,13 @@ static bool HandleCrashedTrain(Train *v) EV_EXPLOSION_SMALL); break; } - } while ((u = u->Next()) != NULL); + } while ((u = u->Next()) != nullptr); } if (state <= 240 && !(v->tick_counter & 3)) ChangeTrainDirRandomly(v); if (state >= 4440 && !(v->tick_counter & 0x1F)) { - bool ret = v->Next() != NULL; + bool ret = v->Next() != nullptr; DeleteLastWagon(v); return ret; } @@ -3711,7 +3704,7 @@ static bool TrainCheckIfLineEnds(Train *v, bool reverse) /* mask unreachable track bits if we are forbidden to do 90deg turns */ TrackBits bits = TrackdirBitsToTrackBits(trackdirbits); - if (_settings_game.pf.forbid_90_deg) { + if (Rail90DegTurnDisallowed(GetTileRailType(v->tile), GetTileRailType(tile))) { bits &= ~TrackCrossesTracks(FindFirstTrack(v->track)); } @@ -3838,7 +3831,7 @@ static bool TrainLocoHandler(Train *v, bool mode) /* Loop until the train has finished moving. */ for (;;) { j -= adv_spd; - TrainController(v, NULL); + TrainController(v, nullptr); /* Don't continue to move if the train crashed. */ if (CheckTrainCollision(v)) break; /* Determine distance to next map position */ @@ -3859,7 +3852,7 @@ static bool TrainLocoHandler(Train *v, bool mode) v->SetLastSpeed(); } - for (Train *u = v; u != NULL; u = u->Next()) { + for (Train *u = v; u != nullptr; u = u->Next()) { if ((u->vehstatus & VS_HIDDEN) != 0) continue; u->UpdateViewport(false, false); @@ -3890,7 +3883,7 @@ Money Train::GetRunningCost() const if (v->IsMultiheaded()) cost_factor /= 2; cost += GetPrice(e->u.rail.running_cost_class, cost_factor, e->GetGRF()); - } while ((v = v->GetNextVehicle()) != NULL); + } while ((v = v->GetNextVehicle()) != nullptr); return cost; } diff --git a/src/train_gui.cpp b/src/train_gui.cpp index 51e772b520..476c8f9cdf 100644 --- a/src/train_gui.cpp +++ b/src/train_gui.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. @@ -27,23 +25,23 @@ * @param tile The tile the command was executed on. * @param p1 Additional data for the command (for the #CommandProc) * @param p2 Additional data for the command (for the #CommandProc) + * @param cmd Unused. */ -void CcBuildWagon(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) +void CcBuildWagon(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) { if (result.Failed()) return; /* find a locomotive in the depot. */ - const Vehicle *found = NULL; - const Train *t; - FOR_ALL_TRAINS(t) { + const Vehicle *found = nullptr; + for (const Train *t : Train::Iterate()) { if (t->IsFrontEngine() && t->tile == tile && t->IsStoppedInDepot()) { - if (found != NULL) return; // must be exactly one. + if (found != nullptr) return; // must be exactly one. found = t; } } /* if we found a loco, */ - if (found != NULL) { + if (found != nullptr) { found = found->Last(); /* put the new wagon at the end of the loco. */ DoCommandP(0, _new_vehicle_id, found->index, CMD_MOVE_RAIL_VEHICLE); @@ -65,8 +63,8 @@ static int HighlightDragPosition(int px, int max_width, VehicleID selection, boo assert(selection != INVALID_VEHICLE); int dragged_width = 0; - for (Train *t = Train::Get(selection); t != NULL; t = chain ? t->Next() : (t->HasArticulatedPart() ? t->GetNextArticulatedPart() : NULL)) { - dragged_width += t->GetDisplayImageWidth(NULL); + for (Train *t = Train::Get(selection); t != nullptr; t = chain ? t->Next() : (t->HasArticulatedPart() ? t->GetNextArticulatedPart() : nullptr)) { + dragged_width += t->GetDisplayImageWidth(nullptr); } int drag_hlight_left = rtl ? max(px - dragged_width + 1, 0) : px; @@ -112,7 +110,7 @@ void DrawTrainImage(const Train *v, int left, int right, int y, VehicleID select 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 != NULL && (rtl ? px > 0 : px < max_width); v = v->Next()) { + 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); @@ -174,13 +172,19 @@ struct CargoSummaryItem { { return this->cargo != other.cargo || this->subtype != other.subtype; } + + /** Used by std::find() and similar functions */ + inline bool operator == (const CargoSummaryItem &other) const + { + return !(this->cargo != other.cargo); + } }; 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 /** Container for the cargo summary information. */ -typedef SmallVector CargoSummary; +typedef std::vector CargoSummary; /** Reused container of cargo details */ static CargoSummary _cargo_summary; @@ -263,7 +267,7 @@ static void TrainDetailsCapacityTab(const CargoSummaryItem *item, int left, int */ static void GetCargoSummaryOfArticulatedVehicle(const Train *v, CargoSummary *summary) { - summary->Clear(); + summary->clear(); do { if (!v->GetEngine()->CanCarryCargo()) continue; @@ -272,9 +276,10 @@ static void GetCargoSummaryOfArticulatedVehicle(const Train *v, CargoSummary *su new_item.subtype = GetCargoSubtypeText(v); if (new_item.cargo == INVALID_CARGO && new_item.subtype == STR_EMPTY) continue; - CargoSummaryItem *item = summary->Find(new_item); - if (item == summary->End()) { - item = summary->Append(); + auto item = std::find(summary->begin(), summary->end(), new_item); + if (item == summary->end()) { + summary->emplace_back(); + item = summary->end() - 1; item->cargo = new_item.cargo; item->subtype = new_item.subtype; item->capacity = 0; @@ -285,7 +290,7 @@ static void GetCargoSummaryOfArticulatedVehicle(const Train *v, CargoSummary *su item->capacity += v->cargo_cap; item->amount += v->cargo.StoredCount(); if (item->source == INVALID_STATION) item->source = v->cargo.Source(); - } while ((v = v->Next()) != NULL && v->IsArticulatedPart()); + } while ((v = v->Next()) != nullptr && v->IsArticulatedPart()); } /** @@ -299,7 +304,7 @@ static uint GetLengthOfArticulatedVehicle(const Train *v) do { length += v->GetDisplayImageWidth(); - } while ((v = v->Next()) != NULL && v->IsArticulatedPart()); + } while ((v = v->Next()) != nullptr && v->IsArticulatedPart()); return length; } @@ -317,7 +322,7 @@ int GetTrainDetailsWndVScroll(VehicleID veh_id, TrainDetailsWindowTabs det_tab) if (det_tab == TDW_TAB_TOTALS) { // Total cargo tab CargoArray act_cargo; CargoArray max_cargo; - for (const Vehicle *v = Vehicle::Get(veh_id); v != NULL; v = v->Next()) { + for (const Vehicle *v = Vehicle::Get(veh_id); v != nullptr; v = v->Next()) { act_cargo[v->cargo_type] += v->cargo.StoredCount(); max_cargo[v->cargo_type] += v->cargo_cap; } @@ -330,9 +335,9 @@ int GetTrainDetailsWndVScroll(VehicleID veh_id, TrainDetailsWindowTabs det_tab) } num++; // needs one more because first line is description string } else { - for (const Train *v = Train::Get(veh_id); v != NULL; v = v->GetNextVehicle()) { + for (const Train *v = Train::Get(veh_id); v != nullptr; v = v->GetNextVehicle()) { GetCargoSummaryOfArticulatedVehicle(v, &_cargo_summary); - num += max(1u, _cargo_summary.Length()); + num += max(1u, (unsigned)_cargo_summary.size()); uint length = GetLengthOfArticulatedVehicle(v); if (length > TRAIN_DETAILS_MAX_INDENT) num++; @@ -368,7 +373,7 @@ void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_po bool rtl = _current_text_dir == TD_RTL; Direction dir = rtl ? DIR_E : DIR_W; int x = rtl ? right : left; - for (; v != NULL && vscroll_pos > -vscroll_cap; v = v->GetNextVehicle()) { + for (; v != nullptr && vscroll_pos > -vscroll_cap; v = v->GetNextVehicle()) { GetCargoSummaryOfArticulatedVehicle(v, &_cargo_summary); /* Draw sprites */ @@ -381,7 +386,7 @@ void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_po if (vscroll_pos <= 0 && vscroll_pos > -vscroll_cap) { int pitch = 0; const Engine *e = Engine::Get(v->engine_type); - if (e->GetGRF() != NULL) { + if (e->GetGRF() != nullptr) { pitch = ScaleGUITrad(e->GetGRF()->traininfo_vehicle_pitch); } PaletteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v); @@ -392,7 +397,7 @@ void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_po px += rtl ? -width : width; dx += width; u = u->Next(); - } while (u != NULL && u->IsArticulatedPart()); + } while (u != nullptr && u->IsArticulatedPart()); bool separate_sprite_row = (dx > (uint)ScaleGUITrad(TRAIN_DETAILS_MAX_INDENT)); if (separate_sprite_row) { @@ -400,7 +405,7 @@ void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_po dx = 0; } - uint num_lines = max(1u, _cargo_summary.Length()); + uint num_lines = max(1u, (unsigned)_cargo_summary.size()); for (uint i = 0; i < num_lines; i++) { int sprite_width = max(dx, ScaleGUITrad(TRAIN_DETAILS_MIN_INDENT)) + 3; int data_left = left + (rtl ? 0 : sprite_width); @@ -412,7 +417,7 @@ void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_po } switch (det_tab) { case TDW_TAB_CARGO: - if (i < _cargo_summary.Length()) { + if (i < _cargo_summary.size()) { TrainDetailsCargoTab(&_cargo_summary[i], data_left, data_right, py); } else { DrawString(data_left, data_right, py, STR_QUANTITY_N_A, TC_LIGHT_BLUE); @@ -424,7 +429,7 @@ void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_po break; case TDW_TAB_CAPACITY: - if (i < _cargo_summary.Length()) { + if (i < _cargo_summary.size()) { TrainDetailsCapacityTab(&_cargo_summary[i], data_left, data_right, py); } else { SetDParam(0, STR_EMPTY); @@ -443,7 +448,7 @@ void DrawTrainDetails(const Train *v, int left, int right, int y, int vscroll_po CargoArray max_cargo; Money feeder_share = 0; - for (const Vehicle *u = v; u != NULL; u = u->Next()) { + for (const Vehicle *u = v; u != nullptr; u = u->Next()) { act_cargo[u->cargo_type] += u->cargo.StoredCount(); max_cargo[u->cargo_type] += u->cargo_cap; feeder_share += u->cargo.FeederShare(); diff --git a/src/transparency.h b/src/transparency.h index ab6f9a6f33..54ba24e933 100644 --- a/src/transparency.h +++ b/src/transparency.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/transparency_gui.cpp b/src/transparency_gui.cpp index af4c7d1d00..c824ab8a71 100644 --- a/src/transparency_gui.cpp +++ b/src/transparency_gui.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. @@ -35,13 +33,13 @@ public: this->InitNested(window_number); } - virtual void OnPaint() + void OnPaint() override { this->OnInvalidateData(0); // Must be sure that the widgets show the transparency variable changes, also when we use shortcuts. this->DrawWidgets(); } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { switch (widget) { case WID_TT_SIGNS: @@ -69,7 +67,7 @@ public: } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { if (widget >= WID_TT_BEGIN && widget < WID_TT_END) { if (_ctrl_pressed) { @@ -104,7 +102,7 @@ public: } } - virtual Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number) + Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number) override { Point pt = GetToolbarAlignedWindowPosition(sm_width); pt.y += 2 * (sm_height - this->GetWidget(WID_TT_BUTTONS)->current_y); @@ -116,7 +114,7 @@ public: * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; for (uint i = WID_TT_BEGIN; i < WID_TT_END; i++) { diff --git a/src/transparency_gui.h b/src/transparency_gui.h index bf9003b497..85dfd453d8 100644 --- a/src/transparency_gui.h +++ b/src/transparency_gui.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/transport_type.h b/src/transport_type.h index 28a1c5cf8f..b244e48b31 100644 --- a/src/transport_type.h +++ b/src/transport_type.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/tree_cmd.cpp b/src/tree_cmd.cpp index 7240cf86d3..012904fdce 100644 --- a/src/tree_cmd.cpp +++ b/src/tree_cmd.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. @@ -342,8 +340,8 @@ CommandCost CmdPlantTree(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 /* 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) : NULL; - int limit = (c == NULL ? INT32_MAX : GB(c->tree_limit, 16, 16)); + 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, p2); TILE_AREA_LOOP(tile, ta) { @@ -364,7 +362,7 @@ CommandCost CmdPlantTree(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 if (flags & DC_EXEC) { AddTreeCount(tile, 1); MarkTileDirtyByTile(tile); - if (c != NULL) c->tree_limit -= 1 << 16; + if (c != nullptr) c->tree_limit -= 1 << 16; } /* 2x as expensive to add more trees to an existing tile */ cost.AddCost(_price[PR_BUILD_TREES] * 2); @@ -419,7 +417,7 @@ CommandCost CmdPlantTree(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 if (_game_mode != GM_EDITOR && Company::IsValidID(_current_company)) { Town *t = ClosestTownFromTile(tile, _settings_game.economy.dist_local_authority); - if (t != NULL) ChangeTownRating(t, RATING_TREE_UP_STEP, RATING_TREE_MAXIMUM, flags); + if (t != nullptr) ChangeTownRating(t, RATING_TREE_UP_STEP, RATING_TREE_MAXIMUM, flags); } if (flags & DC_EXEC) { @@ -431,7 +429,7 @@ CommandCost CmdPlantTree(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 /* Plant full grown trees in scenario editor */ PlantTreesOnTile(tile, treetype, 0, _game_mode == GM_EDITOR ? 3 : 0); MarkTileDirtyByTile(tile); - if (c != NULL) c->tree_limit -= 1 << 16; + if (c != nullptr) c->tree_limit -= 1 << 16; /* When planting rainforest-trees, set tropiczone to rainforest in editor. */ if (_game_mode == GM_EDITOR && IsInsideMM(treetype, TREE_RAINFOREST, TREE_CACTUS)) { @@ -552,7 +550,7 @@ static CommandCost ClearTile_Trees(TileIndex tile, DoCommandFlag flags) if (Company::IsValidID(_current_company)) { Town *t = ClosestTownFromTile(tile, _settings_game.economy.dist_local_authority); - if (t != NULL) ChangeTownRating(t, RATING_TREE_DOWN_STEP, RATING_TREE_MINIMUM, flags); + if (t != nullptr) ChangeTownRating(t, RATING_TREE_DOWN_STEP, RATING_TREE_MINIMUM, flags); } num = GetTreeCount(tile); @@ -803,15 +801,15 @@ extern const TileTypeProcs _tile_type_trees_procs = { DrawTile_Trees, // draw_tile_proc GetSlopePixelZ_Trees, // get_slope_z_proc ClearTile_Trees, // clear_tile_proc - NULL, // add_accepted_cargo_proc + nullptr, // add_accepted_cargo_proc GetTileDesc_Trees, // get_tile_desc_proc GetTileTrackStatus_Trees, // get_tile_track_status_proc - NULL, // click_tile_proc - NULL, // animate_tile_proc + nullptr, // click_tile_proc + nullptr, // animate_tile_proc TileLoop_Trees, // tile_loop_proc ChangeTileOwner_Trees, // change_tile_owner_proc - NULL, // add_produced_cargo_proc - NULL, // vehicle_enter_tile_proc + nullptr, // add_produced_cargo_proc + nullptr, // vehicle_enter_tile_proc GetFoundation_Trees, // get_foundation_proc TerraformTile_Trees, // terraform_tile_proc }; diff --git a/src/tree_gui.cpp b/src/tree_gui.cpp index e444745220..81ac2d31cb 100644 --- a/src/tree_gui.cpp +++ b/src/tree_gui.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. @@ -90,7 +88,7 @@ public: return size; } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { if (widget >= WID_BT_TYPE_11 && widget <= WID_BT_TYPE_34) { Dimension d = GetMaxTreeSpriteSize(); @@ -108,7 +106,7 @@ public: } } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { if (widget < WID_BT_TYPE_11 || widget > WID_BT_TYPE_34 || widget - WID_BT_TYPE_11 >= this->count) return; @@ -117,7 +115,7 @@ public: DrawSprite(tree_sprites[i].sprite, tree_sprites[i].pal, (r.left + r.right) / 2 + WD_FRAMERECT_LEFT, r.bottom - 7); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_BT_TYPE_11: case WID_BT_TYPE_12: case WID_BT_TYPE_13: case WID_BT_TYPE_14: @@ -144,18 +142,18 @@ public: } } - virtual void OnPlaceObject(Point pt, TileIndex tile) + void OnPlaceObject(Point pt, TileIndex tile) override { VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_PLANT_TREES); MoveAllWindowsOffScreen(); } - virtual void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) + void OnPlaceDrag(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt) override { VpSelectTilesWithMethod(pt.x, pt.y, select_method); } - virtual void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) + void OnPlaceMouseUp(ViewportPlaceMethod select_method, ViewportDragDropSelectionProcess select_proc, Point pt, TileIndex start_tile, TileIndex end_tile) override { if (pt.x != -1 && select_proc == DDSP_PLANT_TREES) { DoCommandP(end_tile, this->tree_to_plant, start_tile, @@ -167,13 +165,13 @@ public: /** * Initialize the window data */ - virtual void OnInit() + void OnInit() override { this->base = _tree_base_by_landscape[_settings_game.game_creation.landscape]; this->count = _tree_count_by_landscape[_settings_game.game_creation.landscape]; } - virtual void OnPlaceObjectAbort() + void OnPlaceObjectAbort() override { MoveAllHiddenWindowsBackToScreen(); this->RaiseButtons(); diff --git a/src/tree_map.h b/src/tree_map.h index bd1567b54c..e8f68d825d 100644 --- a/src/tree_map.h +++ b/src/tree_map.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. @@ -100,8 +98,8 @@ static inline TreeGround GetTreeGround(TileIndex t) * that this value doesn't count the number of trees on a tile, use * #GetTreeCount instead. This function instead returns some kind of * groundtype of the tile. As the map-array is finite in size and - * the informations about the trees must be saved somehow other - * informations about a tile must be saved somewhere encoded in the + * the information about the trees must be saved somehow other + * information about a tile must be saved somewhere encoded in the * tile. So this function returns the density of a tile for sub arctic * and sub tropical games. This means for sub arctic the type of snowline * (0 to 3 for all 4 types of snowtiles) and for sub tropical the value @@ -264,7 +262,7 @@ static inline void SetTreeCounter(TileIndex t, uint c) /** * Make a tree-tile. * - * This functions change the tile to a tile with trees and all informations which belongs to it. + * This functions change the tile to a tile with trees and all information which belongs to it. * * @param t The tile to make a tree-tile from * @param type The type of the tree diff --git a/src/tunnel_map.cpp b/src/tunnel_map.cpp index 4e6d5a7e13..9de5235801 100644 --- a/src/tunnel_map.cpp +++ b/src/tunnel_map.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. diff --git a/src/tunnel_map.h b/src/tunnel_map.h index d6f475d05c..0fdfcecae2 100644 --- a/src/tunnel_map.h +++ b/src/tunnel_map.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. @@ -48,7 +46,7 @@ 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, RoadTypes r) +static inline void MakeRoadTunnel(TileIndex t, Owner o, DiagDirection d, RoadType road_rt, RoadType tram_rt) { SetTileType(t, MP_TUNNELBRIDGE); SetTileOwner(t, o); @@ -59,9 +57,9 @@ static inline void MakeRoadTunnel(TileIndex t, Owner o, DiagDirection d, RoadTyp SB(_me[t].m6, 2, 4, 0); _me[t].m7 = 0; _me[t].m8 = 0; - SetRoadOwner(t, ROADTYPE_ROAD, o); - if (o != OWNER_TOWN) SetRoadOwner(t, ROADTYPE_TRAM, o); - SetRoadTypes(t, r); + SetRoadOwner(t, RTT_ROAD, o); + if (o != OWNER_TOWN) SetRoadOwner(t, RTT_TRAM, o); + SetRoadTypes(t, road_rt, tram_rt); } /** diff --git a/src/tunnelbridge.h b/src/tunnelbridge.h index 0a2c2293d5..1e35f891cf 100644 --- a/src/tunnelbridge.h +++ b/src/tunnelbridge.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. @@ -13,6 +11,7 @@ #define TUNNELBRIDGE_H #include "map_func.h" +#include "tile_map.h" void MarkBridgeDirty(TileIndex begin, TileIndex end, DiagDirection direction, uint bridge_height); void MarkBridgeDirty(TileIndex tile); @@ -33,6 +32,18 @@ static inline uint GetTunnelBridgeLength(TileIndex begin, TileIndex end) return abs(x2 + y2 - x1 - y1) - 1; } +/** + * Sets the ownership of the bridge/tunnel ramps + * @param begin The begin of the tunnel or bridge. + * @param end The end of the tunnel or bridge. + * @param owner The new owner to set + */ +static inline void SetTunnelBridgeOwner(TileIndex begin, TileIndex end, Owner owner) +{ + SetTileOwner(begin, owner); + SetTileOwner(end, owner); +} + extern TileIndex _build_tunnel_endtile; #endif /* TUNNELBRIDGE_H */ diff --git a/src/tunnelbridge_cmd.cpp b/src/tunnelbridge_cmd.cpp index 06dc24e84f..9023ea2233 100644 --- a/src/tunnelbridge_cmd.cpp +++ b/src/tunnelbridge_cmd.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. @@ -37,9 +35,11 @@ #include "pbs.h" #include "company_base.h" #include "newgrf_railtype.h" +#include "newgrf_roadtype.h" #include "object_base.h" #include "water.h" #include "company_gui.h" +#include "station_func.h" #include "table/strings.h" #include "table/bridge_land.h" @@ -84,7 +84,7 @@ void ResetBridges() { /* First, free sprite table data */ for (BridgeType i = 0; i < MAX_BRIDGES; i++) { - if (_bridge[i].sprite_table != NULL) { + if (_bridge[i].sprite_table != nullptr) { for (BridgePieces j = BRIDGE_PIECE_NORTH; j < BRIDGE_PIECE_INVALID; j++) free(_bridge[i].sprite_table[j]); free(_bridge[i].sprite_table); } @@ -150,7 +150,7 @@ static inline const PalSpriteID *GetBridgeSpriteTable(int index, BridgePieces ta { const BridgeSpec *bridge = GetBridgeSpec(index); assert(table < BRIDGE_PIECE_INVALID); - if (bridge->sprite_table == NULL || bridge->sprite_table[table] == NULL) { + if (bridge->sprite_table == nullptr || bridge->sprite_table[table] == nullptr) { return _bridge_sprite_table[index][table]; } else { return bridge->sprite_table[table]; @@ -230,7 +230,7 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u CompanyID company = _current_company; RailType railtype = INVALID_RAILTYPE; - RoadTypes roadtypes = ROADTYPES_NONE; + RoadType roadtype = INVALID_ROADTYPE; /* unpack parameters */ BridgeType bridge_type = GB(p2, 0, 8); @@ -242,8 +242,8 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u /* type of bridge */ switch (transport_type) { case TRANSPORT_ROAD: - roadtypes = Extract(p2); - if (!HasExactlyOneBit(roadtypes) || !HasRoadTypesAvail(company, roadtypes)) return CMD_ERROR; + roadtype = Extract(p2); + if (!ValParamRoadType(roadtype)) return CMD_ERROR; break; case TRANSPORT_RAIL: @@ -268,7 +268,7 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u company = OWNER_TOWN; /* If we are not within a town, we are not owned by the town */ - if (town == NULL || DistanceSquare(tile_start, town->xy) > town->cache.squared_town_zone_radius[HZB_TOWN_EDGE]) { + if (town == nullptr || DistanceSquare(tile_start, town->xy) > town->cache.squared_town_zone_radius[HZB_TOWN_EDGE]) { company = OWNER_NONE; } } @@ -313,23 +313,48 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u CommandCost cost(EXPENSES_CONSTRUCTION); Owner owner; bool is_new_owner; + RoadType road_rt = INVALID_ROADTYPE; + RoadType tram_rt = INVALID_ROADTYPE; if (IsBridgeTile(tile_start) && IsBridgeTile(tile_end) && GetOtherBridgeEnd(tile_start) == tile_end && GetTunnelBridgeTransportType(tile_start) == transport_type) { /* Replace a current bridge. */ + switch (transport_type) { + case TRANSPORT_RAIL: + /* Keep the reservation, the path stays valid. */ + pbs_reservation = HasTunnelBridgeReservation(tile_start); + break; + + case TRANSPORT_ROAD: + /* Do not remove road types when upgrading a bridge */ + road_rt = GetRoadTypeRoad(tile_start); + tram_rt = GetRoadTypeTram(tile_start); + break; + + default: break; + } + /* If this is a railway bridge, make sure the railtypes match. */ if (transport_type == TRANSPORT_RAIL && GetRailType(tile_start) != railtype) { return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST); } + /* If this is a road bridge, make sure the roadtype matches. */ + if (transport_type == TRANSPORT_ROAD) { + RoadType existing_rt = RoadTypeIsRoad(roadtype) ? road_rt : tram_rt; + if (existing_rt != roadtype && existing_rt != INVALID_ROADTYPE) { + return_cmd_error(STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST); + } + } + /* Do not replace town bridges with lower speed bridges, unless in scenario editor. */ if (!(flags & DC_QUERY_COST) && IsTileOwner(tile_start, OWNER_TOWN) && GetBridgeSpec(bridge_type)->speed < GetBridgeSpec(GetBridgeType(tile_start))->speed && _game_mode != GM_EDITOR) { Town *t = ClosestTownFromTile(tile_start, UINT_MAX); - if (t == NULL) { + if (t == nullptr) { return CMD_ERROR; } else { SetDParam(0, t->index); @@ -338,7 +363,7 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u } /* Do not replace the bridge with the same bridge type. */ - if (!(flags & DC_QUERY_COST) && (bridge_type == GetBridgeType(tile_start)) && (transport_type != TRANSPORT_ROAD || (roadtypes & ~GetRoadTypes(tile_start)) == 0)) { + if (!(flags & DC_QUERY_COST) && (bridge_type == GetBridgeType(tile_start)) && (transport_type != TRANSPORT_ROAD || road_rt == roadtype || tram_rt == roadtype)) { return_cmd_error(STR_ERROR_ALREADY_BUILT); } @@ -353,20 +378,6 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u /* If bridge belonged to bankrupt company, it has a new owner now */ is_new_owner = (owner == OWNER_NONE); if (is_new_owner) owner = company; - - switch (transport_type) { - case TRANSPORT_RAIL: - /* Keep the reservation, the path stays valid. */ - pbs_reservation = HasTunnelBridgeReservation(tile_start); - break; - - case TRANSPORT_ROAD: - /* Do not remove road types when upgrading a bridge */ - roadtypes |= GetRoadTypes(tile_start); - break; - - default: break; - } } else { /* Build a new bridge. */ @@ -471,6 +482,13 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u is_new_owner = true; } + bool hasroad = road_rt != INVALID_ROADTYPE; + bool hastram = tram_rt != INVALID_ROADTYPE; + if (transport_type == TRANSPORT_ROAD) { + if (RoadTypeIsRoad(roadtype)) road_rt = roadtype; + if (RoadTypeIsTram(roadtype)) tram_rt = roadtype; + } + /* do the drill? */ if (flags & DC_EXEC) { DiagDirection dir = AxisToDiagDir(direction); @@ -479,7 +497,7 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u switch (transport_type) { case TRANSPORT_RAIL: /* Add to company infrastructure count if required. */ - if (is_new_owner && c != NULL) c->infrastructure.rail[railtype] += (bridge_len + 2) * TUNNELBRIDGE_TRACKBIT_FACTOR; + if (is_new_owner && c != nullptr) c->infrastructure.rail[railtype] += (bridge_len + 2) * TUNNELBRIDGE_TRACKBIT_FACTOR; MakeRailBridgeRamp(tile_start, owner, bridge_type, dir, railtype); MakeRailBridgeRamp(tile_end, owner, bridge_type, ReverseDiagDir(dir), railtype); SetTunnelBridgeReservation(tile_start, pbs_reservation); @@ -487,31 +505,35 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u break; case TRANSPORT_ROAD: { - RoadTypes prev_roadtypes = IsBridgeTile(tile_start) ? GetRoadTypes(tile_start) : ROADTYPES_NONE; if (is_new_owner) { /* Also give unowned present roadtypes to new owner */ - if (HasBit(prev_roadtypes, ROADTYPE_ROAD) && GetRoadOwner(tile_start, ROADTYPE_ROAD) == OWNER_NONE) ClrBit(prev_roadtypes, ROADTYPE_ROAD); - if (HasBit(prev_roadtypes, ROADTYPE_TRAM) && GetRoadOwner(tile_start, ROADTYPE_TRAM) == OWNER_NONE) ClrBit(prev_roadtypes, ROADTYPE_TRAM); + if (hasroad && GetRoadOwner(tile_start, RTT_ROAD) == OWNER_NONE) hasroad = false; + if (hastram && GetRoadOwner(tile_start, RTT_TRAM) == OWNER_NONE) hastram = false; } - if (c != NULL) { + if (c != nullptr) { /* Add all new road types to the company infrastructure counter. */ - RoadType new_rt; - FOR_EACH_SET_ROADTYPE(new_rt, roadtypes ^ prev_roadtypes) { + if (!hasroad && road_rt != INVALID_ROADTYPE) { /* A full diagonal road tile has two road bits. */ - c->infrastructure.road[new_rt] += (bridge_len + 2) * 2 * TUNNELBRIDGE_TRACKBIT_FACTOR; + c->infrastructure.road[road_rt] += (bridge_len + 2) * 2 * TUNNELBRIDGE_TRACKBIT_FACTOR; + } + if (!hastram && tram_rt != INVALID_ROADTYPE) { + /* A full diagonal road tile has two road bits. */ + c->infrastructure.road[tram_rt] += (bridge_len + 2) * 2 * TUNNELBRIDGE_TRACKBIT_FACTOR; } } - Owner owner_road = HasBit(prev_roadtypes, ROADTYPE_ROAD) ? GetRoadOwner(tile_start, ROADTYPE_ROAD) : company; - Owner owner_tram = HasBit(prev_roadtypes, ROADTYPE_TRAM) ? GetRoadOwner(tile_start, ROADTYPE_TRAM) : company; - MakeRoadBridgeRamp(tile_start, owner, owner_road, owner_tram, bridge_type, dir, roadtypes); - MakeRoadBridgeRamp(tile_end, owner, owner_road, owner_tram, bridge_type, ReverseDiagDir(dir), roadtypes); + Owner owner_road = hasroad ? GetRoadOwner(tile_start, RTT_ROAD) : company; + Owner owner_tram = hastram ? GetRoadOwner(tile_start, RTT_TRAM) : company; + MakeRoadBridgeRamp(tile_start, owner, owner_road, owner_tram, bridge_type, dir, road_rt, tram_rt); + MakeRoadBridgeRamp(tile_end, owner, owner_road, owner_tram, bridge_type, ReverseDiagDir(dir), road_rt, tram_rt); break; } case TRANSPORT_WATER: - if (is_new_owner && c != NULL) c->infrastructure.water += (bridge_len + 2) * TUNNELBRIDGE_TRACKBIT_FACTOR; + if (is_new_owner && c != nullptr) c->infrastructure.water += (bridge_len + 2) * TUNNELBRIDGE_TRACKBIT_FACTOR; MakeAqueductBridgeRamp(tile_start, owner, dir); MakeAqueductBridgeRamp(tile_end, owner, ReverseDiagDir(dir)); + CheckForDockingTile(tile_start); + CheckForDockingTile(tile_end); break; default: @@ -529,21 +551,29 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u YapfNotifyTrackLayoutChange(tile_start, track); } - /* for human player that builds the bridge he gets a selection to choose from bridges (DC_QUERY_COST) - * It's unnecessary to execute this command every time for every bridge. So it is done only - * and cost is computed in "bridge_gui.c". For AI, Towns this has to be of course calculated - */ + /* Human players that build bridges get a selection to choose from (DC_QUERY_COST) + * It's unnecessary to execute this command every time for every bridge. + * So it is done only for humans and cost is computed in bridge_gui.cpp. + * For (non-spectated) AI, Towns this has to be of course calculated. */ Company *c = Company::GetIfValid(company); - if (!(flags & DC_QUERY_COST) || (c != NULL && c->is_ai)) { + if (!(flags & DC_QUERY_COST) || (c != nullptr && c->is_ai && company != _local_company)) { bridge_len += 2; // begin and end tiles/ramps switch (transport_type) { - case TRANSPORT_ROAD: cost.AddCost(bridge_len * _price[PR_BUILD_ROAD] * 2 * CountBits(roadtypes)); break; + case TRANSPORT_ROAD: + if (road_rt != INVALID_ROADTYPE) { + cost.AddCost(bridge_len * 2 * RoadBuildCost(road_rt)); + } + if (tram_rt != INVALID_ROADTYPE) { + cost.AddCost(bridge_len * 2 * RoadBuildCost(tram_rt)); + } + break; + case TRANSPORT_RAIL: cost.AddCost(bridge_len * RailBuildCost(railtype)); break; default: break; } - if (c != NULL) bridge_len = CalcBridgeLenCostFactor(bridge_len); + if (c != nullptr) bridge_len = CalcBridgeLenCostFactor(bridge_len); if (transport_type != TRANSPORT_WATER) { cost.AddCost((int64)bridge_len * _price[PR_BUILD_BRIDGE] * GetBridgeSpec(bridge_type)->price >> 8); @@ -562,7 +592,7 @@ CommandCost CmdBuildBridge(TileIndex end_tile, DoCommandFlag flags, uint32 p1, u * Build Tunnel. * @param start_tile start tile of tunnel * @param flags type of operation - * @param p1 bit 0-5 railtype or roadtypes + * @param p1 bit 0-5 railtype or roadtype * bit 8-9 transport type * @param p2 unused * @param text unused @@ -573,9 +603,8 @@ CommandCost CmdBuildTunnel(TileIndex start_tile, DoCommandFlag flags, uint32 p1, CompanyID company = _current_company; TransportType transport_type = Extract(p1); - RailType railtype = INVALID_RAILTYPE; - RoadTypes rts = ROADTYPES_NONE; + RoadType roadtype = INVALID_ROADTYPE; _build_tunnel_endtile = 0; switch (transport_type) { case TRANSPORT_RAIL: @@ -584,8 +613,8 @@ CommandCost CmdBuildTunnel(TileIndex start_tile, DoCommandFlag flags, uint32 p1, break; case TRANSPORT_ROAD: - rts = Extract(p1); - if (!HasExactlyOneBit(rts) || !HasRoadTypesAvail(company, rts)) return CMD_ERROR; + roadtype = Extract(p1); + if (!ValParamRoadType(roadtype)) return CMD_ERROR; break; default: return CMD_ERROR; @@ -598,7 +627,7 @@ CommandCost CmdBuildTunnel(TileIndex start_tile, DoCommandFlag flags, uint32 p1, company = OWNER_TOWN; /* If we are not within a town, we are not owned by the town */ - if (town == NULL || DistanceSquare(start_tile, town->xy) > town->cache.squared_town_zone_radius[HZB_TOWN_EDGE]) { + if (town == nullptr || DistanceSquare(start_tile, town->xy) > town->cache.squared_town_zone_radius[HZB_TOWN_EDGE]) { company = OWNER_NONE; } } @@ -680,10 +709,9 @@ CommandCost CmdBuildTunnel(TileIndex start_tile, DoCommandFlag flags, uint32 p1, /* Mark the tile as already cleared for the terraform command. * Do this for all tiles (like trees), not only objects. */ ClearedObjectArea *coa = FindClearedObject(end_tile); - if (coa == NULL) { - coa = _cleared_object_areas.Append(); - coa->first_tile = end_tile; - coa->area = TileArea(end_tile, 1, 1); + if (coa == nullptr) { + /*C++17: coa = &*/ _cleared_object_areas.push_back({end_tile, TileArea(end_tile, 1, 1)}); + coa = &_cleared_object_areas.back(); } /* Hide the tile from the terraforming command */ @@ -699,10 +727,11 @@ CommandCost CmdBuildTunnel(TileIndex start_tile, DoCommandFlag flags, uint32 p1, * Deliberately clear the coa pointer to avoid leaving dangling pointers which could * inadvertently be dereferenced. */ - assert(coa >= _cleared_object_areas.Begin() && coa < _cleared_object_areas.End()); - size_t coa_index = coa - _cleared_object_areas.Begin(); + ClearedObjectArea *begin = _cleared_object_areas.data(); + assert(coa >= begin && coa < begin + _cleared_object_areas.size()); + size_t coa_index = coa - begin; assert(coa_index < UINT_MAX); // more than 2**32 cleared areas would be a bug in itself - coa = NULL; + coa = nullptr; ret = DoCommand(end_tile, end_tileh & start_tileh, 0, flags, CMD_TERRAFORM_LAND); _cleared_object_areas[(uint)coa_index].first_tile = old_first_tile; @@ -713,7 +742,7 @@ CommandCost CmdBuildTunnel(TileIndex start_tile, DoCommandFlag flags, uint32 p1, /* Pay for the rail/road in the tunnel including entrances */ switch (transport_type) { - case TRANSPORT_ROAD: cost.AddCost((tiles + 2) * _price[PR_BUILD_ROAD] * 2); break; + case TRANSPORT_ROAD: cost.AddCost((tiles + 2) * RoadBuildCost(roadtype) * 2); break; case TRANSPORT_RAIL: cost.AddCost((tiles + 2) * RailBuildCost(railtype)); break; default: NOT_REACHED(); } @@ -722,20 +751,17 @@ CommandCost CmdBuildTunnel(TileIndex start_tile, DoCommandFlag flags, uint32 p1, Company *c = Company::GetIfValid(company); uint num_pieces = (tiles + 2) * TUNNELBRIDGE_TRACKBIT_FACTOR; if (transport_type == TRANSPORT_RAIL) { - if (!IsTunnelTile(start_tile) && c != NULL) c->infrastructure.rail[railtype] += num_pieces; + if (c != nullptr) c->infrastructure.rail[railtype] += num_pieces; MakeRailTunnel(start_tile, company, direction, railtype); MakeRailTunnel(end_tile, company, ReverseDiagDir(direction), railtype); AddSideToSignalBuffer(start_tile, INVALID_DIAGDIR, company); YapfNotifyTrackLayoutChange(start_tile, DiagDirToDiagTrack(direction)); } else { - if (c != NULL) { - RoadType rt; - FOR_EACH_SET_ROADTYPE(rt, rts ^ (IsTunnelTile(start_tile) ? GetRoadTypes(start_tile) : ROADTYPES_NONE)) { - c->infrastructure.road[rt] += num_pieces * 2; // A full diagonal road has two road bits. - } - } - MakeRoadTunnel(start_tile, company, direction, rts); - MakeRoadTunnel(end_tile, company, ReverseDiagDir(direction), rts); + if (c != nullptr) c->infrastructure.road[roadtype] += num_pieces * 2; // A full diagonal road has two road bits. + RoadType road_rt = RoadTypeIsRoad(roadtype) ? roadtype : INVALID_ROADTYPE; + RoadType tram_rt = RoadTypeIsTram(roadtype) ? roadtype : INVALID_ROADTYPE; + MakeRoadTunnel(start_tile, company, direction, road_rt, tram_rt); + MakeRoadTunnel(end_tile, company, ReverseDiagDir(direction), road_rt, tram_rt); } DirtyCompanyInfrastructureWindows(company); } @@ -756,12 +782,13 @@ static inline CommandCost CheckAllowRemoveTunnelBridge(TileIndex tile) switch (GetTunnelBridgeTransportType(tile)) { case TRANSPORT_ROAD: { - RoadTypes rts = GetRoadTypes(tile); + RoadType road_rt = GetRoadTypeRoad(tile); + RoadType tram_rt = GetRoadTypeTram(tile); Owner road_owner = _current_company; Owner tram_owner = _current_company; - if (HasBit(rts, ROADTYPE_ROAD)) road_owner = GetRoadOwner(tile, ROADTYPE_ROAD); - if (HasBit(rts, ROADTYPE_TRAM)) tram_owner = GetRoadOwner(tile, ROADTYPE_TRAM); + if (road_rt != INVALID_ROADTYPE) road_owner = GetRoadOwner(tile, RTT_ROAD); + if (tram_rt != INVALID_ROADTYPE) tram_owner = GetRoadOwner(tile, RTT_TRAM); /* We can remove unowned road and if the town allows it */ if (road_owner == OWNER_TOWN && _current_company != OWNER_TOWN && !(_settings_game.construction.extra_dynamite || _cheats.magic_bulldozer.value)) { @@ -808,7 +835,7 @@ static CommandCost DoClearTunnel(TileIndex tile, DoCommandFlag flags) _build_tunnel_endtile = endtile; - Town *t = NULL; + Town *t = nullptr; if (IsTileOwner(tile, OWNER_TOWN) && _game_mode != GM_EDITOR) { t = ClosestTownFromTile(tile, UINT_MAX); // town penalty rating @@ -833,10 +860,10 @@ static CommandCost DoClearTunnel(TileIndex tile, DoCommandFlag flags) Track track = DiagDirToDiagTrack(dir); Owner owner = GetTileOwner(tile); - Train *v = NULL; + Train *v = nullptr; if (HasTunnelBridgeReservation(tile)) { v = GetTrainForReservation(tile, track); - if (v != NULL) FreeTrainTrackReservation(v); + if (v != nullptr) FreeTrainTrackReservation(v); } if (Company::IsValidID(owner)) { @@ -854,17 +881,11 @@ static CommandCost DoClearTunnel(TileIndex tile, DoCommandFlag flags) YapfNotifyTrackLayoutChange(tile, track); YapfNotifyTrackLayoutChange(endtile, track); - if (v != NULL) TryPathReserve(v); + if (v != nullptr) TryPathReserve(v); } else { - RoadType rt; - FOR_EACH_SET_ROADTYPE(rt, GetRoadTypes(tile)) { - /* A full diagonal road tile has two road bits. */ - Company *c = Company::GetIfValid(GetRoadOwner(tile, rt)); - if (c != NULL) { - c->infrastructure.road[rt] -= len * 2 * TUNNELBRIDGE_TRACKBIT_FACTOR; - DirtyCompanyInfrastructureWindows(c->index); - } - } + /* A full diagonal road tile has two road bits. */ + UpdateCompanyRoadInfrastructure(GetRoadTypeRoad(tile), GetRoadOwner(tile, RTT_ROAD), -(int)(len * 2 * TUNNELBRIDGE_TRACKBIT_FACTOR)); + UpdateCompanyRoadInfrastructure(GetRoadTypeTram(tile), GetRoadOwner(tile, RTT_TRAM), -(int)(len * 2 * TUNNELBRIDGE_TRACKBIT_FACTOR)); DoClearSquare(tile); DoClearSquare(endtile); @@ -893,7 +914,7 @@ static CommandCost DoClearBridge(TileIndex tile, DoCommandFlag flags) DiagDirection direction = GetTunnelBridgeDirection(tile); TileIndexDiff delta = TileOffsByDiagDir(direction); - Town *t = NULL; + Town *t = nullptr; if (IsTileOwner(tile, OWNER_TOWN) && _game_mode != GM_EDITOR) { t = ClosestTownFromTile(tile, UINT_MAX); // town penalty rating @@ -917,33 +938,35 @@ static CommandCost DoClearBridge(TileIndex tile, DoCommandFlag flags) bool rail = GetTunnelBridgeTransportType(tile) == TRANSPORT_RAIL; Owner owner = GetTileOwner(tile); int height = GetBridgeHeight(tile); - Train *v = NULL; + Train *v = nullptr; if (rail && HasTunnelBridgeReservation(tile)) { v = GetTrainForReservation(tile, DiagDirToDiagTrack(direction)); - if (v != NULL) FreeTrainTrackReservation(v); + 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; } else if (GetTunnelBridgeTransportType(tile) == TRANSPORT_ROAD) { - RoadType rt; - FOR_EACH_SET_ROADTYPE(rt, GetRoadTypes(tile)) { - Company *c = Company::GetIfValid(GetRoadOwner(tile, rt)); - if (c != NULL) { - /* A full diagonal road tile has two road bits. */ - c->infrastructure.road[rt] -= len * 2 * TUNNELBRIDGE_TRACKBIT_FACTOR; - DirtyCompanyInfrastructureWindows(c->index); - } - } + /* A full diagonal road tile has two road bits. */ + UpdateCompanyRoadInfrastructure(GetRoadTypeRoad(tile), GetRoadOwner(tile, RTT_ROAD), -(int)(len * 2 * TUNNELBRIDGE_TRACKBIT_FACTOR)); + 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) { @@ -963,7 +986,7 @@ static CommandCost DoClearBridge(TileIndex tile, DoCommandFlag flags) YapfNotifyTrackLayoutChange(tile, track); YapfNotifyTrackLayoutChange(endtile, track); - if (v != NULL) TryPathReserve(v, true); + if (v != nullptr) TryPathReserve(v, true); } } @@ -1018,7 +1041,7 @@ static int DrawPillarColumn(int z_bottom, int z_top, const PalSpriteID *psid, in { int cur_z; for (cur_z = z_top; cur_z >= z_bottom; cur_z -= TILE_HEIGHT) { - DrawPillar(psid, x, y, cur_z, w, h, NULL); + DrawPillar(psid, x, y, cur_z, w, h, nullptr); } return cur_z; } @@ -1082,19 +1105,90 @@ static void DrawBridgePillars(const PalSpriteID *psid, const TileInfo *ti, Axis } /** - * Draws the trambits over an already drawn (lower end) of a bridge. - * @param x the x of the bridge - * @param y the y of the bridge - * @param z the z of the bridge - * @param offset number representing whether to level or sloped and the direction - * @param overlay do we want to still see the road? - * @param head are we drawing bridge head? + * Draws the road and trambits over an already drawn (lower end) of a bridge. + * @param head_tile bridge head tile with roadtype information + * @param x the x of the bridge + * @param y the y of the bridge + * @param z the z of the bridge + * @param offset sprite offset identifying flat to sloped bridge tiles + * @param head are we drawing bridge head? */ -static void DrawBridgeTramBits(int x, int y, int z, int offset, bool overlay, bool head) +static void DrawBridgeRoadBits(TileIndex head_tile, int x, int y, int z, int offset, bool head) { - static const SpriteID tram_offsets[2][6] = { { 107, 108, 109, 110, 111, 112 }, { 4, 5, 15, 16, 17, 18 } }; - static const SpriteID back_offsets[6] = { 95, 96, 99, 102, 100, 101 }; - static const SpriteID front_offsets[6] = { 97, 98, 103, 106, 104, 105 }; + RoadType road_rt = GetRoadTypeRoad(head_tile); + RoadType tram_rt = GetRoadTypeTram(head_tile); + const RoadTypeInfo *road_rti = road_rt == INVALID_ROADTYPE ? nullptr : GetRoadTypeInfo(road_rt); + const RoadTypeInfo *tram_rti = tram_rt == INVALID_ROADTYPE ? nullptr : GetRoadTypeInfo(tram_rt); + + SpriteID seq_back[4] = { 0 }; + bool trans_back[4] = { false }; + SpriteID seq_front[4] = { 0 }; + bool trans_front[4] = { false }; + + static const SpriteID overlay_offsets[6] = { 0, 1, 11, 12, 13, 14 }; + static const SpriteID back_offsets[6] = { 95, 96, 99, 102, 100, 101 }; + static const SpriteID front_offsets[6] = { 97, 98, 103, 106, 104, 105 }; + + if (head || !IsInvisibilitySet(TO_BRIDGES)) { + /* Road underlay takes precedence over tram */ + trans_back[0] = !head && IsTransparencySet(TO_BRIDGES); + if (road_rti != nullptr) { + if (road_rti->UsesOverlay()) { + seq_back[0] = GetCustomRoadSprite(road_rti, head_tile, ROTSG_BRIDGE, head ? TCX_NORMAL : TCX_ON_BRIDGE) + offset; + } + } else if (tram_rti != nullptr) { + if (tram_rti->UsesOverlay()) { + seq_back[0] = GetCustomRoadSprite(tram_rti, head_tile, ROTSG_BRIDGE, head ? TCX_NORMAL : TCX_ON_BRIDGE) + offset; + } else { + seq_back[0] = SPR_TRAMWAY_BRIDGE + offset; + } + } + + /* Draw road overlay */ + trans_back[1] = !head && IsTransparencySet(TO_BRIDGES); + if (road_rti != nullptr) { + if (road_rti->UsesOverlay()) { + seq_back[1] = GetCustomRoadSprite(road_rti, head_tile, ROTSG_OVERLAY, head ? TCX_NORMAL : TCX_ON_BRIDGE); + if (seq_back[1] != 0) seq_back[1] += overlay_offsets[offset]; + } + } + + /* Draw tram overlay */ + trans_back[2] = !head && IsTransparencySet(TO_BRIDGES); + if (tram_rti != nullptr) { + if (tram_rti->UsesOverlay()) { + seq_back[2] = GetCustomRoadSprite(tram_rti, head_tile, ROTSG_OVERLAY, head ? TCX_NORMAL : TCX_ON_BRIDGE); + if (seq_back[2] != 0) seq_back[2] += overlay_offsets[offset]; + } else if (road_rti != nullptr) { + seq_back[2] = SPR_TRAMWAY_OVERLAY + overlay_offsets[offset]; + } + } + + /* Road catenary takes precedence over tram */ + trans_back[3] = IsTransparencySet(TO_CATENARY); + trans_front[0] = IsTransparencySet(TO_CATENARY); + if (road_rti != nullptr && HasRoadCatenaryDrawn(road_rt)) { + seq_back[3] = GetCustomRoadSprite(road_rti, head_tile, ROTSG_CATENARY_BACK, head ? TCX_NORMAL : TCX_ON_BRIDGE); + seq_front[0] = GetCustomRoadSprite(road_rti, head_tile, ROTSG_CATENARY_FRONT, head ? TCX_NORMAL : TCX_ON_BRIDGE); + if (seq_back[3] == 0 || seq_front[0] == 0) { + seq_back[3] = SPR_TRAMWAY_BASE + back_offsets[offset]; + seq_front[0] = SPR_TRAMWAY_BASE + front_offsets[offset]; + } else { + seq_back[3] += 23 + offset; + seq_front[0] += 23 + offset; + } + } else if (tram_rti != nullptr && HasRoadCatenaryDrawn(tram_rt)) { + seq_back[3] = GetCustomRoadSprite(tram_rti, head_tile, ROTSG_CATENARY_BACK, head ? TCX_NORMAL : TCX_ON_BRIDGE); + seq_front[0] = GetCustomRoadSprite(tram_rti, head_tile, ROTSG_CATENARY_FRONT, head ? TCX_NORMAL : TCX_ON_BRIDGE); + if (seq_back[3] == 0 || seq_front[0] == 0) { + seq_back[3] = SPR_TRAMWAY_BASE + back_offsets[offset]; + seq_front[0] = SPR_TRAMWAY_BASE + front_offsets[offset]; + } else { + seq_back[3] += 23 + offset; + seq_front[0] += 23 + offset; + } + } + } static const uint size_x[6] = { 1, 16, 16, 1, 16, 1 }; static const uint size_y[6] = { 16, 1, 1, 16, 1, 16 }; @@ -1103,28 +1197,25 @@ static void DrawBridgeTramBits(int x, int y, int z, int offset, bool overlay, bo /* The sprites under the vehicles are drawn as SpriteCombine. StartSpriteCombine() has already been called * The bounding boxes here are the same as for bridge front/roof */ - if (head || !IsInvisibilitySet(TO_BRIDGES)) { - AddSortableSpriteToDraw(SPR_TRAMWAY_BASE + tram_offsets[overlay][offset], PAL_NONE, - x, y, size_x[offset], size_y[offset], 0x28, z, - !head && IsTransparencySet(TO_BRIDGES)); - } - - /* Do not draw catenary if it is set invisible */ - if (!IsInvisibilitySet(TO_CATENARY)) { - AddSortableSpriteToDraw(SPR_TRAMWAY_BASE + back_offsets[offset], PAL_NONE, - x, y, size_x[offset], size_y[offset], 0x28, z, - IsTransparencySet(TO_CATENARY)); + for (uint i = 0; i < lengthof(seq_back); ++i) { + if (seq_back[i] != 0) { + AddSortableSpriteToDraw(seq_back[i], PAL_NONE, + x, y, size_x[offset], size_y[offset], 0x28, z, + trans_back[i]); + } } /* Start a new SpriteCombine for the front part */ EndSpriteCombine(); StartSpriteCombine(); - /* For sloped sprites the bounding box needs to be higher, as the pylons stop on a higher point */ - if (!IsInvisibilitySet(TO_CATENARY)) { - AddSortableSpriteToDraw(SPR_TRAMWAY_BASE + front_offsets[offset], PAL_NONE, - x, y, size_x[offset] + front_bb_offset_x[offset], size_y[offset] + front_bb_offset_y[offset], 0x28, z, - IsTransparencySet(TO_CATENARY), front_bb_offset_x[offset], front_bb_offset_y[offset]); + for (uint i = 0; i < lengthof(seq_front); ++i) { + if (seq_front[i] != 0) { + AddSortableSpriteToDraw(seq_front[i], PAL_NONE, + x, y, size_x[offset] + front_bb_offset_x[offset], size_y[offset] + front_bb_offset_y[offset], 0x28, z, + trans_front[i], + front_bb_offset_x[offset], front_bb_offset_y[offset]); + } } } @@ -1188,19 +1279,36 @@ static void DrawTile_TunnelBridge(TileInfo *ti) DrawGroundSprite(image, PAL_NONE); if (transport_type == TRANSPORT_ROAD) { - RoadTypes rts = GetRoadTypes(ti->tile); + RoadType road_rt = GetRoadTypeRoad(ti->tile); + RoadType tram_rt = GetRoadTypeTram(ti->tile); + 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; - if (HasBit(rts, ROADTYPE_TRAM)) { - static const SpriteID tunnel_sprites[2][4] = { { 28, 78, 79, 27 }, { 5, 76, 77, 4 } }; + DrawRoadOverlays(ti, PAL_NONE, road_rti, tram_rti, sprite_offset, sprite_offset); - DrawGroundSprite(SPR_TRAMWAY_BASE + tunnel_sprites[rts - ROADTYPES_TRAM][tunnelbridge_direction], PAL_NONE); - - /* Do not draw wires if they are invisible */ - if (!IsInvisibilitySet(TO_CATENARY)) { - catenary = true; - StartSpriteCombine(); - AddSortableSpriteToDraw(SPR_TRAMWAY_TUNNEL_WIRES + tunnelbridge_direction, PAL_NONE, ti->x, ti->y, BB_data[10], BB_data[11], TILE_HEIGHT, ti->z, IsTransparencySet(TO_CATENARY), BB_data[8], BB_data[9], BB_Z_SEPARATOR); + /* Road catenary takes precedence over tram */ + SpriteID catenary_sprite_base = 0; + if (road_rti != nullptr && HasRoadCatenaryDrawn(road_rt)) { + catenary_sprite_base = GetCustomRoadSprite(road_rti, ti->tile, ROTSG_CATENARY_FRONT); + if (catenary_sprite_base == 0) { + catenary_sprite_base = SPR_TRAMWAY_TUNNEL_WIRES; + } else { + catenary_sprite_base += 19; } + } else if (tram_rti != nullptr && HasRoadCatenaryDrawn(tram_rt)) { + catenary_sprite_base = GetCustomRoadSprite(tram_rti, ti->tile, ROTSG_CATENARY_FRONT); + if (catenary_sprite_base == 0) { + catenary_sprite_base = SPR_TRAMWAY_TUNNEL_WIRES; + } else { + catenary_sprite_base += 19; + } + } + + if (catenary_sprite_base != 0) { + catenary = true; + StartSpriteCombine(); + AddSortableSpriteToDraw(catenary_sprite_base + tunnelbridge_direction, PAL_NONE, ti->x, ti->y, BB_data[10], BB_data[11], TILE_HEIGHT, ti->z, IsTransparencySet(TO_CATENARY), BB_data[8], BB_data[9], BB_Z_SEPARATOR); } } else { const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile)); @@ -1294,20 +1402,18 @@ static void DrawTile_TunnelBridge(TileInfo *ti) AddSortableSpriteToDraw(psid->sprite, psid->pal, ti->x, ti->y, 16, 16, ti->tileh == SLOPE_FLAT ? 0 : 8, ti->z); if (transport_type == TRANSPORT_ROAD) { - RoadTypes rts = GetRoadTypes(ti->tile); - - if (HasBit(rts, ROADTYPE_TRAM)) { - uint offset = tunnelbridge_direction; - int z = ti->z; - if (ti->tileh != SLOPE_FLAT) { - offset = (offset + 1) & 1; - z += TILE_HEIGHT; - } else { - offset += 2; - } - /* DrawBridgeTramBits() calls EndSpriteCombine() and StartSpriteCombine() */ - DrawBridgeTramBits(ti->x, ti->y, z, offset, HasBit(rts, ROADTYPE_ROAD), true); + uint offset = tunnelbridge_direction; + int z = ti->z; + if (ti->tileh != SLOPE_FLAT) { + offset = (offset + 1) & 1; + z += TILE_HEIGHT; + } else { + offset += 2; } + + /* DrawBridgeRoadBits() calls EndSpriteCombine() and StartSpriteCombine() */ + DrawBridgeRoadBits(ti->tile, ti->x, ti->y, z, offset, true); + EndSpriteCombine(); } else if (transport_type == TRANSPORT_RAIL) { const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(ti->tile)); @@ -1465,15 +1571,8 @@ void DrawBridgeMiddle(const TileInfo *ti) psid++; if (transport_type == TRANSPORT_ROAD) { - RoadTypes rts = GetRoadTypes(rampsouth); - - if (HasBit(rts, ROADTYPE_TRAM)) { - /* DrawBridgeTramBits() calls EndSpriteCombine() and StartSpriteCombine() */ - DrawBridgeTramBits(x, y, bridge_z, axis ^ 1, HasBit(rts, ROADTYPE_ROAD), false); - } else { - EndSpriteCombine(); - StartSpriteCombine(); - } + /* DrawBridgeRoadBits() calls EndSpriteCombine() and StartSpriteCombine() */ + DrawBridgeRoadBits(rampsouth, x, y, bridge_z, axis ^ 1, false); } else if (transport_type == TRANSPORT_RAIL) { const RailtypeInfo *rti = GetRailTypeInfo(GetRailType(rampsouth)); if (rti->UsesOverlay() && !IsInvisibilitySet(TO_BRIDGES)) { @@ -1593,9 +1692,20 @@ static void GetTileDesc_TunnelBridge(TileIndex tile, TileDesc *td) Owner road_owner = INVALID_OWNER; Owner tram_owner = INVALID_OWNER; - RoadTypes rts = GetRoadTypes(tile); - if (HasBit(rts, ROADTYPE_ROAD)) road_owner = GetRoadOwner(tile, ROADTYPE_ROAD); - if (HasBit(rts, ROADTYPE_TRAM)) tram_owner = GetRoadOwner(tile, ROADTYPE_TRAM); + RoadType road_rt = GetRoadTypeRoad(tile); + RoadType tram_rt = GetRoadTypeTram(tile); + 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); + } /* Is there a mix of owners? */ if ((tram_owner != INVALID_OWNER && tram_owner != td->owner[0]) || @@ -1624,7 +1734,9 @@ static void GetTileDesc_TunnelBridge(TileIndex tile, TileDesc *td) } } } else if (tt == TRANSPORT_ROAD && !IsTunnel(tile)) { - td->road_speed = GetBridgeSpec(GetBridgeType(tile))->speed; + uint16 spd = GetBridgeSpec(GetBridgeType(tile))->speed; + 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; } } @@ -1660,7 +1772,7 @@ static void TileLoop_TunnelBridge(TileIndex tile) static TrackStatus GetTileTrackStatus_TunnelBridge(TileIndex tile, TransportType mode, uint sub_mode, DiagDirection side) { TransportType transport_type = GetTunnelBridgeTransportType(tile); - if (transport_type != mode || (transport_type == TRANSPORT_ROAD && (GetRoadTypes(tile) & sub_mode) == 0)) return 0; + if (transport_type != mode || (transport_type == TRANSPORT_ROAD && !HasTileRoadType(tile, (RoadTramType)sub_mode))) return 0; DiagDirection dir = GetTunnelBridgeDirection(tile); if (side != INVALID_DIAGDIR && side != ReverseDiagDir(dir)) return 0; @@ -1674,17 +1786,18 @@ static void ChangeTileOwner_TunnelBridge(TileIndex tile, Owner old_owner, Owner * don't want to update the infrastructure counts twice. */ uint num_pieces = tile < other_end ? (GetTunnelBridgeLength(tile, other_end) + 2) * TUNNELBRIDGE_TRACKBIT_FACTOR : 0; - for (RoadType rt = ROADTYPE_ROAD; rt < ROADTYPE_END; rt++) { + FOR_ALL_ROADTRAMTYPES(rtt) { /* Update all roadtypes, no matter if they are present */ - if (GetRoadOwner(tile, rt) == old_owner) { - if (HasBit(GetRoadTypes(tile), rt)) { + if (GetRoadOwner(tile, rtt) == old_owner) { + RoadType rt = GetRoadType(tile, rtt); + if (rt != INVALID_ROADTYPE) { /* Update company infrastructure counts. A full diagonal road tile has two road bits. * No need to dirty windows here, we'll redraw the whole screen anyway. */ Company::Get(old_owner)->infrastructure.road[rt] -= num_pieces * 2; if (new_owner != INVALID_OWNER) Company::Get(new_owner)->infrastructure.road[rt] += num_pieces * 2; } - SetRoadOwner(tile, rt, new_owner == INVALID_OWNER ? OWNER_NONE : new_owner); + SetRoadOwner(tile, rtt, new_owner == INVALID_OWNER ? OWNER_NONE : new_owner); } } @@ -1906,14 +2019,14 @@ extern const TileTypeProcs _tile_type_tunnelbridge_procs = { DrawTile_TunnelBridge, // draw_tile_proc GetSlopePixelZ_TunnelBridge, // get_slope_z_proc ClearTile_TunnelBridge, // clear_tile_proc - NULL, // add_accepted_cargo_proc + nullptr, // add_accepted_cargo_proc GetTileDesc_TunnelBridge, // get_tile_desc_proc GetTileTrackStatus_TunnelBridge, // get_tile_track_status_proc - NULL, // click_tile_proc - NULL, // animate_tile_proc + nullptr, // click_tile_proc + nullptr, // animate_tile_proc TileLoop_TunnelBridge, // tile_loop_proc ChangeTileOwner_TunnelBridge, // change_tile_owner_proc - NULL, // add_produced_cargo_proc + nullptr, // add_produced_cargo_proc VehicleEnter_TunnelBridge, // vehicle_enter_tile_proc GetFoundation_TunnelBridge, // get_foundation_proc TerraformTile_TunnelBridge, // terraform_tile_proc diff --git a/src/tunnelbridge_map.h b/src/tunnelbridge_map.h index 0f7f17b3ac..62d3c14b2d 100644 --- a/src/tunnelbridge_map.h +++ b/src/tunnelbridge_map.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/vehicle.cpp b/src/vehicle.cpp index f4dc0c4ddb..2c57d970de 100644 --- a/src/vehicle.cpp +++ b/src/vehicle.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. @@ -163,7 +161,7 @@ bool Vehicle::NeedsAutorenewing(const Company *c, bool use_renew_setting) const */ void VehicleServiceInDepot(Vehicle *v) { - assert(v != NULL); + assert(v != nullptr); SetWindowDirty(WC_VEHICLE_DETAILS, v->index); // ensure that last service date and reliability are updated do { @@ -173,7 +171,7 @@ void VehicleServiceInDepot(Vehicle *v) /* Prevent vehicles from breaking down directly after exiting the depot. */ v->breakdown_chance /= 4; v = v->Next(); - } while (v != NULL && v->HasEngineType()); + } while (v != nullptr && v->HasEngineType()); } /** @@ -210,7 +208,7 @@ bool Vehicle::NeedsServicing() const Money needed_money = c->settings.engine_renew_money; if (needed_money > c->money) return false; - for (const Vehicle *v = this; v != NULL; v = (v->type == VEH_TRAIN) ? Train::From(v)->GetNextUnit() : NULL) { + for (const Vehicle *v = this; v != nullptr; v = (v->type == VEH_TRAIN) ? Train::From(v)->GetNextUnit() : nullptr) { bool replace_when_old = false; EngineID new_engine = EngineReplacementForCompany(c, v->engine_type, v->group_id, &replace_when_old); @@ -261,13 +259,13 @@ bool Vehicle::NeedsAutomaticServicing() const uint Vehicle::Crash(bool flooded) { assert((this->vehstatus & VS_CRASHED) == 0); - assert(this->Previous() == NULL); // IsPrimaryVehicle fails for free-wagon-chains + assert(this->Previous() == nullptr); // IsPrimaryVehicle fails for free-wagon-chains uint pass = 0; /* Stop the vehicle. */ if (this->IsPrimaryVehicle()) this->vehstatus |= VS_STOPPED; /* crash all wagons, and count passengers */ - for (Vehicle *v = this; v != NULL; v = v->Next()) { + for (Vehicle *v = this; v != nullptr; v = v->Next()) { /* We do not transfer reserver cargo back, so TotalCount() instead of StoredCount() */ if (IsCargoInClass(v->cargo_type, CC_PASSENGERS)) pass += v->cargo.TotalCount(); v->vehstatus |= VS_CRASHED; @@ -281,7 +279,7 @@ uint Vehicle::Crash(bool flooded) SetWindowDirty(WC_VEHICLE_DEPOT, this->tile); delete this->cargo_payment; - assert(this->cargo_payment == NULL); // cleared by ~CargoPayment + assert(this->cargo_payment == nullptr); // cleared by ~CargoPayment return RandomRange(pass + 1); // Randomise deceased passengers. } @@ -301,7 +299,7 @@ void ShowNewGrfVehicleError(EngineID engine, StringID part1, StringID part2, GRF GRFConfig *grfconfig = GetGRFConfig(e->GetGRFID()); /* Missing GRF. Nothing useful can be done in this situation. */ - if (grfconfig == NULL) return; + if (grfconfig == nullptr) return; if (!HasBit(grfconfig->grf_bugs, bug_type)) { SetBit(grfconfig->grf_bugs, bug_type); @@ -384,16 +382,16 @@ static Vehicle *VehicleFromTileHash(int xl, int yl, int xu, int yu, void *data, for (int y = yl; ; y = (y + (1 << HASH_BITS)) & (HASH_MASK << HASH_BITS)) { for (int x = xl; ; x = (x + 1) & HASH_MASK) { Vehicle *v = _vehicle_tile_hash[(x + y) & TOTAL_HASH_MASK]; - for (; v != NULL; v = v->hash_tile_next) { + for (; v != nullptr; v = v->hash_tile_next) { Vehicle *a = proc(v, data); - if (find_first && a != NULL) return a; + if (find_first && a != nullptr) return a; } if (x == xu) break; } if (y == yu) break; } - return NULL; + return nullptr; } @@ -442,18 +440,18 @@ void FindVehicleOnPosXY(int x, int y, void *data, VehicleFromPosProc *proc) /** * Checks whether a vehicle in on a specific location. It will call proc for - * vehicles until it returns non-NULL. + * vehicles until it returns non-nullptr. * @note Use FindVehicleOnPosXY when you have the intention that all vehicles * should be iterated over. * @param x The X location on the map * @param y The Y location on the map * @param data Arbitrary data passed to proc * @param proc The proc that determines whether a vehicle will be "found". - * @return True if proc returned non-NULL. + * @return True if proc returned non-nullptr. */ bool HasVehicleOnPosXY(int x, int y, void *data, VehicleFromPosProc *proc) { - return VehicleFromPosXY(x, y, data, proc, true) != NULL; + return VehicleFromPosXY(x, y, data, proc, true) != nullptr; } /** @@ -472,14 +470,14 @@ static Vehicle *VehicleFromPos(TileIndex tile, void *data, VehicleFromPosProc *p int y = GB(TileY(tile), HASH_RES, HASH_BITS) << HASH_BITS; Vehicle *v = _vehicle_tile_hash[(x + y) & TOTAL_HASH_MASK]; - for (; v != NULL; v = v->hash_tile_next) { + for (; v != nullptr; v = v->hash_tile_next) { if (v->tile != tile) continue; Vehicle *a = proc(v, data); - if (find_first && a != NULL) return a; + if (find_first && a != nullptr) return a; } - return NULL; + return nullptr; } /** @@ -502,31 +500,31 @@ void FindVehicleOnPos(TileIndex tile, void *data, VehicleFromPosProc *proc) /** * Checks whether a vehicle is on a specific location. It will call \a proc for - * vehicles until it returns non-NULL. + * vehicles until it returns non-nullptr. * @note Use #FindVehicleOnPos when you have the intention that all vehicles * should be iterated over. * @param tile The location on the map * @param data Arbitrary data passed to \a proc. * @param proc The \a proc that determines whether a vehicle will be "found". - * @return True if proc returned non-NULL. + * @return True if proc returned non-nullptr. */ bool HasVehicleOnPos(TileIndex tile, void *data, VehicleFromPosProc *proc) { - return VehicleFromPos(tile, data, proc, true) != NULL; + return VehicleFromPos(tile, data, proc, true) != nullptr; } /** * Callback that returns 'real' vehicles lower or at height \c *(int*)data . * @param v Vehicle to examine. * @param data Pointer to height data. - * @return \a v if conditions are met, else \c NULL. + * @return \a v if conditions are met, else \c nullptr. */ static Vehicle *EnsureNoVehicleProcZ(Vehicle *v, void *data) { int z = *(int*)data; - if (v->type == VEH_DISASTER || (v->type == VEH_AIRCRAFT && v->subtype == AIR_SHADOW)) return NULL; - if (v->z_pos > z) return NULL; + if (v->type == VEH_DISASTER || (v->type == VEH_AIRCRAFT && v->subtype == AIR_SHADOW)) return nullptr; + if (v->z_pos > z) return nullptr; return v; } @@ -545,15 +543,15 @@ CommandCost EnsureNoVehicleOnGround(TileIndex tile) * Such a message does not affect MP synchronisation. */ Vehicle *v = VehicleFromPos(tile, &z, &EnsureNoVehicleProcZ, true); - if (v != NULL) return_cmd_error(STR_ERROR_TRAIN_IN_THE_WAY + v->type); + if (v != nullptr) return_cmd_error(STR_ERROR_TRAIN_IN_THE_WAY + v->type); return CommandCost(); } /** Procedure called for every vehicle found in tunnel/bridge in the hash map */ static Vehicle *GetVehicleTunnelBridgeProc(Vehicle *v, void *data) { - if (v->type != VEH_TRAIN && v->type != VEH_ROAD && v->type != VEH_SHIP) return NULL; - if (v == (const Vehicle *)data) return NULL; + if (v->type != VEH_TRAIN && v->type != VEH_ROAD && v->type != VEH_SHIP) return nullptr; + if (v == (const Vehicle *)data) return nullptr; return v; } @@ -572,9 +570,9 @@ CommandCost TunnelBridgeIsFree(TileIndex tile, TileIndex endtile, const Vehicle * Such a message does not affect MP synchronisation. */ Vehicle *v = VehicleFromPos(tile, const_cast(ignore), &GetVehicleTunnelBridgeProc, true); - if (v == NULL) v = VehicleFromPos(endtile, const_cast(ignore), &GetVehicleTunnelBridgeProc, true); + if (v == nullptr) v = VehicleFromPos(endtile, const_cast(ignore), &GetVehicleTunnelBridgeProc, true); - if (v != NULL) return_cmd_error(STR_ERROR_TRAIN_IN_THE_WAY + v->type); + if (v != nullptr) return_cmd_error(STR_ERROR_TRAIN_IN_THE_WAY + v->type); return CommandCost(); } @@ -582,10 +580,10 @@ static Vehicle *EnsureNoTrainOnTrackProc(Vehicle *v, void *data) { TrackBits rail_bits = *(TrackBits *)data; - if (v->type != VEH_TRAIN) return NULL; + if (v->type != VEH_TRAIN) return nullptr; Train *t = Train::From(v); - if ((t->track != rail_bits) && !TracksOverlap(t->track | rail_bits)) return NULL; + if ((t->track != rail_bits) && !TracksOverlap(t->track | rail_bits)) return nullptr; return v; } @@ -605,7 +603,7 @@ CommandCost EnsureNoTrainOnTrackBits(TileIndex tile, TrackBits track_bits) * Such a message does not affect MP synchronisation. */ Vehicle *v = VehicleFromPos(tile, &track_bits, &EnsureNoTrainOnTrackProc, true); - if (v != NULL) return_cmd_error(STR_ERROR_TRAIN_IN_THE_WAY + v->type); + if (v != nullptr) return_cmd_error(STR_ERROR_TRAIN_IN_THE_WAY + v->type); return CommandCost(); } @@ -615,7 +613,7 @@ static void UpdateVehicleTileHash(Vehicle *v, bool remove) Vehicle **new_hash; if (remove) { - new_hash = NULL; + new_hash = nullptr; } else { int x = GB(TileX(v->tile), HASH_RES, HASH_BITS); int y = GB(TileY(v->tile), HASH_RES, HASH_BITS) << HASH_BITS; @@ -625,15 +623,15 @@ static void UpdateVehicleTileHash(Vehicle *v, bool remove) if (old_hash == new_hash) return; /* Remove from the old position in the hash table */ - if (old_hash != NULL) { - if (v->hash_tile_next != NULL) v->hash_tile_next->hash_tile_prev = v->hash_tile_prev; + if (old_hash != nullptr) { + if (v->hash_tile_next != nullptr) v->hash_tile_next->hash_tile_prev = v->hash_tile_prev; *v->hash_tile_prev = v->hash_tile_next; } /* Insert vehicle at beginning of the new position in the hash table */ - if (new_hash != NULL) { + if (new_hash != nullptr) { v->hash_tile_next = *new_hash; - if (v->hash_tile_next != NULL) v->hash_tile_next->hash_tile_prev = &v->hash_tile_next; + if (v->hash_tile_next != nullptr) v->hash_tile_next->hash_tile_prev = &v->hash_tile_next; v->hash_tile_prev = new_hash; *new_hash = v; } @@ -650,21 +648,21 @@ static void UpdateVehicleViewportHash(Vehicle *v, int x, int y) int old_x = v->coord.left; int old_y = v->coord.top; - new_hash = (x == INVALID_COORD) ? NULL : &_vehicle_viewport_hash[GEN_HASH(x, y)]; - old_hash = (old_x == INVALID_COORD) ? NULL : &_vehicle_viewport_hash[GEN_HASH(old_x, old_y)]; + new_hash = (x == INVALID_COORD) ? nullptr : &_vehicle_viewport_hash[GEN_HASH(x, y)]; + old_hash = (old_x == INVALID_COORD) ? nullptr : &_vehicle_viewport_hash[GEN_HASH(old_x, old_y)]; if (old_hash == new_hash) return; /* remove from hash table? */ - if (old_hash != NULL) { - if (v->hash_viewport_next != NULL) v->hash_viewport_next->hash_viewport_prev = v->hash_viewport_prev; + if (old_hash != nullptr) { + if (v->hash_viewport_next != nullptr) v->hash_viewport_next->hash_viewport_prev = v->hash_viewport_prev; *v->hash_viewport_prev = v->hash_viewport_next; } /* insert into hash table? */ - if (new_hash != NULL) { + if (new_hash != nullptr) { v->hash_viewport_next = *new_hash; - if (v->hash_viewport_next != NULL) v->hash_viewport_next->hash_viewport_prev = &v->hash_viewport_next; + if (v->hash_viewport_next != nullptr) v->hash_viewport_next->hash_viewport_prev = &v->hash_viewport_next; v->hash_viewport_prev = new_hash; *new_hash = v; } @@ -672,35 +670,34 @@ static void UpdateVehicleViewportHash(Vehicle *v, int x, int y) void ResetVehicleHash() { - Vehicle *v; - FOR_ALL_VEHICLES(v) { v->hash_tile_current = NULL; } + for (Vehicle *v : Vehicle::Iterate()) { v->hash_tile_current = nullptr; } memset(_vehicle_viewport_hash, 0, sizeof(_vehicle_viewport_hash)); memset(_vehicle_tile_hash, 0, sizeof(_vehicle_tile_hash)); } void ResetVehicleColourMap() { - Vehicle *v; - FOR_ALL_VEHICLES(v) { v->colourmap = PAL_NONE; } + for (Vehicle *v : Vehicle::Iterate()) { v->colourmap = PAL_NONE; } } /** * List of vehicles that should check for autoreplace this tick. * Mapping of vehicle -> leave depot immediately after autoreplace. */ -typedef SmallMap AutoreplaceMap; +typedef SmallMap AutoreplaceMap; static AutoreplaceMap _vehicles_to_autoreplace; void InitializeVehicles() { - _vehicles_to_autoreplace.Reset(); + _vehicles_to_autoreplace.clear(); + _vehicles_to_autoreplace.shrink_to_fit(); ResetVehicleHash(); } uint CountVehiclesInChain(const Vehicle *v) { uint count = 0; - do count++; while ((v = v->Next()) != NULL); + do count++; while ((v = v->Next()) != nullptr); return count; } @@ -811,7 +808,7 @@ void Vehicle::PreDestructor() HideFillingPercent(&this->fill_percent_te_id); this->CancelReservation(INVALID_STATION, st); delete this->cargo_payment; - assert(this->cargo_payment == NULL); // cleared by ~CargoPayment + assert(this->cargo_payment == nullptr); // cleared by ~CargoPayment } if (this->IsEngineCountable()) { @@ -826,7 +823,7 @@ void Vehicle::PreDestructor() if (this->type == VEH_AIRCRAFT && this->IsPrimaryVehicle()) { Aircraft *a = Aircraft::From(this); Station *st = GetTargetAirportIfValid(a); - if (st != NULL) { + if (st != nullptr) { const AirportFTA *layout = st->airport.GetFTA()->layout; CLRBITS(st->airport.flags, layout[a->previous_pos].block | layout[a->pos].block); } @@ -841,7 +838,7 @@ void Vehicle::PreDestructor() } } - if (this->Previous() == NULL) { + if (this->Previous() == nullptr) { InvalidateWindowData(WC_VEHICLE_DEPOT, this->tile); } @@ -878,7 +875,7 @@ Vehicle::~Vehicle() if (!(this->vehstatus & VS_HIDDEN)) this->MarkAllViewportsDirty(); Vehicle *v = this->Next(); - this->SetNext(NULL); + this->SetNext(nullptr); delete v; @@ -917,7 +914,7 @@ static void RunVehicleDayProc() /* Run the day_proc for every DAY_TICKS vehicle starting at _date_fract. */ for (size_t i = _date_fract; i < Vehicle::GetPoolSize(); i += DAY_TICKS) { Vehicle *v = Vehicle::Get(i); - if (v == NULL) continue; + if (v == nullptr) continue; /* Call the 32-day callback if needed */ if ((v->day_counter & 0x1F) == 0 && v->HasEngineType()) { @@ -942,25 +939,24 @@ static void RunVehicleDayProc() void CallVehicleTicks() { - _vehicles_to_autoreplace.Clear(); + _vehicles_to_autoreplace.clear(); RunVehicleDayProc(); { PerformanceMeasurer framerate(PFE_GL_ECONOMY); - Station *st; - FOR_ALL_STATIONS(st) LoadUnloadStation(st); + for (Station *st : Station::Iterate()) LoadUnloadStation(st); } PerformanceAccumulator::Reset(PFE_GL_TRAINS); PerformanceAccumulator::Reset(PFE_GL_ROADVEHS); PerformanceAccumulator::Reset(PFE_GL_SHIPS); PerformanceAccumulator::Reset(PFE_GL_AIRCRAFT); - Vehicle *v; - FOR_ALL_VEHICLES(v) { + for (Vehicle *v : Vehicle::Iterate()) { + size_t vehicle_index = v->index; /* Vehicle could be deleted in this tick */ if (!v->Tick()) { - assert(Vehicle::Get(vehicle_index) == NULL); + assert(Vehicle::Get(vehicle_index) == nullptr); continue; } @@ -1026,16 +1022,16 @@ void CallVehicleTicks() } } - Backup cur_company(_current_company, FILE_LINE); - for (AutoreplaceMap::iterator it = _vehicles_to_autoreplace.Begin(); it != _vehicles_to_autoreplace.End(); it++) { - v = it->first; + Backup cur_company(_current_company, FILE_LINE); + for (auto &it : _vehicles_to_autoreplace) { + Vehicle *v = it.first; /* Autoreplace needs the current company set as the vehicle owner */ cur_company.Change(v->owner); /* Start vehicle if we stopped them in VehicleEnteredDepotThisTick() * We need to stop them between VehicleEnteredDepotThisTick() and here or we risk that * they are already leaving the depot again before being replaced. */ - if (it->second) v->vehstatus &= ~VS_STOPPED; + if (it.second) v->vehstatus &= ~VS_STOPPED; /* Store the position of the effect as the vehicle pointer will become invalid later */ int x = v->x_pos; @@ -1141,7 +1137,7 @@ void ViewportAddVehicles(DrawPixelInfo *dpi) for (int x = xl;; x = (x + GEN_HASHX_INC) & GEN_HASHX_MASK) { const Vehicle *v = _vehicle_viewport_hash[x + y]; // already masked & 0xFFF - while (v != NULL) { + while (v != nullptr) { if (!(v->vehstatus & VS_HIDDEN) && l <= v->coord.right && t <= v->coord.bottom && @@ -1164,19 +1160,19 @@ void ViewportAddVehicles(DrawPixelInfo *dpi) * @param vp Viewport clicked in. * @param x X coordinate in the viewport. * @param y Y coordinate in the viewport. - * @return Closest vehicle, or \c NULL if none found. + * @return Closest vehicle, or \c nullptr if none found. */ Vehicle *CheckClickOnVehicle(const ViewPort *vp, int x, int y) { - Vehicle *found = NULL, *v; + Vehicle *found = nullptr; uint dist, best_dist = UINT_MAX; - if ((uint)(x -= vp->left) >= (uint)vp->width || (uint)(y -= vp->top) >= (uint)vp->height) return NULL; + if ((uint)(x -= vp->left) >= (uint)vp->width || (uint)(y -= vp->top) >= (uint)vp->height) return nullptr; x = ScaleByZoom(x, vp->zoom) + vp->virtual_left; y = ScaleByZoom(y, vp->zoom) + vp->virtual_top; - FOR_ALL_VEHICLES(v) { + for (Vehicle *v : Vehicle::Iterate()) { if ((v->vehstatus & (VS_HIDDEN | VS_UNCLICKABLE)) == 0 && x >= v->coord.left && x <= v->coord.right && y >= v->coord.top && y <= v->coord.bottom) { @@ -1295,7 +1291,7 @@ bool Vehicle::HandleBreakdown() if (!(this->vehstatus & VS_HIDDEN) && !HasBit(EngInfo(this->engine_type)->misc_flags, EF_NO_BREAKDOWN_SMOKE)) { EffectVehicle *u = CreateEffectVehicleRel(this, 4, 4, 5, EV_BREAKDOWN_SMOKE); - if (u != NULL) u->animation_state = this->breakdown_delay * 2; + if (u != nullptr) u->animation_state = this->breakdown_delay * 2; } } @@ -1346,10 +1342,13 @@ void AgeVehicle(Vehicle *v) SetWindowDirty(WC_VEHICLE_DETAILS, v->index); /* Don't warn about non-primary or not ours vehicles or vehicles that are crashed */ - if (v->Previous() != NULL || v->owner != _local_company || (v->vehstatus & VS_CRASHED) != 0) return; + if (v->Previous() != nullptr || v->owner != _local_company || (v->vehstatus & VS_CRASHED) != 0) return; + const Company *c = Company::Get(v->owner); /* Don't warn if a renew is active */ - if (Company::Get(v->owner)->settings.engine_renew && v->GetEngine()->company_avail != 0) return; + if (c->settings.engine_renew && v->GetEngine()->company_avail != 0) return; + /* Don't warn if a replacement is active */ + if (EngineHasReplacementForCompany(c, v->engine_type, v->group_id)) return; StringID str; if (age == -DAYS_IN_LEAP_YEAR) { @@ -1385,18 +1384,18 @@ uint8 CalcPercentVehicleFilled(const Vehicle *front, StringID *colour) bool is_loading = front->current_order.IsType(OT_LOADING); - /* The station may be NULL when the (colour) string does not need to be set. */ + /* The station may be nullptr when the (colour) string does not need to be set. */ const Station *st = Station::GetIfValid(front->last_station_visited); - assert(colour == NULL || (st != NULL && is_loading)); + assert(colour == nullptr || (st != nullptr && is_loading)); bool order_no_load = is_loading && (front->current_order.GetLoadType() & OLFB_NO_LOAD); bool order_full_load = is_loading && (front->current_order.GetLoadType() & OLFB_FULL_LOAD); /* Count up max and used */ - for (const Vehicle *v = front; v != NULL; v = v->Next()) { + for (const Vehicle *v = front; v != nullptr; v = v->Next()) { count += v->cargo.StoredCount(); max += v->cargo_cap; - if (v->cargo_cap != 0 && colour != NULL) { + if (v->cargo_cap != 0 && colour != nullptr) { unloading += HasBit(v->vehicle_flags, VF_CARGO_UNLOADING) ? 1 : 0; loading |= !order_no_load && (order_full_load || st->goods[v->cargo_type].HasRating()) && @@ -1405,7 +1404,7 @@ uint8 CalcPercentVehicleFilled(const Vehicle *front, StringID *colour) } } - if (colour != NULL) { + if (colour != nullptr) { if (unloading == 0 && loading) { *colour = STR_PERCENT_UP; } else if (unloading == 0 && !loading) { @@ -1503,14 +1502,14 @@ void VehicleEnterDepot(Vehicle *v) /* Test whether we are heading for this depot. If not, do nothing. * Note: The target depot for nearest-/manual-depot-orders is only updated on junctions, but we want to accept every depot. */ if ((v->current_order.GetDepotOrderType() & ODTFB_PART_OF_ORDERS) && - real_order != NULL && !(real_order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) && + real_order != nullptr && !(real_order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) && (v->type == VEH_AIRCRAFT ? v->current_order.GetDestination() != GetStationIndex(v->tile) : v->dest_tile != v->tile)) { /* We are heading for another depot, keep driving. */ return; } if (v->current_order.IsRefit()) { - Backup cur_company(_current_company, v->owner, FILE_LINE); + Backup cur_company(_current_company, v->owner, FILE_LINE); CommandCost cost = DoCommand(v->tile, v->index, v->current_order.GetRefitCargo() | 0xFF << 8, DC_EXEC, GetCmdRefitVeh(v)); cur_company.Restore(); @@ -1684,11 +1683,10 @@ VehicleEnterTileStatus VehicleEnterTile(Vehicle *v, TileIndex tile, int x, int y * @param type type of vehicle * @param owner owner of vehicles */ -FreeUnitIDGenerator::FreeUnitIDGenerator(VehicleType type, CompanyID owner) : cache(NULL), maxid(0), curid(0) +FreeUnitIDGenerator::FreeUnitIDGenerator(VehicleType type, CompanyID owner) : cache(nullptr), maxid(0), curid(0) { /* Find maximum */ - const Vehicle *v; - FOR_ALL_VEHICLES(v) { + for (const Vehicle *v : Vehicle::Iterate()) { if (v->type == type && v->owner == owner) { this->maxid = max(this->maxid, v->unitnumber); } @@ -1702,7 +1700,7 @@ FreeUnitIDGenerator::FreeUnitIDGenerator(VehicleType type, CompanyID owner) : ca this->cache = CallocT(this->maxid + 2); /* Fill the cache */ - FOR_ALL_VEHICLES(v) { + for (const Vehicle *v : Vehicle::Iterate()) { if (v->type == type && v->owner == owner) { this->cache[v->unitnumber] = true; } @@ -1753,7 +1751,7 @@ UnitID GetFreeUnitNumber(VehicleType type) * @return true if there is any reason why you may build * the infrastructure for the given vehicle type */ -bool CanBuildVehicleInfrastructure(VehicleType type) +bool CanBuildVehicleInfrastructure(VehicleType type, byte subtype) { assert(IsCompanyBuildableVehicleType(type)); @@ -1766,7 +1764,10 @@ bool CanBuildVehicleInfrastructure(VehicleType type) if (!HasAnyRailtypesAvail(_local_company)) return false; max = _settings_game.vehicle.max_trains; break; - case VEH_ROAD: max = _settings_game.vehicle.max_roadveh; break; + case VEH_ROAD: + if (!HasAnyRoadTypesAvail(_local_company, (RoadTramType)subtype)) return false; + max = _settings_game.vehicle.max_roadveh; + break; case VEH_SHIP: max = _settings_game.vehicle.max_ships; break; case VEH_AIRCRAFT: max = _settings_game.vehicle.max_aircraft; break; default: NOT_REACHED(); @@ -1775,16 +1776,16 @@ bool CanBuildVehicleInfrastructure(VehicleType type) /* We can build vehicle infrastructure when we may build the vehicle type */ if (max > 0) { /* Can we actually build the vehicle type? */ - const Engine *e; - FOR_ALL_ENGINES_OF_TYPE(e, type) { + for (const Engine *e : Engine::IterateType(type)) { + if (type == VEH_ROAD && GetRoadTramType(e->u.road.roadtype) != (RoadTramType)subtype) continue; if (HasBit(e->company_avail, _local_company)) return true; } return false; } /* We should be able to build infrastructure when we have the actual vehicle type */ - const Vehicle *v; - FOR_ALL_VEHICLES(v) { + for (const Vehicle *v : Vehicle::Iterate()) { + if (v->type == VEH_ROAD && GetRoadTramType(RoadVehicle::From(v)->roadtype) != (RoadTramType)subtype) continue; if (v->owner == _local_company && v->type == type) return true; } @@ -1796,17 +1797,17 @@ bool CanBuildVehicleInfrastructure(VehicleType type) * Determines the #LiveryScheme for a vehicle. * @param engine_type Engine of the vehicle. * @param parent_engine_type Engine of the front vehicle, #INVALID_ENGINE if vehicle is at front itself. - * @param v the vehicle, \c NULL if in purchase list etc. + * @param v the vehicle, \c nullptr if in purchase list etc. * @return livery scheme to use. */ LiveryScheme GetEngineLiveryScheme(EngineID engine_type, EngineID parent_engine_type, const Vehicle *v) { - CargoID cargo_type = v == NULL ? (CargoID)CT_INVALID : v->cargo_type; + CargoID cargo_type = v == nullptr ? (CargoID)CT_INVALID : v->cargo_type; const Engine *e = Engine::Get(engine_type); switch (e->type) { default: NOT_REACHED(); case VEH_TRAIN: - if (v != NULL && parent_engine_type != INVALID_ENGINE && (UsesWagonOverride(v) || (v->IsArticulatedPart() && e->u.rail.railveh_type != RAILVEH_WAGON))) { + if (v != nullptr && parent_engine_type != INVALID_ENGINE && (UsesWagonOverride(v) || (v->IsArticulatedPart() && e->u.rail.railveh_type != RAILVEH_WAGON))) { /* Wagonoverrides use the colour scheme of the front engine. * Articulated parts use the colour scheme of the first part. (Not supported for articulated wagons) */ engine_type = parent_engine_type; @@ -1849,7 +1850,7 @@ LiveryScheme GetEngineLiveryScheme(EngineID engine_type, EngineID parent_engine_ case VEH_ROAD: /* Always use the livery of the front */ - if (v != NULL && parent_engine_type != INVALID_ENGINE) { + if (v != nullptr && parent_engine_type != INVALID_ENGINE) { engine_type = parent_engine_type; e = Engine::Get(engine_type); cargo_type = v->First()->cargo_type; @@ -1886,7 +1887,7 @@ LiveryScheme GetEngineLiveryScheme(EngineID engine_type, EngineID parent_engine_ * @param engine_type EngineID of the vehicle * @param company Owner of the vehicle * @param parent_engine_type EngineID of the front vehicle. INVALID_VEHICLE if vehicle is at front itself. - * @param v the vehicle. NULL if in purchase list etc. + * @param v the vehicle. nullptr if in purchase list etc. * @param livery_setting The livery settings to use for acquiring the livery information. * @return livery to use */ @@ -1896,9 +1897,9 @@ const Livery *GetEngineLivery(EngineID engine_type, CompanyID company, EngineID LiveryScheme scheme = LS_DEFAULT; if (livery_setting == LIT_ALL || (livery_setting == LIT_COMPANY && company == _local_company)) { - if (v != NULL) { + if (v != nullptr) { const Group *g = Group::GetIfValid(v->First()->group_id); - if (g != NULL) { + if (g != nullptr) { /* Traverse parents until we find a livery or reach the top */ while (g->livery.in_use == 0 && g->parent != INVALID_GROUP) { g = Group::Get(g->parent); @@ -1921,7 +1922,7 @@ const Livery *GetEngineLivery(EngineID engine_type, CompanyID company, EngineID static PaletteID GetEngineColourMap(EngineID engine_type, CompanyID company, EngineID parent_engine_type, const Vehicle *v) { - PaletteID map = (v != NULL) ? v->colourmap : PAL_NONE; + PaletteID map = (v != nullptr) ? v->colourmap : PAL_NONE; /* Return cached value if any */ if (map != PAL_NONE) return map; @@ -1939,7 +1940,7 @@ static PaletteID GetEngineColourMap(EngineID engine_type, CompanyID company, Eng * map else it's returned as-is. */ if (!HasBit(callback, 14)) { /* Update cache */ - if (v != NULL) const_cast(v)->colourmap = map; + if (v != nullptr) const_cast(v)->colourmap = map; return map; } } @@ -1958,7 +1959,7 @@ static PaletteID GetEngineColourMap(EngineID engine_type, CompanyID company, Eng if (twocc) map += livery->colour2 * 16; /* Update cache */ - if (v != NULL) const_cast(v)->colourmap = map; + if (v != nullptr) const_cast(v)->colourmap = map; return map; } @@ -1970,7 +1971,7 @@ static PaletteID GetEngineColourMap(EngineID engine_type, CompanyID company, Eng */ PaletteID GetEnginePalette(EngineID engine_type, CompanyID company) { - return GetEngineColourMap(engine_type, company, INVALID_ENGINE, NULL); + return GetEngineColourMap(engine_type, company, INVALID_ENGINE, nullptr); } /** @@ -2004,7 +2005,7 @@ void Vehicle::DeleteUnreachedImplicitOrders() } const Order *order = this->GetOrder(this->cur_implicit_order_index); - while (order != NULL) { + while (order != nullptr) { if (this->cur_implicit_order_index == this->cur_real_order_index) break; if (order->IsType(OT_IMPLICIT)) { @@ -2018,7 +2019,7 @@ void Vehicle::DeleteUnreachedImplicitOrders() } /* Wrap around */ - if (order == NULL) { + if (order == nullptr) { order = this->GetOrder(0); this->cur_implicit_order_index = 0; } @@ -2055,12 +2056,12 @@ void Vehicle::BeginLoading() * the 'wrong' terminal when skipping orders etc. */ Order *in_list = this->GetOrder(this->cur_implicit_order_index); if (this->IsGroundVehicle() && - (in_list == NULL || !in_list->IsType(OT_IMPLICIT) || + (in_list == nullptr || !in_list->IsType(OT_IMPLICIT) || in_list->GetDestination() != this->last_station_visited)) { bool suppress_implicit_orders = HasBit(this->GetGroundVehicleFlags(), GVF_SUPPRESS_IMPLICIT_ORDERS); /* Do not create consecutive duplicates of implicit orders */ - Order *prev_order = this->cur_implicit_order_index > 0 ? this->GetOrder(this->cur_implicit_order_index - 1) : (this->GetNumOrders() > 1 ? this->GetLastOrder() : NULL); - if (prev_order == NULL || + Order *prev_order = this->cur_implicit_order_index > 0 ? this->GetOrder(this->cur_implicit_order_index - 1) : (this->GetNumOrders() > 1 ? this->GetLastOrder() : nullptr); + if (prev_order == nullptr || (!prev_order->IsType(OT_IMPLICIT) && !prev_order->IsType(OT_GOTO_STATION)) || prev_order->GetDestination() != this->last_station_visited) { @@ -2073,7 +2074,7 @@ void Vehicle::BeginLoading() bool found = false; while (target_index != this->cur_real_order_index || this->GetNumManualOrders() == 0) { const Order *order = this->GetOrder(target_index); - if (order == NULL) break; // No orders. + if (order == nullptr) break; // No orders. if (order->IsType(OT_IMPLICIT) && order->GetDestination() == this->last_station_visited) { found = true; break; @@ -2109,15 +2110,15 @@ void Vehicle::BeginLoading() } /* Wrap around */ - if (order == NULL) { + if (order == nullptr) { order = this->GetOrder(0); this->cur_implicit_order_index = 0; } - assert(order != NULL); + assert(order != nullptr); } } } else if (!suppress_implicit_orders && - ((this->orders.list == NULL ? OrderList::CanAllocateItem() : this->orders.list->GetNumOrders() < MAX_VEH_ORDER_ID)) && + ((this->orders.list == nullptr ? OrderList::CanAllocateItem() : this->orders.list->GetNumOrders() < MAX_VEH_ORDER_ID)) && Order::CanAllocateItem()) { /* Insert new implicit order */ Order *implicit_order = new Order(); @@ -2161,7 +2162,7 @@ void Vehicle::BeginLoading() */ void Vehicle::CancelReservation(StationID next, Station *st) { - for (Vehicle *v = this; v != NULL; v = v->next) { + for (Vehicle *v = this; v != nullptr; v = v->next) { VehicleCargoList &cargo = v->cargo; if (cargo.ActionCount(VehicleCargoList::MTA_LOAD) > 0) { DEBUG(misc, 1, "cancelling cargo reservation"); @@ -2181,7 +2182,7 @@ void Vehicle::LeaveStation() assert(this->current_order.IsType(OT_LOADING)); delete this->cargo_payment; - assert(this->cargo_payment == NULL); // cleared by ~CargoPayment + assert(this->cargo_payment == nullptr); // cleared by ~CargoPayment /* Only update the timetable if the vehicle was supposed to stop here. */ if (this->current_order.GetNonStopType() != ONSF_STOP_EVERYWHERE) UpdateVehicleTimetable(this, false); @@ -2210,7 +2211,7 @@ void Vehicle::LeaveStation() st->loading_vehicles.remove(this); HideFillingPercent(&this->fill_percent_te_id); - trip_occupancy = CalcPercentVehicleFilled(this, NULL); + trip_occupancy = CalcPercentVehicleFilled(this, nullptr); if (this->type == VEH_TRAIN && !(this->vehstatus & VS_CRASHED)) { /* Trigger station animation (trains only) */ @@ -2230,7 +2231,7 @@ void Vehicle::LeaveStation() */ void Vehicle::ResetRefitCaps() { - for (Vehicle *v = this; v != NULL; v = v->Next()) v->refit_cap = v->cargo_cap; + for (Vehicle *v = this; v != nullptr; v = v->Next()) v->refit_cap = v->cargo_cap; } /** @@ -2253,7 +2254,7 @@ void Vehicle::HandleLoading(bool mode) /* Only advance to next order if we just loaded at the current one */ const Order *order = this->GetOrder(this->cur_implicit_order_index); - if (order == NULL || + if (order == nullptr || (!order->IsType(OT_IMPLICIT) && !order->IsType(OT_GOTO_STATION)) || order->GetDestination() != this->last_station_visited) { return; @@ -2275,13 +2276,11 @@ void Vehicle::HandleLoading(bool mode) */ void Vehicle::GetConsistFreeCapacities(SmallMap &capacities) const { - for (const Vehicle *v = this; v != NULL; v = v->Next()) { + for (const Vehicle *v = this; v != nullptr; v = v->Next()) { if (v->cargo_cap == 0) continue; SmallPair *pair = capacities.Find(v->cargo_type); if (pair == capacities.End()) { - pair = capacities.Append(); - pair->first = v->cargo_type; - pair->second = v->cargo_cap - v->cargo.StoredCount(); + capacities.push_back({v->cargo_type, v->cargo_cap - v->cargo.StoredCount()}); } else { pair->second += v->cargo_cap - v->cargo.StoredCount(); } @@ -2291,7 +2290,7 @@ void Vehicle::GetConsistFreeCapacities(SmallMap &capacities) cons uint Vehicle::GetConsistTotalCapacity() const { uint result = 0; - for (const Vehicle *v = this; v != NULL; v = v->Next()) { + for (const Vehicle *v = this; v != nullptr; v = v->Next()) { result += v->cargo_cap; } return result; @@ -2325,7 +2324,7 @@ CommandCost Vehicle::SendToDepot(DoCommandFlag flags, DepotCommand command) return CommandCost(); } - if (command & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancelation of depot orders + if (command & DEPOT_DONT_CANCEL) return CMD_ERROR; // Requested no cancellation of depot orders if (flags & DC_EXEC) { /* If the orders to 'goto depot' are in the orders list (forced servicing), * then skip to the next order; effectively cancelling this forced service */ @@ -2648,34 +2647,34 @@ void Vehicle::ShowVisualEffect() const CreateEffectVehicleRel(v, x, y, 10, evt); } - } while ((v = v->Next()) != NULL); + } while ((v = v->Next()) != nullptr); if (sound) PlayVehicleSound(this, VSE_VISUAL_EFFECT); } /** * Set the next vehicle of this vehicle. - * @param next the next vehicle. NULL removes the next vehicle. + * @param next the next vehicle. nullptr removes the next vehicle. */ void Vehicle::SetNext(Vehicle *next) { assert(this != next); - if (this->next != NULL) { + if (this->next != nullptr) { /* We had an old next vehicle. Update the first and previous pointers */ - for (Vehicle *v = this->next; v != NULL; v = v->Next()) { + for (Vehicle *v = this->next; v != nullptr; v = v->Next()) { v->first = this->next; } - this->next->previous = NULL; + this->next->previous = nullptr; } this->next = next; - if (this->next != NULL) { + if (this->next != nullptr) { /* A new next vehicle. Update the first and previous pointers */ - if (this->next->previous != NULL) this->next->previous->next = NULL; + if (this->next->previous != nullptr) this->next->previous->next = nullptr; this->next->previous = this; - for (Vehicle *v = this->next; v != NULL; v = v->Next()) { + for (Vehicle *v = this->next; v != nullptr; v = v->Next()) { v->first = this->first; } } @@ -2688,12 +2687,12 @@ void Vehicle::SetNext(Vehicle *next) */ void Vehicle::AddToShared(Vehicle *shared_chain) { - assert(this->previous_shared == NULL && this->next_shared == NULL); + assert(this->previous_shared == nullptr && this->next_shared == nullptr); - if (shared_chain->orders.list == NULL) { - assert(shared_chain->previous_shared == NULL); - assert(shared_chain->next_shared == NULL); - this->orders.list = shared_chain->orders.list = new OrderList(NULL, shared_chain); + if (shared_chain->orders.list == nullptr) { + assert(shared_chain->previous_shared == nullptr); + assert(shared_chain->next_shared == nullptr); + this->orders.list = shared_chain->orders.list = new OrderList(nullptr, shared_chain); } this->next_shared = shared_chain->next_shared; @@ -2701,7 +2700,7 @@ void Vehicle::AddToShared(Vehicle *shared_chain) shared_chain->next_shared = this; - if (this->next_shared != NULL) this->next_shared->previous_shared = this; + if (this->next_shared != nullptr) this->next_shared->previous_shared = this; shared_chain->orders.list->AddVehicle(this); } @@ -2723,7 +2722,7 @@ void Vehicle::RemoveFromShared() this->previous_shared->next_shared = this->NextShared(); } - if (this->next_shared != NULL) this->next_shared->previous_shared = this->previous_shared; + if (this->next_shared != nullptr) this->next_shared->previous_shared = this->previous_shared; if (this->orders.list->GetNumVehicles() == 1) { @@ -2736,14 +2735,13 @@ void Vehicle::RemoveFromShared() InvalidateWindowData(GetWindowClassForVehicleType(this->type), vli.Pack(), this->FirstShared()->index | (1U << 31)); } - this->next_shared = NULL; - this->previous_shared = NULL; + this->next_shared = nullptr; + this->previous_shared = nullptr; } void VehiclesYearlyLoop() { - Vehicle *v; - FOR_ALL_VEHICLES(v) { + for (Vehicle *v : Vehicle::Iterate()) { if (v->IsPrimaryVehicle()) { /* show warning if vehicle is not generating enough income last 2 years (corresponds to a red icon in the vehicle list) */ Money profit = v->GetDisplayProfitThisYear(); @@ -2781,7 +2779,7 @@ void VehiclesYearlyLoop() bool CanVehicleUseStation(EngineID engine_type, const Station *st) { const Engine *e = Engine::GetIfValid(engine_type); - assert(e != NULL); + assert(e != nullptr); switch (e->type) { case VEH_TRAIN: @@ -2813,7 +2811,7 @@ bool CanVehicleUseStation(EngineID engine_type, const Station *st) */ bool CanVehicleUseStation(const Vehicle *v, const Station *st) { - if (v->type == VEH_ROAD) return st->GetPrimaryRoadStop(RoadVehicle::From(v)) != NULL; + if (v->type == VEH_ROAD) return st->GetPrimaryRoadStop(RoadVehicle::From(v)) != nullptr; return CanVehicleUseStation(v->engine_type, st); } @@ -2894,16 +2892,16 @@ void GetVehicleSet(VehicleSet &set, Vehicle *v, uint8 num_vehicles) u = u->GetFirstEnginePart(); /* Include num_vehicles vehicles, not counting articulated parts */ - for (; u != NULL && num_vehicles > 0; num_vehicles--) { + for (; u != nullptr && num_vehicles > 0; num_vehicles--) { do { /* Include current vehicle in the selection. */ - set.Include(u->index); + include(set, u->index); /* If the vehicle is multiheaded, add the other part too. */ - if (u->IsMultiheaded()) set.Include(u->other_multiheaded_part->index); + if (u->IsMultiheaded()) include(set, u->other_multiheaded_part->index); u = u->Next(); - } while (u != NULL && u->IsArticulatedPart()); + } while (u != nullptr && u->IsArticulatedPart()); } } } diff --git a/src/vehicle_base.h b/src/vehicle_base.h index d02d33e2cc..bc72c6bbfd 100644 --- a/src/vehicle_base.h +++ b/src/vehicle_base.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. @@ -268,9 +266,9 @@ public: int32 x_pos; ///< x coordinate. int32 y_pos; ///< y coordinate. int32 z_pos; ///< z coordinate. - DirectionByte direction; ///< facing + Direction direction; ///< facing - OwnerByte owner; ///< Which company owns the vehicle? + Owner owner; ///< Which company owns the vehicle? /** * currently displayed sprite index * 0xfd == custom sprite, 0xfe == custom second head sprite @@ -459,7 +457,7 @@ public: */ inline void InvalidateNewGRFCacheOfChain() { - for (Vehicle *u = this; u != NULL; u = u->Next()) { + for (Vehicle *u = this; u != nullptr; u = u->Next()) { u->InvalidateNewGRFCache(); } } @@ -576,14 +574,14 @@ public: /** * Get the next vehicle of this vehicle. * @note articulated parts are also counted as vehicles. - * @return the next vehicle or NULL when there isn't a next vehicle. + * @return the next vehicle or nullptr when there isn't a next vehicle. */ inline Vehicle *Next() const { return this->next; } /** * Get the previous vehicle of this vehicle. * @note articulated parts are also counted as vehicles. - * @return the previous vehicle or NULL when there isn't a previous vehicle. + * @return the previous vehicle or nullptr when there isn't a previous vehicle. */ inline Vehicle *Previous() const { return this->previous; } @@ -600,7 +598,7 @@ public: inline Vehicle *Last() { Vehicle *v = this; - while (v->Next() != NULL) v = v->Next(); + while (v->Next() != nullptr) v = v->Next(); return v; } @@ -611,22 +609,22 @@ public: inline const Vehicle *Last() const { const Vehicle *v = this; - while (v->Next() != NULL) v = v->Next(); + while (v->Next() != nullptr) v = v->Next(); return v; } /** * Get the vehicle at offset \a n of this vehicle chain. * @param n Offset from the current vehicle. - * @return The new vehicle or NULL if the offset is out-of-bounds. + * @return The new vehicle or nullptr if the offset is out-of-bounds. */ inline Vehicle *Move(int n) { Vehicle *v = this; if (n < 0) { - for (int i = 0; i != n && v != NULL; i--) v = v->Previous(); + for (int i = 0; i != n && v != nullptr; i--) v = v->Previous(); } else { - for (int i = 0; i != n && v != NULL; i++) v = v->Next(); + for (int i = 0; i != n && v != nullptr; i++) v = v->Next(); } return v; } @@ -634,15 +632,15 @@ public: /** * Get the vehicle at offset \a n of this vehicle chain. * @param n Offset from the current vehicle. - * @return The new vehicle or NULL if the offset is out-of-bounds. + * @return The new vehicle or nullptr if the offset is out-of-bounds. */ inline const Vehicle *Move(int n) const { const Vehicle *v = this; if (n < 0) { - for (int i = 0; i != n && v != NULL; i--) v = v->Previous(); + for (int i = 0; i != n && v != nullptr; i--) v = v->Previous(); } else { - for (int i = 0; i != n && v != NULL; i++) v = v->Next(); + for (int i = 0; i != n && v != nullptr; i++) v = v->Next(); } return v; } @@ -651,20 +649,20 @@ public: * Get the first order of the vehicles order list. * @return first order of order list. */ - inline Order *GetFirstOrder() const { return (this->orders.list == NULL) ? NULL : this->orders.list->GetFirstOrder(); } + inline Order *GetFirstOrder() const { return (this->orders.list == nullptr) ? nullptr : this->orders.list->GetFirstOrder(); } void AddToShared(Vehicle *shared_chain); void RemoveFromShared(); /** * Get the next vehicle of the shared vehicle chain. - * @return the next shared vehicle or NULL when there isn't a next vehicle. + * @return the next shared vehicle or nullptr when there isn't a next vehicle. */ inline Vehicle *NextShared() const { return this->next_shared; } /** * Get the previous vehicle of the shared vehicle chain - * @return the previous shared vehicle or NULL when there isn't a previous vehicle. + * @return the previous shared vehicle or nullptr when there isn't a previous vehicle. */ inline Vehicle *PreviousShared() const { return this->previous_shared; } @@ -672,25 +670,25 @@ public: * Get the first vehicle of this vehicle chain. * @return the first vehicle of the chain. */ - inline Vehicle *FirstShared() const { return (this->orders.list == NULL) ? this->First() : this->orders.list->GetFirstSharedVehicle(); } + inline Vehicle *FirstShared() const { return (this->orders.list == nullptr) ? this->First() : this->orders.list->GetFirstSharedVehicle(); } /** * Check if we share our orders with another vehicle. * @return true if there are other vehicles sharing the same order */ - inline bool IsOrderListShared() const { return this->orders.list != NULL && this->orders.list->IsShared(); } + inline bool IsOrderListShared() const { return this->orders.list != nullptr && this->orders.list->IsShared(); } /** * Get the number of orders this vehicle has. * @return the number of orders this vehicle has. */ - inline VehicleOrderID GetNumOrders() const { return (this->orders.list == NULL) ? 0 : this->orders.list->GetNumOrders(); } + inline VehicleOrderID GetNumOrders() const { return (this->orders.list == nullptr) ? 0 : this->orders.list->GetNumOrders(); } /** * Get the number of manually added orders this vehicle has. * @return the number of manually added orders this vehicle has. */ - inline VehicleOrderID GetNumManualOrders() const { return (this->orders.list == NULL) ? 0 : this->orders.list->GetNumManualOrders(); } + inline VehicleOrderID GetNumManualOrders() const { return (this->orders.list == nullptr) ? 0 : this->orders.list->GetNumManualOrders(); } /** * Get the next station the vehicle will stop at. @@ -698,7 +696,7 @@ public: */ inline StationIDStack GetNextStoppingStation() const { - return (this->orders.list == NULL) ? INVALID_STATION : this->orders.list->GetNextStoppingStation(this); + return (this->orders.list == nullptr) ? INVALID_STATION : this->orders.list->GetNextStoppingStation(this); } void ResetRefitCaps(); @@ -853,22 +851,22 @@ public: } /** - * Returns order 'index' of a vehicle or NULL when it doesn't exists + * Returns order 'index' of a vehicle or nullptr when it doesn't exists * @param index the order to fetch * @return the found (or not) order */ inline Order *GetOrder(int index) const { - return (this->orders.list == NULL) ? NULL : this->orders.list->GetOrderAt(index); + return (this->orders.list == nullptr) ? nullptr : this->orders.list->GetOrderAt(index); } /** - * Returns the last order of a vehicle, or NULL if it doesn't exists + * Returns the last order of a vehicle, or nullptr if it doesn't exists * @return last order of a vehicle, if available */ inline Order *GetLastOrder() const { - return (this->orders.list == NULL) ? NULL : this->orders.list->GetLastOrder(); + return (this->orders.list == nullptr) ? nullptr : this->orders.list->GetLastOrder(); } bool IsEngineCountable() const; @@ -900,7 +898,7 @@ public: */ inline bool HasArticulatedPart() const { - return this->Next() != NULL && this->Next()->IsArticulatedPart(); + return this->Next() != nullptr && this->Next()->IsArticulatedPart(); } /** @@ -967,25 +965,12 @@ public: inline Vehicle *GetPrevVehicle() const { Vehicle *v = this->Previous(); - while (v != NULL && v->IsArticulatedPart()) v = v->Previous(); + while (v != nullptr && v->IsArticulatedPart()) v = v->Previous(); return v; } }; -/** - * Iterate over all vehicles from a given point. - * @param var The variable used to iterate over. - * @param start The vehicle to start the iteration at. - */ -#define FOR_ALL_VEHICLES_FROM(var, start) FOR_ALL_ITEMS_FROM(Vehicle, vehicle_index, var, start) - -/** - * Iterate over all vehicles. - * @param var The variable used to iterate over. - */ -#define FOR_ALL_VEHICLES(var) FOR_ALL_VEHICLES_FROM(var, 0) - /** * Class defining several overloaded accessors so we don't * have to cast vehicle types that often @@ -1103,7 +1088,7 @@ struct SpecializedVehicle : public Vehicle { */ static inline T *GetIfValid(size_t index) { - return IsValidID(index) ? Get(index) : NULL; + return IsValidID(index) ? Get(index) : nullptr; } /** @@ -1148,14 +1133,14 @@ struct SpecializedVehicle : public Vehicle { this->Vehicle::UpdateViewport(true); } } -}; -/** - * Iterate over all vehicles of a particular type. - * @param name The type of vehicle to iterate over. - * @param var The variable used to iterate over. - */ -#define FOR_ALL_VEHICLES_OF_TYPE(name, var) FOR_ALL_ITEMS_FROM(name, vehicle_index, var, 0) if (var->type == name::EXPECTED_TYPE) + /** + * Returns an iterable ensemble of all valid vehicles of type T + * @param from index of the first vehicle to consider + * @return an iterable ensemble of all valid vehicles of type T + */ + static Pool::IterateWrapper Iterate(size_t from = 0) { return Pool::IterateWrapper(from); } +}; /** Generates sequence of free UnitID numbers */ struct FreeUnitIDGenerator { diff --git a/src/vehicle_cmd.cpp b/src/vehicle_cmd.cpp index 8284511dd4..5ba31945fc 100644 --- a/src/vehicle_cmd.cpp +++ b/src/vehicle_cmd.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. @@ -31,6 +29,7 @@ #include "ship.h" #include "newgrf.h" #include "company_base.h" +#include "core/random_func.hpp" #include "table/strings.h" @@ -71,13 +70,16 @@ CommandCost CmdBuildRoadVehicle(TileIndex tile, DoCommandFlag flags, const Engin CommandCost CmdBuildShip (TileIndex tile, DoCommandFlag flags, const Engine *e, uint16 data, Vehicle **v); CommandCost CmdBuildAircraft (TileIndex tile, DoCommandFlag flags, const Engine *e, uint16 data, Vehicle **v); +CommandCost CmdRefitVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text); + /** * Build a vehicle. * @param tile tile of depot where the vehicle is built * @param flags for command * @param p1 various bitstuffed data * bits 0-15: vehicle type being built. - * bits 16-31: vehicle type specific bits passed on to the vehicle build functions. + * bits 16-23: vehicle type specific bits passed on to the vehicle build functions. + * bits 24-31: refit cargo type. * @param p2 User * @param text unused * @return the cost of this operation or an error @@ -93,11 +95,18 @@ CommandCost CmdBuildVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint EngineID eid = GB(p1, 0, 16); if (!IsEngineBuildable(eid, type, _current_company)) return_cmd_error(STR_ERROR_RAIL_VEHICLE_NOT_AVAILABLE + type); + /* Validate the cargo type. */ + CargoID cargo = GB(p1, 24, 8); + if (cargo >= NUM_CARGO && cargo != CT_INVALID) return CMD_ERROR; + const Engine *e = Engine::Get(eid); CommandCost value(EXPENSES_NEW_VEHICLES, e->GetCost()); /* Engines without valid cargo should not be available */ - if (e->GetDefaultCargoType() == CT_INVALID) return CMD_ERROR; + CargoID default_cargo = e->GetDefaultCargoType(); + if (default_cargo == CT_INVALID) return CMD_ERROR; + + bool refitting = cargo != CT_INVALID && cargo != default_cargo; /* Check whether the number of vehicles we need to build can be built according to pool space. */ uint num_vehicles; @@ -116,35 +125,67 @@ CommandCost CmdBuildVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint UnitID unit_num = (flags & DC_AUTOREPLACE || (type == VEH_TRAIN && e->u.rail.railveh_type == RAILVEH_WAGON)) ? 0 : GetFreeUnitNumber(type); if (unit_num == UINT16_MAX) return_cmd_error(STR_ERROR_TOO_MANY_VEHICLES_IN_GAME); - Vehicle *v; + /* If we are refitting we need to temporarily purchase the vehicle to be able to + * test it. */ + DoCommandFlag subflags = flags; + if (refitting) subflags |= DC_EXEC; + + /* Vehicle construction needs random bits, so we have to save the random + * seeds to prevent desyncs. */ + SavedRandomSeeds saved_seeds; + SaveRandomSeeds(&saved_seeds); + + Vehicle *v = nullptr; switch (type) { - case VEH_TRAIN: value.AddCost(CmdBuildRailVehicle(tile, flags, e, GB(p1, 16, 16), &v)); break; - case VEH_ROAD: value.AddCost(CmdBuildRoadVehicle(tile, flags, e, GB(p1, 16, 16), &v)); break; - case VEH_SHIP: value.AddCost(CmdBuildShip (tile, flags, e, GB(p1, 16, 16), &v)); break; - case VEH_AIRCRAFT: value.AddCost(CmdBuildAircraft (tile, flags, e, GB(p1, 16, 16), &v)); break; + case VEH_TRAIN: value.AddCost(CmdBuildRailVehicle(tile, subflags, e, GB(p1, 16, 8), &v)); break; + case VEH_ROAD: value.AddCost(CmdBuildRoadVehicle(tile, subflags, e, GB(p1, 16, 8), &v)); break; + case VEH_SHIP: value.AddCost(CmdBuildShip (tile, subflags, e, GB(p1, 16, 8), &v)); break; + case VEH_AIRCRAFT: value.AddCost(CmdBuildAircraft (tile, subflags, e, GB(p1, 16, 8), &v)); break; default: NOT_REACHED(); // Safe due to IsDepotTile() } - if (value.Succeeded() && flags & DC_EXEC) { - v->unitnumber = unit_num; - v->value = value.GetCost(); - - InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile); - InvalidateWindowClassesData(GetWindowClassForVehicleType(type), 0); - SetWindowDirty(WC_COMPANY, _current_company); - if (IsLocalCompany()) { - InvalidateAutoreplaceWindow(v->engine_type, v->group_id); // updates the auto replace window (must be called before incrementing num_engines) + if (value.Succeeded()) { + if (refitting || (flags & DC_EXEC)) { + v->unitnumber = unit_num; + v->value = value.GetCost(); } - GroupStatistics::CountEngine(v, 1); - GroupStatistics::UpdateAutoreplace(_current_company); + if (refitting) { + value.AddCost(CmdRefitVehicle(tile, flags, v->index, cargo, nullptr)); + } else { + /* Fill in non-refitted capacities */ + _returned_refit_capacity = e->GetDisplayDefaultCapacity(&_returned_mail_refit_capacity); + } - if (v->IsPrimaryVehicle()) { - GroupStatistics::CountVehicle(v, 1); - OrderBackup::Restore(v, p2); + if (flags & DC_EXEC) { + InvalidateWindowData(WC_VEHICLE_DEPOT, v->tile); + InvalidateWindowClassesData(GetWindowClassForVehicleType(type), 0); + SetWindowDirty(WC_COMPANY, _current_company); + if (IsLocalCompany()) { + InvalidateAutoreplaceWindow(v->engine_type, v->group_id); // updates the auto replace window (must be called before incrementing num_engines) + } + } + + if (refitting || (flags & DC_EXEC)) { + GroupStatistics::CountEngine(v, 1); + GroupStatistics::UpdateAutoreplace(_current_company); + + if (v->IsPrimaryVehicle()) { + GroupStatistics::CountVehicle(v, 1); + OrderBackup::Restore(v, p2); + } + } + + + /* If we are not in DC_EXEC undo everything */ + if (refitting && (flags & DC_EXEC) == 0) { + DoCommand(0, v->index, 0, DC_EXEC, GetCmdSellVeh(v)); } } + /* Only restore if we actually did some refitting */ + if (flags != subflags) RestoreRandomSeeds(saved_seeds); + return value; } @@ -165,7 +206,7 @@ CommandCost CmdSellRailWagon(DoCommandFlag flags, Vehicle *v, uint16 data, uint3 CommandCost CmdSellVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { Vehicle *v = Vehicle::GetIfValid(GB(p1, 0, 20)); - if (v == NULL) return CMD_ERROR; + if (v == nullptr) return CMD_ERROR; Vehicle *front = v->First(); @@ -178,7 +219,7 @@ CommandCost CmdSellVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 /* Can we actually make the order backup, i.e. are there enough orders? */ if (p1 & MAKE_ORDER_BACKUP_FLAG && - front->orders.list != NULL && + front->orders.list != nullptr && !front->orders.list->IsShared() && !Order::CanAllocateItem(front->orders.list->GetNumOrders())) { /* Only happens in exceptional cases when there aren't enough orders anyhow. @@ -202,7 +243,7 @@ CommandCost CmdSellVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint3 /** * Helper to run the refit cost callback. - * @param v The vehicle we are refitting, can be NULL. + * @param v The vehicle we are refitting, can be nullptr. * @param engine_type Which engine to refit * @param new_cid Cargo type we are refitting to. * @param new_subtype New cargo subtype. @@ -215,7 +256,7 @@ static int GetRefitCostFactor(const Vehicle *v, EngineID engine_type, CargoID ne const Engine *e = Engine::Get(engine_type); /* Is this vehicle a NewGRF vehicle? */ - if (e->GetGRF() != NULL) { + if (e->GetGRF() != nullptr) { const CargoSpec *cs = CargoSpec::Get(new_cid); uint32 param1 = (cs->classes << 16) | (new_subtype << 8) | e->GetGRF()->cargo_map[new_cid]; @@ -229,12 +270,12 @@ static int GetRefitCostFactor(const Vehicle *v, EngineID engine_type, CargoID ne } *auto_refit_allowed = e->info.refit_cost == 0; - return (v == NULL || v->cargo_type != new_cid) ? e->info.refit_cost : 0; + return (v == nullptr || v->cargo_type != new_cid) ? e->info.refit_cost : 0; } /** * Learn the price of refitting a certain engine - * @param v The vehicle we are refitting, can be NULL. + * @param v The vehicle we are refitting, can be nullptr. * @param engine_type Which engine to refit * @param new_cid Cargo type we are refitting to. * @param new_subtype New cargo subtype. @@ -312,16 +353,15 @@ static CommandCost RefitVehicle(Vehicle *v, bool only_this, uint8 num_vehicles, v = v->First(); } - static SmallVector refit_result; - refit_result.Clear(); + std::vector refit_result; v->InvalidateNewGRFCacheOfChain(); byte actual_subtype = new_subtype; - for (; v != NULL; v = (only_this ? NULL : v->Next())) { + for (; v != nullptr; v = (only_this ? nullptr : v->Next())) { /* Reset actual_subtype for every new vehicle */ if (!v->IsArticulatedPart()) actual_subtype = new_subtype; - if (v->type == VEH_TRAIN && !vehicles_to_refit.Contains(v->index) && !only_this) continue; + if (v->type == VEH_TRAIN && std::find(vehicles_to_refit.begin(), vehicles_to_refit.end(), v->index) == vehicles_to_refit.end() && !only_this) continue; const Engine *e = v->GetEngine(); if (!e->CanCarryCargo()) continue; @@ -383,32 +423,28 @@ static CommandCost RefitVehicle(Vehicle *v, bool only_this, uint8 num_vehicles, * - We have to call the refit cost callback with the pre-refit configuration of the chain because we want refit and * autorefit to behave the same, and we need its result for auto_refit_allowed. */ - RefitResult *result = refit_result.Append(); - result->v = v; - result->capacity = amount; - result->mail_capacity = mail_capacity; - result->subtype = actual_subtype; + refit_result.push_back({v, amount, mail_capacity, actual_subtype}); } if (flags & DC_EXEC) { /* Store the result */ - for (RefitResult *result = refit_result.Begin(); result != refit_result.End(); result++) { - Vehicle *u = result->v; - u->refit_cap = (u->cargo_type == new_cid) ? min(result->capacity, u->refit_cap) : 0; + for (RefitResult &result : refit_result) { + Vehicle *u = result.v; + u->refit_cap = (u->cargo_type == new_cid) ? min(result.capacity, u->refit_cap) : 0; if (u->cargo.TotalCount() > u->refit_cap) u->cargo.Truncate(u->cargo.TotalCount() - u->refit_cap); u->cargo_type = new_cid; - u->cargo_cap = result->capacity; - u->cargo_subtype = result->subtype; + u->cargo_cap = result.capacity; + u->cargo_subtype = result.subtype; if (u->type == VEH_AIRCRAFT) { Vehicle *w = u->Next(); - w->refit_cap = min(w->refit_cap, result->mail_capacity); - w->cargo_cap = result->mail_capacity; + w->refit_cap = 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); } } } - refit_result.Clear(); + refit_result.clear(); _returned_refit_capacity = total_capacity; _returned_mail_refit_capacity = total_mail_capacity; return cost; @@ -432,7 +468,7 @@ static CommandCost RefitVehicle(Vehicle *v, bool only_this, uint8 num_vehicles, CommandCost CmdRefitVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { Vehicle *v = Vehicle::GetIfValid(p1); - if (v == NULL) return CMD_ERROR; + if (v == nullptr) return CMD_ERROR; /* Don't allow disasters and sparks and such to be refitted. * We cannot check for IsPrimaryVehicle as autoreplace also refits in free wagon chains. */ @@ -523,7 +559,7 @@ CommandCost CmdStartStopVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, if ((flags & DC_AUTOREPLACE) == 0) SetBit(p2, 0); Vehicle *v = Vehicle::GetIfValid(p1); - if (v == NULL || !v->IsPrimaryVehicle()) return CMD_ERROR; + if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR; CommandCost ret = CheckOwnership(v->owner); if (ret.Failed()) return ret; @@ -615,10 +651,10 @@ CommandCost CmdMassStartStopVehicle(TileIndex tile, DoCommandFlag flags, uint32 if (!GenerateVehicleSortList(&list, vli)) return CMD_ERROR; } else { /* Get the list of vehicles in the depot */ - BuildDepotVehicleList(vli.vtype, tile, &list, NULL); + BuildDepotVehicleList(vli.vtype, tile, &list, nullptr); } - for (uint i = 0; i < list.Length(); i++) { + for (uint i = 0; i < list.size(); i++) { const Vehicle *v = list[i]; if (!!(v->vehstatus & VS_STOPPED) != do_start) continue; @@ -657,7 +693,7 @@ CommandCost CmdDepotSellAllVehicles(TileIndex tile, DoCommandFlag flags, uint32 CommandCost last_error = CMD_ERROR; bool had_success = false; - for (uint i = 0; i < list.Length(); i++) { + for (uint i = 0; i < list.size(); i++) { CommandCost ret = DoCommand(tile, list[i]->index | (1 << 20), 0, flags, sell_command); if (ret.Succeeded()) { cost.AddCost(ret); @@ -691,7 +727,7 @@ CommandCost CmdDepotMassAutoReplace(TileIndex tile, DoCommandFlag flags, uint32 /* Get the list of vehicles in the depot */ BuildDepotVehicleList(vehicle_type, tile, &list, &list, true); - for (uint i = 0; i < list.Length(); i++) { + for (uint i = 0; i < list.size(); i++) { const Vehicle *v = list[i]; /* Ensure that the vehicle completely in the depot */ @@ -711,10 +747,8 @@ CommandCost CmdDepotMassAutoReplace(TileIndex tile, DoCommandFlag flags, uint32 */ static bool IsUniqueVehicleName(const char *name) { - const Vehicle *v; - - FOR_ALL_VEHICLES(v) { - if (v->name != NULL && strcmp(v->name, name) == 0) return false; + for (const Vehicle *v : Vehicle::Iterate()) { + if (v->name != nullptr && strcmp(v->name, name) == 0) return false; } return true; @@ -784,11 +818,11 @@ CommandCost CmdCloneVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint CommandCost total_cost(EXPENSES_NEW_VEHICLES); Vehicle *v = Vehicle::GetIfValid(p1); - if (v == NULL || !v->IsPrimaryVehicle()) return CMD_ERROR; + if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR; Vehicle *v_front = v; - Vehicle *w = NULL; - Vehicle *w_front = NULL; - Vehicle *w_rear = NULL; + Vehicle *w = nullptr; + Vehicle *w_front = nullptr; + Vehicle *w_rear = nullptr; /* * v_front is the front engine in the original vehicle @@ -808,7 +842,7 @@ CommandCost CmdCloneVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint int veh_counter = 0; do { veh_counter++; - } while ((v = v->Next()) != NULL); + } while ((v = v->Next()) != nullptr); if (!Vehicle::CanAllocateItem(veh_counter)) { return_cmd_error(STR_ERROR_TOO_MANY_VEHICLES_IN_GAME); @@ -832,11 +866,11 @@ CommandCost CmdCloneVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint DoCommandFlag build_flags = flags; if ((flags & DC_EXEC) && !v->IsPrimaryVehicle()) build_flags |= DC_AUTOREPLACE; - CommandCost cost = DoCommand(tile, v->engine_type | (1 << 16), 0, build_flags, GetCmdBuildVeh(v)); + CommandCost cost = DoCommand(tile, v->engine_type | (1 << 16) | (CT_INVALID << 24), 0, build_flags, GetCmdBuildVeh(v)); if (cost.Failed()) { /* Can't build a part, then sell the stuff we already made; clear up the mess */ - if (w_front != NULL) DoCommand(w_front->tile, w_front->index | (1 << 20), 0, flags, GetCmdSellVeh(w_front)); + if (w_front != nullptr) DoCommand(w_front->tile, w_front->index | (1 << 20), 0, flags, GetCmdSellVeh(w_front)); return cost; } @@ -869,7 +903,7 @@ CommandCost CmdCloneVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint } w_rear = w; // trains needs to know the last car in the train, so they can add more in next loop } - } while (v->type == VEH_TRAIN && (v = v->GetNextVehicle()) != NULL); + } while (v->type == VEH_TRAIN && (v = v->GetNextVehicle()) != nullptr); if ((flags & DC_EXEC) && v_front->type == VEH_TRAIN) { /* for trains this needs to be the front engine due to the callback function */ @@ -895,7 +929,7 @@ CommandCost CmdCloneVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint do { do { if (flags & DC_EXEC) { - assert(w != NULL); + assert(w != nullptr); /* Find out what's the best sub type */ byte subtype = GetBestFittingSubType(v, w, v->cargo_type); @@ -915,7 +949,7 @@ CommandCost CmdCloneVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint if (v->cargo_type != initial_cargo && initial_cargo != CT_INVALID) { bool dummy; - total_cost.AddCost(GetRefitCost(NULL, v->engine_type, v->cargo_type, v->cargo_subtype, &dummy)); + total_cost.AddCost(GetRefitCost(nullptr, v->engine_type, v->cargo_type, v->cargo_subtype, &dummy)); } } @@ -924,10 +958,10 @@ CommandCost CmdCloneVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint } else { break; } - } while (v != NULL); + } while (v != nullptr); if ((flags & DC_EXEC) && v->type == VEH_TRAIN) w = w->GetNextVehicle(); - } while (v->type == VEH_TRAIN && (v = v->GetNextVehicle()) != NULL); + } while (v->type == VEH_TRAIN && (v = v->GetNextVehicle()) != nullptr); if (flags & DC_EXEC) { /* @@ -938,7 +972,7 @@ CommandCost CmdCloneVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint DoCommand(0, w_front->index | (p2 & 1 ? CO_SHARE : CO_COPY) << 30, v_front->index, flags, CMD_CLONE_ORDER); /* Now clone the vehicle's name, if it has one. */ - if (v_front->name != NULL) CloneVehicleName(v_front, w_front); + if (v_front->name != nullptr) CloneVehicleName(v_front, w_front); } /* Since we can't estimate the cost of cloning a vehicle accurately we must @@ -969,7 +1003,7 @@ static CommandCost SendAllVehiclesToDepot(DoCommandFlag flags, bool service, con /* Send all the vehicles to a depot */ bool had_success = false; - for (uint i = 0; i < list.Length(); i++) { + for (uint i = 0; i < list.size(); i++) { const Vehicle *v = list[i]; CommandCost ret = DoCommand(v->tile, v->index | (service ? DEPOT_SERVICE : 0U) | DEPOT_DONT_CANCEL, 0, flags, GetCmdSendToDepot(vli.vtype)); @@ -1008,7 +1042,7 @@ CommandCost CmdSendVehicleToDepot(TileIndex tile, DoCommandFlag flags, uint32 p1 } Vehicle *v = Vehicle::GetIfValid(GB(p1, 0, 20)); - if (v == NULL) return CMD_ERROR; + if (v == nullptr) return CMD_ERROR; if (!v->IsPrimaryVehicle()) return CMD_ERROR; return v->SendToDepot(flags, (DepotCommand)(p1 & DEPOT_COMMAND_MASK)); @@ -1026,7 +1060,7 @@ CommandCost CmdSendVehicleToDepot(TileIndex tile, DoCommandFlag flags, uint32 p1 CommandCost CmdRenameVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { Vehicle *v = Vehicle::GetIfValid(p1); - if (v == NULL || !v->IsPrimaryVehicle()) return CMD_ERROR; + if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR; CommandCost ret = CheckOwnership(v->owner); if (ret.Failed()) return ret; @@ -1040,7 +1074,7 @@ CommandCost CmdRenameVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uin if (flags & DC_EXEC) { free(v->name); - v->name = reset ? NULL : stredup(text); + v->name = reset ? nullptr : stredup(text); InvalidateWindowClassesData(GetWindowClassForVehicleType(v->type), 1); MarkWholeScreenDirty(); } @@ -1064,7 +1098,7 @@ CommandCost CmdRenameVehicle(TileIndex tile, DoCommandFlag flags, uint32 p1, uin CommandCost CmdChangeServiceInt(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { Vehicle *v = Vehicle::GetIfValid(p1); - if (v == NULL || !v->IsPrimaryVehicle()) return CMD_ERROR; + if (v == nullptr || !v->IsPrimaryVehicle()) return CMD_ERROR; CommandCost ret = CheckOwnership(v->owner); if (ret.Failed()) return ret; diff --git a/src/vehicle_func.h b/src/vehicle_func.h index 17ec9e28da..aa8334ebb0 100644 --- a/src/vehicle_func.h +++ b/src/vehicle_func.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. @@ -60,7 +58,7 @@ byte GetBestFittingSubType(Vehicle *v_from, Vehicle *v_for, CargoID dest_cargo_t void ViewportAddVehicles(DrawPixelInfo *dpi); void ShowNewGrfVehicleError(EngineID engine, StringID part1, StringID part2, GRFBugs bug_type, bool critical); -CommandCost TunnelBridgeIsFree(TileIndex tile, TileIndex endtile, const Vehicle *ignore = NULL); +CommandCost TunnelBridgeIsFree(TileIndex tile, TileIndex endtile, const Vehicle *ignore = nullptr); void DecreaseVehicleValue(Vehicle *v); void CheckVehicleBreakdown(Vehicle *v); @@ -71,7 +69,7 @@ UnitID GetFreeUnitNumber(VehicleType type); void VehicleEnterDepot(Vehicle *v); -bool CanBuildVehicleInfrastructure(VehicleType type); +bool CanBuildVehicleInfrastructure(VehicleType type, byte subtype = 0); /** Position information of a vehicle after it moved */ struct GetNewVehiclePosResult { @@ -175,7 +173,7 @@ bool CanVehicleUseStation(const Vehicle *v, const struct Station *st); void ReleaseDisastersTargetingVehicle(VehicleID vehicle); -typedef SmallVector VehicleSet; +typedef std::vector VehicleSet; void GetVehicleSet(VehicleSet &set, Vehicle *v, uint8 num_vehicles); void CheckCargoCapacity(Vehicle *v); diff --git a/src/vehicle_gui.cpp b/src/vehicle_gui.cpp index 9781823724..25e11f7c49 100644 --- a/src/vehicle_gui.cpp +++ b/src/vehicle_gui.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. @@ -106,8 +104,8 @@ const StringID BaseVehicleListWindow::vehicle_depot_name[] = { uint GetUnitNumberDigits(VehicleList &vehicles) { uint unitnumber = 0; - for (const Vehicle **v = vehicles.Begin(); v != vehicles.End(); v++) { - unitnumber = max(unitnumber, (*v)->unitnumber); + for (const Vehicle *v : vehicles) { + unitnumber = max(unitnumber, v->unitnumber); } if (unitnumber >= 10000) return 5; @@ -133,7 +131,7 @@ void BaseVehicleListWindow::BuildVehicleList() this->unitnumber_digits = GetUnitNumberDigits(this->vehicles); this->vehicles.RebuildDone(); - this->vscroll->SetCount(this->vehicles.Length()); + this->vscroll->SetCount((uint)this->vehicles.size()); } /** @@ -164,37 +162,37 @@ Dimension BaseVehicleListWindow::GetActionDropdownSize(bool show_autoreplace, bo * @param show_group If true include group-related stuff. * @return Itemlist for dropdown */ -DropDownList *BaseVehicleListWindow::BuildActionDropdownList(bool show_autoreplace, bool show_group) +DropDownList BaseVehicleListWindow::BuildActionDropdownList(bool show_autoreplace, bool show_group) { - DropDownList *list = new DropDownList(); + DropDownList list; - if (show_autoreplace) *list->Append() = new DropDownListStringItem(STR_VEHICLE_LIST_REPLACE_VEHICLES, ADI_REPLACE, false); - *list->Append() = new DropDownListStringItem(STR_VEHICLE_LIST_SEND_FOR_SERVICING, ADI_SERVICE, false); - *list->Append() = new DropDownListStringItem(this->vehicle_depot_name[this->vli.vtype], ADI_DEPOT, false); + if (show_autoreplace) list.emplace_back(new DropDownListStringItem(STR_VEHICLE_LIST_REPLACE_VEHICLES, ADI_REPLACE, false)); + list.emplace_back(new DropDownListStringItem(STR_VEHICLE_LIST_SEND_FOR_SERVICING, ADI_SERVICE, false)); + list.emplace_back(new DropDownListStringItem(this->vehicle_depot_name[this->vli.vtype], ADI_DEPOT, false)); if (show_group) { - *list->Append() = new DropDownListStringItem(STR_GROUP_ADD_SHARED_VEHICLE, ADI_ADD_SHARED, false); - *list->Append() = new DropDownListStringItem(STR_GROUP_REMOVE_ALL_VEHICLES, ADI_REMOVE_ALL, false); + list.emplace_back(new DropDownListStringItem(STR_GROUP_ADD_SHARED_VEHICLE, ADI_ADD_SHARED, false)); + list.emplace_back(new DropDownListStringItem(STR_GROUP_REMOVE_ALL_VEHICLES, ADI_REMOVE_ALL, false)); } return list; } /* cached values for VehicleNameSorter to spare many GetString() calls */ -static const Vehicle *_last_vehicle[2] = { NULL, NULL }; +static const Vehicle *_last_vehicle[2] = { nullptr, nullptr }; void BaseVehicleListWindow::SortVehicleList() { if (this->vehicles.Sort()) return; /* invalidate cached values for name sorter - vehicle names could change */ - _last_vehicle[0] = _last_vehicle[1] = NULL; + _last_vehicle[0] = _last_vehicle[1] = nullptr; } void DepotSortList(VehicleList *list) { - if (list->Length() < 2) return; - QSortT(list->Begin(), list->Length(), &VehicleNumberSorter); + if (list->size() < 2) return; + std::sort(list->begin(), list->end(), &VehicleNumberSorter); } /** draw the vehicle profit button in the vehicle list window. */ @@ -233,19 +231,19 @@ byte GetBestFittingSubType(Vehicle *v_from, Vehicle *v_for, CargoID dest_cargo_t v_for = v_for->GetFirstEnginePart(); /* Create a list of subtypes used by the various parts of v_for */ - static SmallVector subtypes; - subtypes.Clear(); - for (; v_from != NULL; v_from = v_from->HasArticulatedPart() ? v_from->GetNextArticulatedPart() : NULL) { + static std::vector subtypes; + subtypes.clear(); + for (; v_from != nullptr; v_from = v_from->HasArticulatedPart() ? v_from->GetNextArticulatedPart() : nullptr) { const Engine *e_from = v_from->GetEngine(); if (!e_from->CanCarryCargo() || !HasBit(e_from->info.callback_mask, CBM_VEHICLE_CARGO_SUFFIX)) continue; - subtypes.Include(GetCargoSubtypeText(v_from)); + include(subtypes, GetCargoSubtypeText(v_from)); } byte ret_refit_cyc = 0; bool success = false; - if (subtypes.Length() > 0) { + if (subtypes.size() > 0) { /* Check whether any articulated part is refittable to 'dest_cargo_type' with a subtype listed in 'subtypes' */ - for (Vehicle *v = v_for; v != NULL; v = v->HasArticulatedPart() ? v->GetNextArticulatedPart() : NULL) { + for (Vehicle *v = v_for; v != nullptr; v = v->HasArticulatedPart() ? v->GetNextArticulatedPart() : nullptr) { const Engine *e = v->GetEngine(); if (!e->CanCarryCargo() || !HasBit(e->info.callback_mask, CBM_VEHICLE_CARGO_SUFFIX)) continue; if (!HasBit(e->info.refit_mask, dest_cargo_type) && v->cargo_type != dest_cargo_type) continue; @@ -267,7 +265,7 @@ byte GetBestFittingSubType(Vehicle *v_from, Vehicle *v_for, CargoID dest_cargo_t StringID subtype = GetCargoSubtypeText(v); if (subtype == STR_EMPTY) break; - if (!subtypes.Contains(subtype)) continue; + if (std::find(subtypes.begin(), subtypes.end(), subtype) == subtypes.end()) continue; /* We found something matching. */ ret_refit_cyc = refit_cyc; @@ -317,7 +315,7 @@ struct RefitOption { } }; -typedef SmallVector SubtypeList; ///< List of refit subtypes associated to a cargo. +typedef std::vector SubtypeList; ///< List of refit subtypes associated to a cargo. /** * Draw the list of available refit options for a consist and highlight the selected refit option (if any). @@ -347,7 +345,7 @@ static void DrawVehicleRefitWindow(const SubtypeList list[NUM_CARGO], const int /* Draw the list of subtypes for each cargo, and find the selected refit option (by its position). */ for (uint i = 0; current < pos + rows && i < NUM_CARGO; i++) { - for (uint j = 0; current < pos + rows && j < list[i].Length(); j++) { + for (uint j = 0; current < pos + rows && j < list[i].size(); j++) { const RefitOption &refit = list[i][j]; /* Hide subtypes if sel[0] does not match */ @@ -359,11 +357,11 @@ static void DrawVehicleRefitWindow(const SubtypeList list[NUM_CARGO], const int continue; } - if (list[i].Length() > 1) { + 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].Length() - 1 ? ycenter : y - WD_MATRIX_TOP + delta - 1, linecolour); + GfxDrawLine(iconcenter, y - WD_MATRIX_TOP, iconcenter, j == list[i].size() - 1 ? ycenter : y - WD_MATRIX_TOP + delta - 1, linecolour); GfxDrawLine(iconcenter, ycenter, iconinner, ycenter, linecolour); } else { /* Draw expand/collapse icon */ @@ -406,7 +404,7 @@ struct RefitWindow : public Window { */ void BuildRefitList() { - for (uint i = 0; i < NUM_CARGO; i++) this->list[i].Clear(); + for (uint i = 0; i < NUM_CARGO; i++) this->list[i].clear(); Vehicle *v = Vehicle::Get(this->window_number); /* Check only the selected vehicles. */ @@ -414,7 +412,7 @@ struct RefitWindow : public Window { GetVehicleSet(vehicles_to_refit, Vehicle::Get(this->selected_vehicle), this->num_vehicles); do { - if (v->type == VEH_TRAIN && !vehicles_to_refit.Contains(v->index)) continue; + if (v->type == VEH_TRAIN && std::find(vehicles_to_refit.begin(), vehicles_to_refit.end(), v->index) == vehicles_to_refit.end()) continue; const Engine *e = v->GetEngine(); CargoTypes cmask = e->info.refit_mask; byte callback_mask = e->info.callback_mask; @@ -435,13 +433,10 @@ struct RefitWindow : public Window { continue; } - bool first_vehicle = this->list[current_index].Length() == 0; + bool first_vehicle = this->list[current_index].size() == 0; if (first_vehicle) { /* Keeping the current subtype is always an option. It also serves as the option in case of no subtypes */ - RefitOption *option = this->list[current_index].Append(); - option->cargo = cid; - option->subtype = 0xFF; - option->string = STR_EMPTY; + this->list[current_index].push_back({cid, 0xFF, STR_EMPTY}); } /* Check the vehicle's callback mask for cargo suffixes. @@ -473,16 +468,16 @@ struct RefitWindow : public Window { option.cargo = cid; option.subtype = refit_cyc; option.string = subtype; - this->list[current_index].Include(option); + include(this->list[current_index], option); } else { /* Intersect the subtypes of earlier vehicles with the subtypes of this vehicle */ if (subtype == STR_EMPTY) { /* No more subtypes for this vehicle, delete all subtypes >= refit_cyc */ SubtypeList &l = this->list[current_index]; /* 0xFF item is in front, other subtypes are sorted. So just truncate the list in the right spot */ - for (uint i = 1; i < l.Length(); i++) { + for (uint i = 1; i < l.size(); i++) { if (l[i].subtype >= refit_cyc) { - l.Resize(i); + l.resize(i); break; } } @@ -491,10 +486,10 @@ struct RefitWindow : public Window { /* Check whether the subtype matches with the subtype of earlier vehicles. */ uint pos = 1; SubtypeList &l = this->list[current_index]; - while (pos < l.Length() && l[pos].subtype != refit_cyc) pos++; - if (pos < l.Length() && l[pos].string != subtype) { + while (pos < l.size() && l[pos].subtype != refit_cyc) pos++; + if (pos < l.size() && l[pos].string != subtype) { /* String mismatch, remove item keeping the order */ - l.ErasePreservingOrder(pos); + l.erase(l.begin() + pos); } } } @@ -510,7 +505,7 @@ struct RefitWindow : public Window { } current_index++; } - } while (v->IsGroundVehicle() && (v = v->Next()) != NULL); + } while (v->IsGroundVehicle() && (v = v->Next()) != nullptr); } /** @@ -522,7 +517,7 @@ struct RefitWindow : public Window { uint row = 0; for (uint i = 0; i < NUM_CARGO; i++) { - for (uint j = 0; j < this->list[i].Length(); j++) { + for (uint j = 0; j < this->list[i].size(); j++) { const RefitOption &refit = this->list[i][j]; /* Hide subtypes if sel[0] does not match */ @@ -547,7 +542,7 @@ struct RefitWindow : public Window { uint row = 0; for (uint i = 0; i < NUM_CARGO; i++) { - for (uint j = 0; j < this->list[i].Length(); j++) { + for (uint j = 0; j < this->list[i].size(); j++) { const RefitOption &refit = this->list[i][j]; /* Hide subtypes if sel[0] does not match */ @@ -573,10 +568,10 @@ struct RefitWindow : public Window { */ RefitOption *GetRefitOption() { - if (this->sel[0] < 0) return NULL; + if (this->sel[0] < 0) return nullptr; SubtypeList &l = this->list[this->sel[0]]; - if ((uint)this->sel[1] >= l.Length()) return NULL; + if ((uint)this->sel[1] >= l.size()) return nullptr; return &l[this->sel[1]]; } @@ -590,7 +585,7 @@ struct RefitWindow : public Window { this->CreateNestedTree(); this->vscroll = this->GetScrollbar(WID_VR_SCROLLBAR); - this->hscroll = (v->IsGroundVehicle() ? this->GetScrollbar(WID_VR_HSCROLLBAR) : NULL); + this->hscroll = (v->IsGroundVehicle() ? this->GetScrollbar(WID_VR_HSCROLLBAR) : nullptr); this->GetWidget(WID_VR_SELECT_HEADER)->tool_tip = STR_REFIT_TRAIN_LIST_TOOLTIP + v->type; this->GetWidget(WID_VR_MATRIX)->tool_tip = STR_REFIT_TRAIN_LIST_TOOLTIP + v->type; NWidgetCore *nwi = this->GetWidget(WID_VR_REFIT); @@ -605,9 +600,9 @@ struct RefitWindow : public Window { this->SetWidgetDisabledState(WID_VR_REFIT, this->sel[0] < 0); } - virtual void OnInit() + void OnInit() override { - if (this->cargo != NULL) { + if (this->cargo != nullptr) { /* Store the RefitOption currently in use. */ RefitOption current_refit_option = *(this->cargo); @@ -615,9 +610,9 @@ struct RefitWindow : public Window { this->BuildRefitList(); this->sel[0] = -1; this->sel[1] = 0; - this->cargo = NULL; - for (uint i = 0; this->cargo == NULL && i < NUM_CARGO; i++) { - for (uint j = 0; j < list[i].Length(); j++) { + this->cargo = nullptr; + for (uint i = 0; this->cargo == nullptr && i < NUM_CARGO; i++) { + for (uint j = 0; j < list[i].size(); j++) { if (list[i][j] == current_refit_option) { this->sel[0] = i; this->sel[1] = j; @@ -635,10 +630,10 @@ struct RefitWindow : public Window { } } - virtual void OnPaint() + void OnPaint() override { /* Determine amount of items for scroller. */ - if (this->hscroll != NULL) this->hscroll->SetCount(this->vehicle_width); + if (this->hscroll != nullptr) this->hscroll->SetCount(this->vehicle_width); /* Calculate sprite position. */ NWidgetCore *vehicle_panel_display = this->GetWidget(WID_VR_VEHICLE_PANEL_DISPLAY); @@ -656,7 +651,7 @@ struct RefitWindow : public Window { this->DrawWidgets(); } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_VR_MATRIX: @@ -675,7 +670,7 @@ struct RefitWindow : public Window { } } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { if (widget == WID_VR_CAPTION) SetDParam(0, Vehicle::Get(this->window_number)->index); } @@ -727,13 +722,13 @@ struct RefitWindow : public Window { } } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { 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, INVALID_VEHICLE, EIT_IN_DETAILS, this->hscroll != NULL ? this->hscroll->GetPosition() : 0); + r.top, INVALID_VEHICLE, EIT_IN_DETAILS, this->hscroll != nullptr ? this->hscroll->GetPosition() : 0); /* Highlight selected vehicles. */ if (this->order != INVALID_VEH_ORDER_ID) break; @@ -746,16 +741,17 @@ struct RefitWindow : public Window { int left = INT32_MIN; int width = 0; - for (Train *u = Train::From(v); u != NULL; u = u->Next()) { + for (Train *u = Train::From(v); u != nullptr; u = u->Next()) { /* Start checking. */ - if (vehicles_to_refit.Contains(u->index) && left == INT32_MIN) { + const bool contained = std::find(vehicles_to_refit.begin(), vehicles_to_refit.end(), u->index) != vehicles_to_refit.end(); + if (contained && left == INT32_MIN) { left = x - this->hscroll->GetPosition() + r.left + this->vehicle_margin; width = 0; } /* Draw a selection. */ - if ((!vehicles_to_refit.Contains(u->index) || u->Next() == NULL) && left != INT32_MIN) { - if (u->Next() == NULL && vehicles_to_refit.Contains(u->index)) { + if ((!contained || u->Next() == nullptr) && left != INT32_MIN) { + if (u->Next() == nullptr && contained) { int current_width = u->GetDisplayImageWidth(); width += current_width; x += current_width; @@ -793,7 +789,7 @@ struct RefitWindow : public Window { break; case WID_VR_INFO: - if (this->cargo != NULL) { + 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, @@ -809,7 +805,7 @@ struct RefitWindow : public Window { * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { switch (data) { case VIWD_AUTOREPLACE: // Autoreplace replaced the vehicle; selected_vehicle became invalid. @@ -831,7 +827,7 @@ struct RefitWindow : public Window { /* Check the width of all cargo information strings. */ for (uint i = 0; i < NUM_CARGO; i++) { - for (uint j = 0; j < this->list[i].Length(); j++) { + for (uint j = 0; j < this->list[i].size(); j++) { StringID string = this->GetCapacityString(&list[i][j]); if (string != INVALID_STRING_ID) { Dimension dim = GetStringBoundingBox(string); @@ -860,7 +856,7 @@ struct RefitWindow : public Window { const NWidgetCore *matrix_widget = this->GetWidget(WID_VR_VEHICLE_PANEL_DISPLAY); if (_current_text_dir == TD_RTL) click_x = matrix_widget->current_x - click_x; click_x -= this->vehicle_margin; - if (this->hscroll != NULL) click_x += this->hscroll->GetPosition(); + if (this->hscroll != nullptr) click_x += this->hscroll->GetPosition(); return click_x; } @@ -881,7 +877,7 @@ struct RefitWindow : public Window { if (left_x >= 0) { const Train *u = Train::From(v); bool start_counting = false; - for (; u != NULL; u = u->Next()) { + for (; u != nullptr; u = u->Next()) { int current_width = u->GetDisplayImageWidth(); left_x -= current_width; right_x -= current_width; @@ -917,7 +913,7 @@ struct RefitWindow : public Window { } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_VR_VEHICLE_PANEL_DISPLAY: { // Vehicle image. @@ -945,7 +941,7 @@ struct RefitWindow : public Window { } case WID_VR_REFIT: // refit button - if (this->cargo != NULL) { + if (this->cargo != nullptr) { const Vehicle *v = Vehicle::Get(this->window_number); if (this->order == INVALID_VEH_ORDER_ID) { @@ -959,7 +955,7 @@ struct RefitWindow : public Window { } } - virtual void OnMouseDrag(Point pt, int widget) + void OnMouseDrag(Point pt, int widget) override { switch (widget) { case WID_VR_VEHICLE_PANEL_DISPLAY: { // Vehicle image. @@ -972,7 +968,7 @@ struct RefitWindow : public Window { } } - virtual void OnDragDrop(Point pt, int widget) + void OnDragDrop(Point pt, int widget) override { switch (widget) { case WID_VR_VEHICLE_PANEL_DISPLAY: { // Vehicle image. @@ -985,11 +981,11 @@ struct RefitWindow : public Window { } } - virtual void OnResize() + void OnResize() override { this->vehicle_width = GetVehicleWidth(Vehicle::Get(this->window_number), EIT_IN_DETAILS); this->vscroll->SetCapacityFromWidget(this, WID_VR_MATRIX); - if (this->hscroll != NULL) this->hscroll->SetCapacityFromWidget(this, WID_VR_VEHICLE_PANEL_DISPLAY); + if (this->hscroll != nullptr) this->hscroll->SetCapacityFromWidget(this, WID_VR_VEHICLE_PANEL_DISPLAY); } }; @@ -1086,62 +1082,62 @@ StringID GetCargoSubtypeText(const Vehicle *v) } /** Sort vehicles by their number */ -static int CDECL VehicleNumberSorter(const Vehicle * const *a, const Vehicle * const *b) +static bool VehicleNumberSorter(const Vehicle * const &a, const Vehicle * const &b) { - return (*a)->unitnumber - (*b)->unitnumber; + return a->unitnumber < b->unitnumber; } /** Sort vehicles by their name */ -static int CDECL VehicleNameSorter(const Vehicle * const *a, const Vehicle * const *b) +static bool VehicleNameSorter(const Vehicle * const &a, const Vehicle * const &b) { static char last_name[2][64]; - if (*a != _last_vehicle[0]) { - _last_vehicle[0] = *a; - SetDParam(0, (*a)->index); + if (a != _last_vehicle[0]) { + _last_vehicle[0] = a; + SetDParam(0, a->index); GetString(last_name[0], STR_VEHICLE_NAME, lastof(last_name[0])); } - if (*b != _last_vehicle[1]) { - _last_vehicle[1] = *b; - SetDParam(0, (*b)->index); + if (b != _last_vehicle[1]) { + _last_vehicle[1] = b; + SetDParam(0, b->index); GetString(last_name[1], STR_VEHICLE_NAME, lastof(last_name[1])); } int r = strnatcmp(last_name[0], last_name[1]); // Sort by name (natural sorting). - return (r != 0) ? r : VehicleNumberSorter(a, b); + return (r != 0) ? r < 0: VehicleNumberSorter(a, b); } /** Sort vehicles by their age */ -static int CDECL VehicleAgeSorter(const Vehicle * const *a, const Vehicle * const *b) +static bool VehicleAgeSorter(const Vehicle * const &a, const Vehicle * const &b) { - int r = (*a)->age - (*b)->age; - return (r != 0) ? r : VehicleNumberSorter(a, b); + int r = a->age - b->age; + return (r != 0) ? r < 0 : VehicleNumberSorter(a, b); } /** Sort vehicles by this year profit */ -static int CDECL VehicleProfitThisYearSorter(const Vehicle * const *a, const Vehicle * const *b) +static bool VehicleProfitThisYearSorter(const Vehicle * const &a, const Vehicle * const &b) { - int r = ClampToI32((*a)->GetDisplayProfitThisYear() - (*b)->GetDisplayProfitThisYear()); - return (r != 0) ? r : VehicleNumberSorter(a, b); + int r = ClampToI32(a->GetDisplayProfitThisYear() - b->GetDisplayProfitThisYear()); + return (r != 0) ? r < 0 : VehicleNumberSorter(a, b); } /** Sort vehicles by last year profit */ -static int CDECL VehicleProfitLastYearSorter(const Vehicle * const *a, const Vehicle * const *b) +static bool VehicleProfitLastYearSorter(const Vehicle * const &a, const Vehicle * const &b) { - int r = ClampToI32((*a)->GetDisplayProfitLastYear() - (*b)->GetDisplayProfitLastYear()); - return (r != 0) ? r : VehicleNumberSorter(a, b); + int r = ClampToI32(a->GetDisplayProfitLastYear() - b->GetDisplayProfitLastYear()); + return (r != 0) ? r < 0 : VehicleNumberSorter(a, b); } /** Sort vehicles by their cargo */ -static int CDECL VehicleCargoSorter(const Vehicle * const *a, const Vehicle * const *b) +static bool VehicleCargoSorter(const Vehicle * const &a, const Vehicle * const &b) { const Vehicle *v; CargoArray diff; /* Append the cargo of the connected waggons */ - for (v = *a; v != NULL; v = v->Next()) diff[v->cargo_type] += v->cargo_cap; - for (v = *b; v != NULL; v = v->Next()) diff[v->cargo_type] -= v->cargo_cap; + for (v = a; v != nullptr; v = v->Next()) diff[v->cargo_type] += v->cargo_cap; + for (v = b; v != nullptr; v = v->Next()) diff[v->cargo_type] -= v->cargo_cap; int r = 0; for (CargoID i = 0; i < NUM_CARGO; i++) { @@ -1149,62 +1145,62 @@ static int CDECL VehicleCargoSorter(const Vehicle * const *a, const Vehicle * co if (r != 0) break; } - return (r != 0) ? r : VehicleNumberSorter(a, b); + return (r != 0) ? r < 0 : VehicleNumberSorter(a, b); } /** Sort vehicles by their reliability */ -static int CDECL VehicleReliabilitySorter(const Vehicle * const *a, const Vehicle * const *b) +static bool VehicleReliabilitySorter(const Vehicle * const &a, const Vehicle * const &b) { - int r = (*a)->reliability - (*b)->reliability; - return (r != 0) ? r : VehicleNumberSorter(a, b); + int r = a->reliability - b->reliability; + return (r != 0) ? r < 0 : VehicleNumberSorter(a, b); } /** Sort vehicles by their max speed */ -static int CDECL VehicleMaxSpeedSorter(const Vehicle * const *a, const Vehicle * const *b) +static bool VehicleMaxSpeedSorter(const Vehicle * const &a, const Vehicle * const &b) { - int r = (*a)->vcache.cached_max_speed - (*b)->vcache.cached_max_speed; - return (r != 0) ? r : VehicleNumberSorter(a, b); + int r = a->vcache.cached_max_speed - b->vcache.cached_max_speed; + return (r != 0) ? r < 0 : VehicleNumberSorter(a, b); } /** Sort vehicles by model */ -static int CDECL VehicleModelSorter(const Vehicle * const *a, const Vehicle * const *b) +static bool VehicleModelSorter(const Vehicle * const &a, const Vehicle * const &b) { - int r = (*a)->engine_type - (*b)->engine_type; - return (r != 0) ? r : VehicleNumberSorter(a, b); + int r = a->engine_type - b->engine_type; + return (r != 0) ? r < 0 : VehicleNumberSorter(a, b); } /** Sort vehicles by their value */ -static int CDECL VehicleValueSorter(const Vehicle * const *a, const Vehicle * const *b) +static bool VehicleValueSorter(const Vehicle * const &a, const Vehicle * const &b) { const Vehicle *u; Money diff = 0; - for (u = *a; u != NULL; u = u->Next()) diff += u->value; - for (u = *b; u != NULL; u = u->Next()) diff -= u->value; + for (u = a; u != nullptr; u = u->Next()) diff += u->value; + for (u = b; u != nullptr; u = u->Next()) diff -= u->value; int r = ClampToI32(diff); - return (r != 0) ? r : VehicleNumberSorter(a, b); + return (r != 0) ? r < 0 : VehicleNumberSorter(a, b); } /** Sort vehicles by their length */ -static int CDECL VehicleLengthSorter(const Vehicle * const *a, const Vehicle * const *b) +static bool VehicleLengthSorter(const Vehicle * const &a, const Vehicle * const &b) { - int r = (*a)->GetGroundVehicleCache()->cached_total_length - (*b)->GetGroundVehicleCache()->cached_total_length; - return (r != 0) ? r : VehicleNumberSorter(a, b); + int r = a->GetGroundVehicleCache()->cached_total_length - b->GetGroundVehicleCache()->cached_total_length; + return (r != 0) ? r < 0 : VehicleNumberSorter(a, b); } /** Sort vehicles by the time they can still live */ -static int CDECL VehicleTimeToLiveSorter(const Vehicle * const *a, const Vehicle * const *b) +static bool VehicleTimeToLiveSorter(const Vehicle * const &a, const Vehicle * const &b) { - int r = ClampToI32(((*a)->max_age - (*a)->age) - ((*b)->max_age - (*b)->age)); - return (r != 0) ? r : VehicleNumberSorter(a, b); + int r = ClampToI32((a->max_age - a->age) - (b->max_age - b->age)); + return (r != 0) ? r < 0 : VehicleNumberSorter(a, b); } /** Sort vehicles by the timetable delay */ -static int CDECL VehicleTimetableDelaySorter(const Vehicle * const *a, const Vehicle * const *b) +static bool VehicleTimetableDelaySorter(const Vehicle * const &a, const Vehicle * const &b) { - int r = (*a)->lateness_counter - (*b)->lateness_counter; - return (r != 0) ? r : VehicleNumberSorter(a, b); + int r = a->lateness_counter - b->lateness_counter; + return (r != 0) ? r < 0 : VehicleNumberSorter(a, b); } void InitializeGUI() @@ -1221,10 +1217,10 @@ void InitializeGUI() static inline void ChangeVehicleWindow(WindowClass window_class, VehicleID from_index, VehicleID to_index) { Window *w = FindWindowById(window_class, from_index); - if (w != NULL) { + if (w != nullptr) { /* Update window_number */ w->window_number = to_index; - if (w->viewport != NULL) w->viewport->follow_vehicle = to_index; + if (w->viewport != nullptr) w->viewport->follow_vehicle = to_index; /* Update vehicle drag data */ if (_thd.window_class == window_class && _thd.window_number == (WindowNumber)from_index) { @@ -1294,7 +1290,7 @@ static const NWidgetPart _nested_vehicle_list[] = { static void DrawSmallOrderList(const Vehicle *v, int left, int right, int y, VehicleOrderID start = 0) { const Order *order = v->GetOrder(start); - if (order == NULL) return; + if (order == nullptr) return; bool rtl = _current_text_dir == TD_RTL; int l_offset = rtl ? 0 : ScaleGUITrad(6); @@ -1315,7 +1311,7 @@ static void DrawSmallOrderList(const Vehicle *v, int left, int right, int y, Veh oid++; order = order->next; - if (order == NULL) { + if (order == nullptr) { order = v->orders.list->GetFirstOrder(); oid = 0; } @@ -1389,7 +1385,7 @@ void BaseVehicleListWindow::DrawVehicleListItems(VehicleID selected_vehicle, int int vehicle_button_x = rtl ? right - GetSpriteSize(SPR_PROFIT_LOT).width : left; int y = r.top; - uint max = min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->vehicles.Length()); + uint max = min(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), (uint)this->vehicles.size()); for (uint i = this->vscroll->GetPosition(); i < max; ++i) { const Vehicle *v = this->vehicles[i]; StringID str; @@ -1400,7 +1396,7 @@ void BaseVehicleListWindow::DrawVehicleListItems(VehicleID selected_vehicle, int DrawVehicleImage(v, image_left, image_right, y + FONT_HEIGHT_SMALL - 1, selected_vehicle, EIT_IN_LIST, 0); DrawString(text_left, text_right, y + line_height - FONT_HEIGHT_SMALL - WD_FRAMERECT_BOTTOM - 1, STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR); - if (v->name != NULL) { + if (v->name != nullptr) { /* The vehicle got a name so we will print it */ SetDParam(0, v->index); DrawString(text_left, text_right, y, STR_TINY_BLACK_VEHICLE); @@ -1486,7 +1482,7 @@ public: *this->sorting = this->vehicles.GetListing(); } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_VL_LIST: @@ -1523,7 +1519,7 @@ public: } } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { switch (widget) { case WID_VL_AVAILABLE_VEHICLES: @@ -1533,7 +1529,7 @@ public: case WID_VL_CAPTION: { switch (this->vli.type) { case VL_SHARED_ORDERS: // Shared Orders - if (this->vehicles.Length() == 0) { + if (this->vehicles.size() == 0) { /* We can't open this window without vehicles using this order * and we should close the window when deleting the order. */ NOT_REACHED(); @@ -1566,7 +1562,7 @@ public: } } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { switch (widget) { case WID_VL_SORT_ORDER: @@ -1580,12 +1576,12 @@ public: } } - virtual void OnPaint() + void OnPaint() override { this->BuildVehicleList(); this->SortVehicleList(); - if (this->vehicles.Length() == 0 && this->IsWidgetLowered(WID_VL_MANAGE_VEHICLES_DROPDOWN)) { + if (this->vehicles.size() == 0 && this->IsWidgetLowered(WID_VL_MANAGE_VEHICLES_DROPDOWN)) { HideDropDownMenu(this); } @@ -1599,7 +1595,7 @@ public: } if (this->owner == _local_company) { this->SetWidgetDisabledState(WID_VL_AVAILABLE_VEHICLES, this->vli.type != VL_STANDARD); - this->SetWidgetsDisabledState(this->vehicles.Length() == 0, + this->SetWidgetsDisabledState(this->vehicles.size() == 0, WID_VL_MANAGE_VEHICLES_DROPDOWN, WID_VL_STOP_ALL, WID_VL_START_ALL, @@ -1612,7 +1608,7 @@ public: this->DrawWidgets(); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_VL_SORT_ORDER: // Flip sorting method ascending/descending @@ -1627,10 +1623,16 @@ public: case WID_VL_LIST: { // Matrix to show vehicles uint id_v = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_VL_LIST); - if (id_v >= this->vehicles.Length()) return; // click out of list bound + if (id_v >= this->vehicles.size()) return; // click out of list bound const Vehicle *v = this->vehicles[id_v]; - if (!VehicleClicked(v)) ShowVehicleViewWindow(v); + if (!VehicleClicked(v)) { + if (_ctrl_pressed) { + ShowCompanyGroupForVehicle(v); + } else { + ShowVehicleViewWindow(v); + } + } break; } @@ -1639,8 +1641,7 @@ public: break; case WID_VL_MANAGE_VEHICLES_DROPDOWN: { - DropDownList *list = this->BuildActionDropdownList(VehicleListIdentifier::UnPack(this->window_number).type == VL_STANDARD, false); - ShowDropDownList(this, list, 0, WID_VL_MANAGE_VEHICLES_DROPDOWN); + ShowDropDownList(this, this->BuildActionDropdownList(VehicleListIdentifier::UnPack(this->window_number).type == VL_STANDARD, false), 0, WID_VL_MANAGE_VEHICLES_DROPDOWN); break; } @@ -1651,14 +1652,14 @@ public: } } - virtual void OnDropdownSelect(int widget, int index) + void OnDropdownSelect(int widget, int index) override { switch (widget) { case WID_VL_SORT_BY_PULLDOWN: this->vehicles.SetSortType(index); break; case WID_VL_MANAGE_VEHICLES_DROPDOWN: - assert(this->vehicles.Length() != 0); + assert(this->vehicles.size() != 0); switch (index) { case ADI_REPLACE: // Replace window @@ -1677,7 +1678,7 @@ public: this->SetDirty(); } - virtual void OnGameTick() + void OnGameTick() override { if (this->vehicles.NeedResort()) { StationID station = (this->vli.type == VL_STATION_LIST) ? this->vli.index : INVALID_STATION; @@ -1687,7 +1688,7 @@ public: } } - virtual void OnResize() + void OnResize() override { this->vscroll->SetCapacityFromWidget(this, WID_VL_LIST); } @@ -1697,7 +1698,7 @@ public: * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope && HasBit(data, 31) && this->vli.type == VL_SHARED_ORDERS) { /* Needs to be done in command-scope, so everything stays valid */ @@ -1873,7 +1874,7 @@ struct VehicleDetailsWindow : Window { const Vehicle *v = Vehicle::Get(window_number); this->CreateNestedTree(); - this->vscroll = (v->type == VEH_TRAIN ? this->GetScrollbar(WID_VD_SCROLLBAR) : NULL); + this->vscroll = (v->type == VEH_TRAIN ? this->GetScrollbar(WID_VD_SCROLLBAR) : nullptr); this->FinishInitNested(window_number); this->GetWidget(WID_VD_RENAME_VEHICLE)->tool_tip = STR_VEHICLE_DETAILS_TRAIN_RENAME + v->type; @@ -1887,7 +1888,7 @@ struct VehicleDetailsWindow : Window { * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (data == VIWD_AUTOREPLACE) { /* Autoreplace replaced the vehicle. @@ -1918,7 +1919,7 @@ struct VehicleDetailsWindow : Window { /* 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; /* Add space for the cargo amount for each part. */ - for (const Vehicle *u = v; u != NULL; u = u->Next()) { + for (const Vehicle *u = v; u != nullptr; u = u->Next()) { if (u->cargo_cap != 0) desired_height += FONT_HEIGHT_NORMAL + 1; } } else { @@ -1927,7 +1928,7 @@ struct VehicleDetailsWindow : Window { return desired_height; } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { switch (widget) { case WID_VD_TOP_DETAILS: { @@ -2031,12 +2032,12 @@ struct VehicleDetailsWindow : Window { } } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { if (widget == WID_VD_CAPTION) SetDParam(0, Vehicle::Get(this->window_number)->index); } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { const Vehicle *v = Vehicle::Get(this->window_number); @@ -2134,7 +2135,7 @@ struct VehicleDetailsWindow : Window { } /** Repaint vehicle details window. */ - virtual void OnPaint() + void OnPaint() override { const Vehicle *v = Vehicle::Get(this->window_number); @@ -2159,7 +2160,7 @@ struct VehicleDetailsWindow : Window { this->DrawWidgets(); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_VD_RENAME_VEHICLE: { // rename @@ -2207,7 +2208,7 @@ struct VehicleDetailsWindow : Window { } } - virtual void OnDropdownSelect(int widget, int index) + void OnDropdownSelect(int widget, int index) override { switch (widget) { case WID_VD_SERVICE_INTERVAL_DROPDOWN: { @@ -2221,17 +2222,17 @@ struct VehicleDetailsWindow : Window { } } - virtual void OnQueryTextFinished(char *str) + void OnQueryTextFinished(char *str) override { - if (str == NULL) return; + if (str == nullptr) return; - DoCommandP(0, this->window_number, 0, CMD_RENAME_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_RENAME_TRAIN + Vehicle::Get(this->window_number)->type), NULL, str); + DoCommandP(0, this->window_number, 0, CMD_RENAME_VEHICLE | CMD_MSG(STR_ERROR_CAN_T_RENAME_TRAIN + Vehicle::Get(this->window_number)->type), nullptr, str); } - virtual void OnResize() + void OnResize() override { NWidgetCore *nwi = this->GetWidget(WID_VD_MATRIX); - if (nwi != NULL) { + if (nwi != nullptr) { this->vscroll->SetCapacityFromWidget(this, WID_VD_MATRIX); } } @@ -2381,12 +2382,12 @@ static const uint32 _vehicle_command_translation_table[][4] = { * @param p1 vehicle ID * @param p2 unused */ -void CcStartStopVehicle(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) +void CcStartStopVehicle(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) { if (result.Failed()) return; const Vehicle *v = Vehicle::GetIfValid(p1); - if (v == NULL || !v->IsPrimaryVehicle() || v->owner != _local_company) return; + if (v == nullptr || !v->IsPrimaryVehicle() || v->owner != _local_company) return; StringID msg = (v->vehstatus & VS_STOPPED) ? STR_VEHICLE_COMMAND_STOPPED : STR_VEHICLE_COMMAND_STARTED; Point pt = RemapCoords(v->x_pos, v->y_pos, v->z_pos); @@ -2401,7 +2402,7 @@ void CcStartStopVehicle(const CommandCost &result, TileIndex tile, uint32 p1, ui void StartStopVehicle(const Vehicle *v, bool texteffect) { assert(v->IsPrimaryVehicle()); - DoCommandP(v->tile, v->index, 0, _vehicle_command_translation_table[VCT_CMD_START_STOP][v->type], texteffect ? CcStartStopVehicle : NULL); + DoCommandP(v->tile, v->index, 0, _vehicle_command_translation_table[VCT_CMD_START_STOP][v->type], texteffect ? CcStartStopVehicle : nullptr); } /** Checks whether the vehicle may be refitted at the moment.*/ @@ -2411,7 +2412,7 @@ static bool IsVehicleRefitable(const Vehicle *v) do { if (IsEngineRefittable(v->engine_type)) return true; - } while (v->IsGroundVehicle() && (v = v->Next()) != NULL); + } while (v->IsGroundVehicle() && (v = v->Next()) != nullptr); return false; } @@ -2516,7 +2517,7 @@ public: DeleteWindowById(WC_VEHICLE_TIMETABLE, this->window_number, false); } - virtual void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) + void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override { const Vehicle *v = Vehicle::Get(this->window_number); switch (widget) { @@ -2538,7 +2539,7 @@ public: } } - virtual void OnPaint() + void OnPaint() override { const Vehicle *v = Vehicle::Get(this->window_number); bool is_localcompany = v->owner == _local_company; @@ -2557,7 +2558,7 @@ public: this->DrawWidgets(); } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { if (widget != WID_VV_CAPTION) return; @@ -2565,7 +2566,7 @@ public: SetDParam(0, v->index); } - virtual void DrawWidget(const Rect &r, int widget) const + void DrawWidget(const Rect &r, int widget) const override { if (widget != WID_VV_START_STOP) return; @@ -2664,7 +2665,7 @@ public: DrawString(text_left + lowered, text_right + lowered, Center(r.top, r.bottom - r.top) + lowered, str, TC_FROMSTRING, SA_HOR_CENTER); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { const Vehicle *v = Vehicle::Get(this->window_number); @@ -2704,7 +2705,11 @@ public: } break; case WID_VV_SHOW_DETAILS: // show details - ShowVehicleDetailsWindow(v); + if (_ctrl_pressed) { + ShowCompanyGroupForVehicle(v); + } else { + ShowVehicleDetailsWindow(v); + } break; case WID_VV_CLONE: // clone vehicle /* Suppress the vehicle GUI when share-cloning. @@ -2713,7 +2718,7 @@ public: * most likely already open, but is also visible in the vehicle viewport. */ DoCommandP(v->tile, v->index, _ctrl_pressed ? 1 : 0, _vehicle_command_translation_table[VCT_CMD_CLONE_VEH][v->type], - _ctrl_pressed ? NULL : CcCloneVehicle); + _ctrl_pressed ? nullptr : CcCloneVehicle); break; case WID_VV_TURN_AROUND: // turn around assert(v->IsGroundVehicle()); @@ -2727,9 +2732,9 @@ public: } } - virtual void OnResize() + void OnResize() override { - if (this->viewport != NULL) { + if (this->viewport != nullptr) { NWidgetViewport *nvp = this->GetWidget(WID_VV_VIEWPORT); nvp->UpdateViewportCoordinates(this); } @@ -2765,7 +2770,7 @@ public: * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (data == VIWD_AUTOREPLACE) { /* Autoreplace replaced the vehicle. @@ -2776,12 +2781,12 @@ public: this->UpdateButtonStatus(); } - virtual bool IsNewGRFInspectable() const + bool IsNewGRFInspectable() const override { return ::IsNewGRFInspectable(GetGrfSpecFeature(Vehicle::Get(this->window_number)->type), this->window_number); } - virtual void ShowNewGRFInspectWindow() const + void ShowNewGRFInspectWindow() const override { ::ShowNewGRFInspectWindow(GetGrfSpecFeature(Vehicle::Get(this->window_number)->type), this->window_number); } @@ -2801,7 +2806,7 @@ void ShowVehicleViewWindow(const Vehicle *v) */ bool VehicleClicked(const Vehicle *v) { - assert(v != NULL); + assert(v != nullptr); if (!(_thd.place_mode & HT_VEHICLE)) return false; v = v->First(); @@ -2813,7 +2818,7 @@ bool VehicleClicked(const Vehicle *v) void StopGlobalFollowVehicle(const Vehicle *v) { Window *w = FindWindowById(WC_MAIN_WINDOW, 0); - if (w != NULL && w->viewport->follow_vehicle == v->index) { + if (w != nullptr && 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; } @@ -2826,8 +2831,9 @@ void StopGlobalFollowVehicle(const Vehicle *v) * @param tile unused * @param p1 unused * @param p2 unused + * @param cmd unused */ -void CcBuildPrimaryVehicle(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2) +void CcBuildPrimaryVehicle(const CommandCost &result, TileIndex tile, uint32 p1, uint32 p2, uint32 cmd) { if (result.Failed()) return; @@ -2868,7 +2874,7 @@ int GetVehicleWidth(const Vehicle *v, EngineImageType image_type) { if (v->type == VEH_TRAIN || v->type == VEH_ROAD) { int vehicle_width = 0; - for (const Vehicle *u = v; u != NULL; u = u->Next()) { + for (const Vehicle *u = v; u != nullptr; u = u->Next()) { vehicle_width += GetSingleVehicleWidth(u, image_type); } return vehicle_width; @@ -2888,7 +2894,7 @@ void SetMouseCursorVehicle(const Vehicle *v, EngineImageType image_type) _cursor.sprite_count = 0; int total_width = 0; - for (; v != NULL; v = v->HasArticulatedPart() ? v->GetNextArticulatedPart() : NULL) { + for (; v != nullptr; v = v->HasArticulatedPart() ? v->GetNextArticulatedPart() : nullptr) { if (total_width >= 2 * (int)VEHICLEINFO_FULL_VEHICLE_WIDTH) break; PaletteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v); diff --git a/src/vehicle_gui.h b/src/vehicle_gui.h index 92975425df..fe21325168 100644 --- a/src/vehicle_gui.h +++ b/src/vehicle_gui.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. @@ -37,7 +35,15 @@ enum VehicleInvalidateWindowData { VIWD_AUTOREPLACE = -4, ///< Autoreplace replaced the vehicle. }; -int DrawVehiclePurchaseInfo(int left, int right, int y, EngineID engine_number); +/** Extra information about refitted cargo and capacity */ +struct TestedEngineDetails { + Money cost; ///< Refit cost + CargoID cargo; ///< Cargo type + uint16 capacity; ///< Cargo capacity + uint16 mail_capacity; ///< Mail capacity if available +}; + +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); diff --git a/src/vehicle_gui_base.h b/src/vehicle_gui_base.h index 5755c7fa88..89410b17ef 100644 --- a/src/vehicle_gui_base.h +++ b/src/vehicle_gui_base.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. @@ -47,7 +45,7 @@ struct BaseVehicleListWindow : public Window { void SortVehicleList(); void BuildVehicleList(); Dimension GetActionDropdownSize(bool show_autoreplace, bool show_group); - DropDownList *BuildActionDropdownList(bool show_autoreplace, bool show_group); + DropDownList BuildActionDropdownList(bool show_autoreplace, bool show_group); }; uint GetVehicleListHeight(VehicleType type, uint divisor = 1); diff --git a/src/vehicle_type.h b/src/vehicle_type.h index f3e7d535fd..ae4de36665 100644 --- a/src/vehicle_type.h +++ b/src/vehicle_type.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. @@ -19,8 +17,8 @@ typedef uint32 VehicleID; static const int GROUND_ACCELERATION = 9800; ///< Acceleration due to gravity, 9.8 m/s^2 -/** Available vehicle types. */ -enum VehicleType { +/** Available vehicle types. It needs to be 8bits, because we save and load it as such */ +enum VehicleType : byte { VEH_BEGIN, VEH_TRAIN = VEH_BEGIN, ///< %Train vehicle type. @@ -39,8 +37,6 @@ enum VehicleType { DECLARE_POSTFIX_INCREMENT(VehicleType) /** Helper information for extract tool. */ template <> struct EnumPropsT : MakeEnumPropsT {}; -/** It needs to be 8bits, because we save and load it as such */ -typedef SimpleTinyEnumT VehicleTypeByte; struct Vehicle; struct Train; @@ -53,21 +49,21 @@ struct DisasterVehicle; /** Base vehicle class. */ struct BaseVehicle { - VehicleTypeByte type; ///< Type of vehicle + VehicleType type; ///< Type of vehicle }; static const VehicleID INVALID_VEHICLE = 0xFFFFF; ///< Constant representing a non-existing vehicle. /** Pathfinding option states */ enum VehiclePathFinders { - VPF_OPF = 0, ///< The Original PathFinder (only for ships) + // Original PathFinder (OPF) used to be 0 VPF_NPF = 1, ///< New PathFinder VPF_YAPF = 2, ///< Yet Another PathFinder }; /** Flags to add to p1 for goto depot commands. */ enum DepotCommand { - DEPOT_SERVICE = (1U << 28), ///< The vehicle will leave the depot right after arrival (serivce only) + DEPOT_SERVICE = (1U << 28), ///< The vehicle will leave the depot right after arrival (service only) DEPOT_MASS_SEND = (1U << 29), ///< Tells that it's a mass send to depot command (type in VLW flag) DEPOT_DONT_CANCEL = (1U << 30), ///< Don't cancel current goto depot command if any DEPOT_LOCATE_HANGAR = (1U << 31), ///< Find another airport if the target one lacks a hangar diff --git a/src/vehiclelist.cpp b/src/vehiclelist.cpp index bfe4e5ffd1..de37e3abae 100644 --- a/src/vehiclelist.cpp +++ b/src/vehiclelist.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. @@ -65,16 +63,15 @@ bool VehicleListIdentifier::UnpackIfValid(uint32 data) * @param type Type of vehicle * @param tile The tile the depot is located on * @param engines Pointer to list to add vehicles to - * @param wagons Pointer to list to add wagons to (can be NULL) + * @param wagons Pointer to list to add wagons to (can be nullptr) * @param individual_wagons If true add every wagon to \a wagons which is not attached to an engine. If false only add the first wagon of every row. */ void BuildDepotVehicleList(VehicleType type, TileIndex tile, VehicleList *engines, VehicleList *wagons, bool individual_wagons) { - engines->Clear(); - if (wagons != NULL && wagons != engines) wagons->Clear(); + engines->clear(); + if (wagons != nullptr && wagons != engines) wagons->clear(); - const Vehicle *v; - FOR_ALL_VEHICLES(v) { + for (const Vehicle *v : Vehicle::Iterate()) { /* General tests for all vehicle types */ if (v->type != type) continue; if (v->tile != tile) continue; @@ -84,8 +81,8 @@ void BuildDepotVehicleList(VehicleType type, TileIndex tile, VehicleList *engine const Train *t = Train::From(v); if (t->IsArticulatedPart() || t->IsRearDualheaded()) continue; if (t->track != TRACK_BIT_DEPOT) continue; - if (wagons != NULL && t->First()->IsFreeWagon()) { - if (individual_wagons || t->IsFreeWagon()) *wagons->Append() = t; + if (wagons != nullptr && t->First()->IsFreeWagon()) { + if (individual_wagons || t->IsFreeWagon()) wagons->push_back(t); continue; } break; @@ -98,13 +95,13 @@ void BuildDepotVehicleList(VehicleType type, TileIndex tile, VehicleList *engine if (!v->IsPrimaryVehicle()) continue; - *engines->Append() = v; + engines->push_back(v); } /* Ensure the lists are not wasting too much space. If the lists are fresh * (i.e. built within a command) then this will actually do nothing. */ - engines->Compact(); - if (wagons != NULL && wagons != engines) wagons->Compact(); + engines->shrink_to_fit(); + if (wagons != nullptr && wagons != engines) wagons->shrink_to_fit(); } /** @@ -115,20 +112,18 @@ void BuildDepotVehicleList(VehicleType type, TileIndex tile, VehicleList *engine */ bool GenerateVehicleSortList(VehicleList *list, const VehicleListIdentifier &vli) { - list->Clear(); - - const Vehicle *v; + list->clear(); switch (vli.type) { case VL_STATION_LIST: - FOR_ALL_VEHICLES(v) { + for (const Vehicle *v : Vehicle::Iterate()) { if (v->type == vli.vtype && v->IsPrimaryVehicle()) { const Order *order; FOR_VEHICLE_ORDERS(v, order) { if ((order->IsType(OT_GOTO_STATION) || order->IsType(OT_GOTO_WAYPOINT) || order->IsType(OT_IMPLICIT)) && order->GetDestination() == vli.index) { - *list->Append() = v; + list->push_back(v); break; } } @@ -136,22 +131,23 @@ bool GenerateVehicleSortList(VehicleList *list, const VehicleListIdentifier &vli } break; - case VL_SHARED_ORDERS: + case VL_SHARED_ORDERS: { /* Add all vehicles from this vehicle's shared order list */ - v = Vehicle::GetIfValid(vli.index); - if (v == NULL || v->type != vli.vtype || !v->IsPrimaryVehicle()) return false; + const Vehicle *v = Vehicle::GetIfValid(vli.index); + if (v == nullptr || v->type != vli.vtype || !v->IsPrimaryVehicle()) return false; - for (; v != NULL; v = v->NextShared()) { - *list->Append() = v; + for (; v != nullptr; v = v->NextShared()) { + list->push_back(v); } break; + } case VL_GROUP_LIST: if (vli.index != ALL_GROUP) { - FOR_ALL_VEHICLES(v) { + for (const Vehicle *v : Vehicle::Iterate()) { if (v->type == vli.vtype && v->IsPrimaryVehicle() && v->owner == vli.company && GroupIsInGroup(v->group_id, vli.index)) { - *list->Append() = v; + list->push_back(v); } } break; @@ -159,21 +155,21 @@ bool GenerateVehicleSortList(VehicleList *list, const VehicleListIdentifier &vli FALLTHROUGH; case VL_STANDARD: - FOR_ALL_VEHICLES(v) { + for (const Vehicle *v : Vehicle::Iterate()) { if (v->type == vli.vtype && v->owner == vli.company && v->IsPrimaryVehicle()) { - *list->Append() = v; + list->push_back(v); } } break; case VL_DEPOT_LIST: - FOR_ALL_VEHICLES(v) { + for (const Vehicle *v : Vehicle::Iterate()) { if (v->type == vli.vtype && v->IsPrimaryVehicle()) { const Order *order; FOR_VEHICLE_ORDERS(v, order) { if (order->IsType(OT_GOTO_DEPOT) && !(order->GetDepotActionType() & ODATFB_NEAREST_DEPOT) && order->GetDestination() == vli.index) { - *list->Append() = v; + list->push_back(v); break; } } @@ -184,6 +180,6 @@ bool GenerateVehicleSortList(VehicleList *list, const VehicleListIdentifier &vli default: return false; } - list->Compact(); + list->shrink_to_fit(); return true; } diff --git a/src/vehiclelist.h b/src/vehiclelist.h index 996c8c007f..6cb2588ea6 100644 --- a/src/vehiclelist.h +++ b/src/vehiclelist.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. @@ -52,7 +50,7 @@ struct VehicleListIdentifier { }; /** A list of vehicles. */ -typedef SmallVector VehicleList; +typedef std::vector VehicleList; bool GenerateVehicleSortList(VehicleList *list, const VehicleListIdentifier &identifier); void BuildDepotVehicleList(VehicleType type, TileIndex tile, VehicleList *engine_list, VehicleList *wagon_list, bool individual_wagons = false); diff --git a/src/video/allegro_v.cpp b/src/video/allegro_v.cpp index 960d7fb7c8..88e5c528ff 100644 --- a/src/video/allegro_v.cpp +++ b/src/video/allegro_v.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. @@ -25,8 +23,10 @@ #include "../core/random_func.hpp" #include "../core/math_func.hpp" #include "../framerate_type.h" +#include "../thread.h" #include "allegro_v.h" #include +#include #include "../safeguards.h" @@ -138,34 +138,25 @@ static void GetVideoModes() * cards ourselves... and we need a card to get the modes. */ set_gfx_mode(_fullscreen ? GFX_AUTODETECT_FULLSCREEN : GFX_AUTODETECT_WINDOWED, 640, 480, 0, 0); + _resolutions.clear(); + GFX_MODE_LIST *mode_list = get_gfx_mode_list(gfx_driver->id); - if (mode_list == NULL) { - memcpy(_resolutions, default_resolutions, sizeof(default_resolutions)); - _num_resolutions = lengthof(default_resolutions); + if (mode_list == nullptr) { + _resolutions.assign(std::begin(default_resolutions), std::end(default_resolutions)); return; } GFX_MODE *modes = mode_list->mode; - int n = 0; for (int i = 0; modes[i].bpp != 0; i++) { uint w = modes[i].width; uint h = modes[i].height; - if (w >= 640 && h >= 480) { - int j; - for (j = 0; j < n; j++) { - if (_resolutions[j].width == w && _resolutions[j].height == h) break; - } - - if (j == n) { - _resolutions[j].width = w; - _resolutions[j].height = h; - if (++n == lengthof(_resolutions)) break; - } - } + if (w < 640 || h < 480) continue; + if (std::find(_resolutions.begin(), _resolutions.end(), Dimension(w, h)) != _resolutions.end()) continue; + _resolutions.emplace_back(w, h); } - _num_resolutions = n; - SortResolutions(_num_resolutions); + + SortResolutions(); destroy_gfx_mode_list(mode_list); } @@ -173,17 +164,15 @@ static void GetVideoModes() static void GetAvailableVideoMode(uint *w, uint *h) { /* No video modes, so just try it and see where it ends */ - if (_num_resolutions == 0) return; + if (_resolutions.empty()) return; /* is the wanted mode among the available modes? */ - for (int i = 0; i != _num_resolutions; i++) { - if (*w == _resolutions[i].width && *h == _resolutions[i].height) return; - } + if (std::find(_resolutions.begin(), _resolutions.end(), Dimension(*w, *h)) != _resolutions.end()) return; /* use the closest possible resolution */ - int best = 0; + uint best = 0; uint delta = Delta(_resolutions[0].width, *w) * Delta(_resolutions[0].height, *h); - for (int i = 1; i != _num_resolutions; ++i) { + for (uint i = 1; i != _resolutions.size(); ++i) { uint newdelta = Delta(_resolutions[i].width, *w) * Delta(_resolutions[i].height, *h); if (newdelta < delta) { best = i; @@ -242,7 +231,7 @@ static bool CreateMainSurface(uint w, uint h) bool VideoDriver_Allegro::ClaimMousePointer() { select_mouse_cursor(MOUSE_CURSOR_NONE); - show_mouse(NULL); + show_mouse(nullptr); disable_hardware_cursor(); return true; } @@ -423,7 +412,7 @@ int _allegro_instance_count = 0; const char *VideoDriver_Allegro::Start(const char * const *parm) { - if (_allegro_instance_count == 0 && install_allegro(SYSTEM_AUTODETECT, &errno, NULL)) { + if (_allegro_instance_count == 0 && install_allegro(SYSTEM_AUTODETECT, &errno, nullptr)) { DEBUG(driver, 0, "allegro: install_allegro failed '%s'", allegro_error); return "Failed to set up Allegro"; } @@ -436,14 +425,8 @@ const char *VideoDriver_Allegro::Start(const char * const *parm) #if defined _DEBUG /* Allegro replaces SEGV/ABRT signals meaning that the debugger will never * be triggered, so rereplace the signals and make the debugger useful. */ - signal(SIGABRT, NULL); - signal(SIGSEGV, NULL); -#endif - -#if defined(DOS) - /* Force DOS builds to ALWAYS use full screen as - * it can't do windowed. */ - _fullscreen = true; + signal(SIGABRT, nullptr); + signal(SIGSEGV, nullptr); #endif GetVideoModes(); @@ -453,7 +436,7 @@ const char *VideoDriver_Allegro::Start(const char * const *parm) MarkWholeScreenDirty(); set_close_button_callback(HandleExitGameRequest); - return NULL; + return nullptr; } void VideoDriver_Allegro::Stop() @@ -461,14 +444,14 @@ void VideoDriver_Allegro::Stop() if (--_allegro_instance_count == 0) allegro_exit(); } -#if defined(UNIX) || defined(__OS2__) || defined(DOS) +#if defined(UNIX) || defined(__OS2__) # include /* gettimeofday */ static uint32 GetTime() { struct timeval tim; - gettimeofday(&tim, NULL); + gettimeofday(&tim, nullptr); return tim.tv_usec / 1000 + tim.tv_sec * 1000; } #else @@ -548,18 +531,14 @@ bool VideoDriver_Allegro::ChangeResolution(int w, int h) bool VideoDriver_Allegro::ToggleFullscreen(bool fullscreen) { -#ifdef DOS - return false; -#else _fullscreen = fullscreen; GetVideoModes(); // get the list of available video modes - if (_num_resolutions == 0 || !this->ChangeResolution(_cur_resolution.width, _cur_resolution.height)) { + if (_resolutions.empty() || !this->ChangeResolution(_cur_resolution.width, _cur_resolution.height)) { /* switching resolution failed, put back full_screen to original status */ _fullscreen ^= true; return false; } return true; -#endif } bool VideoDriver_Allegro::AfterBlitterChange() diff --git a/src/video/allegro_v.h b/src/video/allegro_v.h index a770635da0..fb7b84ee2c 100644 --- a/src/video/allegro_v.h +++ b/src/video/allegro_v.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. @@ -17,30 +15,30 @@ /** The allegro video driver. */ class VideoDriver_Allegro : public VideoDriver { public: - /* virtual */ const char *Start(const char * const *param); + const char *Start(const char * const *param) override; - /* virtual */ void Stop(); + void Stop() override; - /* virtual */ void MakeDirty(int left, int top, int width, int height); + void MakeDirty(int left, int top, int width, int height) override; - /* virtual */ void MainLoop(); + void MainLoop() override; - /* virtual */ bool ChangeResolution(int w, int h); + bool ChangeResolution(int w, int h) override; - /* virtual */ bool ToggleFullscreen(bool fullscreen); + bool ToggleFullscreen(bool fullscreen) override; - /* virtual */ bool AfterBlitterChange(); + bool AfterBlitterChange() override; - /* virtual */ bool ClaimMousePointer(); + bool ClaimMousePointer() override; - /* virtual */ const char *GetName() const { return "allegro"; } + const char *GetName() const override { return "allegro"; } }; /** Factory for the allegro video driver. */ class FVideoDriver_Allegro : public DriverFactoryBase { public: FVideoDriver_Allegro() : DriverFactoryBase(Driver::DT_VIDEO, 4, "allegro", "Allegro Video Driver") {} - /* virtual */ Driver *CreateInstance() const { return new VideoDriver_Allegro(); } + Driver *CreateInstance() const override { return new VideoDriver_Allegro(); } }; #endif /* VIDEO_ALLEGRO_H */ diff --git a/src/video/cocoa/cocoa_keys.h b/src/video/cocoa/cocoa_keys.h index 426befd184..def145d242 100644 --- a/src/video/cocoa/cocoa_keys.h +++ b/src/video/cocoa/cocoa_keys.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. @@ -126,7 +124,7 @@ #define QZ_KP0 0x52 #define QZ_KP_PERIOD 0x41 -/* Wierd, these keys are on my iBook under MacOS X */ +/* Weird, these keys are on my iBook under MacOS X */ #define QZ_IBOOK_ENTER 0x34 #define QZ_IBOOK_LEFT 0x3B #define QZ_IBOOK_RIGHT 0x3C diff --git a/src/video/cocoa/cocoa_v.h b/src/video/cocoa/cocoa_v.h index 564daefe0f..7535eaada0 100644 --- a/src/video/cocoa/cocoa_v.h +++ b/src/video/cocoa/cocoa_v.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. @@ -16,10 +14,10 @@ class VideoDriver_Cocoa : public VideoDriver { public: - /* virtual */ const char *Start(const char * const *param); + const char *Start(const char * const *param) override; /** Stop the video driver */ - /* virtual */ void Stop(); + void Stop() override; /** Mark dirty a screen region * @param left x-coordinate of left border @@ -27,44 +25,44 @@ public: * @param width width or dirty rectangle * @param height height of dirty rectangle */ - /* virtual */ void MakeDirty(int left, int top, int width, int height); + void MakeDirty(int left, int top, int width, int height) override; /** Programme main loop */ - /* virtual */ void MainLoop(); + void MainLoop() override; /** Change window resolution * @param w New window width * @param h New window height * @return Whether change was successful */ - /* virtual */ bool ChangeResolution(int w, int h); + bool ChangeResolution(int w, int h) override; /** Set a new window mode * @param fullscreen Whether to set fullscreen mode or not * @return Whether changing the screen mode was successful */ - /* virtual */ bool ToggleFullscreen(bool fullscreen); + bool ToggleFullscreen(bool fullscreen) override; /** Callback invoked after the blitter was changed. * @return True if no error. */ - /* virtual */ bool AfterBlitterChange(); + bool AfterBlitterChange() override; /** * An edit box lost the input focus. Abort character compositing if necessary. */ - /* virtual */ void EditBoxLostFocus(); + void EditBoxLostFocus() override; /** Return driver name * @return driver name */ - /* virtual */ const char *GetName() const { return "cocoa"; } + const char *GetName() const override { return "cocoa"; } }; class FVideoDriver_Cocoa : public DriverFactoryBase { public: FVideoDriver_Cocoa() : DriverFactoryBase(Driver::DT_VIDEO, 10, "cocoa", "Cocoa Video Driver") {} - /* virtual */ Driver *CreateInstance() const { return new VideoDriver_Cocoa(); } + Driver *CreateInstance() const override { return new VideoDriver_Cocoa(); } }; @@ -271,6 +269,7 @@ uint QZ_ListModes(OTTD_Point *modes, uint max_modes, CGDirectDisplayID display_i - (BOOL)windowShouldClose:(id)sender; - (void)windowDidEnterFullScreen:(NSNotification *)aNotification; +- (void)windowDidChangeScreenProfile:(NSNotification *)aNotification; @end diff --git a/src/video/cocoa/cocoa_v.mm b/src/video/cocoa/cocoa_v.mm index d165610245..f801d7c041 100644 --- a/src/video/cocoa/cocoa_v.mm +++ b/src/video/cocoa/cocoa_v.mm @@ -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. @@ -234,13 +232,13 @@ static void setupApplication() } -static int CDECL ModeSorter(const OTTD_Point *p1, const OTTD_Point *p2) +static bool ModeSorter(const OTTD_Point &p1, const OTTD_Point &p2) { - if (p1->x < p2->x) return -1; - if (p1->x > p2->x) return +1; - if (p1->y < p2->y) return -1; - if (p1->y > p2->y) return +1; - return 0; + if (p1.x < p2.x) return true; + if (p1.x > p2.x) return false; + if (p1.y < p2.y) return true; + if (p1.y > p2.y) return false; + return false; } static void QZ_GetDisplayModeInfo(CFArrayRef modes, CFIndex i, int &bpp, uint16 &width, uint16 &height) @@ -258,11 +256,10 @@ static void QZ_GetDisplayModeInfo(CFArrayRef modes, CFIndex i, int &bpp, uint16 #if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_11) /* Extract bit depth from mode string. */ - CFStringRef pixEnc = CGDisplayModeCopyPixelEncoding(mode); - if (CFStringCompare(pixEnc, CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) bpp = 32; - if (CFStringCompare(pixEnc, CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) bpp = 16; - if (CFStringCompare(pixEnc, CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) bpp = 8; - CFRelease(pixEnc); + CFAutoRelease pixEnc(CGDisplayModeCopyPixelEncoding(mode)); + if (CFStringCompare(pixEnc.get(), CFSTR(IO32BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) bpp = 32; + if (CFStringCompare(pixEnc.get(), CFSTR(IO16BitDirectPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) bpp = 16; + if (CFStringCompare(pixEnc.get(), CFSTR(IO8BitIndexedPixels), kCFCompareCaseInsensitive) == kCFCompareEqualTo) bpp = 8; #else /* CGDisplayModeCopyPixelEncoding is deprecated on OSX 10.11+, but there are no 8 bpp modes anyway... */ bpp = 32; @@ -326,7 +323,7 @@ uint QZ_ListModes(OTTD_Point *modes, uint max_modes, CGDirectDisplayID display_i } /* Sort list smallest to largest */ - QSortT(modes, count, &ModeSorter); + std::sort(modes, modes + count, ModeSorter); #if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6) if (MacOSVersionIsAtLeast(10, 6, 0)) CFRelease(mode_list); @@ -363,12 +360,10 @@ static void QZ_UpdateVideoModes() OTTD_Point modes[32]; uint count = _cocoa_subdriver->ListModes(modes, lengthof(modes)); + _resolutions.clear(); for (uint i = 0; i < count; i++) { - _resolutions[i].width = modes[i].x; - _resolutions[i].height = modes[i].y; + _resolutions.emplace_back(modes[i].x, modes[i].y); } - - _num_resolutions = count; } /** @@ -689,15 +684,13 @@ void CocoaDialog(const char *title, const char *message, const char *buttonLabel void cocoaSetApplicationBundleDir() { char tmp[MAXPATHLEN]; - CFURLRef url = CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle()); - if (CFURLGetFileSystemRepresentation(url, true, (unsigned char*)tmp, MAXPATHLEN)) { + CFAutoRelease url(CFBundleCopyResourcesDirectoryURL(CFBundleGetMainBundle())); + if (CFURLGetFileSystemRepresentation(url.get(), true, (unsigned char*)tmp, MAXPATHLEN)) { AppendPathSeparator(tmp, lastof(tmp)); _searchpaths[SP_APPLICATION_BUNDLE_DIR] = stredup(tmp); } else { _searchpaths[SP_APPLICATION_BUNDLE_DIR] = NULL; } - - CFRelease(url); } /** @@ -1362,6 +1355,11 @@ static const char *Utf8AdvanceByUtf16Units(const char *str, NSUInteger count) [ e release ]; } } +/** The colour profile of the screen the window is on changed. */ +- (void)windowDidChangeScreenProfile:(NSNotification *)aNotification +{ + if (!driver->setup) driver->WindowResized(); +} @end diff --git a/src/video/cocoa/event.mm b/src/video/cocoa/event.mm index de812a70d6..f45c3e971f 100644 --- a/src/video/cocoa/event.mm +++ b/src/video/cocoa/event.mm @@ -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. @@ -37,6 +35,7 @@ #include "../../core/math_func.hpp" #include "../../texteff.hpp" #include "../../window_func.h" +#include "../../thread.h" #import /* gettimeofday */ diff --git a/src/video/cocoa/fullscreen.mm b/src/video/cocoa/fullscreen.mm index 860866b336..ae4353868d 100644 --- a/src/video/cocoa/fullscreen.mm +++ b/src/video/cocoa/fullscreen.mm @@ -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. @@ -30,6 +28,7 @@ #include "../../core/sort_func.hpp" #include "cocoa_v.h" #include "../../gfx_func.h" +#include "../../thread.h" #include "../../os/macosx/macos.h" /** @@ -174,7 +173,7 @@ class FullscreenSubdriver : public CocoaSubdriver { double adjustment = (target - position) / linesPerSecond; - CSleep((uint32)(adjustment * 1000)); + CSleep((uint32)adjustment * 1000); } diff --git a/src/video/cocoa/wnd_quartz.mm b/src/video/cocoa/wnd_quartz.mm index 4245a3c183..d4c5369414 100644 --- a/src/video/cocoa/wnd_quartz.mm +++ b/src/video/cocoa/wnd_quartz.mm @@ -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. @@ -106,35 +104,6 @@ public: }; -static CGColorSpaceRef QZ_GetCorrectColorSpace() -{ - static CGColorSpaceRef colorSpace = NULL; - - if (colorSpace == NULL) { -#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) - if (MacOSVersionIsAtLeast(10, 5, 0)) { - colorSpace = CGDisplayCopyColorSpace(CGMainDisplayID()); - } else -#endif - { -#if (MAC_OS_X_VERSION_MIN_REQUIRED < MAC_OS_X_VERSION_10_5) && !defined(HAVE_OSX_1011_SDK) - CMProfileRef sysProfile; - if (CMGetSystemProfile(&sysProfile) == noErr) { - colorSpace = CGColorSpaceCreateWithPlatformColorSpace(sysProfile); - CMCloseProfile(sysProfile); - } -#endif - } - - if (colorSpace == NULL) colorSpace = CGColorSpaceCreateDeviceRGB(); - - if (colorSpace == NULL) error("Could not get system colour space. You might need to recalibrate your monitor."); - } - - return colorSpace; -} - - @implementation OTTD_QuartzView - (void)setDriver:(WindowQuartzSubdriver*)drv @@ -596,20 +565,36 @@ bool WindowQuartzSubdriver::WindowResized() this->window_width = (int)newframe.size.width; this->window_height = (int)newframe.size.height; + /* Get screen colour space. */ + CGColorSpaceRef color_space = NULL; + +#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_6) + if ([ this->window respondsToSelector:@selector(colorSpace) ]) { + color_space = [ [ this->window colorSpace ] CGColorSpace ]; + CGColorSpaceRetain(color_space); + } +#endif +#if (MAC_OS_X_VERSION_MAX_ALLOWED >= MAC_OS_X_VERSION_10_5) + if (color_space == NULL && MacOSVersionIsAtLeast(10, 5, 0)) color_space = CGColorSpaceCreateWithName(kCGColorSpaceSRGB); +#endif + if (color_space == NULL) color_space = CGColorSpaceCreateDeviceRGB(); + if (color_space == NULL) error("Could not get system colour space. You might need to recalibrate your monitor."); + /* Create Core Graphics Context */ free(this->window_buffer); this->window_buffer = (uint32*)malloc(this->window_width * this->window_height * 4); CGContextRelease(this->cgcontext); this->cgcontext = CGBitmapContextCreate( - this->window_buffer, // data + this->window_buffer, // data this->window_width, // width this->window_height, // height 8, // bits per component this->window_width * 4, // bytes per row - QZ_GetCorrectColorSpace(), // color space + color_space, // color space kCGImageAlphaNoneSkipFirst | kCGBitmapByteOrder32Host ); + CGColorSpaceRelease(color_space); assert(this->cgcontext != NULL); CGContextSetShouldAntialias(this->cgcontext, FALSE); diff --git a/src/video/cocoa/wnd_quickdraw.mm b/src/video/cocoa/wnd_quickdraw.mm index 8475efb0fd..75d1d416b0 100644 --- a/src/video/cocoa/wnd_quickdraw.mm +++ b/src/video/cocoa/wnd_quickdraw.mm @@ -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/video/dedicated_v.cpp b/src/video/dedicated_v.cpp index 47fa64231a..ac7d38bb7f 100644 --- a/src/video/dedicated_v.cpp +++ b/src/video/dedicated_v.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. @@ -11,8 +9,6 @@ #include "../stdafx.h" -#ifdef ENABLE_NETWORK - #include "../gfx_func.h" #include "../network/network.h" #include "../network/network_internal.h" @@ -24,12 +20,9 @@ #include "../company_func.h" #include "../core/random_func.hpp" #include "../saveload/saveload.h" +#include "../thread.h" #include "dedicated_v.h" -#ifdef BEOS_NET_SERVER -#include -#endif - #ifdef __OS2__ # include /* gettimeofday */ # include @@ -79,6 +72,7 @@ static void DedicatedSignalHandler(int sig) # include # include # include "../os/windows/win32.h" + static HANDLE _hInputReady, _hWaitForInputHandling; static HANDLE _hThread; // Thread to close static char _win_console_thread_buffer[200]; @@ -86,12 +80,12 @@ static char _win_console_thread_buffer[200]; /* Windows Console thread. Just loop and signal when input has been received */ static void WINAPI CheckForConsoleInput() { - SetWin32ThreadName(-1, "ottd:win-console"); + SetCurrentThreadName("ottd:win-console"); DWORD nb; HANDLE hStdin = GetStdHandle(STD_INPUT_HANDLE); for (;;) { - ReadFile(hStdin, _win_console_thread_buffer, lengthof(_win_console_thread_buffer), &nb, NULL); + ReadFile(hStdin, _win_console_thread_buffer, lengthof(_win_console_thread_buffer), &nb, nullptr); if (nb >= lengthof(_win_console_thread_buffer)) nb = lengthof(_win_console_thread_buffer) - 1; _win_console_thread_buffer[nb] = '\0'; @@ -106,12 +100,12 @@ static void CreateWindowsConsoleThread() { DWORD dwThreadId; /* Create event to signal when console input is ready */ - _hInputReady = CreateEvent(NULL, false, false, NULL); - _hWaitForInputHandling = CreateEvent(NULL, false, false, NULL); - if (_hInputReady == NULL || _hWaitForInputHandling == NULL) usererror("Cannot create console event!"); + _hInputReady = CreateEvent(nullptr, false, false, nullptr); + _hWaitForInputHandling = CreateEvent(nullptr, false, false, nullptr); + if (_hInputReady == nullptr || _hWaitForInputHandling == nullptr) usererror("Cannot create console event!"); - _hThread = CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)CheckForConsoleInput, NULL, 0, &dwThreadId); - if (_hThread == NULL) usererror("Cannot create console thread!"); + _hThread = CreateThread(nullptr, 0, (LPTHREAD_START_ROUTINE)CheckForConsoleInput, nullptr, 0, &dwThreadId); + if (_hThread == nullptr) usererror("Cannot create console thread!"); DEBUG(driver, 2, "Windows console thread started"); } @@ -134,7 +128,7 @@ static void *_dedicated_video_mem; /* Whether a fork has been done. */ bool _dedicated_forks; -extern bool SafeLoad(const char *filename, SaveLoadOperation fop, DetailedFileType dft, GameMode newgm, Subdirectory subdir, struct LoadFilter *lf = NULL); +extern bool SafeLoad(const char *filename, SaveLoadOperation fop, DetailedFileType dft, GameMode newgm, Subdirectory subdir, struct LoadFilter *lf = nullptr); static FVideoDriver_Dedicated iFVideoDriver_Dedicated; @@ -142,7 +136,7 @@ static FVideoDriver_Dedicated iFVideoDriver_Dedicated; const char *VideoDriver_Dedicated::Start(const char * const *parm) { int bpp = BlitterFactory::GetCurrentBlitter()->GetScreenDepth(); - _dedicated_video_mem = (bpp == 0) ? NULL : MallocT(_cur_resolution.width * _cur_resolution.height * (bpp / 8)); + _dedicated_video_mem = (bpp == 0) ? nullptr : MallocT(_cur_resolution.width * _cur_resolution.height * (bpp / 8)); _screen.width = _screen.pitch = _cur_resolution.width; _screen.height = _cur_resolution.height; @@ -168,7 +162,7 @@ const char *VideoDriver_Dedicated::Start(const char * const *parm) #endif DEBUG(driver, 1, "Loading dedicated server"); - return NULL; + return nullptr; } void VideoDriver_Dedicated::Stop() @@ -196,14 +190,14 @@ static bool InputWaiting() FD_SET(STDIN, &readfds); /* don't care about writefds and exceptfds: */ - return select(STDIN + 1, &readfds, NULL, NULL, &tv) > 0; + return select(STDIN + 1, &readfds, nullptr, nullptr, &tv) > 0; } static uint32 GetTime() { struct timeval tim; - gettimeofday(&tim, NULL); + gettimeofday(&tim, nullptr); return tim.tv_usec / 1000 + tim.tv_sec * 1000; } @@ -230,7 +224,7 @@ static void DedicatedHandleKeyInput() if (_exit_game) return; #if defined(UNIX) || defined(__OS2__) - if (fgets(input_line, lengthof(input_line), stdin) == NULL) return; + if (fgets(input_line, lengthof(input_line), stdin) == nullptr) return; #else /* Handle console input, and signal console thread, it can accept input again */ assert_compile(lengthof(_win_console_thread_buffer) <= lengthof(input_line)); @@ -320,5 +314,3 @@ void VideoDriver_Dedicated::MainLoop() } } } - -#endif /* ENABLE_NETWORK */ diff --git a/src/video/dedicated_v.h b/src/video/dedicated_v.h index 0c1477d66d..27401aae91 100644 --- a/src/video/dedicated_v.h +++ b/src/video/dedicated_v.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. @@ -17,19 +15,19 @@ /** The dedicated server video driver. */ class VideoDriver_Dedicated : public VideoDriver { public: - /* virtual */ const char *Start(const char * const *param); + const char *Start(const char * const *param) override; - /* virtual */ void Stop(); + void Stop() override; - /* virtual */ void MakeDirty(int left, int top, int width, int height); + void MakeDirty(int left, int top, int width, int height) override; - /* virtual */ void MainLoop(); + void MainLoop() override; - /* virtual */ bool ChangeResolution(int w, int h); + bool ChangeResolution(int w, int h) override; - /* virtual */ bool ToggleFullscreen(bool fullscreen); - /* virtual */ const char *GetName() const { return "dedicated"; } - /* virtual */ bool HasGUI() const { return false; } + bool ToggleFullscreen(bool fullscreen) override; + const char *GetName() const override { return "dedicated"; } + bool HasGUI() const override { return false; } }; /** Factory for the dedicated server video driver. */ @@ -43,7 +41,7 @@ public: static const int PRIORITY = 0; #endif FVideoDriver_Dedicated() : DriverFactoryBase(Driver::DT_VIDEO, PRIORITY, "dedicated", "Dedicated Video Driver") {} - /* virtual */ Driver *CreateInstance() const { return new VideoDriver_Dedicated(); } + Driver *CreateInstance() const override { return new VideoDriver_Dedicated(); } }; #endif /* VIDEO_DEDICATED_H */ diff --git a/src/video/null_v.cpp b/src/video/null_v.cpp index 5037814e5b..3e98ea9258 100644 --- a/src/video/null_v.cpp +++ b/src/video/null_v.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. @@ -29,13 +27,13 @@ const char *VideoDriver_Null::Start(const char * const *parm) this->ticks = GetDriverParamInt(parm, "ticks", 1000); _screen.width = _screen.pitch = _cur_resolution.width; _screen.height = _cur_resolution.height; - _screen.dst_ptr = NULL; + _screen.dst_ptr = nullptr; ScreenSizeChanged(); /* Do not render, nor blit */ DEBUG(misc, 1, "Forcing blitter 'null'..."); BlitterFactory::SelectBlitter("null"); - return NULL; + return nullptr; } void VideoDriver_Null::Stop() { } diff --git a/src/video/null_v.h b/src/video/null_v.h index 9e04e177ef..ed563bffb7 100644 --- a/src/video/null_v.h +++ b/src/video/null_v.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. @@ -20,26 +18,26 @@ private: uint ticks; ///< Amount of ticks to run. public: - /* virtual */ const char *Start(const char * const *param); + const char *Start(const char * const *param) override; - /* virtual */ void Stop(); + void Stop() override; - /* virtual */ void MakeDirty(int left, int top, int width, int height); + void MakeDirty(int left, int top, int width, int height) override; - /* virtual */ void MainLoop(); + void MainLoop() override; - /* virtual */ bool ChangeResolution(int w, int h); + bool ChangeResolution(int w, int h) override; - /* virtual */ bool ToggleFullscreen(bool fullscreen); - /* virtual */ const char *GetName() const { return "null"; } - /* virtual */ bool HasGUI() const { return false; } + bool ToggleFullscreen(bool fullscreen) override; + const char *GetName() const override { return "null"; } + bool HasGUI() const override { return false; } }; /** Factory the null video driver. */ class FVideoDriver_Null : public DriverFactoryBase { public: FVideoDriver_Null() : DriverFactoryBase(Driver::DT_VIDEO, 0, "null", "Null Video Driver") {} - /* virtual */ Driver *CreateInstance() const { return new VideoDriver_Null(); } + Driver *CreateInstance() const override { return new VideoDriver_Null(); } }; #endif /* VIDEO_NULL_H */ diff --git a/src/video/sdl2_v.cpp b/src/video/sdl2_v.cpp new file mode 100644 index 0000000000..0b3b9b8e30 --- /dev/null +++ b/src/video/sdl2_v.cpp @@ -0,0 +1,859 @@ +/* + * 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 sdl2_v.cpp Implementation of the SDL2 video driver. */ + +#ifdef WITH_SDL2 + +#include "../stdafx.h" +#include "../openttd.h" +#include "../gfx_func.h" +#include "../rev.h" +#include "../blitter/factory.hpp" +#include "../network/network.h" +#include "../thread.h" +#include "../progress.h" +#include "../core/random_func.hpp" +#include "../core/math_func.hpp" +#include "../fileio_func.h" +#include "../framerate_type.h" +#include "../window_func.h" +#include "sdl2_v.h" +#include +#include +#include +#include + +#include "../safeguards.h" + +static FVideoDriver_SDL iFVideoDriver_SDL; + +static SDL_Window *_sdl_window; +static SDL_Surface *_sdl_surface; +static SDL_Surface *_sdl_realscreen; + +/** Whether the drawing is/may be done in a separate thread. */ +static bool _draw_threaded; +/** Mutex to keep the access to the shared memory controlled. */ +static std::recursive_mutex *_draw_mutex = nullptr; +/** Signal to draw the next frame. */ +static std::condition_variable_any *_draw_signal = nullptr; +/** Should we keep continue drawing? */ +static volatile bool _draw_continue; +static Palette _local_palette; +static SDL_Palette *_sdl_palette; + +#define MAX_DIRTY_RECTS 100 +static SDL_Rect _dirty_rects[MAX_DIRTY_RECTS]; +static int _num_dirty_rects; + +/* Size of window */ +static int _window_size_w; +static int _window_size_h; + +void VideoDriver_SDL::MakeDirty(int left, int top, int width, int height) +{ + if (_num_dirty_rects < MAX_DIRTY_RECTS) { + _dirty_rects[_num_dirty_rects].x = left; + _dirty_rects[_num_dirty_rects].y = top; + _dirty_rects[_num_dirty_rects].w = width; + _dirty_rects[_num_dirty_rects].h = height; + } + _num_dirty_rects++; +} + +static void UpdatePalette(bool init = false) +{ + SDL_Color pal[256]; + + for (int i = 0; i != _local_palette.count_dirty; i++) { + pal[i].r = _local_palette.palette[_local_palette.first_dirty + i].r; + pal[i].g = _local_palette.palette[_local_palette.first_dirty + i].g; + pal[i].b = _local_palette.palette[_local_palette.first_dirty + i].b; + pal[i].a = 0; + } + + SDL_SetPaletteColors(_sdl_palette, pal, _local_palette.first_dirty, _local_palette.count_dirty); + SDL_SetSurfacePalette(_sdl_surface, _sdl_palette); + + if (_sdl_surface != _sdl_realscreen && init) { + /* When using a shadow surface, also set our palette on the real screen. This lets SDL + * allocate as many colors (or approximations) as + * possible, instead of using only the default SDL + * palette. This allows us to get more colors exactly + * right and might allow using better approximations for + * other colors. + * + * Note that colors allocations are tried in-order, so + * this favors colors further up into the palette. Also + * note that if two colors from the same animation + * sequence are approximated using the same color, that + * animation will stop working. + * + * Since changing the system palette causes the colours + * to change right away, and allocations might + * drastically change, we can't use this for animation, + * since that could cause weird coloring between the + * palette change and the blitting below, so we only set + * the real palette during initialisation. + */ + SDL_SetSurfacePalette(_sdl_realscreen, _sdl_palette); + } + + if (_sdl_surface != _sdl_realscreen && !init) { + /* We're not using real hardware palette, but are letting SDL + * approximate the palette during shadow -> screen copy. To + * change the palette, we need to recopy the entire screen. + * + * Note that this operation can slow down the rendering + * considerably, especially since changing the shadow + * palette will need the next blit to re-detect the + * best mapping of shadow palette colors to real palette + * colors from scratch. + */ + SDL_BlitSurface(_sdl_surface, nullptr, _sdl_realscreen, nullptr); + SDL_UpdateWindowSurface(_sdl_window); + } +} + +static void InitPalette() +{ + _local_palette = _cur_palette; + _local_palette.first_dirty = 0; + _local_palette.count_dirty = 256; + UpdatePalette(true); +} + +static void CheckPaletteAnim() +{ + if (_cur_palette.count_dirty != 0) { + Blitter *blitter = BlitterFactory::GetCurrentBlitter(); + + switch (blitter->UsePaletteAnimation()) { + case Blitter::PALETTE_ANIMATION_VIDEO_BACKEND: + UpdatePalette(); + break; + + case Blitter::PALETTE_ANIMATION_BLITTER: + blitter->PaletteAnimate(_local_palette); + break; + + case Blitter::PALETTE_ANIMATION_NONE: + break; + + default: + NOT_REACHED(); + } + _cur_palette.count_dirty = 0; + } +} + +static void DrawSurfaceToScreen() +{ + PerformanceMeasurer framerate(PFE_VIDEO); + + int n = _num_dirty_rects; + if (n == 0) return; + + _num_dirty_rects = 0; + + if (n > MAX_DIRTY_RECTS) { + if (_sdl_surface != _sdl_realscreen) { + SDL_BlitSurface(_sdl_surface, nullptr, _sdl_realscreen, nullptr); + } + + SDL_UpdateWindowSurface(_sdl_window); + } else { + if (_sdl_surface != _sdl_realscreen) { + for (int i = 0; i < n; i++) { + SDL_BlitSurface( + _sdl_surface, &_dirty_rects[i], + _sdl_realscreen, &_dirty_rects[i]); + } + } + + SDL_UpdateWindowSurfaceRects(_sdl_window, _dirty_rects, n); + } +} + +static void DrawSurfaceToScreenThread() +{ + /* First tell the main thread we're started */ + std::unique_lock lock(*_draw_mutex); + _draw_signal->notify_one(); + + /* Now wait for the first thing to draw! */ + _draw_signal->wait(*_draw_mutex); + + while (_draw_continue) { + CheckPaletteAnim(); + /* Then just draw and wait till we stop */ + DrawSurfaceToScreen(); + _draw_signal->wait(lock); + } +} + +static void GetVideoModes() +{ + int modes = SDL_GetNumDisplayModes(0); + if (modes == 0) usererror("sdl: no modes available"); + + _resolutions.clear(); + + SDL_DisplayMode mode; + for (int i = 0; i < modes; i++) { + SDL_GetDisplayMode(0, i, &mode); + + uint w = mode.w; + uint h = mode.h; + + if (w < 640 || h < 480) continue; // reject too small resolutions + + if (std::find(_resolutions.begin(), _resolutions.end(), Dimension(w, h)) != _resolutions.end()) continue; + _resolutions.emplace_back(w, h); + } + if (_resolutions.empty()) usererror("No usable screen resolutions found!\n"); + SortResolutions(); +} + +static void GetAvailableVideoMode(uint *w, uint *h) +{ + /* All modes available? */ + if (!_fullscreen || _resolutions.empty()) return; + + /* Is the wanted mode among the available modes? */ + if (std::find(_resolutions.begin(), _resolutions.end(), Dimension(*w, *h)) != _resolutions.end()) return; + + /* Use the closest possible resolution */ + uint best = 0; + uint delta = Delta(_resolutions[0].width, *w) * Delta(_resolutions[0].height, *h); + for (uint i = 1; i != _resolutions.size(); ++i) { + uint newdelta = Delta(_resolutions[i].width, *w) * Delta(_resolutions[i].height, *h); + if (newdelta < delta) { + best = i; + delta = newdelta; + } + } + *w = _resolutions[best].width; + *h = _resolutions[best].height; +} + +bool VideoDriver_SDL::CreateMainSurface(uint w, uint h, bool resize) +{ + SDL_Surface *newscreen; + char caption[50]; + int bpp = BlitterFactory::GetCurrentBlitter()->GetScreenDepth(); + + GetAvailableVideoMode(&w, &h); + + DEBUG(driver, 1, "SDL2: using mode %ux%ux%d", w, h, bpp); + + if (bpp == 0) usererror("Can't use a blitter that blits 0 bpp for normal visuals"); + + /* Free any previously allocated shadow surface */ + if (_sdl_surface != nullptr && _sdl_surface != _sdl_realscreen) SDL_FreeSurface(_sdl_surface); + + seprintf(caption, lastof(caption), "OpenTTD %s", _openttd_revision); + + if (_sdl_window == nullptr) { + Uint32 flags = SDL_WINDOW_SHOWN; + + if (_fullscreen) { + flags |= SDL_WINDOW_FULLSCREEN; + } else { + flags |= SDL_WINDOW_RESIZABLE; + } + + _sdl_window = SDL_CreateWindow( + caption, + SDL_WINDOWPOS_UNDEFINED, + SDL_WINDOWPOS_UNDEFINED, + w, h, + flags); + + if (_sdl_window == nullptr) { + DEBUG(driver, 0, "SDL2: Couldn't allocate a window to draw on"); + return false; + } + + char icon_path[MAX_PATH]; + if (FioFindFullPath(icon_path, lastof(icon_path), BASESET_DIR, "openttd.32.bmp") != nullptr) { + /* Give the application an icon */ + SDL_Surface *icon = SDL_LoadBMP(icon_path); + if (icon != nullptr) { + /* Get the colourkey, which will be magenta */ + uint32 rgbmap = SDL_MapRGB(icon->format, 255, 0, 255); + + SDL_SetColorKey(icon, SDL_TRUE, rgbmap); + SDL_SetWindowIcon(_sdl_window, icon); + SDL_FreeSurface(icon); + } + } + } + + if (resize) SDL_SetWindowSize(_sdl_window, w, h); + + newscreen = SDL_GetWindowSurface(_sdl_window); + if (newscreen == NULL) { + DEBUG(driver, 0, "SDL2: Couldn't get window surface: %s", SDL_GetError()); + return false; + } + + _sdl_realscreen = newscreen; + + if (bpp == 8) { + newscreen = SDL_CreateRGBSurface(0, w, h, 8, 0, 0, 0, 0); + + if (newscreen == nullptr) { + DEBUG(driver, 0, "SDL2: Couldn't allocate shadow surface: %s", SDL_GetError()); + return false; + } + } + + if (_sdl_palette == nullptr) { + _sdl_palette = SDL_AllocPalette(256); + } + + if (_sdl_palette == nullptr) { + DEBUG(driver, 0, "SDL_AllocPalette() failed: %s", SDL_GetError()); + return false; + } + + /* Delay drawing for this cycle; the next cycle will redraw the whole screen */ + _num_dirty_rects = 0; + + _screen.width = newscreen->w; + _screen.height = newscreen->h; + _screen.pitch = newscreen->pitch / (bpp / 8); + _screen.dst_ptr = newscreen->pixels; + _sdl_surface = newscreen; + + /* When in full screen, we will always have the mouse cursor + * within the window, even though SDL does not give us the + * appropriate event to know this. */ + if (_fullscreen) _cursor.in_window = true; + + Blitter *blitter = BlitterFactory::GetCurrentBlitter(); + blitter->PostResize(); + + InitPalette(); + + GameSizeChanged(); + + return true; +} + +bool VideoDriver_SDL::ClaimMousePointer() +{ + SDL_ShowCursor(0); + return true; +} + +/** + * This is called to indicate that an edit box has gained focus, text input mode should be enabled. + */ +void VideoDriver_SDL::EditBoxGainedFocus() +{ + if (!this->edit_box_focused) { + SDL_StartTextInput(); + this->edit_box_focused = true; + } +} + +/** + * This is called to indicate that an edit box has lost focus, text input mode should be disabled. + */ +void VideoDriver_SDL::EditBoxLostFocus() +{ + if (this->edit_box_focused) { + SDL_StopTextInput(); + this->edit_box_focused = false; + } +} + + +struct VkMapping { + SDL_Keycode vk_from; + byte vk_count; + byte map_to; + bool unprintable; +}; + +#define AS(x, z) {x, 0, z, false} +#define AM(x, y, z, w) {x, (byte)(y - x), z, false} +#define AS_UP(x, z) {x, 0, z, true} +#define AM_UP(x, y, z, w) {x, (byte)(y - x), z, true} + +static const VkMapping _vk_mapping[] = { + /* Pageup stuff + up/down */ + AS_UP(SDLK_PAGEUP, WKC_PAGEUP), + AS_UP(SDLK_PAGEDOWN, WKC_PAGEDOWN), + AS_UP(SDLK_UP, WKC_UP), + AS_UP(SDLK_DOWN, WKC_DOWN), + AS_UP(SDLK_LEFT, WKC_LEFT), + AS_UP(SDLK_RIGHT, WKC_RIGHT), + + AS_UP(SDLK_HOME, WKC_HOME), + AS_UP(SDLK_END, WKC_END), + + AS_UP(SDLK_INSERT, WKC_INSERT), + AS_UP(SDLK_DELETE, WKC_DELETE), + + /* Map letters & digits */ + AM(SDLK_a, SDLK_z, 'A', 'Z'), + AM(SDLK_0, SDLK_9, '0', '9'), + + AS_UP(SDLK_ESCAPE, WKC_ESC), + AS_UP(SDLK_PAUSE, WKC_PAUSE), + AS_UP(SDLK_BACKSPACE, WKC_BACKSPACE), + + AS(SDLK_SPACE, WKC_SPACE), + AS(SDLK_RETURN, WKC_RETURN), + AS(SDLK_TAB, WKC_TAB), + + /* Function keys */ + AM_UP(SDLK_F1, SDLK_F12, WKC_F1, WKC_F12), + + /* Numeric part. */ + AM(SDLK_KP_0, SDLK_KP_9, '0', '9'), + AS(SDLK_KP_DIVIDE, WKC_NUM_DIV), + AS(SDLK_KP_MULTIPLY, WKC_NUM_MUL), + AS(SDLK_KP_MINUS, WKC_NUM_MINUS), + AS(SDLK_KP_PLUS, WKC_NUM_PLUS), + AS(SDLK_KP_ENTER, WKC_NUM_ENTER), + AS(SDLK_KP_PERIOD, WKC_NUM_DECIMAL), + + /* Other non-letter keys */ + AS(SDLK_SLASH, WKC_SLASH), + AS(SDLK_SEMICOLON, WKC_SEMICOLON), + AS(SDLK_EQUALS, WKC_EQUALS), + AS(SDLK_LEFTBRACKET, WKC_L_BRACKET), + AS(SDLK_BACKSLASH, WKC_BACKSLASH), + AS(SDLK_RIGHTBRACKET, WKC_R_BRACKET), + + AS(SDLK_QUOTE, WKC_SINGLEQUOTE), + AS(SDLK_COMMA, WKC_COMMA), + AS(SDLK_MINUS, WKC_MINUS), + AS(SDLK_PERIOD, WKC_PERIOD) +}; + +static uint ConvertSdlKeyIntoMy(SDL_Keysym *sym, WChar *character) +{ + const VkMapping *map; + uint key = 0; + bool unprintable = false; + + for (map = _vk_mapping; map != endof(_vk_mapping); ++map) { + if ((uint)(sym->sym - map->vk_from) <= map->vk_count) { + key = sym->sym - map->vk_from + map->map_to; + unprintable = map->unprintable; + break; + } + } + + /* check scancode for BACKQUOTE key, because we want the key left of "1", not anything else (on non-US keyboards) */ + if (sym->scancode == SDL_SCANCODE_GRAVE) key = WKC_BACKQUOTE; + + /* META are the command keys on mac */ + if (sym->mod & KMOD_GUI) key |= WKC_META; + if (sym->mod & KMOD_SHIFT) key |= WKC_SHIFT; + if (sym->mod & KMOD_CTRL) key |= WKC_CTRL; + if (sym->mod & KMOD_ALT) key |= WKC_ALT; + + /* The mod keys have no character. Prevent '?' */ + if (sym->mod & KMOD_GUI || + sym->mod & KMOD_CTRL || + sym->mod & KMOD_ALT || + unprintable) { + *character = WKC_NONE; + } else { + *character = sym->sym; + } + + return key; +} + +/** + * Like ConvertSdlKeyIntoMy(), but takes an SDL_Keycode as input + * instead of an SDL_Keysym. + */ +static uint ConvertSdlKeycodeIntoMy(SDL_Keycode kc) +{ + const VkMapping *map; + uint key = 0; + + for (map = _vk_mapping; map != endof(_vk_mapping); ++map) { + if ((uint)(kc - map->vk_from) <= map->vk_count) { + key = kc - map->vk_from + map->map_to; + break; + } + } + + /* check scancode for BACKQUOTE key, because we want the key left + of "1", not anything else (on non-US keyboards) */ + SDL_Scancode sc = SDL_GetScancodeFromKey(kc); + if (sc == SDL_SCANCODE_GRAVE) key = WKC_BACKQUOTE; + + return key; +} + +int VideoDriver_SDL::PollEvent() +{ + SDL_Event ev; + + if (!SDL_PollEvent(&ev)) return -2; + + switch (ev.type) { + case SDL_MOUSEMOTION: + if (_cursor.UpdateCursorPosition(ev.motion.x, ev.motion.y, true)) { + SDL_WarpMouseInWindow(_sdl_window, _cursor.pos.x, _cursor.pos.y); + } + HandleMouseEvents(); + break; + + case SDL_MOUSEWHEEL: + if (ev.wheel.y > 0) { + _cursor.wheel--; + } else if (ev.wheel.y < 0) { + _cursor.wheel++; + } + break; + + case SDL_MOUSEBUTTONDOWN: + if (_rightclick_emulate && SDL_GetModState() & KMOD_CTRL) { + ev.button.button = SDL_BUTTON_RIGHT; + } + + switch (ev.button.button) { + case SDL_BUTTON_LEFT: + _left_button_down = true; + break; + + case SDL_BUTTON_RIGHT: + _right_button_down = true; + _right_button_clicked = true; + break; + + default: break; + } + HandleMouseEvents(); + break; + + case SDL_MOUSEBUTTONUP: + if (_rightclick_emulate) { + _right_button_down = false; + _left_button_down = false; + _left_button_clicked = false; + } else if (ev.button.button == SDL_BUTTON_LEFT) { + _left_button_down = false; + _left_button_clicked = false; + } else if (ev.button.button == SDL_BUTTON_RIGHT) { + _right_button_down = false; + } + HandleMouseEvents(); + break; + + case SDL_QUIT: + HandleExitGameRequest(); + break; + + case SDL_KEYDOWN: // Toggle full-screen on ALT + ENTER/F + if ((ev.key.keysym.mod & (KMOD_ALT | KMOD_GUI)) && + (ev.key.keysym.sym == SDLK_RETURN || ev.key.keysym.sym == SDLK_f)) { + if (ev.key.repeat == 0) ToggleFullScreen(!_fullscreen); + } else { + WChar character; + + uint keycode = ConvertSdlKeyIntoMy(&ev.key.keysym, &character); + // Only handle non-text keys here. Text is handled in + // SDL_TEXTINPUT below. + if (!this->edit_box_focused || + keycode == WKC_DELETE || + keycode == WKC_NUM_ENTER || + keycode == WKC_LEFT || + keycode == WKC_RIGHT || + keycode == WKC_UP || + keycode == WKC_DOWN || + keycode == WKC_HOME || + keycode == WKC_END || + keycode & WKC_META || + keycode & WKC_CTRL || + keycode & WKC_ALT || + (keycode >= WKC_F1 && keycode <= WKC_F12) || + !IsValidChar(character, CS_ALPHANUMERAL)) { + HandleKeypress(keycode, character); + } + } + break; + + case SDL_TEXTINPUT: { + if (!this->edit_box_focused) break; + SDL_Keycode kc = SDL_GetKeyFromName(ev.text.text); + uint keycode = ConvertSdlKeycodeIntoMy(kc); + + if (keycode == WKC_BACKQUOTE && FocusedWindowIsConsole()) { + WChar character; + Utf8Decode(&character, ev.text.text); + HandleKeypress(keycode, character); + } else { + HandleTextInput(ev.text.text); + } + break; + } + case SDL_WINDOWEVENT: { + if (ev.window.event == SDL_WINDOWEVENT_EXPOSED) { + // Force a redraw of the entire screen. + _num_dirty_rects = MAX_DIRTY_RECTS + 1; + } else if (ev.window.event == SDL_WINDOWEVENT_SIZE_CHANGED) { + int w = max(ev.window.data1, 64); + int h = max(ev.window.data2, 64); + CreateMainSurface(w, h, w != ev.window.data1 || h != ev.window.data2); + } else if (ev.window.event == SDL_WINDOWEVENT_ENTER) { + // mouse entered the window, enable cursor + _cursor.in_window = true; + } else if (ev.window.event == SDL_WINDOWEVENT_LEAVE) { + // mouse left the window, undraw cursor + UndrawMouseCursor(); + _cursor.in_window = false; + } + break; + } + } + return -1; +} + +const char *VideoDriver_SDL::Start(const char * const *parm) +{ + /* Explicitly disable hardware acceleration. Enabling this causes + * UpdateWindowSurface() to update the window's texture instead of + * its surface. */ + SDL_SetHint(SDL_HINT_FRAMEBUFFER_ACCELERATION , "0"); + + /* Just on the offchance the audio subsystem started before the video system, + * check whether any part of SDL has been initialised before getting here. + * Slightly duplicated with sound/sdl_s.cpp */ + int ret_code = 0; + if (SDL_WasInit(SDL_INIT_VIDEO) == 0) { + ret_code = SDL_InitSubSystem(SDL_INIT_VIDEO); + } + if (ret_code < 0) return SDL_GetError(); + + GetVideoModes(); + if (!CreateMainSurface(_cur_resolution.width, _cur_resolution.height, false)) { + return SDL_GetError(); + } + + const char *dname = SDL_GetCurrentVideoDriver(); + DEBUG(driver, 1, "SDL2: using driver '%s'", dname); + + MarkWholeScreenDirty(); + + _draw_threaded = GetDriverParam(parm, "no_threads") == nullptr && GetDriverParam(parm, "no_thread") == nullptr; + + SDL_StopTextInput(); + this->edit_box_focused = false; + + return nullptr; +} + +void VideoDriver_SDL::Stop() +{ + SDL_QuitSubSystem(SDL_INIT_VIDEO); + if (SDL_WasInit(SDL_INIT_EVERYTHING) == 0) { + SDL_Quit(); // If there's nothing left, quit SDL + } +} + +void VideoDriver_SDL::MainLoop() +{ + uint32 cur_ticks = SDL_GetTicks(); + uint32 last_cur_ticks = cur_ticks; + uint32 next_tick = cur_ticks + MILLISECONDS_PER_TICK; + uint32 mod; + int numkeys; + const Uint8 *keys; + + CheckPaletteAnim(); + + std::thread draw_thread; + std::unique_lock draw_lock; + if (_draw_threaded) { + /* Initialise the mutex first, because that's the thing we *need* + * directly in the newly created thread. */ + _draw_mutex = new std::recursive_mutex(); + if (_draw_mutex == nullptr) { + _draw_threaded = false; + } else { + draw_lock = std::unique_lock(*_draw_mutex); + _draw_signal = new std::condition_variable_any(); + _draw_continue = true; + + _draw_threaded = StartNewThread(&draw_thread, "ottd:draw-sdl", &DrawSurfaceToScreenThread); + + /* Free the mutex if we won't be able to use it. */ + if (!_draw_threaded) { + draw_lock.unlock(); + draw_lock.release(); + delete _draw_mutex; + delete _draw_signal; + _draw_mutex = nullptr; + _draw_signal = nullptr; + } else { + /* Wait till the draw mutex has started itself. */ + _draw_signal->wait(*_draw_mutex); + } + } + } + + DEBUG(driver, 1, "SDL2: using %sthreads", _draw_threaded ? "" : "no "); + + for (;;) { + uint32 prev_cur_ticks = cur_ticks; // to check for wrapping + InteractiveRandom(); // randomness + + while (PollEvent() == -1) {} + if (_exit_game) break; + + mod = SDL_GetModState(); + keys = SDL_GetKeyboardState(&numkeys); + +#if defined(_DEBUG) + if (_shift_pressed) +#else + /* Speedup when pressing tab, except when using ALT+TAB + * to switch to another application */ + if (keys[SDL_SCANCODE_TAB] && (mod & KMOD_ALT) == 0) +#endif /* defined(_DEBUG) */ + { + if (!_networking && _game_mode != GM_MENU) _fast_forward |= 2; + } else if (_fast_forward & 2) { + _fast_forward = 0; + } + + cur_ticks = SDL_GetTicks(); + if (SDL_TICKS_PASSED(cur_ticks, next_tick) || (_fast_forward && !_pause_mode) || cur_ticks < prev_cur_ticks) { + _realtime_tick += cur_ticks - last_cur_ticks; + last_cur_ticks = cur_ticks; + next_tick = cur_ticks + MILLISECONDS_PER_TICK; + + bool old_ctrl_pressed = _ctrl_pressed; + + _ctrl_pressed = !!(mod & KMOD_CTRL); + _shift_pressed = !!(mod & KMOD_SHIFT); + + /* determine which directional keys are down */ + _dirkeys = + (keys[SDL_SCANCODE_LEFT] ? 1 : 0) | + (keys[SDL_SCANCODE_UP] ? 2 : 0) | + (keys[SDL_SCANCODE_RIGHT] ? 4 : 0) | + (keys[SDL_SCANCODE_DOWN] ? 8 : 0); + if (old_ctrl_pressed != _ctrl_pressed) HandleCtrlChanged(); + + /* The gameloop is the part that can run asynchronously. The rest + * except sleeping can't. */ + if (_draw_mutex != nullptr) draw_lock.unlock(); + + GameLoop(); + + if (_draw_mutex != nullptr) draw_lock.lock(); + + UpdateWindows(); + _local_palette = _cur_palette; + } else { + /* Release the thread while sleeping */ + if (_draw_mutex != nullptr) draw_lock.unlock(); + CSleep(1); + if (_draw_mutex != nullptr) draw_lock.lock(); + + NetworkDrawChatMessage(); + DrawMouseCursor(); + } + + /* End of the critical part. */ + if (_draw_mutex != nullptr && !HasModalProgress()) { + _draw_signal->notify_one(); + } else { + /* Oh, we didn't have threads, then just draw unthreaded */ + CheckPaletteAnim(); + DrawSurfaceToScreen(); + } + } + + if (_draw_mutex != nullptr) { + _draw_continue = false; + /* Sending signal if there is no thread blocked + * is very valid and results in noop */ + _draw_signal->notify_one(); + if (draw_lock.owns_lock()) draw_lock.unlock(); + draw_lock.release(); + draw_thread.join(); + + delete _draw_mutex; + delete _draw_signal; + + _draw_mutex = nullptr; + _draw_signal = nullptr; + } +} + +bool VideoDriver_SDL::ChangeResolution(int w, int h) +{ + std::unique_lock lock; + if (_draw_mutex != nullptr) lock = std::unique_lock(*_draw_mutex); + + return CreateMainSurface(w, h, true); +} + +bool VideoDriver_SDL::ToggleFullscreen(bool fullscreen) +{ + std::unique_lock lock; + if (_draw_mutex != nullptr) lock = std::unique_lock(*_draw_mutex); + + /* Remember current window size */ + if (fullscreen) { + SDL_GetWindowSize(_sdl_window, &_window_size_w, &_window_size_h); + + /* Find fullscreen window size */ + SDL_DisplayMode dm; + if (SDL_GetCurrentDisplayMode(0, &dm) < 0) { + DEBUG(driver, 0, "SDL_GetCurrentDisplayMode() failed: %s", SDL_GetError()); + } else { + SDL_SetWindowSize(_sdl_window, dm.w, dm.h); + } + } + + DEBUG(driver, 1, "SDL2: Setting %s", fullscreen ? "fullscreen" : "windowed"); + int ret = SDL_SetWindowFullscreen(_sdl_window, fullscreen ? SDL_WINDOW_FULLSCREEN : 0); + if (ret == 0) { + /* Switching resolution succeeded, set fullscreen value of window. */ + _fullscreen = fullscreen; + if (!fullscreen) SDL_SetWindowSize(_sdl_window, _window_size_w, _window_size_h); + } else { + DEBUG(driver, 0, "SDL_SetWindowFullscreen() failed: %s", SDL_GetError()); + } + + return ret == 0; +} + +bool VideoDriver_SDL::AfterBlitterChange() +{ + int w, h; + SDL_GetWindowSize(_sdl_window, &w, &h); + return CreateMainSurface(w, h, false); +} + +void VideoDriver_SDL::AcquireBlitterLock() +{ + if (_draw_mutex != nullptr) _draw_mutex->lock(); +} + +void VideoDriver_SDL::ReleaseBlitterLock() +{ + if (_draw_mutex != nullptr) _draw_mutex->unlock(); +} + +#endif /* WITH_SDL2 */ diff --git a/src/video/sdl2_v.h b/src/video/sdl2_v.h new file mode 100644 index 0000000000..ae456a39d1 --- /dev/null +++ b/src/video/sdl2_v.h @@ -0,0 +1,60 @@ +/* + * 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 sdl2_v.h Base of the SDL2 video driver. */ + +#ifndef VIDEO_SDL_H +#define VIDEO_SDL_H + +#include "video_driver.hpp" + +/** The SDL video driver. */ +class VideoDriver_SDL : public VideoDriver { +public: + const char *Start(const char * const *param) override; + + void Stop() override; + + void MakeDirty(int left, int top, int width, int height) override; + + void MainLoop() override; + + bool ChangeResolution(int w, int h) override; + + bool ToggleFullscreen(bool fullscreen) override; + + bool AfterBlitterChange() override; + + void AcquireBlitterLock() override; + + void ReleaseBlitterLock() override; + + bool ClaimMousePointer() override; + + void EditBoxGainedFocus() override; + + void EditBoxLostFocus() override; + + const char *GetName() const override { return "sdl"; } +private: + int PollEvent(); + bool CreateMainSurface(uint w, uint h, bool resize); + + /** + * This is true to indicate that keyboard input is in text input mode, and SDL_TEXTINPUT events are enabled. + */ + bool edit_box_focused; +}; + +/** Factory for the SDL video driver. */ +class FVideoDriver_SDL : public DriverFactoryBase { +public: + FVideoDriver_SDL() : DriverFactoryBase(Driver::DT_VIDEO, 5, "sdl", "SDL Video Driver") {} + Driver *CreateInstance() const override { return new VideoDriver_SDL(); } +}; + +#endif /* VIDEO_SDL_H */ diff --git a/src/video/sdl_v.cpp b/src/video/sdl_v.cpp index 478a21511c..5e5b4abba2 100644 --- a/src/video/sdl_v.cpp +++ b/src/video/sdl_v.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. @@ -17,7 +15,7 @@ #include "../rev.h" #include "../blitter/factory.hpp" #include "../network/network.h" -#include "../thread/thread.h" +#include "../thread.h" #include "../progress.h" #include "../core/random_func.hpp" #include "../core/math_func.hpp" @@ -28,6 +26,9 @@ #include "../viewport_func.h" #include "sdl_v.h" #include +#include +#include +#include #ifdef __ANDROID__ #include #include @@ -43,10 +44,10 @@ static bool _all_modes; /** Whether the drawing is/may be done in a separate thread. */ static bool _draw_threaded; -/** Thread used to 'draw' to the screen, i.e. push data to the screen. */ -static ThreadObject *_draw_thread = NULL; /** Mutex to keep the access to the shared memory controlled. */ -static ThreadMutex *_draw_mutex = NULL; +static std::recursive_mutex *_draw_mutex = nullptr; +/** Signal to draw the next frame. */ +static std::condition_variable_any *_draw_signal = nullptr; /** Should we keep continue drawing? */ static volatile bool _draw_continue; static Palette _local_palette; @@ -119,7 +120,7 @@ static void UpdatePalette(bool init = false) * best mapping of shadow palette colors to real palette * colors from scratch. */ - SDL_BlitSurface(_sdl_screen, NULL, _sdl_realscreen, NULL); + SDL_BlitSurface(_sdl_screen, nullptr, _sdl_realscreen, nullptr); SDL_UpdateRect(_sdl_realscreen, 0, 0, 0, 0); } } @@ -170,7 +171,7 @@ static void DrawSurfaceToScreen() _num_dirty_rects = 0; if (n > MAX_DIRTY_RECTS) { if (_sdl_screen != _sdl_realscreen) { - SDL_BlitSurface(_sdl_screen, NULL, _sdl_realscreen, NULL); + SDL_BlitSurface(_sdl_screen, nullptr, _sdl_realscreen, nullptr); } SDL_UpdateRect(_sdl_realscreen, 0, 0, 0, 0); } else { @@ -185,24 +186,21 @@ static void DrawSurfaceToScreen() } } -static void DrawSurfaceToScreenThread(void *) +static void DrawSurfaceToScreenThread() { /* First tell the main thread we're started */ - _draw_mutex->BeginCritical(); - _draw_mutex->SendSignal(); + std::unique_lock lock(*_draw_mutex); + _draw_signal->notify_one(); /* Now wait for the first thing to draw! */ - _draw_mutex->WaitForSignal(); + _draw_signal->wait(*_draw_mutex); while (_draw_continue) { CheckPaletteAnim(); /* Then just draw and wait till we stop */ DrawSurfaceToScreen(); - _draw_mutex->WaitForSignal(); + _draw_signal->wait(lock); } - - _draw_mutex->EndCritical(); - _draw_thread->Exit(); } static const Dimension _default_resolutions[] = { @@ -221,38 +219,29 @@ static const Dimension _default_resolutions[] = { static void GetVideoModes() { - SDL_Rect **modes = SDL_ListModes(NULL, SDL_SWSURFACE | SDL_FULLSCREEN); - if (modes == NULL) usererror("sdl: no modes available"); + SDL_Rect **modes = SDL_ListModes(nullptr, SDL_SWSURFACE | SDL_FULLSCREEN); + if (modes == nullptr) usererror("sdl: no modes available"); - _all_modes = (SDL_ListModes(NULL, SDL_SWSURFACE | (_fullscreen ? SDL_FULLSCREEN : 0)) == (void*)-1); + _resolutions.clear(); + + _all_modes = (SDL_ListModes(nullptr, SDL_SWSURFACE | (_fullscreen ? SDL_FULLSCREEN : 0)) == (void*)-1); if (modes == (void*)-1) { - int n = 0; for (uint i = 0; i < lengthof(_default_resolutions); i++) { if (SDL_VideoModeOK(_default_resolutions[i].width, _default_resolutions[i].height, 8, SDL_FULLSCREEN) != 0) { - _resolutions[n] = _default_resolutions[i]; - if (++n == lengthof(_resolutions)) break; + _resolutions.push_back(_default_resolutions[i]); } } - _num_resolutions = n; } else { - int n = 0; for (int i = 0; modes[i]; i++) { uint w = modes[i]->w; uint h = modes[i]->h; - int j; - for (j = 0; j < n; j++) { - if (_resolutions[j].width == w && _resolutions[j].height == h) break; - } - - if (j == n) { - _resolutions[j].width = w; - _resolutions[j].height = h; - if (++n == lengthof(_resolutions)) break; - } + if (w < 640 || h < 480) continue; // reject too small resolutions + if (std::find(_resolutions.begin(), _resolutions.end(), Dimension(w, h)) != _resolutions.end()) continue; + _resolutions.emplace_back(w, h); } - _num_resolutions = n; + if (_resolutions.empty()) usererror("No usable screen resolutions found!\n"); #if !defined(__ANDROID__) // Android has native screen sizes first, do not sort them - SortResolutions(_num_resolutions); + SortResolutions(); #endif } } @@ -260,20 +249,18 @@ static void GetVideoModes() static void GetAvailableVideoMode(uint *w, uint *h) { /* All modes available? */ - if (_all_modes || _num_resolutions == 0) return; + if (_all_modes || _resolutions.empty()) return; /* Is the wanted mode among the available modes? */ - for (int i = 0; i != _num_resolutions; i++) { - if (*w == _resolutions[i].width && *h == _resolutions[i].height) return; - } + if (std::find(_resolutions.begin(), _resolutions.end(), Dimension(*w, *h)) != _resolutions.end()) return; /* Use the closest possible resolution */ - int best = 0; + uint best = 0; uint delta = Delta(_resolutions[0].width, *w) * Delta(_resolutions[0].height, *h); if (*w <= 1) { delta = Delta(_resolutions[0].height, *h); } - for (int i = 1; i != _num_resolutions; ++i) { + for (uint i = 1; i != _resolutions.size(); ++i) { uint newdelta = Delta(_resolutions[i].width, *w) * Delta(_resolutions[i].height, *h); if (*w <= 1) { newdelta = Delta(_resolutions[i].height, *h); @@ -301,15 +288,15 @@ bool VideoDriver_SDL::CreateMainSurface(uint w, uint h) if (bpp == 0) usererror("Can't use a blitter that blits 0 bpp for normal visuals"); char icon_path[MAX_PATH]; - if (FioFindFullPath(icon_path, lastof(icon_path), BASESET_DIR, "openttd.32.bmp") != NULL) { + if (FioFindFullPath(icon_path, lastof(icon_path), BASESET_DIR, "openttd.32.bmp") != nullptr) { /* Give the application an icon */ icon = SDL_LoadBMP(icon_path); - if (icon != NULL) { + if (icon != nullptr) { /* Get the colourkey, which will be magenta */ uint32 rgbmap = SDL_MapRGB(icon->format, 255, 0, 255); SDL_SetColorKey(icon, SDL_SRCCOLORKEY, rgbmap); - SDL_WM_SetIcon(icon, NULL); + SDL_WM_SetIcon(icon, nullptr); SDL_FreeSurface(icon); } } @@ -345,9 +332,9 @@ bool VideoDriver_SDL::CreateMainSurface(uint w, uint h) if (want_hwpalette) DEBUG(driver, 1, "SDL: requesting hardware palette"); /* Free any previously allocated shadow surface */ - if (_sdl_screen != NULL && _sdl_screen != _sdl_realscreen) SDL_FreeSurface(_sdl_screen); + if (_sdl_screen != nullptr && _sdl_screen != _sdl_realscreen) SDL_FreeSurface(_sdl_screen); - if (_sdl_realscreen != NULL) { + if (_sdl_realscreen != nullptr) { if (_requested_hwpalette != want_hwpalette) { /* SDL (at least the X11 driver), reuses the * same window and palette settings when the bpp @@ -372,7 +359,7 @@ bool VideoDriver_SDL::CreateMainSurface(uint w, uint h) /* DO NOT CHANGE TO HWSURFACE, IT DOES NOT WORK */ newscreen = SDL_SetVideoMode(w, h, bpp, SDL_SWSURFACE | (want_hwpalette ? SDL_HWPALETTE : 0) | (_fullscreen ? SDL_FULLSCREEN : SDL_RESIZABLE)); - if (newscreen == NULL) { + if (newscreen == nullptr) { DEBUG(driver, 0, "SDL: Couldn't allocate a window to draw on"); return false; } @@ -399,7 +386,7 @@ bool VideoDriver_SDL::CreateMainSurface(uint w, uint h) */ DEBUG(driver, 1, "SDL: using shadow surface"); newscreen = SDL_CreateRGBSurface(SDL_SWSURFACE, w, h, bpp, 0, 0, 0, 0); - if (newscreen == NULL) { + if (newscreen == nullptr) { DEBUG(driver, 0, "SDL: Couldn't allocate a shadow surface to draw on"); return false; } @@ -528,10 +515,6 @@ static uint ConvertSdlKeyIntoMy(SDL_keysym *sym, WChar *character) if (sym->scancode == 41) key = WKC_BACKQUOTE; #elif defined(__APPLE__) if (sym->scancode == 10) key = WKC_BACKQUOTE; -#elif defined(__MORPHOS__) - if (sym->scancode == 0) key = WKC_BACKQUOTE; // yes, that key is code '0' under MorphOS :) -#elif defined(__BEOS__) - if (sym->scancode == 17) key = WKC_BACKQUOTE; #elif defined(__SVR4) && defined(__sun) if (sym->scancode == 60) key = WKC_BACKQUOTE; if (sym->scancode == 49) key = WKC_BACKSPACE; @@ -718,12 +701,12 @@ const char *VideoDriver_SDL::Start(const char * const *parm) MarkWholeScreenDirty(); SetupKeyboard(); - _draw_threaded = GetDriverParam(parm, "no_threads") == NULL && GetDriverParam(parm, "no_thread") == NULL; + _draw_threaded = GetDriverParam(parm, "no_threads") == nullptr && GetDriverParam(parm, "no_thread") == nullptr; #ifdef __ANDROID__ _draw_threaded = false; #endif - return NULL; + return nullptr; } void VideoDriver_SDL::SetupKeyboard() @@ -751,26 +734,32 @@ void VideoDriver_SDL::MainLoop() CheckPaletteAnim(); + std::thread draw_thread; + std::unique_lock draw_lock; if (_draw_threaded) { /* Initialise the mutex first, because that's the thing we *need* * directly in the newly created thread. */ - _draw_mutex = ThreadMutex::New(); - if (_draw_mutex == NULL) { + _draw_mutex = new std::recursive_mutex(); + if (_draw_mutex == nullptr) { _draw_threaded = false; } else { - _draw_mutex->BeginCritical(); + draw_lock = std::unique_lock(*_draw_mutex); + _draw_signal = new std::condition_variable_any(); _draw_continue = true; - _draw_threaded = ThreadObject::New(&DrawSurfaceToScreenThread, NULL, &_draw_thread, "ottd:draw-sdl"); + _draw_threaded = StartNewThread(&draw_thread, "ottd:draw-sdl", &DrawSurfaceToScreenThread); /* Free the mutex if we won't be able to use it. */ if (!_draw_threaded) { - _draw_mutex->EndCritical(); + draw_lock.unlock(); + draw_lock.release(); delete _draw_mutex; - _draw_mutex = NULL; + delete _draw_signal; + _draw_mutex = nullptr; + _draw_signal = nullptr; } else { /* Wait till the draw mutex has started itself. */ - _draw_mutex->WaitForSignal(); + _draw_signal->wait(*_draw_mutex); } } } @@ -837,29 +826,29 @@ void VideoDriver_SDL::MainLoop() /* The gameloop is the part that can run asynchronously. The rest * except sleeping can't. */ - if (_draw_mutex != NULL) _draw_mutex->EndCritical(); + if (_draw_mutex != nullptr) draw_lock.unlock(); for (int i = (_fast_forward ? 5 : 1); i > 0; i--) { GameLoop(); } - if (_draw_mutex != NULL) _draw_mutex->BeginCritical(); + if (_draw_mutex != nullptr) draw_lock.lock(); UpdateWindows(); _local_palette = _cur_palette; } else { /* Release the thread while sleeping */ - if (_draw_mutex != NULL) _draw_mutex->EndCritical(); + if (_draw_mutex != nullptr) draw_lock.unlock(); CSleep(1); - if (_draw_mutex != NULL) _draw_mutex->BeginCritical(); + if (_draw_mutex != nullptr) draw_lock.lock(); NetworkDrawChatMessage(); DrawMouseCursor(); } /* End of the critical part. */ - if (_draw_mutex != NULL && !HasModalProgress()) { - _draw_mutex->SendSignal(); + if (_draw_mutex != nullptr && !HasModalProgress()) { + _draw_signal->notify_one(); } else { /* Oh, we didn't have threads, then just draw unthreaded */ CheckPaletteAnim(); @@ -867,43 +856,45 @@ void VideoDriver_SDL::MainLoop() } } - if (_draw_mutex != NULL) { + if (_draw_mutex != nullptr) { _draw_continue = false; /* Sending signal if there is no thread blocked * is very valid and results in noop */ - _draw_mutex->SendSignal(); - _draw_mutex->EndCritical(); - _draw_thread->Join(); + _draw_signal->notify_one(); + if (draw_lock.owns_lock()) draw_lock.unlock(); + draw_lock.release(); + draw_thread.join(); delete _draw_mutex; - delete _draw_thread; + delete _draw_signal; - _draw_mutex = NULL; - _draw_thread = NULL; + _draw_mutex = nullptr; + _draw_signal = nullptr; } } bool VideoDriver_SDL::ChangeResolution(int w, int h) { - if (_draw_mutex != NULL) _draw_mutex->BeginCritical(true); - bool ret = CreateMainSurface(w, h); - if (_draw_mutex != NULL) _draw_mutex->EndCritical(true); - return ret; + std::unique_lock lock; + if (_draw_mutex != nullptr) lock = std::unique_lock(*_draw_mutex); + + return CreateMainSurface(w, h); } bool VideoDriver_SDL::ToggleFullscreen(bool fullscreen) { - if (_draw_mutex != NULL) _draw_mutex->BeginCritical(true); + std::unique_lock lock; + if (_draw_mutex != nullptr) lock = std::unique_lock(*_draw_mutex); + _fullscreen = fullscreen; GetVideoModes(); // get the list of available video modes - bool ret = _num_resolutions != 0 && CreateMainSurface(_cur_resolution.width, _cur_resolution.height); + bool ret = !_resolutions.empty() && CreateMainSurface(_cur_resolution.width, _cur_resolution.height); if (!ret) { /* switching resolution failed, put back full_screen to original status */ _fullscreen ^= true; } - if (_draw_mutex != NULL) _draw_mutex->EndCritical(true); return ret; } @@ -914,12 +905,12 @@ bool VideoDriver_SDL::AfterBlitterChange() void VideoDriver_SDL::AcquireBlitterLock() { - if (_draw_mutex != NULL) _draw_mutex->BeginCritical(true); + if (_draw_mutex != nullptr) _draw_mutex->lock(); } void VideoDriver_SDL::ReleaseBlitterLock() { - if (_draw_mutex != NULL) _draw_mutex->EndCritical(true); + if (_draw_mutex != nullptr) _draw_mutex->unlock(); } #endif /* WITH_SDL */ diff --git a/src/video/sdl_v.h b/src/video/sdl_v.h index 8855c3566e..39c77e5d33 100644 --- a/src/video/sdl_v.h +++ b/src/video/sdl_v.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. @@ -17,27 +15,27 @@ /** The SDL video driver. */ class VideoDriver_SDL : public VideoDriver { public: - /* virtual */ const char *Start(const char * const *param); + const char *Start(const char * const *param) override; - /* virtual */ void Stop(); + void Stop() override; - /* virtual */ void MakeDirty(int left, int top, int width, int height); + void MakeDirty(int left, int top, int width, int height) override; - /* virtual */ void MainLoop(); + void MainLoop() override; - /* virtual */ bool ChangeResolution(int w, int h); + bool ChangeResolution(int w, int h) override; - /* virtual */ bool ToggleFullscreen(bool fullscreen); + bool ToggleFullscreen(bool fullscreen) override; - /* virtual */ bool AfterBlitterChange(); + bool AfterBlitterChange() override; - /* virtual */ void AcquireBlitterLock(); + void AcquireBlitterLock() override; - /* virtual */ void ReleaseBlitterLock(); + void ReleaseBlitterLock() override; - /* virtual */ bool ClaimMousePointer(); + bool ClaimMousePointer() override; - /* virtual */ const char *GetName() const { return "sdl"; } + const char *GetName() const override { return "sdl"; } private: int PollEvent(); bool CreateMainSurface(uint w, uint h); @@ -48,7 +46,7 @@ private: class FVideoDriver_SDL : public DriverFactoryBase { public: FVideoDriver_SDL() : DriverFactoryBase(Driver::DT_VIDEO, 5, "sdl", "SDL Video Driver") {} - /* virtual */ Driver *CreateInstance() const { return new VideoDriver_SDL(); } + Driver *CreateInstance() const override { return new VideoDriver_SDL(); } }; #endif /* VIDEO_SDL_H */ diff --git a/src/video/video_driver.hpp b/src/video/video_driver.hpp index e8d2f3ea32..2cca66d3b2 100644 --- a/src/video/video_driver.hpp +++ b/src/video/video_driver.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. @@ -14,6 +12,7 @@ #include "../driver.h" #include "../core/geometry_type.hpp" +#include /** The base of all video drivers. */ class VideoDriver : public Driver { @@ -92,6 +91,11 @@ public: */ virtual void EditBoxLostFocus() {} + /** + * An edit box gained the input focus + */ + virtual void EditBoxGainedFocus() {} + /** * Get the currently active instance of the video driver. */ @@ -101,8 +105,7 @@ public: }; extern char *_ini_videodriver; -extern int _num_resolutions; -extern Dimension _resolutions[100]; +extern std::vector _resolutions; extern Dimension _cur_resolution; extern bool _rightclick_emulate; diff --git a/src/video/win32_v.cpp b/src/video/win32_v.cpp index 6cee4fef28..3deb0beb06 100644 --- a/src/video/win32_v.cpp +++ b/src/video/win32_v.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. @@ -19,7 +17,7 @@ #include "../core/math_func.hpp" #include "../core/random_func.hpp" #include "../texteff.hpp" -#include "../thread/thread.h" +#include "../thread.h" #include "../progress.h" #include "../window_gui.h" #include "../window_func.h" @@ -27,6 +25,9 @@ #include "win32_v.h" #include #include +#include +#include +#include #include "../safeguards.h" @@ -40,7 +41,7 @@ #endif typedef BOOL (WINAPI *PFNTRACKMOUSEEVENT)(LPTRACKMOUSEEVENT lpEventTrack); -static PFNTRACKMOUSEEVENT _pTrackMouseEvent = NULL; +static PFNTRACKMOUSEEVENT _pTrackMouseEvent = nullptr; static struct { HWND main_wnd; @@ -65,12 +66,10 @@ DWORD _imm_props; /** Whether the drawing is/may be done in a separate thread. */ static bool _draw_threaded; -/** Thread used to 'draw' to the screen, i.e. push data to the screen. */ -static ThreadObject *_draw_thread = NULL; /** Mutex to keep the access to the shared memory controlled. */ -static ThreadMutex *_draw_mutex = NULL; -/** Event that is signaled when the drawing thread has finished initializing. */ -static HANDLE _draw_thread_initialized = NULL; +static std::recursive_mutex *_draw_mutex = nullptr; +/** Signal to draw the next frame. */ +static std::condition_variable_any *_draw_signal = nullptr; /** Should we keep continue drawing? */ static volatile bool _draw_continue; /** Local copy of the palette for use in the drawing thread. */ @@ -91,7 +90,7 @@ static void MakePalette() } _wnd.gdi_palette = CreatePalette(pal); - if (_wnd.gdi_palette == NULL) usererror("CreatePalette failed!\n"); + if (_wnd.gdi_palette == nullptr) usererror("CreatePalette failed!\n"); _cur_palette.first_dirty = 0; _cur_palette.count_dirty = 256; @@ -309,7 +308,7 @@ bool VideoDriver_Win32::MakeWindow(bool full_screen) } } else if (_wnd.fullscreen) { /* restore display? */ - ChangeDisplaySettings(NULL, 0); + ChangeDisplaySettings(nullptr, 0); /* restore the resolution */ _wnd.width = _bck_resolution.width; _wnd.height = _bck_resolution.height; @@ -336,7 +335,7 @@ bool VideoDriver_Win32::MakeWindow(bool full_screen) w = r.right - r.left; h = r.bottom - r.top; - if (_wnd.main_wnd != NULL) { + if (_wnd.main_wnd != nullptr) { if (!_window_maximize) SetWindowPos(_wnd.main_wnd, 0, 0, 0, w, h, SWP_NOACTIVATE | SWP_NOOWNERZORDER | SWP_NOZORDER | SWP_NOMOVE); } else { int x = (GetSystemMetrics(SM_CXSCREEN) - w) / 2; @@ -345,8 +344,8 @@ bool VideoDriver_Win32::MakeWindow(bool full_screen) char window_title[64]; seprintf(window_title, lastof(window_title), "OpenTTD %s", _openttd_revision); - _wnd.main_wnd = CreateWindow(_T("OTTD"), MB_TO_WIDE(window_title), style, x, y, w, h, 0, 0, GetModuleHandle(NULL), 0); - if (_wnd.main_wnd == NULL) usererror("CreateWindow failed"); + _wnd.main_wnd = CreateWindow(_T("OTTD"), MB_TO_WIDE(window_title), style, x, y, w, h, 0, 0, GetModuleHandle(nullptr), 0); + if (_wnd.main_wnd == nullptr) usererror("CreateWindow failed"); ShowWindow(_wnd.main_wnd, showstyle); } } @@ -393,14 +392,14 @@ static void PaintWindow(HDC dc) DeleteDC(dc2); } -static void PaintWindowThread(void *) +static void PaintWindowThread() { /* First tell the main thread we're started */ - _draw_mutex->BeginCritical(); - SetEvent(_draw_thread_initialized); + std::unique_lock lock(*_draw_mutex); + _draw_signal->notify_one(); /* Now wait for the first thing to draw! */ - _draw_mutex->WaitForSignal(); + _draw_signal->wait(*_draw_mutex); while (_draw_continue) { /* Convert update region from logical to device coordinates. */ @@ -422,11 +421,8 @@ static void PaintWindowThread(void *) /* Flush GDI buffer to ensure drawing here doesn't conflict with any GDI usage in the main WndProc. */ GdiFlush(); - _draw_mutex->WaitForSignal(); + _draw_signal->wait(*_draw_mutex); } - - _draw_mutex->EndCritical(); - _draw_thread->Exit(); } /** Forward key presses to the window system. */ @@ -562,14 +558,14 @@ static LRESULT HandleIMEComposition(HWND hwnd, WPARAM wParam, LPARAM lParam) if (hIMC != NULL) { if (lParam & GCS_RESULTSTR) { /* Read result string from the IME. */ - LONG len = ImmGetCompositionString(hIMC, GCS_RESULTSTR, NULL, 0); // Length is always in bytes, even in UNICODE build. + LONG len = ImmGetCompositionString(hIMC, GCS_RESULTSTR, nullptr, 0); // Length is always in bytes, even in UNICODE build. TCHAR *str = (TCHAR *)_alloca(len + sizeof(TCHAR)); len = ImmGetCompositionString(hIMC, GCS_RESULTSTR, str, len); str[len / sizeof(TCHAR)] = '\0'; /* Transmit text to windowing system. */ if (len > 0) { - HandleTextInput(NULL, true); // Clear marked string. + HandleTextInput(nullptr, true); // Clear marked string. HandleTextInput(FS2OTTD(str)); } SetCompositionPos(hwnd); @@ -580,7 +576,7 @@ static LRESULT HandleIMEComposition(HWND hwnd, WPARAM wParam, LPARAM lParam) if ((lParam & GCS_COMPSTR) && DrawIMECompositionString()) { /* Read composition string from the IME. */ - LONG len = ImmGetCompositionString(hIMC, GCS_COMPSTR, NULL, 0); // Length is always in bytes, even in UNICODE build. + LONG len = ImmGetCompositionString(hIMC, GCS_COMPSTR, nullptr, 0); // Length is always in bytes, even in UNICODE build. TCHAR *str = (TCHAR *)_alloca(len + sizeof(TCHAR)); len = ImmGetCompositionString(hIMC, GCS_COMPSTR, str, len); str[len / sizeof(TCHAR)] = '\0'; @@ -590,7 +586,7 @@ static LRESULT HandleIMEComposition(HWND hwnd, WPARAM wParam, LPARAM lParam) convert_from_fs(str, utf8_buf, lengthof(utf8_buf)); /* Convert caret position from bytes in the input string to a position in the UTF-8 encoded string. */ - LONG caret_bytes = ImmGetCompositionString(hIMC, GCS_CURSORPOS, NULL, 0); + LONG caret_bytes = ImmGetCompositionString(hIMC, GCS_CURSORPOS, nullptr, 0); const char *caret = utf8_buf; for (const TCHAR *c = str; *c != '\0' && *caret != '\0' && caret_bytes > 0; c++, caret_bytes--) { /* Skip DBCS lead bytes or leading surrogates. */ @@ -607,7 +603,7 @@ static LRESULT HandleIMEComposition(HWND hwnd, WPARAM wParam, LPARAM lParam) HandleTextInput(utf8_buf, true, caret); } else { - HandleTextInput(NULL, true); + HandleTextInput(nullptr, true); } lParam &= ~(GCS_COMPSTR | GCS_COMPATTR | GCS_COMPCLAUSE | GCS_CURSORPOS | GCS_DELTASTART); @@ -625,7 +621,7 @@ static void CancelIMEComposition(HWND hwnd) if (hIMC != NULL) ImmNotifyIME(hIMC, NI_COMPOSITIONSTR, CPS_CANCEL, 0); ImmReleaseContext(hwnd, hIMC); /* Clear any marked string from the current edit box. */ - HandleTextInput(NULL, true); + HandleTextInput(nullptr, true); } static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam) @@ -650,15 +646,15 @@ static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP break; case WM_PAINT: - if (!in_sizemove && _draw_mutex != NULL && !HasModalProgress()) { + if (!in_sizemove && _draw_mutex != nullptr && !HasModalProgress()) { /* Get the union of the old update rect and the new update rect. */ RECT r; GetUpdateRect(hwnd, &r, FALSE); UnionRect(&_wnd.update_rect, &_wnd.update_rect, &r); /* Mark the window as updated, otherwise Windows would send more WM_PAINT messages. */ - ValidateRect(hwnd, NULL); - _draw_mutex->SendSignal(); + ValidateRect(hwnd, nullptr); + _draw_signal->notify_one(); } else { PAINTSTRUCT ps; @@ -679,7 +675,7 @@ static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP SelectPalette(hDC, hOldPalette, TRUE); ReleaseDC(hwnd, hDC); - if (nChanged != 0) InvalidateRect(hwnd, NULL, FALSE); + if (nChanged != 0) InvalidateRect(hwnd, nullptr, FALSE); return 0; } @@ -733,7 +729,7 @@ static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP * tracking the mouse for exiting the window */ if (!_cursor.in_window) { _cursor.in_window = true; - if (_pTrackMouseEvent != NULL) { + if (_pTrackMouseEvent != nullptr) { TRACKMOUSEEVENT tme; tme.cbSize = sizeof(tme); tme.dwFlags = TME_LEAVE; @@ -786,7 +782,7 @@ static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP case WM_IME_ENDCOMPOSITION: /* Clear any pending composition string. */ - HandleTextInput(NULL, true); + HandleTextInput(nullptr, true); if (DrawIMECompositionString()) return 0; break; @@ -834,7 +830,7 @@ static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP /* Silently drop all messages handled by WM_CHAR. */ MSG msg; - if (PeekMessage(&msg, NULL, 0, 0, PM_NOREMOVE)) { + if (PeekMessage(&msg, nullptr, 0, 0, PM_NOREMOVE)) { if ((msg.message == WM_CHAR || msg.message == WM_DEADCHAR) && GB(lParam, 16, 8) == GB(msg.lParam, 16, 8)) { return 0; } @@ -996,7 +992,7 @@ static LRESULT CALLBACK WndProcGdi(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lP } else if (!active && !minimized) { /* Minimise the window and restore desktop */ ShowWindow(hwnd, SW_MINIMIZE); - ChangeDisplaySettings(NULL, 0); + ChangeDisplaySettings(nullptr, 0); } } break; @@ -1011,7 +1007,7 @@ static void RegisterWndClass() static bool registered = false; if (!registered) { - HINSTANCE hinst = GetModuleHandle(NULL); + HINSTANCE hinst = GetModuleHandle(nullptr); WNDCLASS wnd = { CS_OWNDC, WndProcGdi, @@ -1019,7 +1015,7 @@ static void RegisterWndClass() 0, hinst, LoadIcon(hinst, MAKEINTRESOURCE(100)), - LoadCursor(NULL, IDC_ARROW), + LoadCursor(nullptr, IDC_ARROW), 0, 0, _T("OTTD") @@ -1060,8 +1056,8 @@ static bool AllocateDibSection(int w, int h, bool force) if (_wnd.dib_sect) DeleteObject(_wnd.dib_sect); dc = GetDC(0); - _wnd.dib_sect = CreateDIBSection(dc, bi, DIB_RGB_COLORS, (VOID**)&_wnd.buffer_bits, NULL, 0); - if (_wnd.dib_sect == NULL) usererror("CreateDIBSection failed"); + _wnd.dib_sect = CreateDIBSection(dc, bi, DIB_RGB_COLORS, (VOID**)&_wnd.buffer_bits, nullptr, 0); + if (_wnd.dib_sect == nullptr) usererror("CreateDIBSection failed"); ReleaseDC(0, dc); _screen.width = w; @@ -1088,45 +1084,29 @@ static const Dimension default_resolutions[] = { static void FindResolutions() { - uint n = 0; uint i; DEVMODEA dm; /* Check modes for the relevant fullscreen bpp */ uint bpp = _support8bpp != S8BPP_HARDWARE ? 32 : BlitterFactory::GetCurrentBlitter()->GetScreenDepth(); + _resolutions.clear(); + /* XXX - EnumDisplaySettingsW crashes with unicows.dll on Windows95 * Doesn't really matter since we don't pass a string anyways, but still * a letdown */ - for (i = 0; EnumDisplaySettingsA(NULL, i, &dm) != 0; i++) { - if (dm.dmBitsPerPel == bpp && - dm.dmPelsWidth >= 640 && dm.dmPelsHeight >= 480) { - uint j; - - for (j = 0; j < n; j++) { - if (_resolutions[j].width == dm.dmPelsWidth && _resolutions[j].height == dm.dmPelsHeight) break; - } - - /* In the previous loop we have checked already existing/added resolutions if - * they are the same as the new ones. If this is not the case (j == n); we have - * looped all and found none, add the new one to the list. If we have reached the - * maximum amount of resolutions, then quit querying the display */ - if (j == n) { - _resolutions[j].width = dm.dmPelsWidth; - _resolutions[j].height = dm.dmPelsHeight; - if (++n == lengthof(_resolutions)) break; - } - } + for (i = 0; EnumDisplaySettingsA(nullptr, i, &dm) != 0; i++) { + if (dm.dmBitsPerPel != bpp || dm.dmPelsWidth < 640 || dm.dmPelsHeight < 480) continue; + if (std::find(_resolutions.begin(), _resolutions.end(), Dimension(dm.dmPelsWidth, dm.dmPelsHeight)) != _resolutions.end()) continue; + _resolutions.emplace_back(dm.dmPelsWidth, dm.dmPelsHeight); } /* We have found no resolutions, show the default list */ - if (n == 0) { - memcpy(_resolutions, default_resolutions, sizeof(default_resolutions)); - n = lengthof(default_resolutions); + if (_resolutions.empty()) { + _resolutions.assign(std::begin(default_resolutions), std::end(default_resolutions)); } - _num_resolutions = n; - SortResolutions(_num_resolutions); + SortResolutions(); } static FVideoDriver_Win32 iFVideoDriver_Win32; @@ -1152,9 +1132,9 @@ const char *VideoDriver_Win32::Start(const char * const *parm) MarkWholeScreenDirty(); - _draw_threaded = GetDriverParam(parm, "no_threads") == NULL && GetDriverParam(parm, "no_thread") == NULL && GetCPUCoreCount() > 1; + _draw_threaded = GetDriverParam(parm, "no_threads") == nullptr && GetDriverParam(parm, "no_thread") == nullptr && std::thread::hardware_concurrency() > 1; - return NULL; + return nullptr; } void VideoDriver_Win32::Stop() @@ -1163,7 +1143,7 @@ void VideoDriver_Win32::Stop() DeleteObject(_wnd.dib_sect); DestroyWindow(_wnd.main_wnd); - if (_wnd.fullscreen) ChangeDisplaySettings(NULL, 0); + if (_wnd.fullscreen) ChangeDisplaySettings(nullptr, 0); MyShowCursor(true); } @@ -1179,7 +1159,7 @@ static void CheckPaletteAnim() if (_cur_palette.count_dirty == 0) return; _local_palette = _cur_palette; - InvalidateRect(_wnd.main_wnd, NULL, FALSE); + InvalidateRect(_wnd.main_wnd, nullptr, FALSE); } void VideoDriver_Win32::MainLoop() @@ -1189,28 +1169,37 @@ void VideoDriver_Win32::MainLoop() uint32 last_cur_ticks = cur_ticks; uint32 next_tick = cur_ticks + MILLISECONDS_PER_TICK; + std::thread draw_thread; + std::unique_lock draw_lock; + if (_draw_threaded) { /* Initialise the mutex first, because that's the thing we *need* * directly in the newly created thread. */ - _draw_mutex = ThreadMutex::New(); - _draw_thread_initialized = CreateEvent(NULL, FALSE, FALSE, NULL); - if (_draw_mutex == NULL || _draw_thread_initialized == NULL) { + try { + _draw_signal = new std::condition_variable_any(); + _draw_mutex = new std::recursive_mutex(); + } catch (...) { _draw_threaded = false; - } else { + } + + if (_draw_threaded) { + draw_lock = std::unique_lock(*_draw_mutex); + _draw_continue = true; - _draw_threaded = ThreadObject::New(&PaintWindowThread, NULL, &_draw_thread, "ottd:draw-win32"); + _draw_threaded = StartNewThread(&draw_thread, "ottd:draw-win32", &PaintWindowThread); /* Free the mutex if we won't be able to use it. */ if (!_draw_threaded) { + draw_lock.unlock(); + draw_lock.release(); delete _draw_mutex; - _draw_mutex = NULL; - CloseHandle(_draw_thread_initialized); - _draw_thread_initialized = NULL; + delete _draw_signal; + _draw_mutex = nullptr; + _draw_signal = nullptr; } else { DEBUG(driver, 1, "Threaded drawing enabled"); /* Wait till the draw thread has started itself. */ - WaitForSingleObject(_draw_thread_initialized, INFINITE); - _draw_mutex->BeginCritical(); + _draw_signal->wait(*_draw_mutex); } } } @@ -1221,13 +1210,13 @@ void VideoDriver_Win32::MainLoop() for (;;) { uint32 prev_cur_ticks = cur_ticks; // to check for wrapping - while (PeekMessage(&mesg, NULL, 0, 0, PM_REMOVE)) { + while (PeekMessage(&mesg, nullptr, 0, 0, PM_REMOVE)) { InteractiveRandom(); // randomness /* Convert key messages to char messages if we want text input. */ if (EditBoxInGlobalFocus()) TranslateMessage(&mesg); DispatchMessage(&mesg); } - if (_exit_game) return; + if (_exit_game) break; #if defined(_DEBUG) if (_wnd.has_focus && GetAsyncKeyState(VK_SHIFT) < 0 && @@ -1270,9 +1259,9 @@ void VideoDriver_Win32::MainLoop() /* The game loop is the part that can run asynchronously. * The rest except sleeping can't. */ - if (_draw_threaded) _draw_mutex->EndCritical(); + if (_draw_threaded) draw_lock.unlock(); GameLoop(); - if (_draw_threaded) _draw_mutex->BeginCritical(); + if (_draw_threaded) draw_lock.lock(); if (_force_full_redraw) MarkWholeScreenDirty(); @@ -1283,9 +1272,9 @@ void VideoDriver_Win32::MainLoop() GdiFlush(); /* Release the thread while sleeping */ - if (_draw_threaded) _draw_mutex->EndCritical(); + if (_draw_threaded) draw_lock.unlock(); Sleep(1); - if (_draw_threaded) _draw_mutex->BeginCritical(); + if (_draw_threaded) draw_lock.lock(); NetworkDrawChatMessage(); DrawMouseCursor(); @@ -1296,35 +1285,37 @@ void VideoDriver_Win32::MainLoop() _draw_continue = false; /* Sending signal if there is no thread blocked * is very valid and results in noop */ - _draw_mutex->SendSignal(); - _draw_mutex->EndCritical(); - _draw_thread->Join(); + _draw_signal->notify_all(); + if (draw_lock.owns_lock()) draw_lock.unlock(); + draw_lock.release(); + draw_thread.join(); - CloseHandle(_draw_thread_initialized); delete _draw_mutex; - delete _draw_thread; + delete _draw_signal; + + _draw_mutex = nullptr; } } bool VideoDriver_Win32::ChangeResolution(int w, int h) { - if (_draw_mutex != NULL) _draw_mutex->BeginCritical(true); + std::unique_lock lock; + if (_draw_mutex != nullptr) lock = std::unique_lock(*_draw_mutex); + if (_window_maximize) ShowWindow(_wnd.main_wnd, SW_SHOWNORMAL); _wnd.width = _wnd.width_org = w; _wnd.height = _wnd.height_org = h; - bool ret = this->MakeWindow(_fullscreen); // _wnd.fullscreen screws up ingame resolution switching - if (_draw_mutex != NULL) _draw_mutex->EndCritical(true); - return ret; + return this->MakeWindow(_fullscreen); // _wnd.fullscreen screws up ingame resolution switching } bool VideoDriver_Win32::ToggleFullscreen(bool full_screen) { - if (_draw_mutex != NULL) _draw_mutex->BeginCritical(true); - bool ret = this->MakeWindow(full_screen); - if (_draw_mutex != NULL) _draw_mutex->EndCritical(true); - return ret; + std::unique_lock lock; + if (_draw_mutex != nullptr) lock = std::unique_lock(*_draw_mutex); + + return this->MakeWindow(full_screen); } bool VideoDriver_Win32::AfterBlitterChange() @@ -1334,19 +1325,20 @@ bool VideoDriver_Win32::AfterBlitterChange() void VideoDriver_Win32::AcquireBlitterLock() { - if (_draw_mutex != NULL) _draw_mutex->BeginCritical(true); + if (_draw_mutex != nullptr) _draw_mutex->lock(); } void VideoDriver_Win32::ReleaseBlitterLock() { - if (_draw_mutex != NULL) _draw_mutex->EndCritical(true); + if (_draw_mutex != nullptr) _draw_mutex->unlock(); } void VideoDriver_Win32::EditBoxLostFocus() { - if (_draw_mutex != NULL) _draw_mutex->BeginCritical(true); + std::unique_lock lock; + if (_draw_mutex != nullptr) lock = std::unique_lock(*_draw_mutex); + CancelIMEComposition(_wnd.main_wnd); SetCompositionPos(_wnd.main_wnd); SetCandidatePos(_wnd.main_wnd); - if (_draw_mutex != NULL) _draw_mutex->EndCritical(true); } diff --git a/src/video/win32_v.h b/src/video/win32_v.h index 7609d0422d..a0b5c7e161 100644 --- a/src/video/win32_v.h +++ b/src/video/win32_v.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. @@ -17,29 +15,29 @@ /** The video driver for windows. */ class VideoDriver_Win32 : public VideoDriver { public: - /* virtual */ const char *Start(const char * const *param); + const char *Start(const char * const *param) override; - /* virtual */ void Stop(); + void Stop() override; - /* virtual */ void MakeDirty(int left, int top, int width, int height); + void MakeDirty(int left, int top, int width, int height) override; - /* virtual */ void MainLoop(); + void MainLoop() override; - /* virtual */ bool ChangeResolution(int w, int h); + bool ChangeResolution(int w, int h) override; - /* virtual */ bool ToggleFullscreen(bool fullscreen); + bool ToggleFullscreen(bool fullscreen) override; - /* virtual */ bool AfterBlitterChange(); + bool AfterBlitterChange() override; - /* virtual */ void AcquireBlitterLock(); + void AcquireBlitterLock() override; - /* virtual */ void ReleaseBlitterLock(); + void ReleaseBlitterLock() override; - /* virtual */ bool ClaimMousePointer(); + bool ClaimMousePointer() override; - /* virtual */ void EditBoxLostFocus(); + void EditBoxLostFocus() override; - /* virtual */ const char *GetName() const { return "win32"; } + const char *GetName() const override { return "win32"; } bool MakeWindow(bool full_screen); }; @@ -48,7 +46,7 @@ public: class FVideoDriver_Win32 : public DriverFactoryBase { public: FVideoDriver_Win32() : DriverFactoryBase(Driver::DT_VIDEO, 10, "win32", "Win32 GDI Video Driver") {} - /* virtual */ Driver *CreateInstance() const { return new VideoDriver_Win32(); } + Driver *CreateInstance() const override { return new VideoDriver_Win32(); } }; #endif /* VIDEO_WIN32_H */ diff --git a/src/viewport.cpp b/src/viewport.cpp index 3f6619490e..fca551b6ad 100644 --- a/src/viewport.cpp +++ b/src/viewport.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. @@ -82,6 +80,8 @@ #include "tilehighlight_func.h" #include "window_gui.h" #include "linkgraph/linkgraph_gui.h" +#include "viewport_kdtree.h" +#include "town_kdtree.h" #include "viewport_sprite_sorter.h" #include "bridge_map.h" #include "company_base.h" @@ -100,6 +100,10 @@ Point _tile_fract_coords; +ViewportSignKdtree _viewport_sign_kdtree(&Kdtree_ViewportSignXYFunc); +static int _viewport_sign_maxwidth = 0; + + static const int MAX_TILE_EXTENT_LEFT = ZOOM_LVL_BASE * TILE_PIXELS; ///< Maximum left extent of tile relative to north corner. static const int MAX_TILE_EXTENT_RIGHT = ZOOM_LVL_BASE * TILE_PIXELS; ///< Maximum right extent of tile relative to north corner. static const int MAX_TILE_EXTENT_TOP = ZOOM_LVL_BASE * MAX_BUILDING_PIXELS; ///< Maximum top extent of tile relative to north corner (not considering bridges). @@ -149,10 +153,10 @@ enum SpriteCombineMode { SPRITE_COMBINE_ACTIVE, ///< %Sprite combining is active. #AddSortableSpriteToDraw outputs child sprites. }; -typedef SmallVector TileSpriteToDrawVector; -typedef SmallVector StringSpriteToDrawVector; -typedef SmallVector ParentSpriteToDrawVector; -typedef SmallVector ChildScreenSpriteToDrawVector; +typedef std::vector TileSpriteToDrawVector; +typedef std::vector StringSpriteToDrawVector; +typedef std::vector ParentSpriteToDrawVector; +typedef std::vector ChildScreenSpriteToDrawVector; /** Data structure storing rendering information */ struct ViewportDrawer { @@ -183,7 +187,7 @@ static TileInfo *_cur_ti; bool _draw_bounding_boxes = false; bool _draw_dirty_blocks = false; uint _dirty_block_colour = 0; -static VpSpriteSorter _vp_sprite_sorter = NULL; +static VpSpriteSorter _vp_sprite_sorter = nullptr; static Point MapXYZToViewport(const ViewPort *vp, int x, int y, int z) { @@ -195,11 +199,11 @@ static Point MapXYZToViewport(const ViewPort *vp, int x, int y, int z) void DeleteWindowViewport(Window *w) { - if (w->viewport == NULL) return; + if (w->viewport == nullptr) return; delete w->viewport->overlay; free(w->viewport); - w->viewport = NULL; + w->viewport = nullptr; } /** @@ -217,7 +221,7 @@ void DeleteWindowViewport(Window *w) void InitializeWindowViewport(Window *w, int x, int y, int width, int height, uint32 follow_flags, ZoomLevel zoom) { - assert(w->viewport == NULL); + assert(w->viewport == nullptr); ViewportData *vp = CallocT(1); @@ -252,7 +256,7 @@ void InitializeWindowViewport(Window *w, int x, int y, vp->dest_scrollpos_x = pt.x; vp->dest_scrollpos_y = pt.y; - vp->overlay = NULL; + vp->overlay = nullptr; w->viewport = vp; vp->virtual_left = 0; // pt.x; @@ -385,18 +389,18 @@ static void SetViewportPosition(Window *w, int x, int y) * @param x X coordinate of the xy position * @param y Y coordinate of the xy position * @return Pointer to the viewport if the xy position is in the viewport of the window, - * otherwise \c NULL is returned. + * otherwise \c nullptr is returned. */ ViewPort *IsPtInWindowViewport(const Window *w, int x, int y) { ViewPort *vp = w->viewport; - if (vp != NULL && + if (vp != nullptr && IsInsideMM(x, vp->left, vp->left + vp->width) && IsInsideMM(y, vp->top, vp->top + vp->height)) return vp; - return NULL; + return nullptr; } /** @@ -432,8 +436,8 @@ static Point GetTileFromScreenXY(int x, int y, int zoom_x, int zoom_y) ViewPort *vp; Point pt; - if ( (w = FindWindowFromPt(x, y)) != NULL && - (vp = IsPtInWindowViewport(w, x, y)) != NULL) + if ( (w = FindWindowFromPt(x, y)) != nullptr && + (vp = IsPtInWindowViewport(w, x, y)) != nullptr) return TranslateXYToTileCoord(vp, zoom_x, zoom_y); pt.y = pt.x = -1; @@ -491,17 +495,18 @@ void HandleZoomMessage(Window *w, const ViewPort *vp, byte widget_zoom_in, byte * @param extra_offs_x Pixel X offset for the sprite position. * @param extra_offs_y Pixel Y offset for the sprite position. */ -static void AddTileSpriteToDraw(SpriteID image, PaletteID pal, int32 x, int32 y, int z, const SubSprite *sub = NULL, int extra_offs_x = 0, int extra_offs_y = 0) +static void AddTileSpriteToDraw(SpriteID image, PaletteID pal, int32 x, int32 y, int z, const SubSprite *sub = nullptr, int extra_offs_x = 0, int extra_offs_y = 0) { assert((image & SPRITE_MASK) < MAX_SPRITES); - TileSpriteToDraw *ts = _vd.tile_sprites_to_draw.Append(); - ts->image = image; - ts->pal = pal; - ts->sub = sub; + /*C++17: TileSpriteToDraw &ts = */ _vd.tile_sprites_to_draw.emplace_back(); + TileSpriteToDraw &ts = _vd.tile_sprites_to_draw.back(); + ts.image = image; + ts.pal = pal; + ts.sub = sub; Point pt = RemapCoords(x, y, z); - ts->x = pt.x + extra_offs_x; - ts->y = pt.y + extra_offs_y; + ts.x = pt.x + extra_offs_x; + ts.y = pt.y + extra_offs_y; } /** @@ -593,8 +598,8 @@ void OffsetGroundSprite(int x, int y) default: NOT_REACHED(); } - /* _vd.last_child == NULL if foundation sprite was clipped by the viewport bounds */ - if (_vd.last_child != NULL) _vd.foundation[_vd.foundation_part] = _vd.parent_sprites_to_draw.Length() - 1; + /* _vd.last_child == nullptr if foundation sprite was clipped by the viewport bounds */ + if (_vd.last_child != nullptr) _vd.foundation[_vd.foundation_part] = (uint)_vd.parent_sprites_to_draw.size() - 1; _vd.foundation_offset[_vd.foundation_part].x = x * ZOOM_LVL_BASE; _vd.foundation_offset[_vd.foundation_part].y = y * ZOOM_LVL_BASE; @@ -623,8 +628,8 @@ static void AddCombinedSprite(SpriteID image, PaletteID pal, int x, int y, int z pt.y + spr->y_offs + spr->height <= _vd.dpi.top) return; - const ParentSpriteToDraw *pstd = _vd.parent_sprites_to_draw.End() - 1; - AddChildSpriteScreen(image, pal, pt.x - pstd->left, pt.y - pstd->top, false, sub, false); + const ParentSpriteToDraw &pstd = _vd.parent_sprites_to_draw.back(); + AddChildSpriteScreen(image, pal, pt.x - pstd.left, pt.y - pstd.top, false, sub, false); } /** @@ -669,7 +674,7 @@ void AddSortableSpriteToDraw(SpriteID image, PaletteID pal, int x, int y, int w, return; } - _vd.last_child = NULL; + _vd.last_child = nullptr; Point pt = RemapCoords(x, y, z); int tmp_left, tmp_top, tmp_x = pt.x, tmp_y = pt.y; @@ -704,29 +709,30 @@ void AddSortableSpriteToDraw(SpriteID image, PaletteID pal, int x, int y, int w, return; } - ParentSpriteToDraw *ps = _vd.parent_sprites_to_draw.Append(); - ps->x = tmp_x; - ps->y = tmp_y; + /*C++17: ParentSpriteToDraw &ps = */ _vd.parent_sprites_to_draw.emplace_back(); + ParentSpriteToDraw &ps = _vd.parent_sprites_to_draw.back(); + ps.x = tmp_x; + ps.y = tmp_y; - ps->left = tmp_left; - ps->top = tmp_top; + ps.left = tmp_left; + ps.top = tmp_top; - ps->image = image; - ps->pal = pal; - ps->sub = sub; - ps->xmin = x + bb_offset_x; - ps->xmax = x + max(bb_offset_x, w) - 1; + ps.image = image; + ps.pal = pal; + ps.sub = sub; + ps.xmin = x + bb_offset_x; + ps.xmax = x + max(bb_offset_x, w) - 1; - ps->ymin = y + bb_offset_y; - ps->ymax = y + max(bb_offset_y, h) - 1; + ps.ymin = y + bb_offset_y; + ps.ymax = y + max(bb_offset_y, h) - 1; - ps->zmin = z + bb_offset_z; - ps->zmax = z + max(bb_offset_z, dz) - 1; + ps.zmin = z + bb_offset_z; + ps.zmax = z + max(bb_offset_z, dz) - 1; - ps->comparison_done = false; - ps->first_child = -1; + ps.comparison_done = false; + ps.first_child = -1; - _vd.last_child = &ps->first_child; + _vd.last_child = &ps.first_child; if (_vd.combine_sprites == SPRITE_COMBINE_PENDING) _vd.combine_sprites = SPRITE_COMBINE_ACTIVE; } @@ -812,7 +818,7 @@ void AddChildSpriteScreen(SpriteID image, PaletteID pal, int x, int y, bool tran assert((image & SPRITE_MASK) < MAX_SPRITES); /* If the ParentSprite was clipped by the viewport bounds, do not draw the ChildSprites either */ - if (_vd.last_child == NULL) return; + if (_vd.last_child == nullptr) return; /* make the sprites transparent with the right palette */ if (transparent) { @@ -820,35 +826,37 @@ void AddChildSpriteScreen(SpriteID image, PaletteID pal, int x, int y, bool tran pal = PALETTE_TO_TRANSPARENT; } - *_vd.last_child = _vd.child_screen_sprites_to_draw.Length(); + *_vd.last_child = (uint)_vd.child_screen_sprites_to_draw.size(); - ChildScreenSpriteToDraw *cs = _vd.child_screen_sprites_to_draw.Append(); - cs->image = image; - cs->pal = pal; - cs->sub = sub; - cs->x = scale ? x * ZOOM_LVL_BASE : x; - cs->y = scale ? y * ZOOM_LVL_BASE : y; - cs->next = -1; + /*C++17: ChildScreenSpriteToDraw &cs = */ _vd.child_screen_sprites_to_draw.emplace_back(); + ChildScreenSpriteToDraw &cs = _vd.child_screen_sprites_to_draw.back(); + cs.image = image; + cs.pal = pal; + cs.sub = sub; + cs.x = scale ? x * ZOOM_LVL_BASE : x; + cs.y = scale ? y * ZOOM_LVL_BASE : y; + cs.next = -1; /* Append the sprite to the active ChildSprite list. * If the active ParentSprite is a foundation, update last_foundation_child as well. * Note: ChildSprites of foundations are NOT sequential in the vector, as selection sprites are added at last. */ - if (_vd.last_foundation_child[0] == _vd.last_child) _vd.last_foundation_child[0] = &cs->next; - if (_vd.last_foundation_child[1] == _vd.last_child) _vd.last_foundation_child[1] = &cs->next; - _vd.last_child = &cs->next; + if (_vd.last_foundation_child[0] == _vd.last_child) _vd.last_foundation_child[0] = &cs.next; + if (_vd.last_foundation_child[1] == _vd.last_child) _vd.last_foundation_child[1] = &cs.next; + _vd.last_child = &cs.next; } static void AddStringToDraw(int x, int y, StringID string, uint64 params_1, uint64 params_2, Colours colour, uint16 width) { assert(width != 0); - StringSpriteToDraw *ss = _vd.string_sprites_to_draw.Append(); - ss->string = string; - ss->x = x; - ss->y = y; - ss->params[0] = params_1; - ss->params[1] = params_2; - ss->width = width; - ss->colour = colour; + /*C++17: StringSpriteToDraw &ss = */ _vd.string_sprites_to_draw.emplace_back(); + StringSpriteToDraw &ss = _vd.string_sprites_to_draw.back(); + ss.string = string; + ss.x = x; + ss.y = y; + ss.params[0] = params_1; + ss.params[1] = params_2; + ss.width = width; + ss.colour = colour; } @@ -871,7 +879,7 @@ static void DrawSelectionSprite(SpriteID image, PaletteID pal, const TileInfo *t AddTileSpriteToDraw(image, pal, ti->x, ti->y, ti->z + z_offset); } else { /* draw on top of foundation */ - AddChildSpriteToFoundation(image, pal, NULL, foundation_part, 0, -z_offset * ZOOM_LVL_BASE); + AddChildSpriteToFoundation(image, pal, nullptr, foundation_part, 0, -z_offset * ZOOM_LVL_BASE); } } @@ -971,16 +979,115 @@ static void DrawAutorailSelection(const TileInfo *ti, uint autorail_type) DrawSelectionSprite(image, _thd.make_square_red ? PALETTE_SEL_TILE_RED : pal, ti, 7, foundation_part); } +enum TileHighlightType { + THT_NONE, + THT_WHITE, + THT_BLUE, + THT_RED, +}; + +const Station *_viewport_highlight_station; ///< Currently selected station for coverage area highlight +const Town *_viewport_highlight_town; ///< Currently selected town for coverage area highlight + +/** + * Get tile highlight type of coverage area for a given tile. + * @param t Tile that is being drawn + * @return Tile highlight type to draw + */ +static TileHighlightType GetTileHighlightType(TileIndex t) +{ + if (_viewport_highlight_station != nullptr) { + if (IsTileType(t, MP_STATION) && GetStationIndex(t) == _viewport_highlight_station->index) return THT_WHITE; + if (_viewport_highlight_station->TileIsInCatchment(t)) return THT_BLUE; + } + + if (_viewport_highlight_town != nullptr) { + if (IsTileType(t, MP_HOUSE)) { + if (GetTownIndex(t) == _viewport_highlight_town->index) { + TileHighlightType type = THT_RED; + for (const Station *st : _viewport_highlight_town->stations_near) { + if (st->owner != _current_company) continue; + if (st->TileIsInCatchment(t)) return THT_BLUE; + } + return type; + } + } else if (IsTileType(t, MP_STATION)) { + for (const Station *st : _viewport_highlight_town->stations_near) { + if (st->owner != _current_company) continue; + if (GetStationIndex(t) == st->index) return THT_WHITE; + } + } + } + + return THT_NONE; +} + +/** + * Draw tile highlight for coverage area highlight. + * @param *ti TileInfo Tile that is being drawn + * @param tht Highlight type to draw. + */ +static void DrawTileHighlightType(const TileInfo *ti, TileHighlightType tht) +{ + switch (tht) { + default: + case THT_NONE: break; + case THT_WHITE: DrawTileSelectionRect(ti, PAL_NONE); break; + case THT_BLUE: DrawTileSelectionRect(ti, PALETTE_SEL_TILE_BLUE); break; + case THT_RED: DrawTileSelectionRect(ti, PALETTE_TILE_RED_PULSATING); break; + } +} + +/** + * Highlights tiles insede local authority of selected towns. + * @param *ti TileInfo Tile that is being drawn + */ +static void HighlightTownLocalAuthorityTiles(const TileInfo *ti) +{ + /* Going through cases in order of computational time. */ + + if (_town_local_authority_kdtree.Count() == 0) return; + + /* Tile belongs to town regardless of distance from town. */ + if (GetTileType(ti->tile) == MP_HOUSE) { + if (!Town::GetByTile(ti->tile)->show_zone) return; + + DrawTileSelectionRect(ti, PALETTE_CRASH); + return; + } + + /* If the closest town in the highlighted list is far, we can stop searching. */ + TownID tid = _town_local_authority_kdtree.FindNearest(TileX(ti->tile), TileY(ti->tile)); + Town *closest_highlighted_town = Town::Get(tid); + + if (DistanceManhattan(ti->tile, closest_highlighted_town->xy) >= _settings_game.economy.dist_local_authority) return; + + /* Tile is inside of the local autrhority distance of a highlighted town, + but it is possible that a non-highlighted town is even closer. */ + Town *closest_town = ClosestTownFromTile(ti->tile, _settings_game.economy.dist_local_authority); + + if (closest_town->show_zone) { + DrawTileSelectionRect(ti, PALETTE_CRASH); + } + +} + /** * Checks if the specified tile is selected and if so draws selection using correct selectionstyle. * @param *ti TileInfo Tile that is being drawn */ static void DrawTileSelection(const TileInfo *ti) { + /* Highlight tiles insede local authority of selected towns. */ + HighlightTownLocalAuthorityTiles(ti); + /* Draw a red error square? */ bool is_redsq = _thd.redsq == ti->tile; if (is_redsq) DrawTileSelectionRect(ti, PALETTE_TILE_RED_PULSATING); + TileHighlightType tht = GetTileHighlightType(ti->tile); + DrawTileHighlightType(ti, tht); + /* No tile selection active? */ if ((_thd.drawstyle & HT_DRAG_MASK) == HT_NONE) return; @@ -1035,7 +1142,7 @@ draw_inner: } /* Check if it's inside the outer area? */ - if (!is_redsq && _thd.outersize.x > 0 && + if (!is_redsq && (tht == THT_NONE || tht == THT_RED) && _thd.outersize.x > 0 && IsInsideBS(ti->x, _thd.pos.x + _thd.offs.x, _thd.size.x + _thd.outersize.x) && IsInsideBS(ti->y, _thd.pos.y + _thd.offs.y, _thd.size.y + _thd.outersize.y)) { /* Draw a blue rect. */ @@ -1163,8 +1270,8 @@ static void ViewportAddLandscape() _vd.foundation_part = FOUNDATION_PART_NONE; _vd.foundation[0] = -1; _vd.foundation[1] = -1; - _vd.last_foundation_child[0] = NULL; - _vd.last_foundation_child[1] = NULL; + _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); @@ -1215,62 +1322,117 @@ void ViewportAddString(const DrawPixelInfo *dpi, ZoomLevel small_from, const Vie } } -static void ViewportAddTownNames(DrawPixelInfo *dpi) +static Rect ExpandRectWithViewportSignMargins(Rect r, ZoomLevel zoom) { - if (!HasBit(_display_opt, DO_SHOW_TOWN_NAMES) || _game_mode == GM_MENU) return; + /* 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 Town *t; - FOR_ALL_TOWNS(t) { - ViewportAddString(dpi, ZOOM_LVL_OUT_16X, &t->cache.sign, - _settings_client.gui.population_in_label ? STR_VIEWPORT_TOWN_POP : STR_VIEWPORT_TOWN, - STR_VIEWPORT_TOWN_TINY_WHITE, STR_VIEWPORT_TOWN_TINY_BLACK, - t->index, t->cache.population); - } + r.left -= expand_x; + r.right += expand_x; + r.top -= expand_y; + r.bottom += expand_y; + + return r; } - -static void ViewportAddStationNames(DrawPixelInfo *dpi) +static void ViewportAddKdtreeSigns(DrawPixelInfo *dpi) { - if (!(HasBit(_display_opt, DO_SHOW_STATION_NAMES) || HasBit(_display_opt, DO_SHOW_WAYPOINT_NAMES)) || _game_mode == GM_MENU) return; + Rect search_rect{ dpi->left, dpi->top, dpi->left + dpi->width, dpi->top + dpi->height }; + search_rect = ExpandRectWithViewportSignMargins(search_rect, dpi->zoom); + + bool show_stations = HasBit(_display_opt, DO_SHOW_STATION_NAMES) && _game_mode != GM_MENU; + bool show_waypoints = HasBit(_display_opt, DO_SHOW_WAYPOINT_NAMES) && _game_mode != GM_MENU; + bool show_towns = HasBit(_display_opt, DO_SHOW_TOWN_NAMES) && _game_mode != GM_MENU; + 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; - FOR_ALL_BASE_STATIONS(st) { - /* Check whether the base station is a station or a waypoint */ - bool is_station = Station::IsExpected(st); - - /* Don't draw if the display options are disabled */ - if (!HasBit(_display_opt, is_station ? DO_SHOW_STATION_NAMES : DO_SHOW_WAYPOINT_NAMES)) continue; - - /* Don't draw if station is owned by another company and competitor station names are hidden. Stations owned by none are never ignored. */ - if (!HasBit(_display_opt, DO_SHOW_COMPETITOR_SIGNS) && _local_company != st->owner && st->owner != OWNER_NONE) continue; - - ViewportAddString(dpi, ZOOM_LVL_OUT_16X, &st->sign, - is_station ? STR_VIEWPORT_STATION : STR_VIEWPORT_WAYPOINT, - (is_station ? STR_VIEWPORT_STATION : STR_VIEWPORT_WAYPOINT) + 1, STR_NULL, - st->index, st->facilities, (st->owner == OWNER_NONE || !st->IsInUse()) ? COLOUR_GREY : _company_colours[st->owner]); - } -} - - -static void ViewportAddSigns(DrawPixelInfo *dpi) -{ - /* Signs are turned off or are invisible */ - if (!HasBit(_display_opt, DO_SHOW_SIGNS) || IsInvisibilitySet(TO_SIGNS)) return; - const Sign *si; - FOR_ALL_SIGNS(si) { - /* 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 - * companies can leave OWNER_NONE signs after them. */ - if (!HasBit(_display_opt, DO_SHOW_COMPETITOR_SIGNS) && _local_company != si->owner && si->owner != OWNER_DEITY) continue; + /* Collect all the items first and draw afterwards, to ensure layering */ + std::vector stations; + std::vector towns; + std::vector signs; + + _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: + if (!show_stations) break; + 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: + if (!show_waypoints) break; + 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: + if (!show_signs) break; + 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 + * companies can leave OWNER_NONE signs after them. */ + if (!show_competitors && _local_company != si->owner && si->owner != OWNER_DEITY) break; + + signs.push_back(si); + break; + + default: + NOT_REACHED(); + } + }); + + /* Layering order (bottom to top): Town names, signs, stations */ + + for (const auto *t : towns) { + ViewportAddString(dpi, ZOOM_LVL_OUT_16X, &t->cache.sign, + _settings_client.gui.population_in_label ? STR_VIEWPORT_TOWN_POP : STR_VIEWPORT_TOWN, + STR_VIEWPORT_TOWN_TINY_WHITE, STR_VIEWPORT_TOWN_TINY_BLACK, + t->index, t->cache.population); + } + + for (const auto *si : signs) { ViewportAddString(dpi, ZOOM_LVL_OUT_16X, &si->sign, - STR_WHITE_SIGN, - (IsTransparencySet(TO_SIGNS) || si->owner == OWNER_DEITY) ? STR_VIEWPORT_SIGN_SMALL_WHITE : STR_VIEWPORT_SIGN_SMALL_BLACK, STR_NULL, - si->index, 0, (si->owner == OWNER_NONE) ? COLOUR_GREY : (si->owner == OWNER_DEITY ? INVALID_COLOUR : _company_colours[si->owner])); + STR_WHITE_SIGN, + (IsTransparencySet(TO_SIGNS) || si->owner == OWNER_DEITY) ? STR_VIEWPORT_SIGN_SMALL_WHITE : STR_VIEWPORT_SIGN_SMALL_BLACK, STR_NULL, + si->index, 0, (si->owner == OWNER_NONE) ? COLOUR_GREY : (si->owner == OWNER_DEITY ? INVALID_COLOUR : _company_colours[si->owner])); + } + + for (const auto *st : stations) { + if (Station::IsExpected(st)) { + /* Station */ + ViewportAddString(dpi, ZOOM_LVL_OUT_16X, &st->sign, + STR_VIEWPORT_STATION, STR_VIEWPORT_STATION + 1, STR_NULL, + st->index, st->facilities, (st->owner == OWNER_NONE || !st->IsInUse()) ? COLOUR_GREY : _company_colours[st->owner]); + } else { + /* Waypoint */ + ViewportAddString(dpi, ZOOM_LVL_OUT_16X, &st->sign, + STR_VIEWPORT_WAYPOINT, STR_VIEWPORT_WAYPOINT + 1, STR_NULL, + st->index, st->facilities, (st->owner == OWNER_NONE || !st->IsInUse()) ? COLOUR_GREY : _company_colours[st->owner]); + } } } + /** * Update the position of the viewport sign. * @param center the (preferred) center of the viewport sign @@ -1320,7 +1482,7 @@ void ViewportSign::MarkDirty(ZoomLevel maxzoom) const Window *w; FOR_ALL_WINDOWS_FROM_BACK(w) { ViewPort *vp = w->viewport; - if (vp != NULL && vp->zoom <= maxzoom) { + if (vp != nullptr && vp->zoom <= maxzoom) { assert(vp->width != 0); Rect &zl = zoomlevels[vp->zoom]; MarkViewportDirty(vp, zl.left, zl.top, zl.right, zl.bottom); @@ -1330,9 +1492,8 @@ void ViewportSign::MarkDirty(ZoomLevel maxzoom) const static void ViewportDrawTileSprites(const TileSpriteToDrawVector *tstdv) { - const TileSpriteToDraw *tsend = tstdv->End(); - for (const TileSpriteToDraw *ts = tstdv->Begin(); ts != tsend; ++ts) { - DrawSpriteViewport(ts->image, ts->pal, ts->x, ts->y, ts->sub); + for (const TileSpriteToDraw &ts : *tstdv) { + DrawSpriteViewport(ts.image, ts.pal, ts.x, ts.y, ts.sub); } } @@ -1345,8 +1506,8 @@ static bool ViewportSortParentSpritesChecker() /** Sort parent sprites pointer array */ static void ViewportSortParentSprites(ParentSpriteToSortVector *psdv) { - ParentSpriteToDraw **psdvend = psdv->End(); - ParentSpriteToDraw **psd = psdv->Begin(); + auto psdvend = psdv->end(); + auto psd = psdv->begin(); while (psd != psdvend) { ParentSpriteToDraw *ps = *psd; @@ -1357,7 +1518,7 @@ static void ViewportSortParentSprites(ParentSpriteToSortVector *psdv) ps->comparison_done = true; - for (ParentSpriteToDraw **psd2 = psd + 1; psd2 != psdvend; psd2++) { + for (auto psd2 = psd + 1; psd2 != psdvend; psd2++) { ParentSpriteToDraw *ps2 = *psd2; if (ps2->comparison_done) continue; @@ -1392,7 +1553,7 @@ static void ViewportSortParentSprites(ParentSpriteToSortVector *psdv) /* Move ps2 in front of ps */ ParentSpriteToDraw *temp = ps2; - for (ParentSpriteToDraw **psd3 = psd2; psd3 > psd; psd3--) { + for (auto psd3 = psd2; psd3 > psd; psd3--) { *psd3 = *(psd3 - 1); } *psd = temp; @@ -1402,14 +1563,12 @@ static void ViewportSortParentSprites(ParentSpriteToSortVector *psdv) static void ViewportDrawParentSprites(const ParentSpriteToSortVector *psd, const ChildScreenSpriteToDrawVector *csstdv) { - const ParentSpriteToDraw * const *psd_end = psd->End(); - for (const ParentSpriteToDraw * const *it = psd->Begin(); it != psd_end; it++) { - const ParentSpriteToDraw *ps = *it; + for (const ParentSpriteToDraw *ps : *psd) { if (ps->image != SPR_EMPTY_BOUNDING_BOX) DrawSpriteViewport(ps->image, ps->pal, ps->x, ps->y, ps->sub); int child_idx = ps->first_child; while (child_idx >= 0) { - const ChildScreenSpriteToDraw *cs = csstdv->Get(child_idx); + 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); } @@ -1422,9 +1581,7 @@ static void ViewportDrawParentSprites(const ParentSpriteToSortVector *psd, const */ static void ViewportDrawBoundingBoxes(const ParentSpriteToSortVector *psd) { - const ParentSpriteToDraw * const *psd_end = psd->End(); - for (const ParentSpriteToDraw * const *it = psd->Begin(); it != psd_end; it++) { - const ParentSpriteToDraw *ps = *it; + for (const ParentSpriteToDraw *ps : *psd) { Point pt1 = RemapCoords(ps->xmax + 1, ps->ymax + 1, ps->zmax + 1); // top front corner Point pt2 = RemapCoords(ps->xmin , ps->ymax + 1, ps->zmax + 1); // top left corner Point pt3 = RemapCoords(ps->xmax + 1, ps->ymin , ps->zmax + 1); // top right corner @@ -1461,38 +1618,37 @@ static void ViewportDrawDirtyBlocks() static void ViewportDrawStrings(ZoomLevel zoom, const StringSpriteToDrawVector *sstdv) { - const StringSpriteToDraw *ssend = sstdv->End(); - for (const StringSpriteToDraw *ss = sstdv->Begin(); ss != ssend; ++ss) { + for (const StringSpriteToDraw &ss : *sstdv) { TextColour colour = TC_BLACK; - bool small = HasBit(ss->width, 15); - int w = GB(ss->width, 0, 15); - int x = UnScaleByZoom(ss->x, zoom); - int y = UnScaleByZoom(ss->y, zoom); + bool small = HasBit(ss.width, 15); + 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; - SetDParam(0, ss->params[0]); - SetDParam(1, ss->params[1]); + SetDParam(0, ss.params[0]); + SetDParam(1, ss.params[1]); - if (ss->colour != INVALID_COLOUR) { + if (ss.colour != INVALID_COLOUR) { /* Do not draw signs nor station names if they are set invisible */ - if (IsInvisibilitySet(TO_SIGNS) && ss->string != STR_WHITE_SIGN) continue; + if (IsInvisibilitySet(TO_SIGNS) && ss.string != STR_WHITE_SIGN) continue; - if (IsTransparencySet(TO_SIGNS) && ss->string != STR_WHITE_SIGN) { + if (IsTransparencySet(TO_SIGNS) && ss.string != STR_WHITE_SIGN) { /* Don't draw the rectangle. * Real colours need the TC_IS_PALETTE_COLOUR flag. * Otherwise colours from _string_colourmap are assumed. */ - colour = (TextColour)_colour_gradient[ss->colour][6] | TC_IS_PALETTE_COLOUR; + colour = (TextColour)_colour_gradient[ss.colour][6] | TC_IS_PALETTE_COLOUR; } else { /* 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, y + h, 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 + VPSM_LEFT, x + w - 1 - VPSM_RIGHT, y + VPSM_TOP, ss.string, colour, SA_HOR_CENTER); } } @@ -1511,7 +1667,7 @@ void ViewportDoDraw(const ViewPort *vp, int left, int top, int right, int bottom _vd.dpi.left = left & mask; _vd.dpi.top = top & mask; _vd.dpi.pitch = old_dpi->pitch; - _vd.last_child = NULL; + _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; @@ -1521,17 +1677,14 @@ void ViewportDoDraw(const ViewPort *vp, int left, int top, int right, int bottom ViewportAddLandscape(); ViewportAddVehicles(&_vd.dpi); - ViewportAddTownNames(&_vd.dpi); - ViewportAddStationNames(&_vd.dpi); - ViewportAddSigns(&_vd.dpi); + ViewportAddKdtreeSigns(&_vd.dpi); DrawTextEffects(&_vd.dpi); - if (_vd.tile_sprites_to_draw.Length() != 0) ViewportDrawTileSprites(&_vd.tile_sprites_to_draw); + if (_vd.tile_sprites_to_draw.size() != 0) ViewportDrawTileSprites(&_vd.tile_sprites_to_draw); - ParentSpriteToDraw *psd_end = _vd.parent_sprites_to_draw.End(); - for (ParentSpriteToDraw *it = _vd.parent_sprites_to_draw.Begin(); it != psd_end; it++) { - *_vd.parent_sprites_to_sort.Append() = it; + for (auto &psd : _vd.parent_sprites_to_draw) { + _vd.parent_sprites_to_sort.push_back(&psd); } _vp_sprite_sorter(&_vd.parent_sprites_to_sort); @@ -1547,14 +1700,14 @@ void ViewportDoDraw(const ViewPort *vp, int left, int top, int right, int bottom dp.height = UnScaleByZoom(dp.height, zoom); _cur_dpi = &dp; - if (vp->overlay != NULL && vp->overlay->GetCargoMask() != 0 && vp->overlay->GetCompanyMask() != 0) { + if (vp->overlay != nullptr && vp->overlay->GetCargoMask() != 0 && vp->overlay->GetCompanyMask() != 0) { /* translate to window coordinates */ dp.left = x; dp.top = y; vp->overlay->Draw(&dp); } - if (_vd.string_sprites_to_draw.Length() != 0) { + if (_vd.string_sprites_to_draw.size() != 0) { /* translate to world coordinates */ dp.left = UnScaleByZoom(_vd.dpi.left, zoom); dp.top = UnScaleByZoom(_vd.dpi.top, zoom); @@ -1563,11 +1716,11 @@ void ViewportDoDraw(const ViewPort *vp, int left, int top, int right, int bottom _cur_dpi = old_dpi; - _vd.string_sprites_to_draw.Clear(); - _vd.tile_sprites_to_draw.Clear(); - _vd.parent_sprites_to_draw.Clear(); - _vd.parent_sprites_to_sort.Clear(); - _vd.child_screen_sprites_to_draw.Clear(); + _vd.string_sprites_to_draw.clear(); + _vd.tile_sprites_to_draw.clear(); + _vd.parent_sprites_to_draw.clear(); + _vd.parent_sprites_to_sort.clear(); + _vd.child_screen_sprites_to_draw.clear(); } /** @@ -1576,7 +1729,7 @@ void ViewportDoDraw(const ViewPort *vp, int left, int top, int right, int bottom */ static void ViewportDrawChk(const ViewPort *vp, int left, int top, int right, int bottom) { - if (ScaleByZoom(bottom - top, vp->zoom) * ScaleByZoom(right - left, vp->zoom) > 180000 * ZOOM_LVL_BASE * ZOOM_LVL_BASE) { + if ((int64)ScaleByZoom(bottom - top, vp->zoom) * (int64)ScaleByZoom(right - left, vp->zoom) > (int64)(180000 * ZOOM_LVL_BASE * ZOOM_LVL_BASE)) { if ((bottom - top) > (right - left)) { int t = (top + bottom) >> 1; ViewportDrawChk(vp, left, top, right, t); @@ -1755,7 +1908,7 @@ void MarkAllViewportsDirty(int left, int top, int right, int bottom) Window *w; FOR_ALL_WINDOWS_FROM_BACK(w) { ViewPort *vp = w->viewport; - if (vp != NULL) { + if (vp != nullptr) { assert(vp->width != 0); MarkViewportDirty(vp, left, top, right, bottom); } @@ -1766,7 +1919,7 @@ void ConstrainAllViewportsZoom() { Window *w; FOR_ALL_WINDOWS_FROM_FRONT(w) { - if (w->viewport == NULL) continue; + if (w->viewport == nullptr) continue; ZoomLevel zoom = static_cast(Clamp(w->viewport->zoom, _settings_client.gui.zoom_min, _settings_client.gui.zoom_max)); if (zoom != w->viewport->zoom) { @@ -1931,75 +2084,187 @@ static bool CheckClickOnViewportSign(const ViewPort *vp, int x, int y, const Vie 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); - x = ScaleByZoom(x - vp->left, vp->zoom) + vp->virtual_left; - y = ScaleByZoom(y - vp->top, vp->zoom) + vp->virtual_top; - return y >= sign->top && y < sign->top + sign_height && x >= sign->center - sign_half_width && x < sign->center + sign_half_width; } -static bool CheckClickOnTown(const ViewPort *vp, int x, int y) + +/** + * Check whether any viewport sign was clicked, and dispatch the click. + * @param vp the clicked viewport + * @param x X position of click + * @param y Y position of click + * @return true if the sign was hit + */ +static bool CheckClickOnViewportSign(const ViewPort *vp, int x, int y) { - if (!HasBit(_display_opt, DO_SHOW_TOWN_NAMES)) return false; + if (_game_mode == GM_MENU) return false; - const Town *t; - FOR_ALL_TOWNS(t) { - if (CheckClickOnViewportSign(vp, x, y, &t->cache.sign)) { - ShowTownViewWindow(t->index); - return true; + x = ScaleByZoom(x - vp->left, vp->zoom) + vp->virtual_left; + y = ScaleByZoom(y - vp->top, vp->zoom) + vp->virtual_top; + + Rect search_rect{ x - 1, y - 1, x + 1, y + 1 }; + search_rect = ExpandRectWithViewportSignMargins(search_rect, vp->zoom); + + bool show_stations = HasBit(_display_opt, DO_SHOW_STATION_NAMES) && !IsInvisibilitySet(TO_SIGNS); + bool show_waypoints = HasBit(_display_opt, DO_SHOW_WAYPOINT_NAMES) && !IsInvisibilitySet(TO_SIGNS); + bool show_towns = HasBit(_display_opt, DO_SHOW_TOWN_NAMES); + bool show_signs = HasBit(_display_opt, DO_SHOW_SIGNS) && !IsInvisibilitySet(TO_SIGNS); + bool show_competitors = HasBit(_display_opt, DO_SHOW_COMPETITOR_SIGNS); + + /* Topmost of each type that was hit */ + BaseStation *st = nullptr, *last_st = nullptr; + Town *t = nullptr, *last_t = nullptr; + Sign *si = nullptr, *last_si = nullptr; + + /* See ViewportAddKdtreeSigns() for details on the search logic */ + _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: + if (!show_stations) break; + st = BaseStation::Get(item.id.station); + if (!show_competitors && _local_company != st->owner && st->owner != OWNER_NONE) break; + if (CheckClickOnViewportSign(vp, x, y, &st->sign)) last_st = st; + break; + + case ViewportSignKdtreeItem::VKI_WAYPOINT: + if (!show_waypoints) break; + st = BaseStation::Get(item.id.station); + if (!show_competitors && _local_company != st->owner && st->owner != OWNER_NONE) break; + if (CheckClickOnViewportSign(vp, x, y, &st->sign)) last_st = st; + break; + + case ViewportSignKdtreeItem::VKI_TOWN: + if (!show_towns) break; + t = Town::Get(item.id.town); + if (CheckClickOnViewportSign(vp, x, y, &t->cache.sign)) last_t = t; + break; + + case ViewportSignKdtreeItem::VKI_SIGN: + if (!show_signs) break; + si = Sign::Get(item.id.sign); + if (!show_competitors && _local_company != si->owner && si->owner != OWNER_DEITY) break; + if (CheckClickOnViewportSign(vp, x, y, &si->sign)) last_si = si; + break; + + default: + NOT_REACHED(); } - } + }); - return false; -} - -static bool CheckClickOnStation(const ViewPort *vp, int x, int y) -{ - if (!(HasBit(_display_opt, DO_SHOW_STATION_NAMES) || HasBit(_display_opt, DO_SHOW_WAYPOINT_NAMES)) || IsInvisibilitySet(TO_SIGNS)) return false; - - const BaseStation *st; - FOR_ALL_BASE_STATIONS(st) { - /* Check whether the base station is a station or a waypoint */ - bool is_station = Station::IsExpected(st); - - /* Don't check if the display options are disabled */ - if (!HasBit(_display_opt, is_station ? DO_SHOW_STATION_NAMES : DO_SHOW_WAYPOINT_NAMES)) continue; - - /* Don't check if competitor signs are not shown and the sign isn't owned by the local company */ - if (!HasBit(_display_opt, DO_SHOW_COMPETITOR_SIGNS) && _local_company != st->owner && st->owner != OWNER_NONE) continue; - - if (CheckClickOnViewportSign(vp, x, y, &st->sign)) { - if (is_station) { - ShowStationViewWindow(st->index); - } else { - ShowWaypointWindow(Waypoint::From(st)); - } - return true; + /* Select which hit to handle based on priority */ + if (last_st != nullptr) { + if (Station::IsExpected(last_st)) { + ShowStationViewWindow(last_st->index); + } else { + ShowWaypointWindow(Waypoint::From(last_st)); } + return true; + } else if (last_t != nullptr) { + ShowTownViewWindow(last_t->index); + return true; + } else if (last_si != nullptr) { + HandleClickOnSign(last_si); + return true; + } else { + return false; } - - return false; } -static bool CheckClickOnSign(const ViewPort *vp, int x, int y) +ViewportSignKdtreeItem ViewportSignKdtreeItem::MakeStation(StationID id) { - /* Signs are turned off, or they are transparent and invisibility is ON, or company is a spectator */ - if (!HasBit(_display_opt, DO_SHOW_SIGNS) || IsInvisibilitySet(TO_SIGNS) || _local_company == COMPANY_SPECTATOR) return false; + ViewportSignKdtreeItem item; + item.type = VKI_STATION; + item.id.station = id; - const Sign *si; - FOR_ALL_SIGNS(si) { - /* If competitor signs are hidden, don't check signs that aren't owned by local company */ - if (!HasBit(_display_opt, DO_SHOW_COMPETITOR_SIGNS) && _local_company != si->owner && si->owner != OWNER_DEITY) continue; - if (si->owner == OWNER_DEITY && _game_mode != GM_EDITOR) continue; + const Station *st = Station::Get(id); + assert(st->sign.kdtree_valid); + item.center = st->sign.center; + item.top = st->sign.top; - if (CheckClickOnViewportSign(vp, x, y, &si->sign)) { - HandleClickOnSign(si); - return true; - } + /* Assume the sign can be a candidate for drawing, so measure its width */ + _viewport_sign_maxwidth = max(_viewport_sign_maxwidth, st->sign.width_normal); + + return item; +} + +ViewportSignKdtreeItem ViewportSignKdtreeItem::MakeWaypoint(StationID id) +{ + ViewportSignKdtreeItem item; + item.type = VKI_WAYPOINT; + item.id.station = id; + + const Waypoint *st = Waypoint::Get(id); + assert(st->sign.kdtree_valid); + item.center = st->sign.center; + item.top = st->sign.top; + + /* Assume the sign can be a candidate for drawing, so measure its width */ + _viewport_sign_maxwidth = max(_viewport_sign_maxwidth, st->sign.width_normal); + + return item; +} + +ViewportSignKdtreeItem ViewportSignKdtreeItem::MakeTown(TownID id) +{ + ViewportSignKdtreeItem item; + item.type = VKI_TOWN; + item.id.town = id; + + const Town *town = Town::Get(id); + assert(town->cache.sign.kdtree_valid); + item.center = town->cache.sign.center; + item.top = town->cache.sign.top; + + /* Assume the sign can be a candidate for drawing, so measure its width */ + _viewport_sign_maxwidth = max(_viewport_sign_maxwidth, town->cache.sign.width_normal); + + return item; +} + +ViewportSignKdtreeItem ViewportSignKdtreeItem::MakeSign(SignID id) +{ + ViewportSignKdtreeItem item; + item.type = VKI_SIGN; + item.id.sign = id; + + const Sign *sign = Sign::Get(id); + assert(sign->sign.kdtree_valid); + item.center = sign->sign.center; + item.top = sign->sign.top; + + /* Assume the sign can be a candidate for drawing, so measure its width */ + _viewport_sign_maxwidth = max(_viewport_sign_maxwidth, sign->sign.width_normal); + + return item; +} + +void RebuildViewportKdtree() +{ + /* Reset biggest size sign seen */ + _viewport_sign_maxwidth = 0; + + std::vector items; + items.reserve(BaseStation::GetNumItems() + Town::GetNumItems() + Sign::GetNumItems()); + + for (const Station *st : Station::Iterate()) { + if (st->sign.kdtree_valid) items.push_back(ViewportSignKdtreeItem::MakeStation(st->index)); } - return false; + for (const Waypoint *wp : Waypoint::Iterate()) { + if (wp->sign.kdtree_valid) items.push_back(ViewportSignKdtreeItem::MakeWaypoint(wp->index)); + } + + for (const Town *town : Town::Iterate()) { + if (town->cache.sign.kdtree_valid) items.push_back(ViewportSignKdtreeItem::MakeTown(town->index)); + } + + for (const Sign *sign : Sign::Iterate()) { + if (sign->sign.kdtree_valid) items.push_back(ViewportSignKdtreeItem::MakeSign(sign->index)); + } + + _viewport_sign_kdtree.Build(items.begin(), items.end()); } @@ -2030,7 +2295,7 @@ static void PlaceObject() _tile_fract_coords.y = pt.y & TILE_UNIT_MASK; w = _thd.GetCallbackWnd(); - if (w != NULL) w->OnPlaceObject(pt, TileVirtXY(pt.x, pt.y)); + if (w != nullptr) w->OnPlaceObject(pt, TileVirtXY(pt.x, pt.y)); } @@ -2055,7 +2320,7 @@ bool HandleViewportMouseUp(const ViewPort *vp, int x, int y) const Vehicle *v = CheckClickOnVehicle(vp, x, y); if (_thd.place_mode & HT_VEHICLE) { - if (v != NULL && VehicleClicked(v)) return true; + if (v != nullptr && VehicleClicked(v)) return true; } /* Vehicle placement mode already handled above. */ @@ -2064,12 +2329,10 @@ bool HandleViewportMouseUp(const ViewPort *vp, int x, int y) return true; } - if (CheckClickOnTown(vp, x, y)) return true; - if (CheckClickOnStation(vp, x, y)) return true; - if (CheckClickOnSign(vp, x, y)) return true; + if (CheckClickOnViewportSign(vp, x, y)) return true; bool result = CheckClickOnLandscape(vp, x, y); - if (v != NULL) { + if (v != nullptr) { DEBUG(misc, 2, "Vehicle %d (index %d) at %p", v->unitnumber, v->index, v); if (IsCompanyBuildableVehicleType(v)) { v = v->First(); @@ -2086,7 +2349,7 @@ bool HandleViewportMouseUp(const ViewPort *vp, int x, int y) void RebuildViewportOverlay(Window *w) { - if (w->viewport->overlay != NULL && + if (w->viewport->overlay != nullptr && w->viewport->overlay->GetCompanyMask() != 0 && w->viewport->overlay->GetCargoMask() != 0) { w->viewport->overlay->SetDirty(); @@ -2220,7 +2483,7 @@ bool TileHighlightData::IsDraggingDiagonal() /** * Get the window that started the current highlighting. - * @return The window that requested the current tile highlighting, or \c NULL if not available. + * @return The window that requested the current tile highlighting, or \c nullptr if not available. */ Window *TileHighlightData::GetCallbackWnd() { @@ -2241,6 +2504,8 @@ void UpdateTileSelection() int x1; int y1; + if (_thd.freeze) return; + HighLightStyle new_drawstyle = HT_NONE; bool new_diagonal = false; @@ -3013,7 +3278,7 @@ EventState VpHandlePlaceSizingDrag() /* stop drag mode if the window has been closed */ Window *w = _thd.GetCallbackWnd(); - if (w == NULL) { + if (w == nullptr) { ResetObjectToPlace(); return ES_HANDLED; } @@ -3099,7 +3364,7 @@ void SetObjectToPlace(CursorID icon, PaletteID pal, HighLightStyle mode, WindowC * this function might in some cases reset the newly set object to * place or not properly reset the original selection. */ _thd.window_class = WC_INVALID; - if (w != NULL) { + if (w != nullptr) { w->OnPlaceObjectAbort(); HideMeasurementTooltips(); } @@ -3189,7 +3454,7 @@ void InitializeSpriteSorter() break; } } - assert(_vp_sprite_sorter != NULL); + assert(_vp_sprite_sorter != nullptr); } /** @@ -3212,12 +3477,8 @@ CommandCost CmdScrollViewport(TileIndex tile, DoCommandFlag flags, uint32 p1, ui if (_local_company != (CompanyID)p2) return CommandCost(); break; case VST_CLIENT: -#ifdef ENABLE_NETWORK if (_network_own_client_id != (ClientID)p2) return CommandCost(); break; -#else - return CommandCost(); -#endif default: return CMD_ERROR; } @@ -3228,3 +3489,65 @@ CommandCost CmdScrollViewport(TileIndex tile, DoCommandFlag flags, uint32 p1, ui } return CommandCost(); } + +static void MarkCatchmentTilesDirty() +{ + if (_viewport_highlight_town != nullptr) { + MarkWholeScreenDirty(); + return; + } + if (_viewport_highlight_station != nullptr) { + if (_viewport_highlight_station->catchment_tiles.tile == INVALID_TILE) { + MarkWholeScreenDirty(); + _viewport_highlight_station = nullptr; + } else { + BitmapTileIterator it(_viewport_highlight_station->catchment_tiles); + for (TileIndex tile = it; tile != INVALID_TILE; tile = ++it) { + MarkTileDirtyByTile(tile); + } + } + } +} + +/** + * Select or deselect station for coverage area highlight. + * Selecting a station will deselect a town. + * @param *st Station in question + * @param sel Select or deselect given station + */ +void SetViewportCatchmentStation(const Station *st, bool sel) +{ + if (_viewport_highlight_station != nullptr) SetWindowDirty(WC_STATION_VIEW, _viewport_highlight_station->index); + if (_viewport_highlight_town != nullptr) SetWindowDirty(WC_TOWN_VIEW, _viewport_highlight_town->index); + if (sel && _viewport_highlight_station != st) { + MarkCatchmentTilesDirty(); + _viewport_highlight_station = st; + _viewport_highlight_town = nullptr; + MarkCatchmentTilesDirty(); + } else if (!sel && _viewport_highlight_station == st) { + MarkCatchmentTilesDirty(); + _viewport_highlight_station = nullptr; + } + if (_viewport_highlight_station != nullptr) SetWindowDirty(WC_STATION_VIEW, _viewport_highlight_station->index); +} + +/** + * Select or deselect town for coverage area highlight. + * Selecting a town will deselect a station. + * @param *t Town in question + * @param sel Select or deselect given town + */ +void SetViewportCatchmentTown(const Town *t, bool sel) +{ + if (_viewport_highlight_town != nullptr) SetWindowDirty(WC_TOWN_VIEW, _viewport_highlight_town->index); + if (_viewport_highlight_station != nullptr) SetWindowDirty(WC_STATION_VIEW, _viewport_highlight_station->index); + if (sel && _viewport_highlight_town != t) { + _viewport_highlight_station = nullptr; + _viewport_highlight_town = t; + MarkWholeScreenDirty(); + } else if (!sel && _viewport_highlight_town == t) { + _viewport_highlight_town = nullptr; + MarkWholeScreenDirty(); + } + if (_viewport_highlight_town != nullptr) SetWindowDirty(WC_TOWN_VIEW, _viewport_highlight_town->index); +} diff --git a/src/viewport_func.h b/src/viewport_func.h index 1ae5e20a0b..6958b28b02 100644 --- a/src/viewport_func.h +++ b/src/viewport_func.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. @@ -34,6 +32,7 @@ void MarkAllViewportsDirty(int left, int top, int right, int bottom); bool DoZoomInOutWindow(ZoomStateChange how, Window *w); void ZoomInOrOutToCursorWindow(bool in, Window * w); Point GetTileZoomCenterWindow(bool in, Window * w); +void FixTitleGameZoom(); void HandleZoomMessage(Window *w, const ViewPort *vp, byte widget_zoom_in, byte widget_zoom_out); /** @@ -49,10 +48,10 @@ static inline void MaxZoomInOut(ZoomStateChange how, Window *w) void OffsetGroundSprite(int x, int y); -void DrawGroundSprite(SpriteID image, PaletteID pal, const SubSprite *sub = NULL, 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 = NULL, 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 = NULL); -void AddChildSpriteScreen(SpriteID image, PaletteID pal, int x, int y, bool transparent = false, const SubSprite *sub = NULL, bool scale = true); +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 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); @@ -76,6 +75,7 @@ bool ScrollMainWindowToTile(TileIndex tile, bool instant = false); bool ScrollMainWindowTo(int x, int y, int z = -1, bool instant = false); void UpdateAllVirtCoords(); +void ClearAllCachedNames(); extern Point _tile_fract_coords; @@ -94,6 +94,11 @@ static inline void MarkTileDirtyByTile(TileIndex tile, int bridge_level_offset = Point GetViewportStationMiddle(const ViewPort *vp, const Station *st); +struct Station; +struct Town; + +void SetViewportCatchmentStation(const Station *st, bool sel); +void SetViewportCatchmentTown(const Town *t, bool sel); void ToolbarSelectLastTool(); #endif /* VIEWPORT_FUNC_H */ diff --git a/src/viewport_gui.cpp b/src/viewport_gui.cpp index 3f08fccc36..cd66ce0d08 100644 --- a/src/viewport_gui.cpp +++ b/src/viewport_gui.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. @@ -77,7 +75,7 @@ public: this->viewport->dest_scrollpos_y = this->viewport->scrollpos_y; } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { switch (widget) { case WID_EV_CAPTION: @@ -87,7 +85,7 @@ public: } } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_EV_ZOOM_IN: DoZoomInOutWindow(ZOOM_IN, this); break; @@ -117,15 +115,15 @@ public: } } - virtual void OnResize() + void OnResize() override { - if (this->viewport != NULL) { + if (this->viewport != nullptr) { NWidgetViewport *nvp = this->GetWidget(WID_EV_VIEWPORT); nvp->UpdateViewportCoordinates(this); } } - virtual void OnScroll(Point delta) + void OnScroll(Point delta) override { this->viewport->scrollpos_x += ScaleByZoom(delta.x, this->viewport->zoom); this->viewport->scrollpos_y += ScaleByZoom(delta.y, this->viewport->zoom); @@ -133,7 +131,7 @@ public: this->viewport->dest_scrollpos_y = this->viewport->scrollpos_y; } - virtual void OnMouseWheel(int wheel) + void OnMouseWheel(int wheel) override { if (_settings_client.gui.scrollwheel_scrolling != 2) { ZoomInOrOutToCursorWindow(wheel < 0, this); @@ -145,7 +143,7 @@ public: * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; /* Only handle zoom message if intended for us (msg ZOOM_IN/ZOOM_OUT) */ @@ -169,7 +167,7 @@ void ShowExtraViewPortWindow(TileIndex tile) int i = 0; /* find next free window number for extra viewport */ - while (FindWindowById(WC_EXTRA_VIEW_PORT, i) != NULL) i++; + while (FindWindowById(WC_EXTRA_VIEW_PORT, i) != nullptr) i++; new ExtraViewportWindow(&_extra_view_port_desc, i, tile); } diff --git a/src/viewport_kdtree.h b/src/viewport_kdtree.h new file mode 100644 index 0000000000..93344a5e63 --- /dev/null +++ b/src/viewport_kdtree.h @@ -0,0 +1,83 @@ +/* +* 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 town_kdtree.h Declarations for accessing the k-d tree of towns */ + +#ifndef VIEWPORT_KDTREE_H +#define VIEWPORT_KDTREE_H + +#include "core/kdtree.hpp" +#include "viewport_type.h" +#include "station_base.h" +#include "town_type.h" +#include "signs_base.h" + +struct ViewportSignKdtreeItem { + enum ItemType : uint16 { + VKI_STATION, + VKI_WAYPOINT, + VKI_TOWN, + VKI_SIGN, + }; + ItemType type; + union { + StationID station; + TownID town; + SignID sign; + } id; + int32 center; + int32 top; + + bool operator== (const ViewportSignKdtreeItem &other) const + { + if (this->type != other.type) return false; + switch (this->type) { + case VKI_STATION: + case VKI_WAYPOINT: + return this->id.station == other.id.station; + case VKI_TOWN: + return this->id.town == other.id.town; + case VKI_SIGN: + return this->id.sign == other.id.sign; + default: + NOT_REACHED(); + } + } + + bool operator< (const ViewportSignKdtreeItem &other) const + { + if (this->type != other.type) return this->type < other.type; + switch (this->type) { + case VKI_STATION: + case VKI_WAYPOINT: + return this->id.station < other.id.station; + case VKI_TOWN: + return this->id.town < other.id.town; + case VKI_SIGN: + return this->id.sign < other.id.sign; + default: + NOT_REACHED(); + } + } + + static ViewportSignKdtreeItem MakeStation(StationID id); + static ViewportSignKdtreeItem MakeWaypoint(StationID id); + static ViewportSignKdtreeItem MakeTown(TownID id); + static ViewportSignKdtreeItem MakeSign(SignID id); +}; + +inline int32 Kdtree_ViewportSignXYFunc(const ViewportSignKdtreeItem &item, int dim) +{ + return (dim == 0) ? item.center : item.top; +} + +typedef Kdtree ViewportSignKdtree; +extern ViewportSignKdtree _viewport_sign_kdtree; + +void RebuildViewportKdtree(); + +#endif diff --git a/src/viewport_sprite_sorter.h b/src/viewport_sprite_sorter.h index 324ece3020..d9948b7c22 100644 --- a/src/viewport_sprite_sorter.h +++ b/src/viewport_sprite_sorter.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. @@ -41,7 +39,7 @@ struct ParentSpriteToDraw { bool comparison_done; ///< Used during sprite sorting: true if sprite has been compared with all other sprites }; -typedef SmallVector ParentSpriteToSortVector; +typedef std::vector ParentSpriteToSortVector; /** Type for method for checking whether a viewport sprite sorter exists. */ typedef bool (*VpSorterChecker)(); diff --git a/src/viewport_sprite_sorter_sse4.cpp b/src/viewport_sprite_sorter_sse4.cpp index fb78c51c86..46068c41d2 100644 --- a/src/viewport_sprite_sorter_sse4.cpp +++ b/src/viewport_sprite_sorter_sse4.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. @@ -29,8 +27,8 @@ void ViewportSortParentSpritesSSE41(ParentSpriteToSortVector *psdv) { const __m128i mask_ptest = _mm_setr_epi8(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0); - ParentSpriteToDraw ** const psdvend = psdv->End(); - ParentSpriteToDraw **psd = psdv->Begin(); + auto const psdvend = psdv->end(); + auto psd = psdv->begin(); while (psd != psdvend) { ParentSpriteToDraw * const ps = *psd; @@ -41,7 +39,7 @@ void ViewportSortParentSpritesSSE41(ParentSpriteToSortVector *psdv) ps->comparison_done = true; - for (ParentSpriteToDraw **psd2 = psd + 1; psd2 != psdvend; psd2++) { + for (auto psd2 = psd + 1; psd2 != psdvend; psd2++) { ParentSpriteToDraw * const ps2 = *psd2; if (ps2->comparison_done) continue; @@ -85,7 +83,7 @@ void ViewportSortParentSpritesSSE41(ParentSpriteToSortVector *psdv) /* Move ps2 in front of ps */ ParentSpriteToDraw * const temp = ps2; - for (ParentSpriteToDraw **psd3 = psd2; psd3 > psd; psd3--) { + for (auto psd3 = psd2; psd3 > psd; psd3--) { *psd3 = *(psd3 - 1); } *psd = temp; diff --git a/src/viewport_type.h b/src/viewport_type.h index d2adff8a63..047d7c6cba 100644 --- a/src/viewport_type.h +++ b/src/viewport_type.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. @@ -22,7 +20,7 @@ class LinkGraphOverlay; * Data structure for viewport, display of a part of the world */ struct ViewPort { - int left; ///< Screen coordinate left egde of the viewport + int left; ///< Screen coordinate left edge of the viewport int top; ///< Screen coordinate top edge of the viewport int width; ///< Screen width of the viewport int height; ///< Screen height of the viewport @@ -55,6 +53,26 @@ struct ViewportSign { void MarkDirty(ZoomLevel maxzoom = ZOOM_LVL_MAX) const; }; +/** Specialised ViewportSign that tracks whether it is valid for entering into a Kdtree */ +struct TrackedViewportSign : ViewportSign { + bool kdtree_valid; ///< Are the sign data valid for use with the _viewport_sign_kdtree? + + /** + * Update the position of the viewport sign. + * Note that this function hides the base class function. + */ + void UpdatePosition(int center, int top, StringID str, StringID str_small = STR_NULL) + { + this->kdtree_valid = true; + this->ViewportSign::UpdatePosition(center, top, str, str_small); + } + + + TrackedViewportSign() : kdtree_valid{ false } + { + } +}; + /** * Directions of zooming. * @see DoZoomInOutWindow @@ -122,6 +140,7 @@ enum ViewportDragDropSelectionProcess { DDSP_BUILD_TRUCKSTOP, ///< Road stop placement (trucks) DDSP_REMOVE_BUSSTOP, ///< Road stop removal (buses) DDSP_REMOVE_TRUCKSTOP, ///< Road stop removal (trucks) + DDSP_CONVERT_ROAD, ///< Road conversion /* Single tile dragging */ DDSP_SINGLE_TILE, ///< Single tile actions (build industry, town, etc.) diff --git a/src/void_cmd.cpp b/src/void_cmd.cpp index a2a45e7227..cf159d69cc 100644 --- a/src/void_cmd.cpp +++ b/src/void_cmd.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. @@ -28,7 +26,7 @@ static void DrawTile_Void(TileInfo *ti) static int GetSlopePixelZ_Void(TileIndex tile, uint x, uint y) { - /* This function may be called on tiles outside the map, don't asssume + /* This function may be called on tiles outside the map, don't assume * that 'tile' is a valid tile index. See GetSlopePixelZOutsideMap. */ int z; Slope tileh = GetTilePixelSlopeOutsideMap(x >> 4, y >> 4, &z); @@ -77,15 +75,15 @@ extern const TileTypeProcs _tile_type_void_procs = { DrawTile_Void, // draw_tile_proc GetSlopePixelZ_Void, // get_slope_z_proc ClearTile_Void, // clear_tile_proc - NULL, // add_accepted_cargo_proc + nullptr, // add_accepted_cargo_proc GetTileDesc_Void, // get_tile_desc_proc GetTileTrackStatus_Void, // get_tile_track_status_proc - NULL, // click_tile_proc - NULL, // animate_tile_proc + nullptr, // click_tile_proc + nullptr, // animate_tile_proc TileLoop_Void, // tile_loop_proc ChangeTileOwner_Void, // change_tile_owner_proc - NULL, // add_produced_cargo_proc - NULL, // vehicle_enter_tile_proc + nullptr, // add_produced_cargo_proc + nullptr, // vehicle_enter_tile_proc GetFoundation_Void, // get_foundation_proc TerraformTile_Void, // terraform_tile_proc }; diff --git a/src/void_map.h b/src/void_map.h index 5ccc4e9d7d..415e0a5803 100644 --- a/src/void_map.h +++ b/src/void_map.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/water.h b/src/water.h index 1b804720ff..27c3339c18 100644 --- a/src/water.h +++ b/src/water.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. @@ -38,6 +36,7 @@ void DrawWaterClassGround(const struct TileInfo *ti); void DrawShoreTile(Slope tileh); void MakeWaterKeepingClass(TileIndex tile, Owner o); +void CheckForDockingTile(TileIndex t); bool RiverModifyDesertZone(TileIndex tile, void *data); static const uint RIVER_OFFSET_DESERT_DISTANCE = 5; ///< Circular tile search radius to create non-desert around a river tile. diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp index 03b321e686..d1ab57f347 100644 --- a/src/water_cmd.cpp +++ b/src/water_cmd.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. @@ -39,6 +37,7 @@ #include "company_base.h" #include "company_gui.h" #include "newgrf_generic.h" +#include "industry.h" #include "table/strings.h" @@ -148,6 +147,8 @@ CommandCost CmdBuildShipDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, ui MakeShipDepot(tile, _current_company, depot->index, DEPOT_PART_NORTH, axis, wc1); MakeShipDepot(tile2, _current_company, depot->index, DEPOT_PART_SOUTH, axis, wc2); + CheckForDockingTile(tile); + CheckForDockingTile(tile2); MarkTileDirtyByTile(tile); MarkTileDirtyByTile(tile2); MakeDefaultName(depot); @@ -156,6 +157,48 @@ CommandCost CmdBuildShipDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, ui return cost; } +bool IsPossibleDockingTile(TileIndex t) +{ + assert(IsValidTile(t)); + switch (GetTileType(t)) { + case MP_WATER: + if (IsLock(t) && GetLockPart(t) == LOCK_PART_MIDDLE) return false; + FALLTHROUGH; + case MP_RAILWAY: + case MP_STATION: + case MP_TUNNELBRIDGE: + return TrackStatusToTrackBits(GetTileTrackStatus(t, TRANSPORT_WATER, 0)) != TRACK_BIT_NONE; + + default: + return false; + } +} + +/** + * Mark the supplied tile as a docking tile if it is suitable for docking. + * Tiles surrounding the tile are tested to be docks with correct orientation. + * @param t Tile to test. + */ +void CheckForDockingTile(TileIndex t) +{ + for (DiagDirection d = DIAGDIR_BEGIN; d != DIAGDIR_END; d++) { + TileIndex tile = t + TileOffsByDiagDir(d); + if (!IsValidTile(tile)) continue; + + if (IsDockTile(tile) && IsValidDockingDirectionForDock(tile, d)) { + Station::GetByTile(tile)->docking_station.Add(t); + SetDockingTile(t, true); + } + if (IsTileType(tile, MP_INDUSTRY)) { + Station *st = Industry::GetByTile(tile)->neutral_station; + if (st != nullptr) { + st->docking_station.Add(t); + SetDockingTile(t, true); + } + } + } +} + void MakeWaterKeepingClass(TileIndex tile, Owner o) { WaterClass wc = GetWaterClass(tile); @@ -168,7 +211,7 @@ void MakeWaterKeepingClass(TileIndex tile, Owner o) if (wc == WATER_CLASS_CANAL) { /* If we clear the canal, we have to remove it from the infrastructure count as well. */ Company *c = Company::GetIfValid(o); - if (c != NULL) { + if (c != nullptr) { c->infrastructure.water--; DirtyCompanyInfrastructureWindows(c->index); } @@ -185,7 +228,7 @@ void MakeWaterKeepingClass(TileIndex tile, Owner o) if (wc == WATER_CLASS_SEA && z > 0) { /* Update company infrastructure count. */ Company *c = Company::GetIfValid(o); - if (c != NULL) { + if (c != nullptr) { c->infrastructure.water++; DirtyCompanyInfrastructureWindows(c->index); } @@ -204,6 +247,7 @@ void MakeWaterKeepingClass(TileIndex tile, Owner o) default: break; } + if (wc != WATER_CLASS_INVALID) CheckForDockingTile(tile); MarkTileDirtyByTile(tile); } @@ -227,7 +271,7 @@ static CommandCost RemoveShipDepot(TileIndex tile, DoCommandFlag flags) delete Depot::GetByTile(tile); Company *c = Company::GetIfValid(GetTileOwner(tile)); - if (c != NULL) { + if (c != nullptr) { c->infrastructure.water -= 2 * LOCK_DEPOT_TILE_FACTOR; DirtyCompanyInfrastructureWindows(c->index); } @@ -293,7 +337,7 @@ static CommandCost DoBuildLock(TileIndex tile, DiagDirection dir, DoCommandFlag if (flags & DC_EXEC) { /* Update company infrastructure counts. */ Company *c = Company::GetIfValid(_current_company); - if (c != NULL) { + if (c != nullptr) { /* Counts for the water. */ if (!IsWaterTile(tile - delta)) c->infrastructure.water++; if (!IsWaterTile(tile + delta)) c->infrastructure.water++; @@ -303,6 +347,8 @@ static CommandCost DoBuildLock(TileIndex tile, DiagDirection dir, DoCommandFlag } MakeLock(tile, _current_company, dir, wc_lower, wc_upper, wc_middle); + CheckForDockingTile(tile - delta); + CheckForDockingTile(tile + delta); MarkTileDirtyByTile(tile); MarkTileDirtyByTile(tile - delta); MarkTileDirtyByTile(tile + delta); @@ -338,7 +384,7 @@ static CommandCost RemoveLock(TileIndex tile, DoCommandFlag flags) if (flags & DC_EXEC) { /* Remove middle part from company infrastructure count. */ Company *c = Company::GetIfValid(GetTileOwner(tile)); - if (c != NULL) { + if (c != nullptr) { c->infrastructure.water -= 3 * LOCK_DEPOT_TILE_FACTOR; // three parts of the lock. DirtyCompanyInfrastructureWindows(c->index); } @@ -428,7 +474,7 @@ CommandCost CmdBuildCanal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 MakeRiver(tile, Random()); if (_game_mode == GM_EDITOR) { TileIndex tile2 = tile; - CircularTileSearch(&tile2, RIVER_OFFSET_DESERT_DISTANCE, RiverModifyDesertZone, NULL); + CircularTileSearch(&tile2, RIVER_OFFSET_DESERT_DISTANCE, RiverModifyDesertZone, nullptr); } break; @@ -449,6 +495,7 @@ CommandCost CmdBuildCanal(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 } MarkTileDirtyByTile(tile); MarkCanalsAndRiversAroundDirty(tile); + CheckForDockingTile(tile); } cost.AddCost(_price[PR_BUILD_CANAL]); @@ -489,8 +536,10 @@ 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); @@ -504,8 +553,10 @@ 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]); @@ -931,11 +982,11 @@ static void FloodVehicle(Vehicle *v) * Flood a vehicle if we are allowed to flood it, i.e. when it is on the ground. * @param v The vehicle to test for flooding. * @param data The z of level to flood. - * @return NULL as we always want to remove everything. + * @return nullptr as we always want to remove everything. */ static Vehicle *FloodVehicleProc(Vehicle *v, void *data) { - if ((v->vehstatus & VS_CRASHED) != 0) return NULL; + if ((v->vehstatus & VS_CRASHED) != 0) return nullptr; switch (v->type) { default: break; @@ -963,7 +1014,7 @@ static Vehicle *FloodVehicleProc(Vehicle *v, void *data) } } - return NULL; + return nullptr; } /** @@ -1044,7 +1095,7 @@ void DoFloodTile(TileIndex target) bool flooded = false; // Will be set to true if something is changed. - Backup cur_company(_current_company, OWNER_WATER, FILE_LINE); + Backup cur_company(_current_company, OWNER_WATER, FILE_LINE); Slope tileh = GetTileSlope(target); if (tileh != SLOPE_FLAT) { @@ -1095,6 +1146,8 @@ void DoFloodTile(TileIndex target) /* update signals if needed */ UpdateSignalsInBuffer(); + + if (IsPossibleDockingTile(target)) CheckForDockingTile(target); } cur_company.Restore(); @@ -1105,7 +1158,7 @@ void DoFloodTile(TileIndex target) */ static void DoDryUp(TileIndex tile) { - Backup cur_company(_current_company, OWNER_WATER, FILE_LINE); + Backup cur_company(_current_company, OWNER_WATER, FILE_LINE); switch (GetTileType(tile)) { case MP_RAILWAY: @@ -1321,14 +1374,14 @@ extern const TileTypeProcs _tile_type_water_procs = { DrawTile_Water, // draw_tile_proc GetSlopePixelZ_Water, // get_slope_z_proc ClearTile_Water, // clear_tile_proc - NULL, // add_accepted_cargo_proc + nullptr, // add_accepted_cargo_proc GetTileDesc_Water, // get_tile_desc_proc GetTileTrackStatus_Water, // get_tile_track_status_proc ClickTile_Water, // click_tile_proc - NULL, // animate_tile_proc + nullptr, // animate_tile_proc TileLoop_Water, // tile_loop_proc ChangeTileOwner_Water, // change_tile_owner_proc - NULL, // add_produced_cargo_proc + nullptr, // add_produced_cargo_proc VehicleEnter_Water, // vehicle_enter_tile_proc GetFoundation_Water, // get_foundation_proc TerraformTile_Water, // terraform_tile_proc diff --git a/src/water_map.h b/src/water_map.h index 5d84d5ba66..22e54e967f 100644 --- a/src/water_map.h +++ b/src/water_map.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. @@ -28,8 +26,8 @@ enum WaterTileTypeBitLayout { WBL_COAST_FLAG = 0, ///< Flag for coast. - WBL_LOCK_ORIENT_BEGIN = 0, ///< Start of lock orientiation bitfield. - WBL_LOCK_ORIENT_COUNT = 2, ///< Length of lock orientiation bitfield. + WBL_LOCK_ORIENT_BEGIN = 0, ///< Start of lock orientation bitfield. + WBL_LOCK_ORIENT_COUNT = 2, ///< Length of lock orientation bitfield. WBL_LOCK_PART_BEGIN = 2, ///< Start of lock part bitfield. WBL_LOCK_PART_COUNT = 2, ///< Length of lock part bitfield. @@ -69,6 +67,8 @@ enum LockPart { LOCK_PART_UPPER = 2, ///< Upper part of a lock. }; +bool IsPossibleDockingTile(TileIndex t); + /** * Get the water tile type at a tile. * @param t Water tile to query. @@ -346,6 +346,27 @@ static inline bool HasTileWaterGround(TileIndex t) return HasTileWaterClass(t) && IsTileOnWater(t) && !IsCoastTile(t); } +/** + * Set the docking tile state of a tile. This is used by pathfinders to reach their destination. + * As well as water tiles, half-rail tiles, buoys and aqueduct ends can also be docking tiles. + * @param t the tile + * @param b the docking tile state + */ +static inline void SetDockingTile(TileIndex 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); +} + +/** + * 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) +{ + return (IsTileType(t, MP_WATER) || IsTileType(t, MP_RAILWAY) || IsTileType(t, MP_STATION) || IsTileType(t, MP_TUNNELBRIDGE)) && HasBit(_m[t].m1, 7); +} + /** * Helper function to make a coast tile. @@ -356,6 +377,7 @@ static inline void MakeShore(TileIndex 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; @@ -376,6 +398,7 @@ static inline void MakeWater(TileIndex t, Owner o, WaterClass wc, uint8 random_b 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; @@ -429,6 +452,7 @@ static inline void MakeShipDepot(TileIndex t, Owner o, DepotID did, DepotPart pa 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; @@ -451,6 +475,7 @@ static inline void MakeLockTile(TileIndex t, Owner o, LockPart part, DiagDirecti 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; diff --git a/src/waypoint.cpp b/src/waypoint.cpp index 857f8ba874..f602eee6d0 100644 --- a/src/waypoint.cpp +++ b/src/waypoint.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. @@ -15,6 +13,7 @@ #include "window_func.h" #include "newgrf_station.h" #include "waypoint_base.h" +#include "viewport_kdtree.h" #include "safeguards.h" @@ -54,4 +53,5 @@ Waypoint::~Waypoint() if (CleaningPool()) return; DeleteWindowById(WC_WAYPOINT_VIEW, this->index); RemoveOrderFromAllVehicles(OT_GOTO_WAYPOINT, this->index); + if (this->sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeWaypoint(this->index)); } diff --git a/src/waypoint_base.h b/src/waypoint_base.h index 8d544a3b99..2c7cc530f6 100644 --- a/src/waypoint_base.h +++ b/src/waypoint_base.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. @@ -25,23 +23,25 @@ struct Waypoint FINAL : SpecializedStation { Waypoint(TileIndex tile = INVALID_TILE) : SpecializedStation(tile) { } ~Waypoint(); - void UpdateVirtCoord(); + void UpdateVirtCoord() override; - /* virtual */ inline bool TileBelongsToRailStation(TileIndex tile) const + void MoveSign(TileIndex new_xy) override; + + inline bool TileBelongsToRailStation(TileIndex tile) const override { return IsRailWaypointTile(tile) && GetStationIndex(tile) == this->index; } - /* virtual */ uint32 GetNewGRFVariable(const struct ResolverObject &object, byte variable, byte parameter, bool *available) const; + uint32 GetNewGRFVariable(const struct ResolverObject &object, byte variable, byte parameter, bool *available) const override; - /* virtual */ void GetTileArea(TileArea *ta, StationType type) const; + void GetTileArea(TileArea *ta, StationType type) const override; - /* virtual */ uint GetPlatformLength(TileIndex tile, DiagDirection dir) const + uint GetPlatformLength(TileIndex tile, DiagDirection dir) const override { return 1; } - /* virtual */ uint GetPlatformLength(TileIndex tile) const + uint GetPlatformLength(TileIndex tile) const override { return 1; } @@ -67,10 +67,4 @@ struct Waypoint FINAL : SpecializedStation { } }; -/** - * Iterate over all waypoints. - * @param var The variable used for iteration. - */ -#define FOR_ALL_WAYPOINTS(var) FOR_ALL_BASE_STATIONS_OF_TYPE(Waypoint, var) - #endif /* WAYPOINT_BASE_H */ diff --git a/src/waypoint_cmd.cpp b/src/waypoint_cmd.cpp index 639dce13bc..51d791fc28 100644 --- a/src/waypoint_cmd.cpp +++ b/src/waypoint_cmd.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. @@ -20,6 +18,7 @@ #include "pathfinder/yapf/yapf_cache.h" #include "strings_func.h" #include "viewport_func.h" +#include "viewport_kdtree.h" #include "window_func.h" #include "date_func.h" #include "vehicle_func.h" @@ -40,12 +39,28 @@ void Waypoint::UpdateVirtCoord() { Point pt = RemapCoords2(TileX(this->xy) * TILE_SIZE, TileY(this->xy) * TILE_SIZE); + if (this->sign.kdtree_valid) _viewport_sign_kdtree.Remove(ViewportSignKdtreeItem::MakeWaypoint(this->index)); + SetDParam(0, this->index); this->sign.UpdatePosition(pt.x, pt.y - 32 * ZOOM_LVL_BASE, STR_VIEWPORT_WAYPOINT); + + _viewport_sign_kdtree.Insert(ViewportSignKdtreeItem::MakeWaypoint(this->index)); + /* Recenter viewport */ InvalidateWindowData(WC_WAYPOINT_VIEW, this->index); } +/** + * Move the waypoint main coordinate somewhere else. + * @param new_xy new tile location of the sign + */ +void Waypoint::MoveSign(TileIndex new_xy) +{ + if (this->xy == new_xy) return; + + this->BaseStation::MoveSign(new_xy); +} + /** * Find a deleted waypoint close to a tile. * @param tile to search from @@ -55,10 +70,10 @@ void Waypoint::UpdateVirtCoord() */ static Waypoint *FindDeletedWaypointCloseTo(TileIndex tile, StringID str, CompanyID cid) { - Waypoint *wp, *best = NULL; + Waypoint *best = nullptr; uint thres = 8; - FOR_ALL_WAYPOINTS(wp) { + for (Waypoint *wp : Waypoint::Iterate()) { if (!wp->IsInUse() && wp->string_id == str && wp->owner == cid) { uint cur_dist = DistanceManhattan(tile, wp->xy); @@ -107,7 +122,7 @@ static CommandCost IsValidTileForWaypoint(TileIndex tile, Axis axis, StationID * /* if waypoint is set, then we have special handling to allow building on top of already existing waypoints. * so waypoint points to INVALID_STATION if we can build on any waypoint. * Or it points to a waypoint if we're only allowed to build on exactly that waypoint. */ - if (waypoint != NULL && IsTileType(tile, MP_STATION)) { + if (waypoint != nullptr && IsTileType(tile, MP_STATION)) { if (!IsRailWaypoint(tile)) { return ClearTile_Station(tile, DC_AUTO); // get error message } else { @@ -198,16 +213,16 @@ CommandCost CmdBuildRailWaypoint(TileIndex start_tile, DoCommandFlag flags, uint if (ret.Failed()) return ret; } - Waypoint *wp = NULL; - TileArea new_location(TileArea(start_tile, width, height)); + 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; /* Check if there is an already existing, deleted, waypoint close to us that we can reuse. */ TileIndex center_tile = start_tile + (count / 2) * offset; - if (wp == NULL && reuse) wp = FindDeletedWaypointCloseTo(center_tile, STR_SV_STNAME_WAYPOINT, _current_company); + if (wp == nullptr && reuse) wp = FindDeletedWaypointCloseTo(center_tile, STR_SV_STNAME_WAYPOINT, _current_company); - if (wp != NULL) { + if (wp != nullptr) { /* Reuse an existing waypoint. */ if (wp->owner != _current_company) return_cmd_error(STR_ERROR_TOO_CLOSE_TO_ANOTHER_WAYPOINT); @@ -225,7 +240,7 @@ CommandCost CmdBuildRailWaypoint(TileIndex start_tile, DoCommandFlag flags, uint } if (flags & DC_EXEC) { - if (wp == NULL) { + if (wp == nullptr) { wp = new Waypoint(start_tile); } else if (!wp->IsInUse()) { /* Move existing (recently deleted) waypoint to the new location */ @@ -241,13 +256,13 @@ CommandCost CmdBuildRailWaypoint(TileIndex start_tile, DoCommandFlag flags, uint wp->string_id = STR_SV_STNAME_WAYPOINT; wp->train_station = new_location; - if (wp->town == NULL) MakeDefaultName(wp); + if (wp->town == nullptr) MakeDefaultName(wp); wp->UpdateVirtCoord(); const StationSpec *spec = StationClass::Get(spec_class)->GetSpec(spec_index); byte *layout_ptr = AllocaM(byte, count); - if (spec == NULL) { + if (spec == nullptr) { /* The layout must be 0 for the 'normal' waypoints by design. */ memset(layout_ptr, 0, count); } else { @@ -296,7 +311,7 @@ CommandCost CmdBuildBuoy(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 /* Check if there is an already existing, deleted, waypoint close to us that we can reuse. */ Waypoint *wp = FindDeletedWaypointCloseTo(tile, STR_SV_STNAME_BUOY, OWNER_NONE); - if (wp == NULL && !Waypoint::CanAllocateItem()) return_cmd_error(STR_ERROR_TOO_MANY_STATIONS_LOADING); + if (wp == nullptr && !Waypoint::CanAllocateItem()) return_cmd_error(STR_ERROR_TOO_MANY_STATIONS_LOADING); CommandCost cost(EXPENSES_CONSTRUCTION, _price[PR_BUILD_WAYPOINT_BUOY]); if (!IsWaterTile(tile)) { @@ -306,7 +321,7 @@ CommandCost CmdBuildBuoy(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 } if (flags & DC_EXEC) { - if (wp == NULL) { + if (wp == nullptr) { wp = new Waypoint(tile); } else { /* Move existing (recently deleted) buoy to the new location */ @@ -322,9 +337,10 @@ CommandCost CmdBuildBuoy(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 wp->build_date = _date; - if (wp->town == NULL) MakeDefaultName(wp); + if (wp->town == nullptr) MakeDefaultName(wp); MakeBuoy(tile, wp->index, GetWaterClass(tile)); + CheckForDockingTile(tile); MarkTileDirtyByTile(tile); wp->UpdateVirtCoord(); @@ -381,10 +397,8 @@ CommandCost RemoveBuoy(TileIndex tile, DoCommandFlag flags) */ static bool IsUniqueWaypointName(const char *name) { - const Waypoint *wp; - - FOR_ALL_WAYPOINTS(wp) { - if (wp->name != NULL && strcmp(wp->name, name) == 0) return false; + for (const Waypoint *wp : Waypoint::Iterate()) { + if (wp->name != nullptr && strcmp(wp->name, name) == 0) return false; } return true; @@ -402,7 +416,7 @@ static bool IsUniqueWaypointName(const char *name) CommandCost CmdRenameWaypoint(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text) { Waypoint *wp = Waypoint::GetIfValid(p1); - if (wp == NULL) return CMD_ERROR; + if (wp == nullptr) return CMD_ERROR; if (wp->owner != OWNER_NONE) { CommandCost ret = CheckOwnership(wp->owner); @@ -418,7 +432,7 @@ CommandCost CmdRenameWaypoint(TileIndex tile, DoCommandFlag flags, uint32 p1, ui if (flags & DC_EXEC) { free(wp->name); - wp->name = reset ? NULL : stredup(text); + wp->name = reset ? nullptr : stredup(text); wp->UpdateVirtCoord(); } diff --git a/src/waypoint_func.h b/src/waypoint_func.h index b44264dc13..2906fa6369 100644 --- a/src/waypoint_func.h +++ b/src/waypoint_func.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/waypoint_gui.cpp b/src/waypoint_gui.cpp index fa4deaac68..64ef0eb251 100644 --- a/src/waypoint_gui.cpp +++ b/src/waypoint_gui.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. @@ -81,12 +79,12 @@ public: DeleteWindowById(GetWindowClassForVehicleType(this->vt), VehicleListIdentifier(VL_STATION_LIST, this->vt, this->owner, this->window_number).Pack(), false); } - virtual void SetStringParameters(int widget) const + void SetStringParameters(int widget) const override { if (widget == WID_W_CAPTION) SetDParam(0, this->wp->index); } - virtual void OnClick(Point pt, int widget, int click_count) + void OnClick(Point pt, int widget, int click_count) override { switch (widget) { case WID_W_CENTER_VIEW: // scroll to location @@ -113,7 +111,7 @@ public: * @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. */ - virtual void OnInvalidateData(int data = 0, bool gui_scope = true) + void OnInvalidateData(int data = 0, bool gui_scope = true) override { if (!gui_scope) return; /* You can only change your own waypoints */ @@ -124,9 +122,9 @@ public: ScrollWindowToTile(this->GetCenterTile(), this, true); } - virtual void OnResize() + void OnResize() override { - if (this->viewport != NULL) { + if (this->viewport != nullptr) { NWidgetViewport *nvp = this->GetWidget(WID_W_VIEWPORT); nvp->UpdateViewportCoordinates(this); this->wp->UpdateVirtCoord(); @@ -135,11 +133,11 @@ public: } } - virtual void OnQueryTextFinished(char *str) + void OnQueryTextFinished(char *str) override { - if (str == NULL) return; + if (str == nullptr) return; - DoCommandP(0, this->window_number, 0, CMD_RENAME_WAYPOINT | CMD_MSG(STR_ERROR_CAN_T_CHANGE_WAYPOINT_NAME), NULL, str); + DoCommandP(0, this->window_number, 0, CMD_RENAME_WAYPOINT | CMD_MSG(STR_ERROR_CAN_T_CHANGE_WAYPOINT_NAME), nullptr, str); } }; diff --git a/src/widget.cpp b/src/widget.cpp index 900778a53d..9683c741d8 100644 --- a/src/widget.cpp +++ b/src/widget.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. @@ -169,7 +167,7 @@ void ScrollbarClickHandler(Window *w, NWidgetCore *nw, int x, int y) ma = nw->pos_y + nw->current_y; } NWidgetScrollbar *scrollbar = dynamic_cast(nw); - assert(scrollbar != NULL); + assert(scrollbar != nullptr); ScrollbarClickPositioning(w, scrollbar, x, y, mi, ma); } @@ -184,7 +182,7 @@ void ScrollbarClickHandler(Window *w, NWidgetCore *nw, int x, int y) int GetWidgetFromPos(const Window *w, int x, int y) { NWidgetCore *nw = w->nested_root->GetWidgetFromPos(x, y); - return (nw != NULL) ? nw->index : -1; + return (nw != nullptr) ? nw->index : -1; } /** @@ -634,7 +632,7 @@ void Window::DrawWidgets() const extern bool _window_highlight_colour; for (uint i = 0; i < this->nested_array_size; i++) { const NWidgetBase *widget = this->GetWidget(i); - if (widget == NULL || !widget->IsHighlighted()) continue; + if (widget == nullptr || !widget->IsHighlighted()) continue; int left = widget->pos_x; int top = widget->pos_y; @@ -665,7 +663,7 @@ void Window::DrawSortButtonState(int widget, SortButtonState state) const { if (state == SBS_OFF) return; - assert(this->nested_array != NULL); + assert(this->nested_array != nullptr); const NWidgetBase *nwid = this->GetWidget(widget); /* Sort button uses the same sprites as vertical scrollbar */ @@ -809,17 +807,17 @@ void NWidgetBase::SetDirty(const Window *w) const * Retrieve a widget by its position. * @param x Horizontal position relative to the left edge of the window. * @param y Vertical position relative to the top edge of the window. - * @return Returns the deepest nested widget that covers the given position, or \c NULL if no widget can be found. + * @return Returns the deepest nested widget that covers the given position, or \c nullptr if no widget can be found. */ /** * Retrieve a widget by its type. * @param tp Widget type to search for. - * @return Returns the first widget of the specified type, or \c NULL if no widget can be found. + * @return Returns the first widget of the specified type, or \c nullptr if no widget can be found. */ NWidgetBase *NWidgetBase::GetWidgetOfType(WidgetType tp) { - return (this->type == tp) ? this : NULL; + return (this->type == tp) ? this : nullptr; } /** @@ -952,7 +950,7 @@ void NWidgetCore::FillNestedArray(NWidgetBase **array, uint length) NWidgetCore *NWidgetCore::GetWidgetFromPos(int x, int y) { - return (IsInsideBS(x, this->pos_x, this->current_x) && IsInsideBS(y, this->pos_y, this->current_y)) ? this : NULL; + return (IsInsideBS(x, this->pos_x, this->current_x) && IsInsideBS(y, this->pos_y, this->current_y)) ? this : nullptr; } void NWidgetCore::DrawEdgeOrnament(const Window *w) const @@ -1147,28 +1145,28 @@ void NWidgetCore::DrawEdgeOrnamentB() const */ NWidgetContainer::NWidgetContainer(WidgetType tp) : NWidgetBase(tp) { - this->head = NULL; - this->tail = NULL; + this->head = nullptr; + this->tail = nullptr; } NWidgetContainer::~NWidgetContainer() { - while (this->head != NULL) { + while (this->head != nullptr) { NWidgetBase *wid = this->head->next; delete this->head; this->head = wid; } - this->tail = NULL; + this->tail = nullptr; } NWidgetBase *NWidgetContainer::GetWidgetOfType(WidgetType tp) { if (this->type == tp) return this; - for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) { + for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { NWidgetBase *nwid = child_wid->GetWidgetOfType(tp); - if (nwid != NULL) return nwid; + if (nwid != nullptr) return nwid; } - return NULL; + return nullptr; } /** @@ -1177,14 +1175,14 @@ NWidgetBase *NWidgetContainer::GetWidgetOfType(WidgetType tp) */ void NWidgetContainer::Add(NWidgetBase *wid) { - assert(wid->next == NULL && wid->prev == NULL); + assert(wid->next == nullptr && wid->prev == nullptr); - if (this->head == NULL) { + if (this->head == nullptr) { this->head = wid; this->tail = wid; } else { - assert(this->tail != NULL); - assert(this->tail->next == NULL); + assert(this->tail != nullptr); + assert(this->tail->next == nullptr); this->tail->next = wid; wid->prev = this->tail; @@ -1194,7 +1192,7 @@ void NWidgetContainer::Add(NWidgetBase *wid) void NWidgetContainer::FillNestedArray(NWidgetBase **array, uint length) { - for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) { + for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { child_wid->FillNestedArray(array, length); } } @@ -1240,11 +1238,11 @@ void NWidgetStacked::SetupSmallestSize(Window *w, bool init_array) /* First sweep, recurse down and compute minimal size and filling. */ this->smallest_x = 0; this->smallest_y = 0; - this->fill_x = (this->head != NULL) ? 1 : 0; - this->fill_y = (this->head != NULL) ? 1 : 0; - this->resize_x = (this->head != NULL) ? 1 : 0; - this->resize_y = (this->head != NULL) ? 1 : 0; - for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) { + this->fill_x = (this->head != nullptr) ? 1 : 0; + this->fill_y = (this->head != nullptr) ? 1 : 0; + this->resize_x = (this->head != nullptr) ? 1 : 0; + this->resize_y = (this->head != nullptr) ? 1 : 0; + for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { child_wid->SetupSmallestSize(w, init_array); this->smallest_x = max(this->smallest_x, child_wid->smallest_x + child_wid->padding_left + child_wid->padding_right); @@ -1263,7 +1261,7 @@ void NWidgetStacked::AssignSizePosition(SizingType sizing, uint x, uint y, uint if (this->shown_plane >= SZSP_BEGIN) return; - for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) { + 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); @@ -1287,7 +1285,7 @@ void NWidgetStacked::Draw(const Window *w) if (this->shown_plane >= SZSP_BEGIN) return; int plane = 0; - for (NWidgetBase *child_wid = this->head; child_wid != NULL; plane++, child_wid = child_wid->next) { + for (NWidgetBase *child_wid = this->head; child_wid != nullptr; plane++, child_wid = child_wid->next) { if (plane == this->shown_plane) { child_wid->Draw(w); return; @@ -1299,16 +1297,16 @@ void NWidgetStacked::Draw(const Window *w) NWidgetCore *NWidgetStacked::GetWidgetFromPos(int x, int y) { - if (this->shown_plane >= SZSP_BEGIN) return NULL; + if (this->shown_plane >= SZSP_BEGIN) return nullptr; - if (!IsInsideBS(x, this->pos_x, this->current_x) || !IsInsideBS(y, this->pos_y, this->current_y)) return NULL; + if (!IsInsideBS(x, this->pos_x, this->current_x) || !IsInsideBS(y, this->pos_y, this->current_y)) return nullptr; int plane = 0; - for (NWidgetBase *child_wid = this->head; child_wid != NULL; plane++, child_wid = child_wid->next) { + for (NWidgetBase *child_wid = this->head; child_wid != nullptr; plane++, child_wid = child_wid->next) { if (plane == this->shown_plane) { return child_wid->GetWidgetFromPos(x, y); } } - return NULL; + return nullptr; } /** @@ -1343,20 +1341,20 @@ void NWidgetPIPContainer::SetPIP(uint8 pip_pre, uint8 pip_inter, uint8 pip_post) void NWidgetPIPContainer::Draw(const Window *w) { - for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) { + for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { child_wid->Draw(w); } } NWidgetCore *NWidgetPIPContainer::GetWidgetFromPos(int x, int y) { - if (!IsInsideBS(x, this->pos_x, this->current_x) || !IsInsideBS(y, this->pos_y, this->current_y)) return NULL; + if (!IsInsideBS(x, this->pos_x, this->current_x) || !IsInsideBS(y, this->pos_y, this->current_y)) return nullptr; - for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) { + for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { NWidgetCore *nwid = child_wid->GetWidgetFromPos(x, y); - if (nwid != NULL) return nwid; + if (nwid != nullptr) return nwid; } - return NULL; + return nullptr; } /** Horizontal container widget. */ @@ -1376,7 +1374,7 @@ void NWidgetHorizontal::SetupSmallestSize(Window *w, bool init_array) /* 1a. Forward call, collect biggest nested array index, and longest/widest child length. */ uint longest = 0; // Longest child found. uint max_vert_fill = 0; // Biggest vertical fill step. - for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) { + for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { child_wid->SetupSmallestSize(w, init_array); longest = max(longest, child_wid->smallest_x); max_vert_fill = max(max_vert_fill, child_wid->GetVerticalStepSize(ST_SMALLEST)); @@ -1386,7 +1384,7 @@ void NWidgetHorizontal::SetupSmallestSize(Window *w, bool init_array) uint max_smallest = this->smallest_y + 3 * max_vert_fill; // Upper limit to computing smallest height. uint cur_height = this->smallest_y; for (;;) { - for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) { + 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; if (step_size > 1 && child_height < cur_height) { // Small step sizes or already fitting children are not interesting. @@ -1403,14 +1401,14 @@ void NWidgetHorizontal::SetupSmallestSize(Window *w, bool init_array) } /* 2. For containers that must maintain equal width, extend child minimal size. */ if (this->flags & NC_EQUALSIZE) { - for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) { + for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { if (child_wid->fill_x == 1) child_wid->smallest_x = longest; } } /* 3. Move PIP space to the children, compute smallest, fill, and resize values of the container. */ - if (this->head != NULL) this->head->padding_left += this->pip_pre; - for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) { - if (child_wid->next != NULL) { + 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; } else { child_wid->padding_right += this->pip_post; @@ -1439,7 +1437,7 @@ void NWidgetHorizontal::AssignSizePosition(SizingType sizing, uint x, uint y, ui uint additional_length = given_width; 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 != NULL; child_wid = child_wid->next) { + 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; } } else { @@ -1464,7 +1462,7 @@ void NWidgetHorizontal::AssignSizePosition(SizingType sizing, uint x, uint y, ui */ int num_changing_childs = 0; // Number of children that can change size. uint biggest_stepsize = 0; - for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) { + 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++; @@ -1480,7 +1478,7 @@ void NWidgetHorizontal::AssignSizePosition(SizingType sizing, uint x, uint y, ui /* Second loop: Allocate the additional horizontal space over the resizing children, starting with the biggest resize steps. */ while (biggest_stepsize > 0) { uint next_biggest_stepsize = 0; - for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) { + 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) continue; // Already done if (hor_step == biggest_stepsize) { @@ -1500,7 +1498,7 @@ void NWidgetHorizontal::AssignSizePosition(SizingType sizing, uint x, uint y, ui /* Third loop: Compute position and call the child. */ uint position = rtl ? this->current_x : 0; // Place to put next child relative to origin of the container. NWidgetBase *child_wid = this->head; - while (child_wid != NULL) { + 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; @@ -1541,7 +1539,7 @@ void NWidgetVertical::SetupSmallestSize(Window *w, bool init_array) /* 1a. Forward call, collect biggest nested array index, and longest/widest child length. */ uint highest = 0; // Highest child found. uint max_hor_fill = 0; // Biggest horizontal fill step. - for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) { + for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { child_wid->SetupSmallestSize(w, init_array); highest = max(highest, child_wid->smallest_y); max_hor_fill = max(max_hor_fill, child_wid->GetHorizontalStepSize(ST_SMALLEST)); @@ -1551,7 +1549,7 @@ void NWidgetVertical::SetupSmallestSize(Window *w, bool init_array) uint max_smallest = this->smallest_x + 3 * max_hor_fill; // Upper limit to computing smallest height. uint cur_width = this->smallest_x; for (;;) { - for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) { + 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; if (step_size > 1 && child_width < cur_width) { // Small step sizes or already fitting children are not interesting. @@ -1568,14 +1566,14 @@ void NWidgetVertical::SetupSmallestSize(Window *w, bool init_array) } /* 2. For containers that must maintain equal width, extend children minimal size. */ if (this->flags & NC_EQUALSIZE) { - for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) { + for (NWidgetBase *child_wid = this->head; child_wid != nullptr; child_wid = child_wid->next) { if (child_wid->fill_y == 1) child_wid->smallest_y = highest; } } /* 3. Move PIP space to the child, compute smallest, fill, and resize values of the container. */ - if (this->head != NULL) this->head->padding_top += this->pip_pre; - for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) { - if (child_wid->next != NULL) { + 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; } else { child_wid->padding_bottom += this->pip_post; @@ -1604,7 +1602,7 @@ void NWidgetVertical::AssignSizePosition(SizingType sizing, uint x, uint y, uint uint additional_length = given_height; 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 != NULL; child_wid = child_wid->next) { + 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; } } else { @@ -1620,7 +1618,7 @@ void NWidgetVertical::AssignSizePosition(SizingType sizing, uint x, uint y, uint /* First loop: Find biggest stepsize, find number of children that want a piece of the pie, handle horizontal size for all children, handle vertical size for non-resizing child. */ int num_changing_childs = 0; // Number of children that can change size. uint biggest_stepsize = 0; - for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) { + 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++; @@ -1636,7 +1634,7 @@ void NWidgetVertical::AssignSizePosition(SizingType sizing, uint x, uint y, uint /* Second loop: Allocate the additional vertical space over the resizing children, starting with the biggest resize steps. */ while (biggest_stepsize > 0) { uint next_biggest_stepsize = 0; - for (NWidgetBase *child_wid = this->head; child_wid != NULL; child_wid = child_wid->next) { + 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) continue; // Already done if (vert_step == biggest_stepsize) { @@ -1655,7 +1653,7 @@ void NWidgetVertical::AssignSizePosition(SizingType sizing, uint x, uint y, uint /* 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 != NULL; child_wid = child_wid->next) { + 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_height = child_wid->current_y; @@ -1697,7 +1695,7 @@ void NWidgetSpacer::SetDirty(const Window *w) const NWidgetCore *NWidgetSpacer::GetWidgetFromPos(int x, int y) { - return NULL; + return nullptr; } NWidgetMatrix::NWidgetMatrix() : NWidgetPIPContainer(NWID_MATRIX, NC_EQUALSIZE), index(-1), clicked(-1), count(-1) @@ -1721,7 +1719,7 @@ void NWidgetMatrix::SetColour(Colours colour) void NWidgetMatrix::SetClicked(int clicked) { this->clicked = clicked; - if (this->clicked >= 0 && this->sb != NULL && this->widgets_x != 0) { + if (this->clicked >= 0 && this->sb != nullptr && this->widgets_x != 0) { int vpos = (this->clicked / this->widgets_x) * this->widget_h; // Vertical position of the top. /* Need to scroll down -> Scroll to the bottom. * However, last entry has no 'this->pip_inter' underneath, and we must stay below this->sb->GetCount() */ @@ -1739,7 +1737,7 @@ void NWidgetMatrix::SetCount(int count) { this->count = count; - if (this->sb == NULL || this->widgets_x == 0) return; + if (this->sb == nullptr || this->widgets_x == 0) return; /* We need to get the number of pixels the matrix is high/wide. * So, determine the number of rows/columns based on the number of @@ -1777,8 +1775,8 @@ int NWidgetMatrix::GetScrollbarWidget() void NWidgetMatrix::SetupSmallestSize(Window *w, bool init_array) { - assert(this->head != NULL); - assert(this->head->next == NULL); + assert(this->head != nullptr); + assert(this->head->next == nullptr); if (this->index >= 0 && init_array) { // Fill w->nested_array[] assert(w->nested_array_size > (uint)this->index); @@ -1787,7 +1785,7 @@ void NWidgetMatrix::SetupSmallestSize(Window *w, bool init_array) /* Reset the widget number. */ NWidgetCore *nw = dynamic_cast(this->head); - assert(nw != NULL); + assert(nw != nullptr); SB(nw->index, 16, 16, 0); this->head->SetupSmallestSize(w, init_array); @@ -1839,7 +1837,7 @@ void NWidgetMatrix::FillNestedArray(NWidgetBase **array, uint length) NWidgetCore *NWidgetMatrix::GetWidgetFromPos(int x, int y) { /* Falls outside of the matrix widget. */ - if (!IsInsideBS(x, this->pos_x, this->current_x) || !IsInsideBS(y, this->pos_y, this->current_y)) return NULL; + if (!IsInsideBS(x, this->pos_x, this->current_x) || !IsInsideBS(y, this->pos_y, this->current_y)) return nullptr; int start_x, start_y, base_offs_x, base_offs_y; this->GetScrollOffsets(start_x, start_y, base_offs_x, base_offs_y); @@ -1854,10 +1852,10 @@ NWidgetCore *NWidgetMatrix::GetWidgetFromPos(int x, int y) int widget_row = (y - base_offs_y - (int)this->pip_pre - (int)this->pos_y) / this->widget_h; int sub_wid = (widget_row + start_y) * this->widgets_x + start_x + widget_col; - if (sub_wid >= this->count) return NULL; + if (sub_wid >= this->count) return nullptr; NWidgetCore *child = dynamic_cast(this->head); - assert(child != NULL); + assert(child != nullptr); child->AssignSizePosition(ST_RESIZE, this->pos_x + (rtl ? this->pip_post - widget_col * this->widget_w : this->pip_pre + widget_col * this->widget_w) + base_offs_x, this->pos_y + this->pip_pre + widget_row * this->widget_h + base_offs_y, @@ -1882,7 +1880,7 @@ NWidgetCore *NWidgetMatrix::GetWidgetFromPos(int x, int y) /* Get the appropriate offsets so we can draw the right widgets. */ NWidgetCore *child = dynamic_cast(this->head); - assert(child != NULL); + assert(child != nullptr); int start_x, start_y, base_offs_x, base_offs_y; this->GetScrollOffsets(start_x, start_y, base_offs_x, base_offs_y); @@ -1929,7 +1927,7 @@ void NWidgetMatrix::GetScrollOffsets(int &start_x, int &start_y, int &base_offs_ base_offs_y = 0; start_x = 0; start_y = 0; - if (this->sb != NULL) { + if (this->sb != nullptr) { if (this->sb->IsVertical()) { start_y = this->sb->GetPosition() / this->widget_h; base_offs_y += -this->sb->GetPosition() + start_y * this->widget_h; @@ -1963,7 +1961,7 @@ NWidgetBackground::NWidgetBackground(WidgetType tp, Colours colour, int index, N NWidgetBackground::~NWidgetBackground() { - if (this->child != NULL) delete this->child; + if (this->child != nullptr) delete this->child; } /** @@ -1975,7 +1973,7 @@ NWidgetBackground::~NWidgetBackground() */ void NWidgetBackground::Add(NWidgetBase *nwid) { - if (this->child == NULL) { + if (this->child == nullptr) { this->child = new NWidgetVertical(); } this->child->Add(nwid); @@ -1993,7 +1991,7 @@ void NWidgetBackground::Add(NWidgetBase *nwid) */ void NWidgetBackground::SetPIP(uint8 pip_pre, uint8 pip_inter, uint8 pip_post) { - if (this->child == NULL) { + if (this->child == nullptr) { this->child = new NWidgetVertical(); } this->child->SetPIP(pip_pre, pip_inter, pip_post); @@ -2005,7 +2003,7 @@ void NWidgetBackground::SetupSmallestSize(Window *w, bool init_array) assert(w->nested_array_size > (uint)this->index); w->nested_array[this->index] = this; } - if (this->child != NULL) { + if (this->child != nullptr) { this->child->SetupSmallestSize(w, init_array); this->smallest_x = this->child->smallest_x; @@ -2016,7 +2014,7 @@ void NWidgetBackground::SetupSmallestSize(Window *w, bool init_array) this->resize_y = this->child->resize_y; /* Account for the size of the frame's text if that exists */ - if (w != NULL && this->type == WWT_FRAME) { + if (w != nullptr && this->type == WWT_FRAME) { this->child->padding_left = WD_FRAMETEXT_LEFT; this->child->padding_right = WD_FRAMETEXT_RIGHT; this->child->padding_top = max((int)WD_FRAMETEXT_TOP, this->widget_data != STR_NULL ? FONT_HEIGHT_NORMAL + WD_FRAMETEXT_TOP / 2 : 0); @@ -2032,7 +2030,7 @@ void NWidgetBackground::SetupSmallestSize(Window *w, bool init_array) Dimension d = {this->min_x, this->min_y}; Dimension fill = {this->fill_x, this->fill_y}; Dimension resize = {this->resize_x, this->resize_y}; - if (w != NULL) { // A non-NULL window pointer acts as switch to turn dynamic widget size on. + if (w != nullptr) { // A non-nullptr window pointer acts as switch to turn dynamic widget size on. if (this->type == WWT_FRAME || this->type == WWT_INSET) { if (this->index >= 0) w->SetStringParameters(this->index); Dimension background = GetStringBoundingBox(this->widget_data); @@ -2057,7 +2055,7 @@ void NWidgetBackground::AssignSizePosition(SizingType sizing, uint x, uint y, ui { this->StoreSizePosition(sizing, x, y, given_width, given_height); - if (this->child != NULL) { + 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; @@ -2068,7 +2066,7 @@ void NWidgetBackground::AssignSizePosition(SizingType sizing, uint x, uint y, ui void NWidgetBackground::FillNestedArray(NWidgetBase **array, uint length) { if (this->index >= 0 && (uint)(this->index) < length) array[this->index] = this; - if (this->child != NULL) this->child->FillNestedArray(array, length); + if (this->child != nullptr) this->child->FillNestedArray(array, length); } void NWidgetBackground::Draw(const Window *w) @@ -2107,7 +2105,7 @@ void NWidgetBackground::Draw(const Window *w) DrawEdgeOrnament(w); if (this->index >= 0) w->DrawWidget(r, this->index); - if (this->child != NULL) this->child->Draw(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); @@ -2117,19 +2115,19 @@ void NWidgetBackground::Draw(const Window *w) NWidgetCore *NWidgetBackground::GetWidgetFromPos(int x, int y) { - NWidgetCore *nwid = NULL; + NWidgetCore *nwid = nullptr; if (IsInsideBS(x, this->pos_x, this->current_x) && IsInsideBS(y, this->pos_y, this->current_y)) { - if (this->child != NULL) nwid = this->child->GetWidgetFromPos(x, y); - if (nwid == NULL) nwid = this; + if (this->child != nullptr) nwid = this->child->GetWidgetFromPos(x, y); + if (nwid == nullptr) nwid = this; } return nwid; } NWidgetBase *NWidgetBackground::GetWidgetOfType(WidgetType tp) { - NWidgetBase *nwid = NULL; - if (this->child != NULL) nwid = this->child->GetWidgetOfType(tp); - if (nwid == NULL && this->type == tp) nwid = this; + NWidgetBase *nwid = nullptr; + if (this->child != nullptr) nwid = this->child->GetWidgetOfType(tp); + if (nwid == nullptr && this->type == tp) nwid = this; return nwid; } @@ -2184,7 +2182,7 @@ void NWidgetViewport::InitializeViewport(Window *w, uint32 follow_flags, ZoomLev void NWidgetViewport::UpdateViewportCoordinates(Window *w) { ViewPort *vp = w->viewport; - if (vp != NULL) { + if (vp != nullptr) { vp->left = w->left + this->pos_x; vp->top = w->top + this->pos_y; vp->width = this->current_x; @@ -2494,7 +2492,7 @@ void NWidgetLeaf::SetupSmallestSize(Window *w, bool init_array) 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 = NULL; + const Dimension *padding = nullptr; if (!_settings_client.gui.windows_titlebars && w->window_class != WC_NEWS_WINDOW && (this->type == WWT_CAPTION || this->type == WWT_STICKYBOX || this->type == WWT_SHADEBOX || this->type == WWT_DEFSIZEBOX || this->type == WWT_CLOSEBOX || this->type == WWT_DEBUGBOX)) { @@ -2766,7 +2764,7 @@ void NWidgetLeaf::Draw(const Window *w) case WWT_EDITBOX: { const QueryString *query = w->GetQueryString(this->index); - if (query != NULL) query->DrawEditBox(w, this->index); + if (query != nullptr) query->DrawEditBox(w, this->index); break; } @@ -2798,7 +2796,7 @@ void NWidgetLeaf::Draw(const Window *w) case WWT_RESIZEBOX: assert(this->widget_data == 0); - DrawResizeBox(r, this->colour, this->pos_x < (uint)(w->width / 2), !!(w->flags & WF_SIZING)); + DrawResizeBox(r, this->colour, this->pos_x < (w->width / 2), !!(w->flags & WF_SIZING)); break; case WWT_CLOSEBOX: @@ -2862,30 +2860,30 @@ bool NWidgetLeaf::ButtonHit(const Point &pt) * @param fill_dest Fill the composed widget with child widgets. * @param biggest_index Pointer to biggest nested widget index in the tree encountered so far. * @return Number of widget part elements used to compose the widget. - * @pre \c biggest_index != NULL. + * @pre \c biggest_index != nullptr. */ static int MakeNWidget(const NWidgetPart *parts, int count, NWidgetBase **dest, bool *fill_dest, int *biggest_index) { int num_used = 0; - *dest = NULL; + *dest = nullptr; *fill_dest = false; while (count > num_used) { switch (parts->type) { case NWID_SPACER: - if (*dest != NULL) return num_used; + if (*dest != nullptr) return num_used; *dest = new NWidgetSpacer(0, 0); break; case NWID_HORIZONTAL: - if (*dest != NULL) return num_used; + if (*dest != nullptr) return num_used; *dest = new NWidgetHorizontal(parts->u.cont_flags); *fill_dest = true; break; case NWID_HORIZONTAL_LTR: - if (*dest != NULL) return num_used; + if (*dest != nullptr) return num_used; *dest = new NWidgetHorizontalLTR(parts->u.cont_flags); *fill_dest = true; break; @@ -2893,20 +2891,20 @@ static int MakeNWidget(const NWidgetPart *parts, int count, NWidgetBase **dest, case WWT_PANEL: case WWT_INSET: case WWT_FRAME: - if (*dest != NULL) return num_used; + if (*dest != nullptr) return num_used; *dest = new NWidgetBackground(parts->type, parts->u.widget.colour, parts->u.widget.index); *biggest_index = max(*biggest_index, (int)parts->u.widget.index); *fill_dest = true; break; case NWID_VERTICAL: - if (*dest != NULL) return num_used; + if (*dest != nullptr) return num_used; *dest = new NWidgetVertical(parts->u.cont_flags); *fill_dest = true; break; case NWID_MATRIX: { - if (*dest != NULL) return num_used; + if (*dest != nullptr) return num_used; NWidgetMatrix *nwm = new NWidgetMatrix(); *dest = nwm; *fill_dest = true; @@ -2917,7 +2915,7 @@ static int MakeNWidget(const NWidgetPart *parts, int count, NWidgetBase **dest, } case WPT_FUNCTION: { - if (*dest != NULL) return num_used; + if (*dest != nullptr) return num_used; /* Ensure proper functioning even when the called code simply writes its largest index. */ int biggest = -1; *dest = parts->u.func_ptr(&biggest); @@ -2928,7 +2926,7 @@ static int MakeNWidget(const NWidgetPart *parts, int count, NWidgetBase **dest, case WPT_RESIZE: { NWidgetResizeBase *nwrb = dynamic_cast(*dest); - if (nwrb != NULL) { + if (nwrb != nullptr) { assert(parts->u.xy.x >= 0 && parts->u.xy.y >= 0); nwrb->SetResize(parts->u.xy.x, parts->u.xy.y); } @@ -2947,16 +2945,16 @@ static int MakeNWidget(const NWidgetPart *parts, int count, NWidgetBase **dest, case WPT_MINSIZE: { NWidgetResizeBase *nwrb = dynamic_cast(*dest); - if (nwrb != NULL) { + if (nwrb != nullptr) { assert(parts->u.xy.x >= 0 && parts->u.xy.y >= 0); - nwrb->SetMinimalSize(parts->u.xy.x, parts->u.xy.y); + nwrb->SetMinimalSize(ScaleGUITrad(parts->u.xy.x), ScaleGUITrad(parts->u.xy.y)); } break; } case WPT_MINTEXTLINES: { NWidgetResizeBase *nwrb = dynamic_cast(*dest); - if (nwrb != NULL) { + if (nwrb != nullptr) { assert(parts->u.text_lines.size >= FS_BEGIN && parts->u.text_lines.size < FS_END); nwrb->SetMinimalTextLines(parts->u.text_lines.lines, parts->u.text_lines.spacing, parts->u.text_lines.size); } @@ -2965,13 +2963,13 @@ static int MakeNWidget(const NWidgetPart *parts, int count, NWidgetBase **dest, case WPT_FILL: { NWidgetResizeBase *nwrb = dynamic_cast(*dest); - if (nwrb != NULL) nwrb->SetFill(parts->u.xy.x, parts->u.xy.y); + if (nwrb != nullptr) nwrb->SetFill(parts->u.xy.x, parts->u.xy.y); break; } case WPT_DATATIP: { NWidgetCore *nwc = dynamic_cast(*dest); - if (nwc != NULL) { + if (nwc != nullptr) { nwc->widget_data = parts->u.data_tip.data; nwc->tool_tip = parts->u.data_tip.tooltip; } @@ -2979,21 +2977,21 @@ static int MakeNWidget(const NWidgetPart *parts, int count, NWidgetBase **dest, } case WPT_PADDING: - if (*dest != NULL) (*dest)->SetPadding(parts->u.padding.top, parts->u.padding.right, parts->u.padding.bottom, parts->u.padding.left); + if (*dest != nullptr) (*dest)->SetPadding(ScaleGUITrad(parts->u.padding.top), ScaleGUITrad(parts->u.padding.right), ScaleGUITrad(parts->u.padding.bottom), ScaleGUITrad(parts->u.padding.left)); break; case WPT_PIPSPACE: { NWidgetPIPContainer *nwc = dynamic_cast(*dest); - if (nwc != NULL) nwc->SetPIP(parts->u.pip.pre, parts->u.pip.inter, parts->u.pip.post); + if (nwc != nullptr) nwc->SetPIP(parts->u.pip.pre, parts->u.pip.inter, parts->u.pip.post); NWidgetBackground *nwb = dynamic_cast(*dest); - if (nwb != NULL) nwb->SetPIP(parts->u.pip.pre, parts->u.pip.inter, parts->u.pip.post); + if (nwb != nullptr) nwb->SetPIP(parts->u.pip.pre, parts->u.pip.inter, parts->u.pip.post); break; } case WPT_SCROLLBAR: { NWidgetCore *nwc = dynamic_cast(*dest); - if (nwc != NULL) { + if (nwc != nullptr) { nwc->scrollbar_index = parts->u.widget.index; } break; @@ -3003,20 +3001,20 @@ static int MakeNWidget(const NWidgetPart *parts, int count, NWidgetBase **dest, return num_used; case NWID_VIEWPORT: - if (*dest != NULL) return num_used; + if (*dest != nullptr) return num_used; *dest = new NWidgetViewport(parts->u.widget.index); *biggest_index = max(*biggest_index, (int)parts->u.widget.index); break; case NWID_HSCROLLBAR: case NWID_VSCROLLBAR: - if (*dest != NULL) return num_used; + if (*dest != nullptr) return num_used; *dest = new NWidgetScrollbar(parts->type, parts->u.widget.colour, parts->u.widget.index); *biggest_index = max(*biggest_index, (int)parts->u.widget.index); break; case NWID_SELECTION: { - if (*dest != NULL) return num_used; + if (*dest != nullptr) return num_used; NWidgetStacked *nws = new NWidgetStacked(); *dest = nws; *fill_dest = true; @@ -3026,7 +3024,7 @@ static int MakeNWidget(const NWidgetPart *parts, int count, NWidgetBase **dest, } default: - if (*dest != NULL) return num_used; + if (*dest != nullptr) return num_used; assert((parts->type & WWT_MASK) < WWT_LAST || (parts->type & WWT_MASK) == NWID_BUTTON_DROPDOWN); *dest = new NWidgetLeaf(parts->type, parts->u.widget.colour, parts->u.widget.index, 0x0, STR_NULL); *biggest_index = max(*biggest_index, (int)parts->u.widget.index); @@ -3043,29 +3041,29 @@ static int MakeNWidget(const NWidgetPart *parts, int count, NWidgetBase **dest, * Build a nested widget tree by recursively filling containers with nested widgets read from their parts. * @param parts Array with parts of the nested widgets. * @param count Length of the \a parts array. - * @param parent Pointer or container to use for storing the child widgets (*parent == NULL or *parent == container or background widget). + * @param parent Pointer or container to use for storing the child widgets (*parent == nullptr or *parent == container or background widget). * @param biggest_index Pointer to biggest nested widget index in the tree. * @return Number of widget part elements used to fill the container. * @post \c *biggest_index contains the largest widget index of the tree and \c -1 if no index is used. */ static int MakeWidgetTree(const NWidgetPart *parts, int count, NWidgetBase **parent, int *biggest_index) { - /* If *parent == NULL, only the first widget is read and returned. Otherwise, *parent must point to either + /* If *parent == nullptr, only the first widget is read and returned. Otherwise, *parent must point to either * a #NWidgetContainer or a #NWidgetBackground object, and parts are added as much as possible. */ NWidgetContainer *nwid_cont = dynamic_cast(*parent); NWidgetBackground *nwid_parent = dynamic_cast(*parent); - assert(*parent == NULL || (nwid_cont != NULL && nwid_parent == NULL) || (nwid_cont == NULL && nwid_parent != NULL)); + assert(*parent == nullptr || (nwid_cont != nullptr && nwid_parent == nullptr) || (nwid_cont == nullptr && nwid_parent != nullptr)); int total_used = 0; for (;;) { - NWidgetBase *sub_widget = NULL; + NWidgetBase *sub_widget = nullptr; bool fill_sub = false; int num_used = MakeNWidget(parts, count - total_used, &sub_widget, &fill_sub, biggest_index); parts += num_used; total_used += num_used; /* Break out of loop when end reached */ - if (sub_widget == NULL) break; + if (sub_widget == nullptr) break; /* If sub-widget is a container, recursively fill that container. */ WidgetType tp = sub_widget->type; @@ -3078,9 +3076,9 @@ static int MakeWidgetTree(const NWidgetPart *parts, int count, NWidgetBase **par } /* Add sub_widget to parent container if available, otherwise return the widget to the caller. */ - if (nwid_cont != NULL) nwid_cont->Add(sub_widget); - if (nwid_parent != NULL) nwid_parent->Add(sub_widget); - if (nwid_cont == NULL && nwid_parent == NULL) { + if (nwid_cont != nullptr) nwid_cont->Add(sub_widget); + if (nwid_parent != nullptr) nwid_parent->Add(sub_widget); + if (nwid_cont == nullptr && nwid_parent == nullptr) { *parent = sub_widget; return total_used; } @@ -3098,16 +3096,16 @@ static int MakeWidgetTree(const NWidgetPart *parts, int count, NWidgetBase **par * @param parts Array with parts of the widgets. * @param count Length of the \a parts array. * @param biggest_index Pointer to biggest nested widget index collected in the tree. - * @param container Container to add the nested widgets to. In case it is NULL a vertical container is used. + * @param container Container to add the nested widgets to. In case it is nullptr a vertical container is used. * @return Root of the nested widget tree, a vertical container containing the entire GUI. * @ingroup NestedWidgetParts - * @pre \c biggest_index != NULL + * @pre \c biggest_index != nullptr * @post \c *biggest_index contains the largest widget index of the tree and \c -1 if no index is used. */ NWidgetContainer *MakeNWidgets(const NWidgetPart *parts, int count, int *biggest_index, NWidgetContainer *container) { *biggest_index = -1; - if (container == NULL) container = new NWidgetVertical(); + if (container == nullptr) container = new NWidgetVertical(); NWidgetBase *cont_ptr = container; MakeWidgetTree(parts, count, &cont_ptr, biggest_index); return container; @@ -3120,10 +3118,10 @@ NWidgetContainer *MakeNWidgets(const NWidgetPart *parts, int count, int *biggest * @param parts Array with parts of the widgets. * @param count Length of the \a parts array. * @param biggest_index Pointer to biggest nested widget index collected in the tree. - * @param[out] shade_select Pointer to the inserted shade selection widget (\c NULL if not unserted). + * @param[out] shade_select Pointer to the inserted shade selection widget (\c nullptr if not unserted). * @return Root of the nested widget tree, a vertical container containing the entire GUI. * @ingroup NestedWidgetParts - * @pre \c biggest_index != NULL + * @pre \c biggest_index != nullptr * @post \c *biggest_index contains the largest widget index of the tree and \c -1 if no index is used. */ NWidgetContainer *MakeWindowNWidgetTree(const NWidgetPart *parts, int count, int *biggest_index, NWidgetStacked **shade_select) @@ -3131,16 +3129,16 @@ NWidgetContainer *MakeWindowNWidgetTree(const NWidgetPart *parts, int count, int *biggest_index = -1; /* Read the first widget recursively from the array. */ - NWidgetBase *nwid = NULL; + NWidgetBase *nwid = nullptr; int num_used = MakeWidgetTree(parts, count, &nwid, biggest_index); - assert(nwid != NULL); + assert(nwid != nullptr); parts += num_used; count -= num_used; NWidgetContainer *root = new NWidgetVertical; root->Add(nwid); if (count == 0) { // There is no body at all. - *shade_select = NULL; + *shade_select = nullptr; return root; } @@ -3148,13 +3146,13 @@ NWidgetContainer *MakeWindowNWidgetTree(const NWidgetPart *parts, int count, int * If it has a shading box, silently add a shade selection widget in the tree. */ NWidgetHorizontal *hor_cont = dynamic_cast(nwid); NWidgetContainer *body; - if (hor_cont != NULL && hor_cont->GetWidgetOfType(WWT_CAPTION) != NULL && hor_cont->GetWidgetOfType(WWT_SHADEBOX) != NULL) { + if (hor_cont != nullptr && hor_cont->GetWidgetOfType(WWT_CAPTION) != nullptr && hor_cont->GetWidgetOfType(WWT_SHADEBOX) != nullptr) { *shade_select = new NWidgetStacked; root->Add(*shade_select); body = new NWidgetVertical; (*shade_select)->Add(body); } else { - *shade_select = NULL; + *shade_select = nullptr; body = root; } @@ -3179,8 +3177,8 @@ NWidgetContainer *MakeWindowNWidgetTree(const NWidgetPart *parts, int count, int NWidgetBase *MakeCompanyButtonRows(int *biggest_index, int widget_first, int widget_last, int max_length, StringID button_tooltip) { assert(max_length >= 1); - NWidgetVertical *vert = NULL; // Storage for all rows. - NWidgetHorizontal *hor = NULL; // Storage for buttons in one row. + NWidgetVertical *vert = nullptr; // Storage for all rows. + NWidgetHorizontal *hor = nullptr; // Storage for buttons in one row. int hor_length = 0; Dimension sprite_size = GetSpriteSize(SPR_COMPANY_ICON); @@ -3190,12 +3188,12 @@ NWidgetBase *MakeCompanyButtonRows(int *biggest_index, int widget_first, int wid for (int widnum = widget_first; widnum <= widget_last; widnum++) { /* Ensure there is room in 'hor' for another button. */ if (hor_length == max_length) { - if (vert == NULL) vert = new NWidgetVertical(); + if (vert == nullptr) vert = new NWidgetVertical(); vert->Add(hor); - hor = NULL; + hor = nullptr; hor_length = 0; } - if (hor == NULL) { + if (hor == nullptr) { hor = new NWidgetHorizontal(); hor_length = 0; } @@ -3210,7 +3208,7 @@ NWidgetBase *MakeCompanyButtonRows(int *biggest_index, int widget_first, int wid hor_length++; } *biggest_index = widget_last; - if (vert == NULL) return hor; // All buttons fit in a single row. + if (vert == nullptr) return hor; // All buttons fit in a single row. if (hor_length > 0 && hor_length < max_length) { /* Last row is partial, add a spacer at the end to force all buttons to the left. */ @@ -3219,7 +3217,7 @@ NWidgetBase *MakeCompanyButtonRows(int *biggest_index, int widget_first, int wid spc->SetResize(1, 0); hor->Add(spc); } - if (hor != NULL) vert->Add(hor); + if (hor != nullptr) vert->Add(hor); return vert; } diff --git a/src/widget_type.h b/src/widget_type.h index 6db7c7ba4b..9d76271f96 100644 --- a/src/widget_type.h +++ b/src/widget_type.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. @@ -190,8 +188,8 @@ public: uint current_x; ///< Current horizontal size (after resizing). uint current_y; ///< Current vertical size (after resizing). - uint pos_x; ///< Horizontal position of top-left corner of the widget in the window. - uint pos_y; ///< Vertical position of top-left corner of the widget in the window. + int pos_x; ///< Horizontal position of top-left corner of the widget in the window. + int pos_y; ///< Vertical position of top-left corner of the widget in the window. 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. @@ -263,7 +261,7 @@ public: uint min_y; ///< Minimal vertical size of only this widget. }; -/** Nested widget flags that affect display and interaction withe 'real' widgets. */ +/** Nested widget flags that affect display and interaction with 'real' widgets. */ enum NWidgetDisplay { /* Generic. */ NDB_LOWERED = 0, ///< Widget is lowered (pressed down) bit. @@ -315,11 +313,11 @@ public: inline void DrawEdgeOrnamentT() const; inline void DrawEdgeOrnamentB() const; - /* virtual */ void FillNestedArray(NWidgetBase **array, uint length); - /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y); - /* virtual */ bool IsHighlighted() const; - /* virtual */ TextColour GetHighlightColour() const; - /* virtual */ void SetHighlighted(TextColour highlight_colour); + void FillNestedArray(NWidgetBase **array, uint length) override; + NWidgetCore *GetWidgetFromPos(int x, int y) override; + bool IsHighlighted() const override; + TextColour GetHighlightColour() const override; + void SetHighlighted(TextColour highlight_colour) override; NWidgetDisplay disp_flags; ///< Flags that affect display and interaction with the widget. Colours colour; ///< Colour of this widget. @@ -393,12 +391,12 @@ public: ~NWidgetContainer(); void Add(NWidgetBase *wid); - /* virtual */ void FillNestedArray(NWidgetBase **array, uint length); + void FillNestedArray(NWidgetBase **array, uint length) override; /** Return whether the container is empty. */ - inline bool IsEmpty() { return head == NULL; } + inline bool IsEmpty() { return head == nullptr; } - /* virtual */ NWidgetBase *GetWidgetOfType(WidgetType tp); + NWidgetBase *GetWidgetOfType(WidgetType tp) override; protected: NWidgetBase *head; ///< Pointer to first widget in container. @@ -430,12 +428,12 @@ public: void SetIndex(int index); - void SetupSmallestSize(Window *w, bool init_array); - void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl); - /* virtual */ void FillNestedArray(NWidgetBase **array, uint length); + void SetupSmallestSize(Window *w, bool init_array) override; + void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl) override; + void FillNestedArray(NWidgetBase **array, uint length) override; - /* virtual */ void Draw(const Window *w); - /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y); + void Draw(const Window *w) override; + NWidgetCore *GetWidgetFromPos(int x, int y) override; void SetDisplayedPlane(int plane); @@ -459,8 +457,8 @@ public: void SetPIP(uint8 pip_pre, uint8 pip_inter, uint8 pip_post); - /* virtual */ void Draw(const Window *w); - /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y); + void Draw(const Window *w) override; + NWidgetCore *GetWidgetFromPos(int x, int y) override; protected: NWidContainerFlags flags; ///< Flags of the container. @@ -524,12 +522,12 @@ public: Scrollbar *GetScrollbar(); int GetScrollbarWidget(); - void SetupSmallestSize(Window *w, bool init_array); - void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl); - /* virtual */ void FillNestedArray(NWidgetBase **array, uint length); + void SetupSmallestSize(Window *w, bool init_array) override; + void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl) override; + void FillNestedArray(NWidgetBase **array, uint length) override; - /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y); - /* virtual */ void Draw(const Window *w); + NWidgetCore *GetWidgetFromPos(int x, int y) override; + void Draw(const Window *w) override; protected: int index; ///< If non-negative, index in the #Window::nested_array. Colours colour; ///< Colour of this widget. @@ -555,12 +553,12 @@ class NWidgetSpacer : public NWidgetResizeBase { public: NWidgetSpacer(int length, int height); - void SetupSmallestSize(Window *w, bool init_array); - /* virtual */ void FillNestedArray(NWidgetBase **array, uint length); + void SetupSmallestSize(Window *w, bool init_array) override; + void FillNestedArray(NWidgetBase **array, uint length) override; - /* virtual */ void Draw(const Window *w); - /* virtual */ void SetDirty(const Window *w) const; - /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y); + void Draw(const Window *w) override; + void SetDirty(const Window *w) const override; + NWidgetCore *GetWidgetFromPos(int x, int y) override; }; /** @@ -569,20 +567,20 @@ public: */ class NWidgetBackground : public NWidgetCore { public: - NWidgetBackground(WidgetType tp, Colours colour, int index, NWidgetPIPContainer *child = NULL); + NWidgetBackground(WidgetType tp, Colours colour, int index, NWidgetPIPContainer *child = nullptr); ~NWidgetBackground(); void Add(NWidgetBase *nwid); void SetPIP(uint8 pip_pre, uint8 pip_inter, uint8 pip_post); - void SetupSmallestSize(Window *w, bool init_array); - void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl); + void SetupSmallestSize(Window *w, bool init_array) override; + void AssignSizePosition(SizingType sizing, uint x, uint y, uint given_width, uint given_height, bool rtl) override; - /* virtual */ void FillNestedArray(NWidgetBase **array, uint length); + void FillNestedArray(NWidgetBase **array, uint length) override; - /* virtual */ void Draw(const Window *w); - /* virtual */ NWidgetCore *GetWidgetFromPos(int x, int y); - /* virtual */ NWidgetBase *GetWidgetOfType(WidgetType tp); + void Draw(const Window *w) override; + NWidgetCore *GetWidgetFromPos(int x, int y) override; + NWidgetBase *GetWidgetOfType(WidgetType tp) override; private: NWidgetPIPContainer *child; ///< Child widget. @@ -601,8 +599,8 @@ class NWidgetViewport : public NWidgetCore { public: NWidgetViewport(int index); - /* virtual */ void SetupSmallestSize(Window *w, bool init_array); - /* virtual */ void Draw(const Window *w); + void SetupSmallestSize(Window *w, bool init_array) override; + void Draw(const Window *w) override; void InitializeViewport(Window *w, uint32 follow_flags, ZoomLevel zoom); void UpdateViewportCoordinates(Window *w); @@ -776,8 +774,8 @@ class NWidgetScrollbar : public NWidgetCore, public Scrollbar { public: NWidgetScrollbar(WidgetType tp, Colours colour, int index); - /* virtual */ void SetupSmallestSize(Window *w, bool init_array); - /* virtual */ void Draw(const Window *w); + void SetupSmallestSize(Window *w, bool init_array) override; + void Draw(const Window *w) override; static void InvalidateDimensionCache(); static Dimension GetVerticalDimension(); @@ -796,8 +794,8 @@ class NWidgetLeaf : public NWidgetCore { public: NWidgetLeaf(WidgetType tp, Colours colour, int index, uint32 data, StringID tip); - /* virtual */ void SetupSmallestSize(Window *w, bool init_array); - /* virtual */ void Draw(const Window *w); + void SetupSmallestSize(Window *w, bool init_array) override; + void Draw(const Window *w) override; bool ButtonHit(const Point &pt); diff --git a/src/widgets/ai_widget.h b/src/widgets/ai_widget.h index b6ef02fa55..163894df4c 100644 --- a/src/widgets/ai_widget.h +++ b/src/widgets/ai_widget.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/widgets/airport_widget.h b/src/widgets/airport_widget.h index f0d2113328..da0770bcb9 100644 --- a/src/widgets/airport_widget.h +++ b/src/widgets/airport_widget.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/widgets/autoreplace_widget.h b/src/widgets/autoreplace_widget.h index 4b761ca45d..3522dbc8d6 100644 --- a/src/widgets/autoreplace_widget.h +++ b/src/widgets/autoreplace_widget.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. @@ -34,9 +32,11 @@ enum ReplaceVehicleWidgets { WID_RV_INFO_TAB, ///< Info tab. WID_RV_STOP_REPLACE, ///< Stop Replacing button. + /* Train/road only widgets */ + WID_RV_RAIL_ROAD_TYPE_DROPDOWN, ///< Dropdown menu about the rail/roadtype. + /* Train only widgets. */ WID_RV_TRAIN_ENGINEWAGON_DROPDOWN, ///< Dropdown to select engines and/or wagons. - WID_RV_TRAIN_RAILTYPE_DROPDOWN, ///< Dropdown menu about the railtype. WID_RV_TRAIN_WAGONREMOVE_TOGGLE, ///< Button to toggle removing wagons. }; diff --git a/src/widgets/bootstrap_widget.h b/src/widgets/bootstrap_widget.h index a371a3bdb0..4870f62d5a 100644 --- a/src/widgets/bootstrap_widget.h +++ b/src/widgets/bootstrap_widget.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/widgets/bridge_widget.h b/src/widgets/bridge_widget.h index 942b230758..d9b6adedda 100644 --- a/src/widgets/bridge_widget.h +++ b/src/widgets/bridge_widget.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/widgets/build_vehicle_widget.h b/src/widgets/build_vehicle_widget.h index ae548587e2..861c01f680 100644 --- a/src/widgets/build_vehicle_widget.h +++ b/src/widgets/build_vehicle_widget.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/widgets/cheat_widget.h b/src/widgets/cheat_widget.h index 3209cae239..c43799d5d3 100644 --- a/src/widgets/cheat_widget.h +++ b/src/widgets/cheat_widget.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/widgets/company_widget.h b/src/widgets/company_widget.h index ceb81ae195..2fb2234d41 100644 --- a/src/widgets/company_widget.h +++ b/src/widgets/company_widget.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. @@ -177,6 +175,8 @@ enum CompanyInfrastructureWidgets { WID_CI_RAIL_COUNT, ///< Count of rail. WID_CI_ROAD_DESC, ///< Description of road. WID_CI_ROAD_COUNT, ///< Count of road. + WID_CI_TRAM_DESC, ///< Description of tram. + WID_CI_TRAM_COUNT, ///< Count of tram. WID_CI_WATER_DESC, ///< Description of water. WID_CI_WATER_COUNT, ///< Count of water. WID_CI_STATION_DESC, ///< Description of station. diff --git a/src/widgets/console_widget.h b/src/widgets/console_widget.h index 13fa2395cf..1bc1be1f67 100644 --- a/src/widgets/console_widget.h +++ b/src/widgets/console_widget.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/widgets/date_widget.h b/src/widgets/date_widget.h index 79476606df..3b397dae47 100644 --- a/src/widgets/date_widget.h +++ b/src/widgets/date_widget.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/widgets/depot_widget.h b/src/widgets/depot_widget.h index 5864564ceb..c162cb8b7d 100644 --- a/src/widgets/depot_widget.h +++ b/src/widgets/depot_widget.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/widgets/dock_widget.h b/src/widgets/dock_widget.h index 080282bd30..139fcd55bc 100644 --- a/src/widgets/dock_widget.h +++ b/src/widgets/dock_widget.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/widgets/dropdown.cpp b/src/widgets/dropdown.cpp index 366f146119..d3192f8458 100644 --- a/src/widgets/dropdown.cpp +++ b/src/widgets/dropdown.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. @@ -22,7 +20,7 @@ #include "../safeguards.h" -void DropDownListItem::Draw(int left, int right, int top, int bottom, bool sel, int bg_colour) const +void DropDownListItem::Draw(int left, int right, int top, int bottom, bool sel, Colours bg_colour) const { int c1 = _colour_gradient[bg_colour][3]; int c2 = _colour_gradient[bg_colour][7]; @@ -39,7 +37,7 @@ uint DropDownListStringItem::Width() const return GetStringBoundingBox(buffer).width; } -void DropDownListStringItem::Draw(int left, int right, int top, int bottom, bool sel, int bg_colour) const +void DropDownListStringItem::Draw(int left, int right, int top, int bottom, bool sel, Colours bg_colour) const { DrawString(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, Center(top, bottom - top), this->String(), sel ? TC_WHITE : TC_BLACK); } @@ -51,12 +49,12 @@ void DropDownListStringItem::Draw(int left, int right, int top, int bottom, bool * @return true if \a first precedes \a second. * @warning All items in the list need to be derivates of DropDownListStringItem. */ -/* static */ int DropDownListStringItem::NatSortFunc(const DropDownListItem * const *first, const DropDownListItem * const * second) +/* static */ bool DropDownListStringItem::NatSortFunc(std::unique_ptr const &first, std::unique_ptr const &second) { char buffer1[512], buffer2[512]; - GetString(buffer1, static_cast(*first)->String(), lastof(buffer1)); - GetString(buffer2, static_cast(*second)->String(), lastof(buffer2)); - return strnatcmp(buffer1, buffer2); + GetString(buffer1, static_cast(first.get())->String(), lastof(buffer1)); + GetString(buffer2, static_cast(second.get())->String(), lastof(buffer2)); + return strnatcmp(buffer1, buffer2) < 0; } StringID DropDownListParamStringItem::String() const @@ -71,6 +69,40 @@ StringID DropDownListCharStringItem::String() const return this->string; } +DropDownListIconItem::DropDownListIconItem(SpriteID sprite, PaletteID pal, StringID string, int result, bool masked) : DropDownListParamStringItem(string, result, masked), sprite(sprite), pal(pal) +{ + this->dim = GetSpriteSize(sprite); + if (this->dim.height < (uint)FONT_HEIGHT_NORMAL) { + this->sprite_y = (FONT_HEIGHT_NORMAL - dim.height) / 2; + this->text_y = 0; + } else { + this->sprite_y = 0; + this->text_y = (dim.height - FONT_HEIGHT_NORMAL) / 2; + } +} + +uint DropDownListIconItem::Height(uint width) const +{ + return max(this->dim.height, (uint)FONT_HEIGHT_NORMAL); +} + +uint DropDownListIconItem::Width() const +{ + return DropDownListStringItem::Width() + this->dim.width + WD_FRAMERECT_LEFT; +} + +void DropDownListIconItem::Draw(int left, int right, int top, int bottom, 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, top + 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), top + this->text_y, this->String(), sel ? TC_WHITE : TC_BLACK); +} + +void DropDownListIconItem::SetDimension(Dimension d) +{ + this->dim = d; +} + static const NWidgetPart _nested_dropdown_menu_widgets[] = { NWidget(NWID_HORIZONTAL), NWidget(WWT_PANEL, COLOUR_END, WID_DM_ITEMS), SetMinimalSize(1, 1), SetScrollbar(WID_DM_SCROLL), EndContainer(), @@ -81,7 +113,7 @@ static const NWidgetPart _nested_dropdown_menu_widgets[] = { }; static WindowDesc _dropdown_desc( - WDP_MANUAL, NULL, 0, 0, + WDP_MANUAL, nullptr, 0, 0, WC_DROPDOWN_MENU, WC_NONE, WDF_NO_FOCUS, _nested_dropdown_menu_widgets, lengthof(_nested_dropdown_menu_widgets) @@ -92,7 +124,7 @@ struct DropdownWindow : Window { WindowClass parent_wnd_class; ///< Parent window class. WindowNumber parent_wnd_num; ///< Parent window number. int parent_button; ///< Parent widget number where the window is dropped from. - const DropDownList *list; ///< List with dropdown menu items. + const DropDownList list; ///< List with dropdown menu items. int selected_index; ///< Index of the selected item in the list. byte click_delay; ///< Timer to delay selection. bool drag_mode; @@ -117,10 +149,10 @@ struct DropdownWindow : Window { * @param wi_colour Colour of the parent widget. * @param scroll Dropdown menu has a scrollbar. */ - DropdownWindow(Window *parent, const DropDownList *list, int selected, int button, bool instant_close, const Point &position, const Dimension &size, Colours wi_colour, bool scroll) - : Window(&_dropdown_desc) + DropdownWindow(Window *parent, DropDownList &&list, int selected, int button, bool instant_close, const Point &position, const Dimension &size, Colours wi_colour, bool scroll) + : Window(&_dropdown_desc), list(std::move(list)) { - assert(list->Length() > 0); + assert(this->list.size() > 0); this->position = position; @@ -145,15 +177,14 @@ struct DropdownWindow : Window { int list_height = 0; int scroll_pos = 0; int count = 0; - for (const DropDownListItem * const *it = list->Begin(); it != list->End(); ++it) { - const DropDownListItem *item = *it; + for (const auto &item : this->list) { list_height += item->Height(items_width); if (item->result == selected) scroll_pos = count; count++; } /* Capacity is the average number of items visible */ - this->vscroll->SetCapacity(size.height * (uint16)list->Length() / list_height); - this->vscroll->SetCount((uint16)list->Length()); + this->vscroll->SetCapacity(size.height * (uint16)this->list.size() / list_height); + this->vscroll->SetCount((uint16)this->list.size()); if (this->vscroll->GetCount() <= this->vscroll->GetCapacity()) { scroll_pos = 0; } @@ -163,7 +194,6 @@ struct DropdownWindow : Window { this->parent_wnd_class = parent->window_class; this->parent_wnd_num = parent->window_number; this->parent_button = button; - this->list = list; this->selected_index = selected; this->click_delay = 0; this->drag_mode = instant_close; @@ -183,13 +213,12 @@ struct DropdownWindow : Window { this->SetDirty(); Window *w2 = FindWindowById(this->parent_wnd_class, this->parent_wnd_num); - if (w2 != NULL) { + if (w2 != nullptr) { Point pt = _cursor.pos; pt.x -= w2->left; pt.y -= w2->top; w2->OnDropdownClose(pt, this->parent_button, this->selected_index, this->instant_close); } - delete this->list; } virtual Point OnInitialPosition(int16 sm_width, int16 sm_height, int window_number) @@ -211,13 +240,10 @@ struct DropdownWindow : Window { int width = nwi->current_x - 4; int pos = this->vscroll->GetPosition(); - const DropDownList *list = this->list; - - for (const DropDownListItem * const *it = list->Begin(); it != list->End(); ++it) { + for (const auto &item : this->list) { /* Skip items that are scrolled up */ if (--pos >= 0) continue; - const DropDownListItem *item = *it; int item_height = item->Height(width); if (y < item_height) { @@ -240,8 +266,7 @@ struct DropdownWindow : Window { int y = r.top + 2; int pos = this->vscroll->GetPosition(); - for (const DropDownListItem * const *it = this->list->Begin(); it != this->list->End(); ++it) { - const DropDownListItem *item = *it; + for (const auto &item : this->list) { int item_height = item->Height(r.right - r.left + 1); /* Skip items that are scrolled up */ @@ -293,7 +318,7 @@ struct DropdownWindow : Window { virtual void OnMouseLoop() { Window *w2 = FindWindowById(this->parent_wnd_class, this->parent_wnd_num); - if (w2 == NULL) { + if (w2 == nullptr) { delete this; return; } @@ -383,8 +408,7 @@ struct DropdownWindow : Window { /** * Show a drop down list. * @param w Parent window for the list. - * @param list Prepopulated DropDownList. Will be deleted when the list is - * closed. + * @param list Prepopulated DropDownList. * @param selected The initially selected list item. * @param button The widget which is passed to Window::OnDropdownSelect and OnDropdownClose. * Unless you override those functions, this should be then widget index of the dropdown button. @@ -394,7 +418,7 @@ struct DropdownWindow : Window { * @param instant_close Set to true if releasing mouse button should close the * list regardless of where the cursor is. */ -void ShowDropDownListAt(Window *w, const DropDownList *list, int selected, int button, Rect wi_rect, Colours wi_colour, bool auto_width, bool instant_close) +void ShowDropDownListAt(Window *w, DropDownList &&list, int selected, int button, Rect wi_rect, Colours wi_colour, bool auto_width, bool instant_close) { DeleteWindowById(WC_DROPDOWN_MENU, 0); @@ -410,8 +434,7 @@ void ShowDropDownListAt(Window *w, const DropDownList *list, int selected, int b /* Total height of list */ uint height = 0; - for (const DropDownListItem * const *it = list->Begin(); it != list->End(); ++it) { - const DropDownListItem *item = *it; + for (const auto &item : list) { height += item->Height(width); if (auto_width) max_item_width = max(max_item_width, item->Width() + 5); } @@ -439,7 +462,7 @@ void ShowDropDownListAt(Window *w, const DropDownList *list, int selected, int b /* If the dropdown doesn't fully fit, we need a dropdown. */ if (height > available_height) { scroll = true; - uint avg_height = height / list->Length(); + uint avg_height = height / (uint)list.size(); /* Check at least there is space for one item. */ assert(available_height >= avg_height); @@ -462,7 +485,7 @@ void ShowDropDownListAt(Window *w, const DropDownList *list, int selected, int b Point dw_pos = { w->left + (_current_text_dir == TD_RTL ? wi_rect.right + 1 - (int)width : wi_rect.left), top}; Dimension dw_size = {width, height}; - DropdownWindow *dropdown = new DropdownWindow(w, list, selected, button, instant_close, dw_pos, dw_size, wi_colour, scroll); + DropdownWindow *dropdown = new DropdownWindow(w, std::move(list), selected, button, instant_close, dw_pos, dw_size, wi_colour, scroll); /* The dropdown starts scrolling downwards when opening it towards * the top and holding down the mouse button. It can be fooled by @@ -473,8 +496,7 @@ void ShowDropDownListAt(Window *w, const DropDownList *list, int selected, int b /** * Show a drop down list. * @param w Parent window for the list. - * @param list Prepopulated DropDownList. Will be deleted when the list is - * closed. + * @param list Prepopulated DropDownList. * @param selected The initially selected list item. * @param button The widget within the parent window that is used to determine * the list's location. @@ -483,7 +505,7 @@ void ShowDropDownListAt(Window *w, const DropDownList *list, int selected, int b * @param instant_close Set to true if releasing mouse button should close the * list regardless of where the cursor is. */ -void ShowDropDownList(Window *w, const DropDownList *list, int selected, int button, uint width, bool auto_width, bool instant_close) +void ShowDropDownList(Window *w, DropDownList &&list, int selected, int button, uint width, bool auto_width, bool instant_close) { /* Our parent's button widget is used to determine where to place the drop * down list window. */ @@ -510,7 +532,7 @@ void ShowDropDownList(Window *w, const DropDownList *list, int selected, int but } } - ShowDropDownListAt(w, list, selected, button, wi_rect, wi_colour, auto_width, instant_close); + ShowDropDownListAt(w, std::move(list), selected, button, wi_rect, wi_colour, auto_width, instant_close); } /** @@ -526,21 +548,15 @@ void ShowDropDownList(Window *w, const DropDownList *list, int selected, int but */ void ShowDropDownMenu(Window *w, const StringID *strings, int selected, int button, uint32 disabled_mask, uint32 hidden_mask, uint width) { - DropDownList *list = new DropDownList(); + DropDownList list; for (uint i = 0; strings[i] != INVALID_STRING_ID; i++) { if (!HasBit(hidden_mask, i)) { - *list->Append() = new DropDownListStringItem(strings[i], i, HasBit(disabled_mask, i)); + list.emplace_back(new DropDownListStringItem(strings[i], i, HasBit(disabled_mask, i))); } } - /* No entries in the list? */ - if (list->Length() == 0) { - delete list; - return; - } - - ShowDropDownList(w, list, selected, button, width); + if (!list.empty()) ShowDropDownList(w, std::move(list), selected, button, width); } /** @@ -555,7 +571,7 @@ int HideDropDownMenu(Window *pw) if (w->window_class != WC_DROPDOWN_MENU) continue; DropdownWindow *dw = dynamic_cast(w); - assert(dw != NULL); + assert(dw != nullptr); if (pw->window_class == dw->parent_wnd_class && pw->window_number == dw->parent_wnd_num) { int parent_button = dw->parent_button; diff --git a/src/widgets/dropdown_func.h b/src/widgets/dropdown_func.h index 4c7e134562..f047fb43df 100644 --- a/src/widgets/dropdown_func.h +++ b/src/widgets/dropdown_func.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/widgets/dropdown_type.h b/src/widgets/dropdown_type.h index 4c330117e7..bda1e4407a 100644 --- a/src/widgets/dropdown_type.h +++ b/src/widgets/dropdown_type.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. @@ -33,7 +31,7 @@ public: virtual bool Selectable() const { return false; } virtual uint Height(uint width) const { return GetMinSizing(NWST_STEP, FONT_HEIGHT_NORMAL); } virtual uint Width() const { return 0; } - virtual void Draw(int left, int right, int top, int bottom, bool sel, int bg_colour) const; + virtual void Draw(int left, int right, int top, int bottom, bool sel, Colours bg_colour) const; }; /** @@ -44,14 +42,13 @@ public: StringID string; ///< String ID of item DropDownListStringItem(StringID string, int result, bool masked) : DropDownListItem(result, masked), string(string) {} - virtual ~DropDownListStringItem() {} - virtual bool Selectable() const { return true; } - virtual uint Width() const; - virtual void Draw(int left, int right, int top, int bottom, bool sel, int bg_colour) const; + 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; virtual StringID String() const { return this->string; } - static int CDECL NatSortFunc(const DropDownListItem * const *first, const DropDownListItem * const *second); + static bool NatSortFunc(std::unique_ptr const &first, std::unique_ptr const &second); }; /** @@ -62,10 +59,9 @@ public: uint64 decode_params[10]; ///< Parameters of the string DropDownListParamStringItem(StringID string, int result, bool masked) : DropDownListStringItem(string, result, masked) {} - virtual ~DropDownListParamStringItem() {} - virtual StringID String() const; - virtual void SetParam(uint index, uint64 value) { decode_params[index] = value; } + StringID String() const override; + void SetParam(uint index, uint64 value) { decode_params[index] = value; } }; /** @@ -76,18 +72,35 @@ public: const char *raw_string; DropDownListCharStringItem(const char *raw_string, int result, bool masked) : DropDownListStringItem(STR_JUST_RAW_STRING, result, masked), raw_string(raw_string) {} - virtual ~DropDownListCharStringItem() {} - virtual StringID String() const; + StringID String() const override; +}; + +/** + * List item with icon and string. + */ +class DropDownListIconItem : public DropDownListParamStringItem { + SpriteID sprite; + PaletteID pal; + Dimension dim; + uint sprite_y; + uint text_y; +public: + DropDownListIconItem(SpriteID sprite, PaletteID pal, StringID string, int result, bool masked); + + 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 SetDimension(Dimension d); }; /** * A drop down list is a collection of drop down list items. */ -typedef AutoDeleteSmallVector DropDownList; +typedef std::vector> DropDownList; -void ShowDropDownListAt(Window *w, const DropDownList *list, int selected, int button, Rect wi_rect, Colours wi_colour, bool auto_width = false, bool instant_close = false); +void ShowDropDownListAt(Window *w, DropDownList &&list, int selected, int button, Rect wi_rect, Colours wi_colour, bool auto_width = false, bool instant_close = false); -void ShowDropDownList(Window *w, const DropDownList *list, int selected, int button, uint width = 0, bool auto_width = false, bool instant_close = false); +void ShowDropDownList(Window *w, DropDownList &&list, int selected, int button, uint width = 0, bool auto_width = false, bool instant_close = false); #endif /* WIDGETS_DROPDOWN_TYPE_H */ diff --git a/src/widgets/dropdown_widget.h b/src/widgets/dropdown_widget.h index 0390a950ac..21223179e9 100644 --- a/src/widgets/dropdown_widget.h +++ b/src/widgets/dropdown_widget.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/widgets/engine_widget.h b/src/widgets/engine_widget.h index b131a1dd4b..5d3468efc6 100644 --- a/src/widgets/engine_widget.h +++ b/src/widgets/engine_widget.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/widgets/error_widget.h b/src/widgets/error_widget.h index b1fcb1b01c..18ce79c103 100644 --- a/src/widgets/error_widget.h +++ b/src/widgets/error_widget.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/widgets/fios_widget.h b/src/widgets/fios_widget.h index 1199fdaa9a..0b3de3870a 100644 --- a/src/widgets/fios_widget.h +++ b/src/widgets/fios_widget.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/widgets/framerate_widget.h b/src/widgets/framerate_widget.h index 2c82c85e5e..49ee2f9528 100644 --- a/src/widgets/framerate_widget.h +++ b/src/widgets/framerate_widget.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. @@ -22,6 +20,8 @@ enum FramerateWindowWidgets { WID_FRW_TIMES_NAMES, WID_FRW_TIMES_CURRENT, WID_FRW_TIMES_AVERAGE, + WID_FRW_ALLOCSIZE, + WID_FRW_SEL_MEMORY, WID_FRW_SCROLLBAR, }; diff --git a/src/widgets/genworld_widget.h b/src/widgets/genworld_widget.h index 877efbb921..f7bf20e950 100644 --- a/src/widgets/genworld_widget.h +++ b/src/widgets/genworld_widget.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/widgets/goal_widget.h b/src/widgets/goal_widget.h index 388930a102..e5da620510 100644 --- a/src/widgets/goal_widget.h +++ b/src/widgets/goal_widget.h @@ -1,6 +1,4 @@ -/* $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/widgets/graph_widget.h b/src/widgets/graph_widget.h index 7af5297abf..7c6478f640 100644 --- a/src/widgets/graph_widget.h +++ b/src/widgets/graph_widget.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/widgets/group_widget.h b/src/widgets/group_widget.h index fe5ae81174..beca5a3a65 100644 --- a/src/widgets/group_widget.h +++ b/src/widgets/group_widget.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/widgets/highscore_widget.h b/src/widgets/highscore_widget.h index 3a2a1bfbb7..394b8c9bf7 100644 --- a/src/widgets/highscore_widget.h +++ b/src/widgets/highscore_widget.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/widgets/industry_widget.h b/src/widgets/industry_widget.h index 711694db72..e9fb2b1148 100644 --- a/src/widgets/industry_widget.h +++ b/src/widgets/industry_widget.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. @@ -32,10 +30,12 @@ enum IndustryViewWidgets { /** Widgets of the #IndustryDirectoryWindow class. */ enum IndustryDirectoryWidgets { - WID_ID_DROPDOWN_ORDER, ///< Dropdown for the order of the sort. - WID_ID_DROPDOWN_CRITERIA, ///< Dropdown for the criteria of the sort. - WID_ID_INDUSTRY_LIST, ///< Industry list. - WID_ID_SCROLLBAR, ///< Scrollbar of the list. + WID_ID_DROPDOWN_ORDER, ///< Dropdown for the order of the sort. + 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_INDUSTRY_LIST, ///< Industry list. + WID_ID_SCROLLBAR, ///< Scrollbar of the list. }; /** Widgets of the #IndustryCargoesWindow class */ diff --git a/src/widgets/intro_widget.h b/src/widgets/intro_widget.h index 4b772852e5..5450ef6ec0 100644 --- a/src/widgets/intro_widget.h +++ b/src/widgets/intro_widget.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/widgets/link_graph_legend_widget.h b/src/widgets/link_graph_legend_widget.h index 9537b896df..a0ff68ab07 100644 --- a/src/widgets/link_graph_legend_widget.h +++ b/src/widgets/link_graph_legend_widget.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/widgets/main_widget.h b/src/widgets/main_widget.h index 3ffc1214b8..51627da5c0 100644 --- a/src/widgets/main_widget.h +++ b/src/widgets/main_widget.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/widgets/misc_widget.h b/src/widgets/misc_widget.h index a6dd081a9d..bc0c07030b 100644 --- a/src/widgets/misc_widget.h +++ b/src/widgets/misc_widget.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. @@ -32,6 +30,7 @@ enum AboutWidgets { enum QueryStringWidgets { WID_QS_CAPTION, ///< Caption of the window. WID_QS_TEXT, ///< Text of the query. + WID_QS_WARNING, ///< Warning label about password security WID_QS_DEFAULT, ///< Default button. WID_QS_CANCEL, ///< Cancel button. WID_QS_OK, ///< OK button. diff --git a/src/widgets/music_widget.h b/src/widgets/music_widget.h index cd48dc469a..ce6c7b395b 100644 --- a/src/widgets/music_widget.h +++ b/src/widgets/music_widget.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/widgets/network_chat_widget.h b/src/widgets/network_chat_widget.h index cd13cf6a96..ccfb467f71 100644 --- a/src/widgets/network_chat_widget.h +++ b/src/widgets/network_chat_widget.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/widgets/network_content_widget.h b/src/widgets/network_content_widget.h index e659743d4f..fd77f90aaf 100644 --- a/src/widgets/network_content_widget.h +++ b/src/widgets/network_content_widget.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/widgets/network_widget.h b/src/widgets/network_widget.h index f5773b8ea8..23ea95a61a 100644 --- a/src/widgets/network_widget.h +++ b/src/widgets/network_widget.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. @@ -122,6 +120,7 @@ enum NetworkCompanyPasswordWidgets { WID_NCP_LABEL, ///< Label in front of the password field. WID_NCP_PASSWORD, ///< Input field for the password. WID_NCP_SAVE_AS_DEFAULT_PASSWORD, ///< Toggle 'button' for saving the current password as default password. + WID_NCP_WARNING, ///< Warning text about password security WID_NCP_CANCEL, ///< Close the window without changing anything. WID_NCP_OK, ///< Safe the password etc. }; diff --git a/src/widgets/newgrf_debug_widget.h b/src/widgets/newgrf_debug_widget.h index 22a5cda40e..6ae41de348 100644 --- a/src/widgets/newgrf_debug_widget.h +++ b/src/widgets/newgrf_debug_widget.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/widgets/newgrf_widget.h b/src/widgets/newgrf_widget.h index 271b6669ad..7f5fefde06 100644 --- a/src/widgets/newgrf_widget.h +++ b/src/widgets/newgrf_widget.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/widgets/news_widget.h b/src/widgets/news_widget.h index f12786640f..e5b8934439 100644 --- a/src/widgets/news_widget.h +++ b/src/widgets/news_widget.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. @@ -33,6 +31,7 @@ enum NewsWidgets { WID_N_VEH_NAME, ///< Name of the new vehicle. WID_N_VEH_SPR, ///< Graphical display of the new vehicle. WID_N_VEH_INFO, ///< Some technical data of the new vehicle. + WID_N_SHOW_GROUP, ///< Show vehicle's group }; /** Widgets of the #MessageHistoryWindow class. */ diff --git a/src/widgets/object_widget.h b/src/widgets/object_widget.h index 45533ae98e..9ca06e2fea 100644 --- a/src/widgets/object_widget.h +++ b/src/widgets/object_widget.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/widgets/order_widget.h b/src/widgets/order_widget.h index 825f791ea8..82ca472e20 100644 --- a/src/widgets/order_widget.h +++ b/src/widgets/order_widget.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/widgets/osk_widget.h b/src/widgets/osk_widget.h index 25cd928a86..ccda502fff 100644 --- a/src/widgets/osk_widget.h +++ b/src/widgets/osk_widget.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/widgets/rail_widget.h b/src/widgets/rail_widget.h index d334f02c5a..aab2a1c919 100644 --- a/src/widgets/rail_widget.h +++ b/src/widgets/rail_widget.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/widgets/road_widget.h b/src/widgets/road_widget.h index f022489e53..3d49e9ae9d 100644 --- a/src/widgets/road_widget.h +++ b/src/widgets/road_widget.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. @@ -15,6 +13,7 @@ /** Widgets of the #BuildRoadToolbarWindow class. */ enum RoadToolbarWidgets { /* Name starts with RO instead of R, because of collision with RailToolbarWidgets */ + WID_ROT_CAPTION, ///< Caption of the window WID_ROT_ROAD_X, ///< Build road in x-direction. WID_ROT_ROAD_Y, ///< Build road in y-direction. WID_ROT_AUTOROAD, ///< Autorail. @@ -26,6 +25,7 @@ enum RoadToolbarWidgets { WID_ROT_BUILD_BRIDGE, ///< Build bridge. WID_ROT_BUILD_TUNNEL, ///< Build tunnel. WID_ROT_REMOVE, ///< Remove road. + WID_ROT_CONVERT_ROAD, ///< Convert road. }; /** Widgets of the #BuildRoadDepotWindow class. */ diff --git a/src/widgets/screenshot_widget.h b/src/widgets/screenshot_widget.h new file mode 100644 index 0000000000..6f42b784d6 --- /dev/null +++ b/src/widgets/screenshot_widget.h @@ -0,0 +1,26 @@ +/* + * 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 screenshot_widget.h Types related to the screenshot widgets. */ + +#ifndef WIDGETS_SCREENSHOT_WIDGET_H +#define WIDGETS_SCREENSHOT_WIDGET_H + +/** Widgets of the #ScreenshotWindow class. */ + +enum ScreenshotWindowWidgets { + WID_SC_TAKE, ///< Button for taking a normal screenshot + WID_SC_TAKE_ZOOMIN, ///< Button for taking a zoomed in screenshot + WID_SC_TAKE_DEFAULTZOOM, ///< Button for taking a screenshot at normal zoom + WID_SC_TAKE_WORLD, ///< Button for taking a screenshot of the whole world + WID_SC_TAKE_HEIGHTMAP, ///< Button for taking a heightmap "screenshot" + WID_SC_TAKE_MINIMAP, ///< Button for taking a minimap screenshot +}; + + +#endif /* WIDGETS_SCREENSHOT_WIDGET_H */ + diff --git a/src/widgets/settings_widget.h b/src/widgets/settings_widget.h index 48ee83c933..e28efa3a3c 100644 --- a/src/widgets/settings_widget.h +++ b/src/widgets/settings_widget.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/widgets/sign_widget.h b/src/widgets/sign_widget.h index f390793ceb..2225eb8b1c 100644 --- a/src/widgets/sign_widget.h +++ b/src/widgets/sign_widget.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/widgets/smallmap_widget.h b/src/widgets/smallmap_widget.h index 0b1daea03f..79769a21cc 100644 --- a/src/widgets/smallmap_widget.h +++ b/src/widgets/smallmap_widget.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/widgets/station_widget.h b/src/widgets/station_widget.h index 82fe392e33..8ab89bbf31 100644 --- a/src/widgets/station_widget.h +++ b/src/widgets/station_widget.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. @@ -30,6 +28,7 @@ enum StationViewWidgets { WID_SV_ROADVEHS, ///< List of scheduled road vehs button. WID_SV_SHIPS, ///< List of scheduled ships button. WID_SV_PLANES, ///< List of scheduled planes button. + WID_SV_CATCHMENT, ///< Toggle catchment area highlight. }; /** Widgets of the #CompanyStationsWindow class. */ diff --git a/src/widgets/statusbar_widget.h b/src/widgets/statusbar_widget.h index 1cfbe7ff29..bb8149e461 100644 --- a/src/widgets/statusbar_widget.h +++ b/src/widgets/statusbar_widget.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/widgets/story_widget.h b/src/widgets/story_widget.h index 139b6d2d6b..3492aed419 100644 --- a/src/widgets/story_widget.h +++ b/src/widgets/story_widget.h @@ -1,6 +1,4 @@ -/* $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/widgets/subsidy_widget.h b/src/widgets/subsidy_widget.h index 07d0f6cfbb..b3edd897c5 100644 --- a/src/widgets/subsidy_widget.h +++ b/src/widgets/subsidy_widget.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/widgets/terraform_widget.h b/src/widgets/terraform_widget.h index 7f8a4c4d1b..0fd216d721 100644 --- a/src/widgets/terraform_widget.h +++ b/src/widgets/terraform_widget.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/widgets/timetable_widget.h b/src/widgets/timetable_widget.h index 09beb61672..15c44f33c5 100644 --- a/src/widgets/timetable_widget.h +++ b/src/widgets/timetable_widget.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/widgets/toolbar_widget.h b/src/widgets/toolbar_widget.h index 1692a9505e..3c88daae0c 100644 --- a/src/widgets/toolbar_widget.h +++ b/src/widgets/toolbar_widget.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. @@ -39,6 +37,7 @@ enum ToolbarNormalWidgets { WID_TN_BUILDING_TOOLS_START, ///< Helper for the offset of the building tools WID_TN_RAILS = WID_TN_BUILDING_TOOLS_START, ///< Rail building menu. WID_TN_ROADS, ///< Road building menu. + WID_TN_TRAMS, ///< Tram building menu. WID_TN_WATER, ///< Water building toolbar. WID_TN_AIR, ///< Airport building toolbar. WID_TN_LANDSCAPE, ///< Landscaping toolbar. @@ -69,14 +68,14 @@ enum ToolbarEditorWidgets { WID_TE_TOWN_GENERATE, ///< Town building window. WID_TE_INDUSTRY, ///< Industry building window. WID_TE_ROADS, ///< Road building menu. + WID_TE_TRAMS, ///< Tram building menu. WID_TE_WATER, ///< Water building toolbar. WID_TE_TREES, ///< Tree building toolbar. WID_TE_SIGNS, ///< Sign building. WID_TE_DATE_PANEL, ///< Container for the date widgets. - /* The following three need to have the same actual widget number as the normal toolbar due to shared code. */ - WID_TE_MUSIC_SOUND = WID_TN_MUSIC_SOUND, ///< Music/sound configuration menu. - WID_TE_HELP = WID_TN_HELP, ///< Help menu. - WID_TE_SWITCH_BAR = WID_TN_SWITCH_BAR, ///< Only available when toolbar has been split to switch between different subsets. + WID_TE_MUSIC_SOUND, ///< Music/sound configuration menu. + WID_TE_HELP, ///< Help menu. + WID_TE_SWITCH_BAR, ///< Only available when toolbar has been split to switch between different subsets. }; #endif /* WIDGETS_TOOLBAR_WIDGET_H */ diff --git a/src/widgets/town_widget.h b/src/widgets/town_widget.h index 4f5443c36e..1a3291a3db 100644 --- a/src/widgets/town_widget.h +++ b/src/widgets/town_widget.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. @@ -16,6 +14,7 @@ enum TownDirectoryWidgets { WID_TD_SORT_ORDER, ///< Direction of sort dropdown. WID_TD_SORT_CRITERIA, ///< Criteria of sort dropdown. + WID_TD_FILTER, ///< Filter of name. WID_TD_LIST, ///< List of towns. WID_TD_SCROLLBAR, ///< Scrollbar for the town list. WID_TD_WORLD_POPULATION, ///< The world's population. @@ -24,6 +23,7 @@ enum TownDirectoryWidgets { /** Widgets of the #TownAuthorityWindow class. */ enum TownAuthorityWidgets { WID_TA_CAPTION, ///< Caption of window. + WID_TA_ZONE_BUTTON, ///< Turn on/off showing local authority zone. WID_TA_RATING_INFO, ///< Overview with ratings for each company. WID_TA_COMMAND_LIST, ///< List of commands for the player. WID_TA_SCROLLBAR, ///< Scrollbar of the list of commands. @@ -39,6 +39,7 @@ enum TownViewWidgets { WID_TV_CENTER_VIEW, ///< Center the main view on this town. WID_TV_SHOW_AUTHORITY, ///< Show the town authority window. WID_TV_CHANGE_NAME, ///< Change the name of this town. + WID_TV_CATCHMENT, ///< Toggle catchment area highlight. WID_TV_EXPAND, ///< Expand this town (scenario editor only). WID_TV_DELETE, ///< Delete this town (scenario editor only). }; diff --git a/src/widgets/transparency_widget.h b/src/widgets/transparency_widget.h index 87618fcb6e..2b096e733b 100644 --- a/src/widgets/transparency_widget.h +++ b/src/widgets/transparency_widget.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/widgets/tree_widget.h b/src/widgets/tree_widget.h index cd0b85c9d1..7da9fa4a84 100644 --- a/src/widgets/tree_widget.h +++ b/src/widgets/tree_widget.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/widgets/vehicle_widget.h b/src/widgets/vehicle_widget.h index a0902dab44..5ecb8dffea 100644 --- a/src/widgets/vehicle_widget.h +++ b/src/widgets/vehicle_widget.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/widgets/viewport_widget.h b/src/widgets/viewport_widget.h index 187659f362..81a6983e89 100644 --- a/src/widgets/viewport_widget.h +++ b/src/widgets/viewport_widget.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/widgets/waypoint_widget.h b/src/widgets/waypoint_widget.h index 8fceddaa70..a5b316034f 100644 --- a/src/widgets/waypoint_widget.h +++ b/src/widgets/waypoint_widget.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/window.cpp b/src/window.cpp index d0ae836b4a..c9db47bc18 100644 --- a/src/window.cpp +++ b/src/window.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. @@ -54,15 +52,15 @@ enum ViewportAutoscrolling { static bool _dragging_window; ///< A window is being dragged or resized. static Point _drag_delta; ///< delta between mouse cursor and upper left corner of dragged window -static Window *_mouseover_last_w = NULL; ///< Window of the last OnMouseOver event. +static Window *_mouseover_last_w = nullptr; ///< Window of the last OnMouseOver event. static Point _left_button_down_pos; ///< Position of left mouse button down event, to handle the difference between click and drag static bool _dragging_widget; ///< A widget inside the window is being dragged, prevent the window itself from being dragged -static Window *_last_scroll_window = NULL; ///< Window of the last scroll event. +static Window *_last_scroll_window = nullptr; ///< Window of the last scroll event. /** List of windows opened at the screen sorted from the front. */ -Window *_z_front_window = NULL; +Window *_z_front_window = nullptr; /** List of windows opened at the screen sorted from the back. */ -Window *_z_back_window = NULL; +Window *_z_back_window = nullptr; /** If false, highlight is white, otherwise the by the widget defined colour. */ bool _window_highlight_colour = false; @@ -91,7 +89,7 @@ SpecialMouseMode _special_mouse_mode; ///< Mode of the mouse. * List of all WindowDescs. * This is a pointer to ensure initialisation order with the various static WindowDesc instances. */ -static SmallVector *_window_descs = NULL; +static std::vector *_window_descs = nullptr; /** Config file to store WindowDesc */ char *_windows_file; @@ -114,18 +112,18 @@ WindowDesc::WindowDesc(WindowPosition def_pos, const char *ini_key, int16 def_wi default_width_trad(def_width_trad), default_height_trad(def_height_trad) { - if (_window_descs == NULL) _window_descs = new SmallVector(); - *_window_descs->Append() = this; + if (_window_descs == nullptr) _window_descs = new std::vector(); + _window_descs->push_back(this); } WindowDesc::~WindowDesc() { - _window_descs->Erase(_window_descs->Find(this)); + _window_descs->erase(std::find(_window_descs->begin(), _window_descs->end(), this)); } /** * Determine default width of window. - * This is either a stored user preferred size, or the build-in default. + * This is either a stored user preferred size, or the built-in default. * @return Width in pixels. */ int16 WindowDesc::GetDefaultWidth() const @@ -135,7 +133,7 @@ int16 WindowDesc::GetDefaultWidth() const /** * Determine default height of window. - * This is either a stored user preferred size, or the build-in default. + * This is either a stored user preferred size, or the built-in default. * @return Height in pixels. */ int16 WindowDesc::GetDefaultHeight() const @@ -150,9 +148,9 @@ void WindowDesc::LoadFromConfig() { IniFile *ini = new IniFile(); ini->LoadFromDisk(_windows_file, NO_DIRECTORY); - for (WindowDesc **it = _window_descs->Begin(); it != _window_descs->End(); ++it) { - if ((*it)->ini_key == NULL) continue; - IniLoadWindowSettings(ini, (*it)->ini_key, *it); + for (WindowDesc *wd : *_window_descs) { + if (wd->ini_key == nullptr) continue; + IniLoadWindowSettings(ini, wd->ini_key, wd); } delete ini; } @@ -160,10 +158,10 @@ void WindowDesc::LoadFromConfig() /** * Sort WindowDesc by ini_key. */ -static int CDECL DescSorter(WindowDesc * const *a, WindowDesc * const *b) +static bool DescSorter(WindowDesc* const &a, WindowDesc* const &b) { - if ((*a)->ini_key != NULL && (*b)->ini_key != NULL) return strcmp((*a)->ini_key, (*b)->ini_key); - return ((*b)->ini_key != NULL ? 1 : 0) - ((*a)->ini_key != NULL ? 1 : 0); + if (a->ini_key != nullptr && b->ini_key != nullptr) return strcmp(a->ini_key, b->ini_key) < 0; + return a->ini_key != nullptr; } /** @@ -172,13 +170,13 @@ static int CDECL DescSorter(WindowDesc * const *a, WindowDesc * const *b) void WindowDesc::SaveToConfig() { /* Sort the stuff to get a nice ini file on first write */ - QSortT(_window_descs->Begin(), _window_descs->Length(), DescSorter); + std::sort(_window_descs->begin(), _window_descs->end(), DescSorter); IniFile *ini = new IniFile(); ini->LoadFromDisk(_windows_file, NO_DIRECTORY); - for (WindowDesc **it = _window_descs->Begin(); it != _window_descs->End(); ++it) { - if ((*it)->ini_key == NULL) continue; - IniSaveWindowSettings(ini, (*it)->ini_key, *it); + for (WindowDesc *wd : *_window_descs) { + if (wd->ini_key == nullptr) continue; + IniSaveWindowSettings(ini, wd->ini_key, wd); } ini->SaveToDisk(_windows_file); delete ini; @@ -189,7 +187,7 @@ void WindowDesc::SaveToConfig() */ void Window::ApplyDefaults() { - if (this->nested_root != NULL && this->nested_root->GetWidgetOfType(WWT_STICKYBOX) != NULL) { + if (this->nested_root != nullptr && this->nested_root->GetWidgetOfType(WWT_STICKYBOX) != nullptr) { if (this->window_desc->pref_sticky) this->flags |= WF_STICKY; } else { /* There is no stickybox; clear the preference in case someone tried to be funny */ @@ -221,7 +219,7 @@ void Window::DisableAllWidgetHighlight() { for (uint i = 0; i < this->nested_array_size; i++) { NWidgetBase *nwid = this->GetWidget(i); - if (nwid == NULL) continue; + if (nwid == nullptr) continue; if (nwid->IsHighlighted()) { nwid->SetHighlighted(TC_INVALID); @@ -242,7 +240,7 @@ void Window::SetWidgetHighlight(byte widget_index, TextColour highlighted_colour assert(widget_index < this->nested_array_size); NWidgetBase *nwid = this->GetWidget(widget_index); - if (nwid == NULL) return; + if (nwid == nullptr) return; nwid->SetHighlighted(highlighted_colour); this->SetWidgetDirty(widget_index); @@ -255,7 +253,7 @@ void Window::SetWidgetHighlight(byte widget_index, TextColour highlighted_colour bool valid = false; for (uint i = 0; i < this->nested_array_size; i++) { NWidgetBase *nwid = this->GetWidget(i); - if (nwid == NULL) continue; + if (nwid == nullptr) continue; if (!nwid->IsHighlighted()) continue; valid = true; @@ -275,7 +273,7 @@ bool Window::IsWidgetHighlighted(byte widget_index) const assert(widget_index < this->nested_array_size); const NWidgetBase *nwid = this->GetWidget(widget_index); - if (nwid == NULL) return false; + if (nwid == nullptr) return false; return nwid->IsHighlighted(); } @@ -332,63 +330,63 @@ Scrollbar *Window::GetScrollbar(uint widnum) /** * Return the querystring associated to a editbox. * @param widnum Editbox widget index - * @return QueryString or NULL. + * @return QueryString or nullptr. */ const QueryString *Window::GetQueryString(uint widnum) const { - const SmallMap::Pair *query = this->querystrings.Find(widnum); - return query != this->querystrings.End() ? query->second : NULL; + auto query = this->querystrings.Find(widnum); + return query != this->querystrings.end() ? query->second : nullptr; } /** * Return the querystring associated to a editbox. * @param widnum Editbox widget index - * @return QueryString or NULL. + * @return QueryString or nullptr. */ QueryString *Window::GetQueryString(uint widnum) { SmallMap::Pair *query = this->querystrings.Find(widnum); - return query != this->querystrings.End() ? query->second : NULL; + return query != this->querystrings.End() ? query->second : nullptr; } /** * Get the current input text if an edit box has the focus. - * @return The currently focused input text or NULL if no input focused. + * @return The currently focused input text or nullptr if no input focused. */ /* virtual */ const char *Window::GetFocusedText() const { - if (this->nested_focus != NULL && this->nested_focus->type == WWT_EDITBOX) { + if (this->nested_focus != nullptr && this->nested_focus->type == WWT_EDITBOX) { return this->GetQueryString(this->nested_focus->index)->GetText(); } - return NULL; + return nullptr; } /** * Get the string at the caret if an edit box has the focus. - * @return The text at the caret or NULL if no edit box is focused. + * @return The text at the caret or nullptr if no edit box is focused. */ /* virtual */ const char *Window::GetCaret() const { - if (this->nested_focus != NULL && this->nested_focus->type == WWT_EDITBOX) { + if (this->nested_focus != nullptr && this->nested_focus->type == WWT_EDITBOX) { return this->GetQueryString(this->nested_focus->index)->GetCaret(); } - return NULL; + return nullptr; } /** * Get the range of the currently marked input text. * @param[out] length Length of the marked text. - * @return Pointer to the start of the marked text or NULL if no text is marked. + * @return Pointer to the start of the marked text or nullptr if no text is marked. */ /* virtual */ const char *Window::GetMarkedText(size_t *length) const { - if (this->nested_focus != NULL && this->nested_focus->type == WWT_EDITBOX) { + if (this->nested_focus != nullptr && this->nested_focus->type == WWT_EDITBOX) { return this->GetQueryString(this->nested_focus->index)->GetMarkedText(length); } - return NULL; + return nullptr; } /** @@ -397,7 +395,7 @@ QueryString *Window::GetQueryString(uint widnum) */ /* virtual */ Point Window::GetCaretPosition() const { - if (this->nested_focus != NULL && this->nested_focus->type == WWT_EDITBOX) { + if (this->nested_focus != nullptr && this->nested_focus->type == WWT_EDITBOX && !this->querystrings.empty()) { return this->GetQueryString(this->nested_focus->index)->GetCaretPosition(this, this->nested_focus->index); } @@ -413,7 +411,7 @@ QueryString *Window::GetQueryString(uint widnum) */ /* virtual */ Rect Window::GetTextBoundingRect(const char *from, const char *to) const { - if (this->nested_focus != NULL && this->nested_focus->type == WWT_EDITBOX) { + if (this->nested_focus != nullptr && this->nested_focus->type == WWT_EDITBOX) { return this->GetQueryString(this->nested_focus->index)->GetBoundingRect(this, this->nested_focus->index, from, to); } @@ -424,15 +422,15 @@ QueryString *Window::GetQueryString(uint widnum) /** * Get the character that is rendered at a position by the focused edit box. * @param pt The position to test. - * @return Pointer to the character at the position or NULL if no character is at the position. + * @return Pointer to the character at the position or nullptr if no character is at the position. */ /* virtual */ const char *Window::GetTextCharacterAtPosition(const Point &pt) const { - if (this->nested_focus != NULL && this->nested_focus->type == WWT_EDITBOX) { + if (this->nested_focus != nullptr && this->nested_focus->type == WWT_EDITBOX) { return this->GetQueryString(this->nested_focus->index)->GetCharAtPosition(this, this->nested_focus->index, pt); } - return NULL; + return nullptr; } /** @@ -444,8 +442,8 @@ void SetFocusedWindow(Window *w) if (_focused_window == w) return; /* Invalidate focused widget */ - if (_focused_window != NULL) { - if (_focused_window->nested_focus != NULL) _focused_window->nested_focus->SetDirty(_focused_window); + if (_focused_window != nullptr) { + if (_focused_window->nested_focus != nullptr) _focused_window->nested_focus->SetDirty(_focused_window); } /* Remember which window was previously focused */ @@ -453,8 +451,8 @@ void SetFocusedWindow(Window *w) _focused_window = w; /* So we can inform it that it lost focus */ - if (old_focused != NULL) old_focused->OnFocusLost(); - if (_focused_window != NULL) _focused_window->OnFocus(); + if (old_focused != nullptr) old_focused->OnFocusLost(); + if (_focused_window != nullptr) _focused_window->OnFocus(); } /** @@ -464,12 +462,21 @@ void SetFocusedWindow(Window *w) */ bool EditBoxInGlobalFocus() { - if (_focused_window == NULL) return false; + if (_focused_window == nullptr) return false; /* The console does not have an edit box so a special case is needed. */ if (_focused_window->window_class == WC_CONSOLE) return true; - return _focused_window->nested_focus != NULL && _focused_window->nested_focus->type == WWT_EDITBOX; + return _focused_window->nested_focus != nullptr && _focused_window->nested_focus->type == WWT_EDITBOX; +} + +/** + * Check if a console is focused. + * @return returns true if the focused window is a console, else false + */ +bool FocusedWindowIsConsole() +{ + return _focused_window && _focused_window->window_class == WC_CONSOLE; } /** @@ -477,12 +484,12 @@ bool EditBoxInGlobalFocus() */ void Window::UnfocusFocusedWidget() { - if (this->nested_focus != NULL) { + if (this->nested_focus != nullptr) { if (this->nested_focus->type == WWT_EDITBOX) VideoDriver::GetInstance()->EditBoxLostFocus(); /* Repaint the widget that lost focus. A focused edit box may else leave the caret on the screen. */ this->nested_focus->SetDirty(this); - this->nested_focus = NULL; + this->nested_focus = nullptr; } } @@ -496,8 +503,8 @@ bool Window::SetFocusedWidget(int widget_index) /* Do nothing if widget_index is already focused, or if it wasn't a valid widget. */ if ((uint)widget_index >= this->nested_array_size) return false; - assert(this->nested_array[widget_index] != NULL); // Setting focus to a non-existing widget is a bad idea. - if (this->nested_focus != NULL) { + assert(this->nested_array[widget_index] != nullptr); // Setting focus to a non-existing widget is a bad idea. + if (this->nested_focus != nullptr) { if (this->GetWidget(widget_index) == this->nested_focus) return false; /* Repaint the widget that lost focus. A focused edit box may else leave the caret on the screen. */ @@ -505,15 +512,24 @@ bool Window::SetFocusedWidget(int widget_index) if (this->nested_focus->type == WWT_EDITBOX) VideoDriver::GetInstance()->EditBoxLostFocus(); } this->nested_focus = this->GetWidget(widget_index); + if (this->nested_focus->type == WWT_EDITBOX) VideoDriver::GetInstance()->EditBoxGainedFocus(); return true; } /** - * Called when window looses focus + * Called when window gains focus + */ +void Window::OnFocus() +{ + if (this->nested_focus != nullptr && this->nested_focus->type == WWT_EDITBOX) VideoDriver::GetInstance()->EditBoxGainedFocus(); +} + +/** + * Called when window loses focus */ void Window::OnFocusLost() { - if (this->nested_focus != NULL && this->nested_focus->type == WWT_EDITBOX) VideoDriver::GetInstance()->EditBoxLostFocus(); + if (this->nested_focus != nullptr && this->nested_focus->type == WWT_EDITBOX) VideoDriver::GetInstance()->EditBoxLostFocus(); } /** @@ -563,7 +579,7 @@ void CDECL Window::SetWidgetsLoweredState(bool lowered_stat, int widgets, ...) void Window::RaiseButtons(bool autoraise) { for (uint i = 0; i < this->nested_array_size; i++) { - if (this->nested_array[i] == NULL) continue; + if (this->nested_array[i] == nullptr) continue; WidgetType type = this->nested_array[i]->type; if (((type & ~WWB_PUSHBUTTON) < WWT_LAST || type == NWID_PUSHBUTTON_DROPDOWN) && (!autoraise || (type & WWB_PUSHBUTTON) || type == WWT_EDITBOX) && this->IsWidgetLowered(i)) { @@ -573,8 +589,8 @@ void Window::RaiseButtons(bool autoraise) } /* Special widgets without widget index */ - NWidgetCore *wid = this->nested_root != NULL ? (NWidgetCore*)this->nested_root->GetWidgetOfType(WWT_DEFSIZEBOX) : NULL; - if (wid != NULL) { + NWidgetCore *wid = this->nested_root != nullptr ? (NWidgetCore*)this->nested_root->GetWidgetOfType(WWT_DEFSIZEBOX) : nullptr; + if (wid != nullptr) { wid->SetLowered(false); wid->SetDirty(this); } @@ -587,7 +603,7 @@ void Window::RaiseButtons(bool autoraise) void Window::SetWidgetDirty(byte widget_index) const { /* Sometimes this function is called before the window is even fully initialized */ - if (this->nested_array == NULL) return; + if (this->nested_array == nullptr) return; this->nested_array[widget_index]->SetDirty(this); } @@ -602,7 +618,7 @@ EventState Window::OnHotkey(int hotkey) if (hotkey < 0) return ES_NOT_HANDLED; NWidgetCore *nw = this->GetWidget(hotkey); - if (nw == NULL || nw->IsDisabled()) return ES_NOT_HANDLED; + if (nw == nullptr || nw->IsDisabled()) return ES_NOT_HANDLED; if (nw->type == WWT_EDITBOX) { if (this->IsShaded()) return ES_NOT_HANDLED; @@ -643,7 +659,7 @@ static void StartWindowSizing(Window *w, bool to_left); static void DispatchLeftClickEvent(Window *w, int x, int y, int click_count, bool mouse_down) { NWidgetCore *nw = w->nested_root->GetWidgetFromPos(x, y); - WidgetType widget_type = (nw != NULL) ? nw->type : WWT_EMPTY; + WidgetType widget_type = (nw != nullptr) ? nw->type : WWT_EMPTY; bool focused_widget_changed = false; /* If clicked on a window that previously did dot have focus */ @@ -654,7 +670,7 @@ static void DispatchLeftClickEvent(Window *w, int x, int y, int click_count, boo SetFocusedWindow(w); } - if (nw == NULL) return; // exit if clicked outside of widgets + if (nw == nullptr) return; // exit if clicked outside of widgets /* don't allow any interaction if the button has been disabled */ if (nw->IsDisabled()) return; @@ -710,7 +726,7 @@ static void DispatchLeftClickEvent(Window *w, int x, int y, int click_count, boo case WWT_EDITBOX: { QueryString *query = w->GetQueryString(widget_index); - if (query != NULL) query->ClickEditBox(w, pt, widget_index, click_count, focused_widget_changed); + if (query != nullptr) query->ClickEditBox(w, pt, widget_index, click_count, focused_widget_changed); break; } @@ -819,7 +835,9 @@ static void DispatchLeftButtonUpEvent(Window *w, int x, int y) static void DispatchRightClickEvent(Window *w, int x, int y) { NWidgetCore *wid = w->nested_root->GetWidgetFromPos(x, y); - if (wid == NULL) return; + if (wid == nullptr) return; + + Point pt = { x, y }; Point pt = { x, y }; @@ -832,7 +850,7 @@ static void DispatchRightClickEvent(Window *w, int x, int y) if (_settings_client.gui.right_mouse_wnd_close && w->nested_root->GetWidgetOfType(WWT_CLOSEBOX)) { delete w; } else if (_settings_client.gui.hover_delay_ms == 0 && !w->OnTooltip(pt, wid->index, TCC_RIGHT_CLICK) && wid->tool_tip != 0) { - GuiShowTooltips(w, wid->tool_tip, 0, NULL, TCC_RIGHT_CLICK); + GuiShowTooltips(w, wid->tool_tip, 0, nullptr, TCC_RIGHT_CLICK); } } @@ -847,7 +865,9 @@ static void DispatchHoverEvent(Window *w, int x, int y) NWidgetCore *wid = w->nested_root->GetWidgetFromPos(x, y); /* No widget to handle */ - if (wid == NULL) return; + if (wid == nullptr) return; + + Point pt = { x, y }; Point pt = { x, y }; @@ -872,7 +892,7 @@ static void DispatchHoverEvent(Window *w, int x, int y) */ static void DispatchMouseWheelEvent(Window *w, NWidgetCore *nwid, int wheel) { - if (nwid == NULL) return; + if (nwid == nullptr) return; /* Using wheel on caption/shade-box shades or unshades the window. */ if (nwid->type == WWT_CAPTION || nwid->type == WWT_SHADEBOX) { @@ -891,8 +911,8 @@ static void DispatchMouseWheelEvent(Window *w, NWidgetCore *nwid, int wheel) } /* Scroll the widget attached to the scrollbar. */ - Scrollbar *sb = (nwid->scrollbar_index >= 0 ? w->GetScrollbar(nwid->scrollbar_index) : NULL); - if (sb != NULL && sb->GetCount() > sb->GetCapacity()) { + Scrollbar *sb = (nwid->scrollbar_index >= 0 ? w->GetScrollbar(nwid->scrollbar_index) : nullptr); + if (sb != nullptr && sb->GetCount() > sb->GetCapacity()) { sb->UpdatePosition(wheel); w->SetDirty(); } @@ -1065,12 +1085,12 @@ void Window::ReInit(int rx, int ry) */ void Window::SetShaded(bool make_shaded) { - if (this->shade_select == NULL) return; + if (this->shade_select == nullptr) return; int desired = make_shaded ? SZSP_HORIZONTAL : 0; if (this->shade_select->shown_plane != desired) { if (make_shaded) { - if (this->nested_focus != NULL) this->UnfocusFocusedWidget(); + if (this->nested_focus != nullptr) this->UnfocusFocusedWidget(); this->unshaded_size.width = this->width; this->unshaded_size.height = this->height; this->shade_select->SetDisplayedPlane(desired); @@ -1088,7 +1108,7 @@ void Window::SetShaded(bool make_shaded) * Find the Window whose parent pointer points to this window * @param w parent Window to find child of * @param wc Window class of the window to remove; #WC_INVALID if class does not matter - * @return a Window pointer that is the child of \a w, or \c NULL otherwise + * @return a Window pointer that is the child of \a w, or \c nullptr otherwise */ static Window *FindChildWindow(const Window *w, WindowClass wc) { @@ -1097,7 +1117,7 @@ static Window *FindChildWindow(const Window *w, WindowClass wc) if ((wc == WC_INVALID || wc == v->window_class) && v->parent == w) return v; } - return NULL; + return nullptr; } /** @@ -1107,7 +1127,7 @@ static Window *FindChildWindow(const Window *w, WindowClass wc) void Window::DeleteChildWindows(WindowClass wc) const { Window *child = FindChildWindow(this, wc); - while (child != NULL) { + while (child != nullptr) { delete child; child = FindChildWindow(this, wc); } @@ -1124,20 +1144,23 @@ Window::~Window() } /* Prevent Mouseover() from resetting mouse-over coordinates on a non-existing window */ - if (_mouseover_last_w == this) _mouseover_last_w = NULL; + if (_mouseover_last_w == this) _mouseover_last_w = nullptr; /* We can't scroll the window when it's closed. */ - if (_last_scroll_window == this) _last_scroll_window = NULL; + if (_last_scroll_window == this) _last_scroll_window = nullptr; + + /* Make sure we don't try to access non-existing query strings. */ + this->querystrings.clear(); /* Make sure we don't try to access this window as the focused window when it doesn't exist anymore. */ if (_focused_window == this) { this->OnFocusLost(); - _focused_window = NULL; + _focused_window = nullptr; } this->DeleteChildWindows(); - if (this->viewport != NULL) DeleteWindowViewport(this); + if (this->viewport != nullptr) DeleteWindowViewport(this); this->SetDirty(); @@ -1160,7 +1183,7 @@ Window::~Window() * Find a window by its class and window number * @param cls Window class * @param number Number of the window within the window class - * @return Pointer to the found window, or \c NULL if not available + * @return Pointer to the found window, or \c nullptr if not available */ Window *FindWindowById(WindowClass cls, WindowNumber number) { @@ -1169,14 +1192,14 @@ Window *FindWindowById(WindowClass cls, WindowNumber number) if (w->window_class == cls && w->window_number == number) return w; } - return NULL; + return nullptr; } /** * Find any window by its class. Useful when searching for a window that uses * the window number as a #WindowClass, like #WC_SEND_NETWORK_MSG. * @param cls Window class - * @return Pointer to the found window, or \c NULL if not available + * @return Pointer to the found window, or \c nullptr if not available */ Window *FindWindowByClass(WindowClass cls) { @@ -1185,7 +1208,7 @@ Window *FindWindowByClass(WindowClass cls) if (w->window_class == cls) return w; } - return NULL; + return nullptr; } /** @@ -1197,7 +1220,7 @@ Window *FindWindowByClass(WindowClass cls) void DeleteWindowById(WindowClass cls, WindowNumber number, bool force) { Window *w = FindWindowById(cls, number); - if (force || w == NULL || + if (force || w == nullptr || (w->flags & WF_STICKY) == 0) { delete w; } @@ -1295,7 +1318,7 @@ Window *BringWindowToFrontById(WindowClass cls, WindowNumber number) { Window *w = FindWindowById(cls, number); - if (w != NULL) { + if (w != nullptr) { if (w->IsShaded()) w->SetShaded(false); // Restore original window size if it was shaded. w->SetWhiteBorder(); @@ -1412,17 +1435,17 @@ static uint GetWindowZPriority(WindowClass wc) */ static void AddWindowToZOrdering(Window *w) { - assert(w->z_front == NULL && w->z_back == NULL); + assert(w->z_front == nullptr && w->z_back == nullptr); - if (_z_front_window == NULL) { + if (_z_front_window == nullptr) { /* It's the only window. */ _z_front_window = _z_back_window = w; - w->z_front = w->z_back = NULL; + w->z_front = w->z_back = nullptr; } else { /* Search down the z-ordering for its location. */ Window *v = _z_front_window; uint last_z_priority = UINT_MAX; - while (v != NULL && (v->window_class == WC_INVALID || GetWindowZPriority(v->window_class) > GetWindowZPriority(w->window_class))) { + while (v != nullptr && (v->window_class == WC_INVALID || GetWindowZPriority(v->window_class) > GetWindowZPriority(w->window_class))) { if (v->window_class != WC_INVALID) { /* Sanity check z-ordering, while we're at it. */ assert(last_z_priority >= GetWindowZPriority(v->window_class)); @@ -1432,15 +1455,15 @@ static void AddWindowToZOrdering(Window *w) v = v->z_back; } - if (v == NULL) { + if (v == nullptr) { /* It's the new back window. */ w->z_front = _z_back_window; - w->z_back = NULL; + w->z_back = nullptr; _z_back_window->z_back = w; _z_back_window = w; } else if (v == _z_front_window) { /* It's the new front window. */ - w->z_front = NULL; + w->z_front = nullptr; w->z_back = _z_front_window; _z_front_window->z_front = w; _z_front_window = w; @@ -1461,21 +1484,21 @@ static void AddWindowToZOrdering(Window *w) */ static void RemoveWindowFromZOrdering(Window *w) { - if (w->z_front == NULL) { + if (w->z_front == nullptr) { assert(_z_front_window == w); _z_front_window = w->z_back; } else { w->z_front->z_back = w->z_back; } - if (w->z_back == NULL) { + if (w->z_back == nullptr) { assert(_z_back_window == w); _z_back_window = w->z_front; } else { w->z_back->z_front = w->z_front; } - w->z_front = w->z_back = NULL; + w->z_front = w->z_back = nullptr; } /** @@ -1495,8 +1518,8 @@ static void BringWindowToFront(Window *w) * Initializes the data (except the position and initial size) of a new Window. * @param window_number Number being assigned to the new window * @return Window pointer of the newly created window - * @pre If nested widgets are used (\a widget is \c NULL), #nested_root and #nested_array_size must be initialized. - * In addition, #nested_array is either \c NULL, or already initialized. + * @pre If nested widgets are used (\a widget is \c nullptr), #nested_root and #nested_array_size must be initialized. + * In addition, #nested_array is either \c nullptr, or already initialized. */ void Window::InitializeData(WindowNumber window_number) { @@ -1505,7 +1528,7 @@ void Window::InitializeData(WindowNumber window_number) this->SetWhiteBorder(); if (this->window_desc->default_pos == WDP_CENTER) this->flags |= WF_CENTERED; this->owner = INVALID_OWNER; - this->nested_focus = NULL; + this->nested_focus = nullptr; this->window_number = window_number; if (this->window_class != WC_BUILD_CONFIRMATION && @@ -1518,7 +1541,7 @@ void Window::InitializeData(WindowNumber window_number) this->OnInit(); /* Initialize nested widget tree. */ - if (this->nested_array == NULL) { + if (this->nested_array == nullptr) { this->nested_array = CallocT(this->nested_array_size); this->nested_root->SetupSmallestSize(this, true); } else { @@ -1535,7 +1558,7 @@ void Window::InitializeData(WindowNumber window_number) /* Give focus to the opened window unless a text box * of focused window has focus (so we don't interrupt typing). But if the new * window has a text box, then take focus anyway. */ - if (!EditBoxInGlobalFocus() || this->nested_root->GetWidgetOfType(WWT_EDITBOX) != NULL) SetFocusedWindow(this); + if (!EditBoxInGlobalFocus() || this->nested_root->GetWidgetOfType(WWT_EDITBOX) != nullptr) SetFocusedWindow(this); /* Insert the window into the correct location in the z-ordering. */ AddWindowToZOrdering(this); @@ -1580,9 +1603,9 @@ void Window::FindWindowPlacementAndResize(int def_width, int def_height) /* Think about the overlapping toolbars when determining the minimum window size */ int free_height = _screen.height; const Window *wt = FindWindowById(WC_STATUS_BAR, 0); - if (wt != NULL) free_height -= wt->height; + if (wt != nullptr) free_height -= wt->height; wt = FindWindowById(WC_MAIN_TOOLBAR, 0); - if (wt != NULL && !vertical_toolbar) free_height -= wt->height; + if (wt != nullptr && !vertical_toolbar) free_height -= wt->height; int enlarge_x = max(min(def_width - this->width, _screen.width - this->width), 0); int enlarge_y = max(min(def_height - this->height, free_height - this->height), 0); @@ -1610,14 +1633,14 @@ void Window::FindWindowPlacementAndResize(int def_width, int def_height) const Window *wt = FindWindowById(WC_MAIN_TOOLBAR, 0); if (!vertical_toolbar) { - ny = max(ny, (wt == NULL || this == wt || this->top == 0) ? 0 : wt->height); + ny = max(ny, (wt == nullptr || this == wt || this->top == 0) ? 0 : wt->height); nx = max(nx, 0); } else { - nx = max(nx, (wt == NULL || this == wt || this == FindWindowById(WC_MAIN_TOOLBAR_RIGHT, 0) || this->left == 0) ? 0 : wt->width); + nx = max(nx, (wt == nullptr || this == wt || this == FindWindowById(WC_MAIN_TOOLBAR_RIGHT, 0) || this->left == 0) ? 0 : wt->width); ny = max(ny, 0); } - if (this->viewport != NULL) { + if (this->viewport != nullptr) { this->viewport->left += nx - this->left; this->viewport->top += ny - this->top; } @@ -1731,9 +1754,9 @@ static Point GetAutoPlacePosition(int width, int height) /* First attempt, try top-left of the screen */ const Window *main_toolbar = FindWindowByClass(WC_MAIN_TOOLBAR); - const int toolbar_y = !vertical_toolbar && main_toolbar != NULL ? main_toolbar->height : 0; + const int toolbar_y = !vertical_toolbar && main_toolbar != nullptr ? main_toolbar->height : 0; if (vertical_toolbar) { - if (IsGoodAutoPlace1(main_toolbar != NULL ? main_toolbar->width : 0, 0, width, height, toolbar_y, pt)) return pt; + if (IsGoodAutoPlace1(main_toolbar != nullptr ? main_toolbar->width : 0, 0, width, height, toolbar_y, pt)) return pt; } else { if (IsGoodAutoPlace1(rtl ? _screen.width - width : 0, toolbar_y, width, height, toolbar_y, pt)) return pt; } @@ -1803,15 +1826,12 @@ restart: Point GetToolbarAlignedWindowPosition(int window_width) { const Window *w = FindWindowById(WC_MAIN_TOOLBAR, 0); - assert(w != NULL); - Point pt; + assert(w != nullptr); + Point pt = { _current_text_dir == TD_RTL ? w->left : (w->left + w->width) - window_width, w->top + w->height }; if (_settings_client.gui.vertical_toolbar && _game_mode != GM_EDITOR) { // Retermine if the window was opened from the left or the right toolbar pt.x = (_last_clicked_toolbar_idx == 0) ? w->left + w->width : _screen.width - w->width - window_width; pt.y = w->top; - } else { - pt.x = _current_text_dir == TD_RTL ? w->left : (w->left + w->width) - window_width; - pt.y = w->top + w->height; } return pt; } @@ -1841,7 +1861,7 @@ static Point LocalGetWindowPlacement(const WindowDesc *desc, int16 sm_width, int int16 default_width = max(desc->GetDefaultWidth(), sm_width); int16 default_height = max(desc->GetDefaultHeight(), sm_height); - if (desc->parent_cls != WC_NONE && (w = FindWindowById(desc->parent_cls, window_number)) != NULL && + if (desc->parent_cls != WC_NONE && (w = FindWindowById(desc->parent_cls, window_number)) != nullptr && w->left < _screen.width - 20 && w->left > -60 && w->top < _screen.height - 20) { bool rtl = _current_text_dir == TD_RTL; if (desc->parent_cls == WC_BUILD_TOOLBAR || desc->parent_cls == WC_SCEN_LAND_GEN) { @@ -1963,7 +1983,7 @@ Window::Window(WindowDesc *desc) : window_desc(desc), mouse_capture_widget(-1) * at the topmost window, obviously and work our way down to the bottom * @param x position x to query * @param y position y to query - * @return a pointer to the found window if any, NULL otherwise + * @return a pointer to the found window if any, nullptr otherwise */ Window *FindWindowFromPt(int x, int y) { @@ -1974,7 +1994,7 @@ Window *FindWindowFromPt(int x, int y) } } - return NULL; + return nullptr; } int SETTING_BUTTON_WIDTH = 20; @@ -1999,11 +2019,11 @@ void InitWindowSystem() { IConsoleClose(); - _z_back_window = NULL; - _z_front_window = NULL; - _focused_window = NULL; - _mouseover_last_w = NULL; - _last_scroll_window = NULL; + _z_back_window = nullptr; + _z_front_window = nullptr; + _focused_window = nullptr; + _mouseover_last_w = nullptr; + _last_scroll_window = nullptr; _scrolling_viewport = false; _mouse_hovering = false; @@ -2023,14 +2043,14 @@ void UnInitWindowSystem() Window *w; FOR_ALL_WINDOWS_FROM_FRONT(w) delete w; - for (w = _z_front_window; w != NULL; /* nothing */) { + for (w = _z_front_window; w != nullptr; /* nothing */) { Window *to_del = w; w = w->z_back; free(to_del); } - _z_front_window = NULL; - _z_back_window = NULL; + _z_front_window = nullptr; + _z_back_window = nullptr; } /** @@ -2053,7 +2073,7 @@ static void DecreaseWindowCounters() /* Unclick scrollbar buttons if they are pressed. */ for (uint i = 0; i < w->nested_array_size; i++) { NWidgetBase *nwid = w->nested_array[i]; - if (nwid != NULL && (nwid->type == NWID_HSCROLLBAR || nwid->type == NWID_VSCROLLBAR)) { + if (nwid != nullptr && (nwid->type == NWID_HSCROLLBAR || nwid->type == NWID_VSCROLLBAR)) { NWidgetScrollbar *sb = static_cast(nwid); if (sb->disp_flags & (ND_SCROLLBAR_UP | ND_SCROLLBAR_DOWN)) { sb->disp_flags &= ~(ND_SCROLLBAR_UP | ND_SCROLLBAR_DOWN); @@ -2065,8 +2085,8 @@ static void DecreaseWindowCounters() } /* Handle editboxes */ - for (SmallMap::Pair *it = w->querystrings.Begin(); it != w->querystrings.End(); ++it) { - it->second->HandleEditBox(w, it->first); + for (SmallMap::Pair &pair : w->querystrings) { + pair.second->HandleEditBox(w, pair.first); } w->OnMouseLoop(); @@ -2087,7 +2107,7 @@ static void HandlePlacePresize() if (_special_mouse_mode != WSM_PRESIZE) return; Window *w = _thd.GetCallbackWnd(); - if (w == NULL) return; + if (w == nullptr) return; Point pt = GetTileBelowCursor(); if (pt.x == -1) { @@ -2163,7 +2183,7 @@ static EventState HandleMouseDragDrop() if (button && _cursor.delta.x == 0 && _cursor.delta.y == 0) return ES_HANDLED; // Dragging, but the mouse did not move. Window *w = _thd.GetCallbackWnd(); - if (w != NULL) { + if (w != nullptr) { /* Send an event in client coordinates. */ Point pt; pt.x = _cursor.pos.x - w->left; @@ -2189,7 +2209,7 @@ static void HandleMouseOver() Window *w = FindWindowFromPt(_cursor.pos.x, _cursor.pos.y); /* We changed window, put an OnMouseOver event to the last window */ - if (_mouseover_last_w != NULL && _mouseover_last_w != w) { + if (_mouseover_last_w != nullptr && _mouseover_last_w != w) { /* Reset mouse-over coordinates of previous window */ Point pt = { -1, -1 }; _mouseover_last_w->OnMouseOver(pt, 0); @@ -2198,11 +2218,11 @@ static void HandleMouseOver() /* _mouseover_last_w will get reset when the window is deleted, see DeleteWindow() */ _mouseover_last_w = w; - if (w != NULL) { + if (w != nullptr) { /* send an event in client coordinates. */ Point pt = { _cursor.pos.x - w->left, _cursor.pos.y - w->top }; const NWidgetCore *widget = w->nested_root->GetWidgetFromPos(pt.x, pt.y); - if (widget != NULL) w->OnMouseOver(pt, widget->index); + if (widget != nullptr) w->OnMouseOver(pt, widget->index); } } @@ -2227,7 +2247,7 @@ enum PreventHideDirection { */ static void PreventHiding(int *nx, int *ny, const Rect &rect, const Window *v, int px, PreventHideDirection dir) { - if (v == NULL) return; + if (v == nullptr) return; int v_bottom = v->top + v->height; int v_right = v->left + v->width; @@ -2268,7 +2288,7 @@ static void EnsureVisibleCaption(Window *w, int nx, int ny) /* Search for the title bar rectangle. */ Rect caption_rect; const NWidgetBase *caption = w->nested_root->GetWidgetOfType(WWT_CAPTION); - if (caption != NULL && _settings_client.gui.windows_titlebars) { + if (caption != nullptr && _settings_client.gui.windows_titlebars) { caption_rect.left = caption->pos_x; caption_rect.right = caption->pos_x + caption->current_x; caption_rect.top = caption->pos_y; @@ -2285,7 +2305,7 @@ static void EnsureVisibleCaption(Window *w, int nx, int ny) PreventHiding(&nx, &ny, caption_rect, FindWindowById(WC_STATUS_BAR, 0), w->left, PHD_UP); } - if (w->viewport != NULL) { + if (w->viewport != nullptr) { w->viewport->left += nx - w->left; w->viewport->top += ny - w->top; } @@ -2344,7 +2364,7 @@ int GetMainViewTop() { if (_settings_client.gui.vertical_toolbar && _game_mode != GM_EDITOR) return 0; Window *w = FindWindowById(WC_MAIN_TOOLBAR, 0); - return (w == NULL) ? 0 : w->top + w->height; + return (w == nullptr) ? 0 : w->top + w->height; } /** @@ -2355,7 +2375,7 @@ int GetMainViewTop() int GetMainViewBottom() { Window *w = FindWindowById(WC_STATUS_BAR, 0); - return (w == NULL) ? _screen.height : w->top; + return (w == nullptr) ? _screen.height : w->top; } bool GetWindowDraggedOffScreen(const Window *w) @@ -2633,7 +2653,7 @@ static void HandleScrollbarScrolling(Window *w) } /* Find the item we want to move to and make sure it's inside bounds. */ - int pos = min(max(0, i + _scrollbar_start_pos) * sb->GetCount() / _scrollbar_size, max(0, sb->GetCount() - sb->GetCapacity())); + int pos = min(RoundDivSU(max(0, i + _scrollbar_start_pos) * sb->GetCount(), _scrollbar_size), max(0, sb->GetCount() - sb->GetCapacity())); if (rtl) pos = max(0, sb->GetCount() - sb->GetCapacity() - pos); if (pos != sb->GetPosition()) { sb->SetPosition(pos); @@ -2704,15 +2724,12 @@ static EventState HandleViewportScroll() /* When we don't have a last scroll window we are starting to scroll. * When the last scroll window and this are not the same we went * outside of the window and should not left-mouse scroll anymore. */ - if (_last_scroll_window == NULL) _last_scroll_window = FindWindowFromPt(_cursor.pos.x, _cursor.pos.y); + if (_last_scroll_window == nullptr) _last_scroll_window = FindWindowFromPt(_cursor.pos.x, _cursor.pos.y); - if (_last_scroll_window == NULL || !( - (_settings_client.gui.scroll_mode != VSM_MAP_LMB && _right_button_down) || - scrollwheel_scrolling || - ((_move_pressed || _settings_client.gui.scroll_mode == VSM_MAP_LMB) && (_left_button_down || _right_button_down)))) { + if (_last_scroll_window == nullptr || !((_settings_client.gui.scroll_mode != VSM_MAP_LMB && _right_button_down) || scrollwheel_scrolling || (_settings_client.gui.scroll_mode == VSM_MAP_LMB && (_left_button_down || _right_button_down)))) { _cursor.fix_at = false; _scrolling_viewport = false; - _last_scroll_window = NULL; + _last_scroll_window = nullptr; return ES_NOT_HANDLED; } @@ -2819,7 +2836,7 @@ static bool MaybeBringWindowToFront(Window *w) EventState Window::HandleEditBoxKey(int wid, WChar key, uint16 keycode) { QueryString *query = this->GetQueryString(wid); - if (query == NULL) return ES_NOT_HANDLED; + if (query == nullptr) return ES_NOT_HANDLED; int action = QueryString::ACTION_NOTHING; @@ -2923,7 +2940,7 @@ void HandleKeypress(uint keycode, WChar key) Window *w; FOR_ALL_WINDOWS_FROM_FRONT(w) { if (w->window_class == WC_MAIN_TOOLBAR) continue; - if (w->window_desc->hotkeys != NULL) { + if (w->window_desc->hotkeys != nullptr) { int hotkey = w->window_desc->hotkeys->CheckMatch(keycode); if (hotkey >= 0 && w->OnHotkey(hotkey) == ES_HANDLED) return; } @@ -2932,8 +2949,8 @@ void HandleKeypress(uint keycode, WChar key) w = FindWindowById(WC_MAIN_TOOLBAR, 0); /* When there is no toolbar w is null, check for that */ - if (w != NULL) { - if (w->window_desc->hotkeys != NULL) { + if (w != nullptr) { + if (w->window_desc->hotkeys != nullptr) { int hotkey = w->window_desc->hotkeys->CheckMatch(keycode); if (hotkey >= 0 && w->OnHotkey(hotkey) == ES_HANDLED) return; } @@ -2963,7 +2980,7 @@ void HandleCtrlChanged() /* virtual */ void Window::InsertTextString(int wid, const char *str, bool marked, const char *caret, const char *insert_location, const char *replacement_end) { QueryString *query = this->GetQueryString(wid); - if (query == NULL) return; + if (query == nullptr) return; if (query->text.InsertString(str, marked, caret, insert_location, replacement_end) || marked) { this->SetWidgetDirty(wid); @@ -3007,11 +3024,11 @@ static void HandleAutoscroll() int y = _cursor.pos.y; int border = RescaleFrom854x480(_settings_client.gui.min_button); Window *w = FindWindowFromPt(x, y); - if (w == NULL || w->flags & WF_DISABLE_VP_SCROLL) return; + if (w == nullptr || w->flags & WF_DISABLE_VP_SCROLL) return; if (_settings_client.gui.auto_scrolling != VA_EVERY_VIEWPORT && w->window_class != WC_MAIN_WINDOW) return; ViewPort *vp = IsPtInWindowViewport(w, x, y); - if (vp == NULL) return; + if (vp == nullptr) return; x -= vp->left; y -= vp->top; @@ -3149,19 +3166,26 @@ static void MouseLoop(MouseClick click, int mousewheel) bool scrollwheel_scrolling = _settings_client.gui.scrollwheel_scrolling == 1 && (_cursor.v_wheel != 0 || _cursor.h_wheel != 0); if (click == MC_NONE && mousewheel == 0 && !scrollwheel_scrolling) return; - if (w == NULL) return; + int x = _cursor.pos.x; + int y = _cursor.pos.y; + Window *w = FindWindowFromPt(x, y); + if (w == nullptr) return; - if (click != MC_NONE && click != MC_HOVER && click != MC_LEFT_UP && !MaybeBringWindowToFront(w)) return; + if (click != MC_HOVER && !MaybeBringWindowToFront(w)) return; + ViewPort *vp = IsPtInWindowViewport(w, x, y); + + /* Don't allow any action in a viewport if either in menu or when having a modal progress window */ + if (vp != nullptr && (_game_mode == GM_MENU || HasModalProgress())) return; if (mousewheel != 0) { /* Send mousewheel event to window, unless we're scrolling a viewport or the map */ - if (!scrollwheel_scrolling || (vp == NULL && w->window_class != WC_SMALLMAP)) w->OnMouseWheel(mousewheel); + if (!scrollwheel_scrolling || (vp == nullptr && w->window_class != WC_SMALLMAP)) w->OnMouseWheel(mousewheel); /* Dispatch a MouseWheelEvent for widgets if it is not a viewport */ - if (vp == NULL) DispatchMouseWheelEvent(w, w->nested_root->GetWidgetFromPos(x - w->left, y - w->top), mousewheel); + if (vp == nullptr) DispatchMouseWheelEvent(w, w->nested_root->GetWidgetFromPos(x - w->left, y - w->top), mousewheel); } - if (vp != NULL) { + if (vp != nullptr) { if (scrollwheel_scrolling && !(w->flags & WF_DISABLE_VP_SCROLL)) { _scrolling_viewport = true; _cursor.fix_at = true; @@ -3213,7 +3237,7 @@ static void MouseLoop(MouseClick click, int mousewheel) } } - if (vp == NULL || (w->flags & WF_DISABLE_VP_SCROLL)) { + if (vp == nullptr || (w->flags & WF_DISABLE_VP_SCROLL)) { switch (click) { case MC_LEFT_UP: DispatchLeftButtonUpEvent(w, x - w->left, y - w->top); @@ -3226,7 +3250,7 @@ static void MouseLoop(MouseClick click, int mousewheel) return; default: - if (!scrollwheel_scrolling || w == NULL || w->window_class != WC_SMALLMAP) break; + 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; @@ -3327,7 +3351,7 @@ void HandleMouseEvents() Blitter *blitter = BlitterFactory::GetCurrentBlitter(); _newgrf_debug_sprite_picker.clicked_pixel = blitter->MoveTo(_screen.dst_ptr, _cursor.pos.x, _cursor.pos.y); _newgrf_debug_sprite_picker.click_time = _realtime_tick; - _newgrf_debug_sprite_picker.sprites.Clear(); + _newgrf_debug_sprite_picker.sprites.clear(); _newgrf_debug_sprite_picker.mode = SPM_REDRAW; MarkWholeScreenDirty(); } else { @@ -3349,7 +3373,7 @@ static void CheckSoftLimit() for (;;) { uint deletable_count = 0; - Window *w, *last_deletable = NULL; + Window *w, *last_deletable = nullptr; FOR_ALL_WINDOWS_FROM_FRONT(w) { if (w->window_class == WC_MAIN_WINDOW || IsVitalWindow(w) || (w->flags & WF_STICKY)) continue; @@ -3360,7 +3384,7 @@ static void CheckSoftLimit() /* We've not reached the soft limit yet. */ if (deletable_count <= _settings_client.gui.window_soft_limit) break; - assert(last_deletable != NULL); + assert(last_deletable != nullptr); delete last_deletable; } } @@ -3377,7 +3401,7 @@ void InputLoop() CheckSoftLimit(); /* Do the actual free of the deleted windows. */ - for (Window *v = _z_front_window; v != NULL; /* nothing */) { + for (Window *v = _z_front_window; v != nullptr; /* nothing */) { Window *w = v; v = v->z_back; @@ -3427,13 +3451,11 @@ void UpdateWindows() CallWindowRealtimeTickEvent(delta_ms); -#ifdef ENABLE_NETWORK static GUITimer network_message_timer = GUITimer(1); if (network_message_timer.Elapsed(delta_ms)) { network_message_timer.SetInterval(1000); NetworkChatMessageLoop(); } -#endif Window *w; @@ -3491,7 +3513,7 @@ void UpdateWindows() FOR_ALL_WINDOWS_FROM_BACK(w) { /* Update viewport only if window is not shaded. */ - if (w->viewport != NULL && !w->IsShaded()) UpdateViewportPosition(w); + if (w->viewport != nullptr && !w->IsShaded()) UpdateViewportPosition(w); } NetworkDrawChatMessage(); /* Redraw mouse cursor in case it was hidden */ @@ -3549,7 +3571,7 @@ void Window::InvalidateData(int data, bool gui_scope) this->SetDirty(); if (!gui_scope) { /* Schedule GUI-scope invalidation for next redraw. */ - *this->scheduled_invalidation_data.Append() = data; + this->scheduled_invalidation_data.push_back(data); } this->OnInvalidateData(data, gui_scope); } @@ -3559,10 +3581,11 @@ void Window::InvalidateData(int data, bool gui_scope) */ void Window::ProcessScheduledInvalidations() { - for (int *data = this->scheduled_invalidation_data.Begin(); this->window_class != WC_INVALID && data != this->scheduled_invalidation_data.End(); data++) { - this->OnInvalidateData(*data, true); + for (int data : this->scheduled_invalidation_data) { + if (this->window_class == WC_INVALID) break; + this->OnInvalidateData(data, true); } - this->scheduled_invalidation_data.Clear(); + this->scheduled_invalidation_data.clear(); } /** @@ -3774,10 +3797,9 @@ void ReInitAllWindows() FOR_ALL_WINDOWS_FROM_BACK(w) { w->ReInit(); } -#ifdef ENABLE_NETWORK + void NetworkReInitChatBoxSize(); NetworkReInitChatBoxSize(); -#endif /* Make sure essential parts of all windows are visible */ RelocateAllWindows(_cur_resolution.width, _cur_resolution.height); @@ -3786,17 +3808,17 @@ void ReInitAllWindows() /** * (Re)position a window at the screen. - * @param w Window structure of the window, may also be \c NULL. + * @param w Window structure of the window, may also be \c nullptr. * @param clss The class of the window to position. * @param setting The actual setting used for the window's position. * @return X coordinate of left edge of the repositioned window. */ static int PositionWindow(Window *w, WindowClass clss, int setting) { - if (w == NULL || w->window_class != clss) { + if (w == nullptr || w->window_class != clss) { w = FindWindowById(clss, 0); } - if (w == NULL) return 0; + if (w == nullptr) return 0; int old_left = w->left; switch (setting) { @@ -3804,14 +3826,14 @@ static int PositionWindow(Window *w, WindowClass clss, int setting) case 2: w->left = _screen.width - w->width; break; default: w->left = 0; break; } - if (w->viewport != NULL) w->viewport->left += w->left - old_left; + if (w->viewport != nullptr) w->viewport->left += w->left - old_left; SetDirtyBlocks(0, w->top, _screen.width, w->top + w->height); // invalidate the whole row return w->left; } /** * (Re)position main toolbar window at the screen. - * @param w Window structure of the main toolbar window, may also be \c NULL. + * @param w Window structure of the main toolbar window, may also be \c nullptr. * @return X coordinate of left edge of the repositioned toolbar window. */ int PositionMainToolbar(Window *w) @@ -3823,7 +3845,7 @@ int PositionMainToolbar(Window *w) /** * (Re)position statusbar window at the screen. - * @param w Window structure of the statusbar window, may also be \c NULL. + * @param w Window structure of the statusbar window, may also be \c nullptr. * @return X coordinate of left edge of the repositioned statusbar. */ int PositionStatusbar(Window *w) @@ -3834,7 +3856,7 @@ int PositionStatusbar(Window *w) /** * (Re)position news message window at the screen. - * @param w Window structure of the news message window, may also be \c NULL. + * @param w Window structure of the news message window, may also be \c nullptr. * @return X coordinate of left edge of the repositioned news message. */ int PositionNewsMessage(Window *w) @@ -3845,7 +3867,7 @@ int PositionNewsMessage(Window *w) /** * (Re)position network chat window at the screen. - * @param w Window structure of the network chat window, may also be \c NULL. + * @param w Window structure of the network chat window, may also be \c nullptr. * @return X coordinate of left edge of the repositioned network chat window. */ int PositionNetworkChatWindow(Window *w) @@ -3864,7 +3886,7 @@ void ChangeVehicleViewports(VehicleID from_index, VehicleID to_index) { Window *w; FOR_ALL_WINDOWS_FROM_BACK(w) { - if (w->viewport != NULL && w->viewport->follow_vehicle == from_index) { + if (w->viewport != nullptr && w->viewport->follow_vehicle == from_index) { w->viewport->follow_vehicle = to_index; w->SetDirty(); } diff --git a/src/window_func.h b/src/window_func.h index 821b695fd7..5393bc6566 100644 --- a/src/window_func.h +++ b/src/window_func.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. @@ -57,6 +55,7 @@ void DeleteWindowById(WindowClass cls, WindowNumber number, bool force = true); void DeleteWindowByClass(WindowClass cls); bool EditBoxInGlobalFocus(); +bool FocusedWindowIsConsole(); Point GetCaretPosition(); #endif /* WINDOW_FUNC_H */ diff --git a/src/window_gui.h b/src/window_gui.h index 18079941a1..ca3f465181 100644 --- a/src/window_gui.h +++ b/src/window_gui.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. @@ -169,14 +167,14 @@ struct WindowDesc : ZeroedMemoryAllocator { WindowDesc(WindowPosition default_pos, const char *ini_key, int16 def_width_trad, int16 def_height_trad, WindowClass window_class, WindowClass parent_class, uint32 flags, - const NWidgetPart *nwid_parts, int16 nwid_length, HotkeyList *hotkeys = NULL); + const NWidgetPart *nwid_parts, int16 nwid_length, HotkeyList *hotkeys = nullptr); ~WindowDesc(); WindowPosition default_pos; ///< Preferred position of the window. @see WindowPosition() WindowClass cls; ///< Class of the window, @see WindowClass. WindowClass parent_cls; ///< Class of the parent window. @see WindowClass - const char *ini_key; ///< Key to store window defaults in openttd.cfg. \c NULL if nothing shall be stored. + const char *ini_key; ///< Key to store window defaults in openttd.cfg. \c nullptr if nothing shall be stored. uint32 flags; ///< Flags. @see WindowDefaultFlag const NWidgetPart *nwid_parts; ///< Nested widget parts describing the window. int16 nwid_length; ///< Length of the #nwid_parts array. @@ -281,7 +279,7 @@ protected: void InitializePositionSize(int x, int y, int min_width, int min_height); virtual void FindWindowPlacementAndResize(int def_width, int def_height); - SmallVector scheduled_invalidation_data; ///< Data of scheduled OnInvalidateData() calls. + std::vector scheduled_invalidation_data; ///< Data of scheduled OnInvalidateData() calls. public: Window(WindowDesc *desc); @@ -326,12 +324,12 @@ public: Owner owner; ///< The owner of the content shown in this window. Company colour is acquired from this variable. ViewportData *viewport; ///< Pointer to viewport data, if present. - const NWidgetCore *nested_focus; ///< Currently focused nested widget, or \c NULL if no nested widget has focus. + const NWidgetCore *nested_focus; ///< Currently focused nested widget, or \c nullptr if no nested widget has focus. SmallMap querystrings; ///< QueryString associated to WWT_EDITBOX widgets. NWidgetBase *nested_root; ///< Root of the nested tree. NWidgetBase **nested_array; ///< Array of pointers into the tree. Do not access directly, use #Window::GetWidget() instead. uint nested_array_size; ///< Size of the nested array. - NWidgetStacked *shade_select; ///< Selection widget (#NWID_SELECTION) to use for shading the window. If \c NULL, window cannot shade. + NWidgetStacked *shade_select; ///< Selection widget (#NWID_SELECTION) to use for shading the window. If \c nullptr, window cannot shade. Dimension unshaded_size; ///< Last known unshaded size (only valid while shaded). int mouse_capture_widget; ///< Widgetindex of current mouse capture widget (e.g. dragged scrollbar). -1 if no widget has mouse capture. @@ -394,7 +392,7 @@ public: inline void SetWidgetDisabledState(byte widget_index, bool disab_stat) { assert(widget_index < this->nested_array_size); - if (this->nested_array[widget_index] != NULL) this->GetWidget(widget_index)->SetDisabled(disab_stat); + if (this->nested_array[widget_index] != nullptr) this->GetWidget(widget_index)->SetDisabled(disab_stat); } /** @@ -433,7 +431,7 @@ public: */ inline bool IsWidgetFocused(byte widget_index) const { - return this->nested_focus != NULL && this->nested_focus->index == widget_index; + return this->nested_focus != nullptr && this->nested_focus->index == widget_index; } /** @@ -525,7 +523,7 @@ public: /** Is window shaded currently? */ inline bool IsShaded() const { - return this->shade_select != NULL && this->shade_select->shown_plane == SZSP_HORIZONTAL; + return this->shade_select != nullptr && this->shade_select->shown_plane == SZSP_HORIZONTAL; } void SetShaded(bool make_shaded); @@ -592,10 +590,7 @@ public: */ virtual void SetStringParameters(int widget) const {} - /** - * Called when window gains focus - */ - virtual void OnFocus() {} + virtual void OnFocus(); virtual void OnFocusLost(); @@ -734,7 +729,7 @@ public: /** * The query window opened from this window has closed. - * @param str the new value of the string, NULL if the window + * @param str the new value of the string, nullptr if the window * was cancelled or an empty string when the default * button was pressed, i.e. StrEmpty(str). */ @@ -822,14 +817,14 @@ public: * Get the nested widget with number \a widnum from the nested widget tree. * @tparam NWID Type of the nested widget. * @param widnum Widget number of the widget to retrieve. - * @return The requested widget if it is instantiated, \c NULL otherwise. + * @return The requested widget if it is instantiated, \c nullptr otherwise. */ template inline NWID *Window::GetWidget(uint widnum) { - if (widnum >= this->nested_array_size || this->nested_array[widnum] == NULL) return NULL; + if (widnum >= this->nested_array_size || this->nested_array[widnum] == nullptr) return nullptr; NWID *nwid = dynamic_cast(this->nested_array[widnum]); - assert(nwid != NULL); + assert(nwid != nullptr); return nwid; } @@ -837,7 +832,7 @@ inline NWID *Window::GetWidget(uint widnum) template <> inline const NWidgetBase *Window::GetWidget(uint widnum) const { - if (widnum >= this->nested_array_size) return NULL; + if (widnum >= this->nested_array_size) return nullptr; return this->nested_array[widnum]; } @@ -845,7 +840,7 @@ inline const NWidgetBase *Window::GetWidget(uint widnum) const * Get the nested widget with number \a widnum from the nested widget tree. * @tparam NWID Type of the nested widget. * @param widnum Widget number of the widget to retrieve. - * @return The requested widget if it is instantiated, \c NULL otherwise. + * @return The requested widget if it is instantiated, \c nullptr otherwise. */ template inline const NWID *Window::GetWidget(uint widnum) const @@ -877,13 +872,13 @@ Window *FindWindowFromPt(int x, int y); * @param desc The pointer to the WindowDesc to be created * @param window_number the window number of the new window * @param return_existing If set, also return the window if it already existed. - * @return %Window pointer of the newly created window, or the existing one if \a return_existing is set, or \c NULL. + * @return %Window pointer of the newly created window, or the existing one if \a return_existing is set, or \c nullptr. */ template Wcls *AllocateWindowDescFront(WindowDesc *desc, int window_number, bool return_existing = false) { Wcls *w = static_cast(BringWindowToFrontById(desc->cls, window_number)); - if (w != NULL) return return_existing ? w : NULL; + if (w != nullptr) return return_existing ? w : nullptr; return new Wcls(desc, window_number); } @@ -891,14 +886,14 @@ void RelocateAllWindows(int neww, int newh); void MoveAllWindowsOffScreen(); void MoveAllHiddenWindowsBackToScreen(); -void GuiShowTooltips(Window *parent, StringID str, uint paramcount = 0, const uint64 params[] = NULL, TooltipCloseCondition close_tooltip = TCC_HOVER); +void GuiShowTooltips(Window *parent, StringID str, uint paramcount = 0, const uint64 params[] = nullptr, TooltipCloseCondition close_tooltip = TCC_HOVER); /* widget.cpp */ int GetWidgetFromPos(const Window *w, int x, int y); /** Iterate over all windows */ -#define FOR_ALL_WINDOWS_FROM_BACK_FROM(w, start) for (w = start; w != NULL; w = w->z_front) if (w->window_class != WC_INVALID) -#define FOR_ALL_WINDOWS_FROM_FRONT_FROM(w, start) for (w = start; w != NULL; w = w->z_back) if (w->window_class != WC_INVALID) +#define FOR_ALL_WINDOWS_FROM_BACK_FROM(w, start) for (w = start; w != nullptr; w = w->z_front) if (w->window_class != WC_INVALID) +#define FOR_ALL_WINDOWS_FROM_FRONT_FROM(w, start) for (w = start; w != nullptr; w = w->z_back) if (w->window_class != WC_INVALID) #define FOR_ALL_WINDOWS_FROM_BACK(w) FOR_ALL_WINDOWS_FROM_BACK_FROM(w, _z_back_window) #define FOR_ALL_WINDOWS_FROM_FRONT(w) FOR_ALL_WINDOWS_FROM_FRONT_FROM(w, _z_front_window) diff --git a/src/window_type.h b/src/window_type.h index c3d0b059dc..fd7a312948 100644 --- a/src/window_type.h +++ b/src/window_type.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. @@ -706,6 +704,12 @@ enum WindowClass { */ WC_FRAMETIME_GRAPH, + /** + * Screenshot window; %Window numbers: + * - 0 = #ScreenshotWidgets + */ + WC_SCREENSHOT, + WC_INVALID = 0xFFFF, ///< Invalid window. }; diff --git a/src/zoom_func.h b/src/zoom_func.h index 0e8fa8c9ef..485284a06c 100644 --- a/src/zoom_func.h +++ b/src/zoom_func.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. @@ -23,7 +21,6 @@ */ static inline int ScaleByZoom(int value, ZoomLevel zoom) { - assert(zoom >= 0); return value << zoom; } @@ -36,7 +33,6 @@ static inline int ScaleByZoom(int value, ZoomLevel zoom) */ static inline int UnScaleByZoom(int value, ZoomLevel zoom) { - assert(zoom >= 0); return (value + (1 << zoom) - 1) >> zoom; } @@ -48,7 +44,6 @@ static inline int UnScaleByZoom(int value, ZoomLevel zoom) */ static inline int ScaleByZoomLower(int value, ZoomLevel zoom) { - assert(zoom >= 0); return value << zoom; } @@ -60,7 +55,6 @@ static inline int ScaleByZoomLower(int value, ZoomLevel zoom) */ static inline int UnScaleByZoomLower(int value, ZoomLevel zoom) { - assert(zoom >= 0); return value >> zoom; } diff --git a/src/zoom_type.h b/src/zoom_type.h index ea8302761f..2606e07677 100644 --- a/src/zoom_type.h +++ b/src/zoom_type.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. @@ -14,11 +12,11 @@ #include "core/enum_type.hpp" -static int const ZOOM_LVL_SHIFT = 2; -static int const ZOOM_LVL_BASE = 1 << ZOOM_LVL_SHIFT; +static uint const ZOOM_LVL_SHIFT = 2; +static uint const ZOOM_LVL_BASE = 1 << ZOOM_LVL_SHIFT; /** All zoom levels we know. */ -enum ZoomLevel { +enum ZoomLevel : byte { /* Our possible zoom-levels */ ZOOM_LVL_BEGIN = 0, ///< Begin for iteration. ZOOM_LVL_NORMAL = 0, ///< The normal zoom level. @@ -46,14 +44,12 @@ enum ZoomLevel { ZOOM_LVL_MIN = ZOOM_LVL_NORMAL, ///< Minimum zoom level. ZOOM_LVL_MAX = ZOOM_LVL_OUT_32X, ///< Maximum zoom level. + }; DECLARE_POSTFIX_INCREMENT(ZoomLevel) -/** Type for storing the zoom level in a byte. */ -typedef SimpleTinyEnumT ZoomLevelByte; - -extern ZoomLevelByte _gui_zoom; -extern ZoomLevelByte _font_zoom; +extern ZoomLevel _gui_zoom; +extern ZoomLevel _font_zoom; #define ZOOM_LVL_GUI (_gui_zoom) #define ZOOM_LVL_FONT (_font_zoom)
       
        +
      • m1 bit 7: Ship docking tile status
      • m1 bits 6..5 : Water class (sea, canal or river)
      • m1 bits 4..0: owner (for sea, rivers, and coasts normally 11)
      • m2: Depot index (for depots only)
      • @@ -1443,8 +1462,10 @@
       
        +
      • m1 bit 7: Ship docking tile status (for aqueducts)
      • m1 bits 4..0: owner
      • m3 bits 7..4: owner of tram
      • +
      • m4: Roadtype
      • m5 bit 4: pbs reservation state for railway
      • m5 bits 7 clear: tunnel entrance/exit
      • m5 bit 7 set: bridge ramp @@ -1581,7 +1602,7 @@
      • m7 bits 4..0: owner of road
      • m7 bit 5 set = on snow or desert
      • -
      • m7 bits 7..6: present road types for road
      • +
      • m8 bits 11..6: Tramtype
      • m8 bits 5..0: track type for railway
      rail XXXX XXXX XXXX XXXXOOOX XXXXXOOX XXXX OOOO XXXX OOOO OOOO OOOO OOOO OOOO XXXXOOOX XXXX XXXX XXXX XXXX XXXX XXXX XXXXOOOO OOOOOOXX XXXX XXXX XXXX OOXX XOOOXXXO XXXXOOOO OOOO OOOO OOOOOOXO XXXXOOOO XXXX XXOO OOOO
      level crossingOOOO OOOO XXXX OOOX OOXX XOOOXXXX XXXXOOOO OOOO OOXX XXXXOOXX XXXXOOOO XXXX XXXX XXXX
      road depot-inherit- -inherit- XXXX OOOOOOOO OOOO-inherit- XXOO OOXX OOOO OOOOXXXO XXXXOOOO OOOO OOOO OOOOOOXO XXXX-inherit-
      3rail station XXXX XXXX XXXX XXXXOXXX XXXXXXXX XXXX XXXX XXXX XXXX XXXX XXXX OOOO XXXX XXXX-inherit- -inherit- XXXX OOOOOOOO OOOOOOXX XXXX ~~~~ ~XXX OOXX XOOOXXOX XXXXOOOO OOOO OOOO OOOOOOOX XXXXOOOO XXXX XXOO OOOO
      docksea, shore XXXX XXXX XXXX XXXXOXXX XXXXXXXX XXXX OOOO OOOO OOOO OOOO OOOO OOOO OOOO OOOOtunnel entrance XXXX XXXX XXXX XXXXOOOX XXXXXOOX XXXX OOOO OOOO OOOO OOOO XXXX OOOOOOOO OOOOOOXX XXXX XOOX XXXX OOOO OOOOXXXX XXXXOOOO OOOO OOXX XXXXOOXX XXXXOOOO XXXX XXXX XXXX
      bridge ramp-inherit- OOOO OOOO OOOO OOOO -inherit-OOOO OOOO-inherit- -inherit- OOXX XXOO -inherit-