Merge branch 'openttd'

This commit is contained in:
Pavel Stupnikov
2023-01-03 19:05:48 +04:00
326 changed files with 12923 additions and 8705 deletions

View File

@@ -1,3 +1,79 @@
13.0-RC1 (2023-01-01)
------------------------------------------------------------------------
Feature: 'font' console command to configure fonts within game (#10278)
Feature: Ctrl-click to bulk edit timetable speeds/waiting times (#10265)
Feature: [NewGRF] Vehicle variants in expandable purchase list (#10220)
Feature: Expand all towns in the scenario editor (#10215)
Add: [NewGRF] Slope-aware and roadtype-specific one-way sprites (#10282)
Change: Display text files in black (#10291)
Change: Make vehicle list dropdown buttons resize to fit strings (#10286)
Change: [NewGRF] Support flipping shorter engines without explicit support (#10262)
Change: Separate ground sprite from foundation sprite offsets (#10256)
Change: Vertically centre sprite font relative to TrueType font (#10254)
Change: [macOS] Set minimum macOS version to 10.13 (#10253)
Change: Use lowered not disabled widget for current vehicle details tab (#10252)
Change: Various improvements to NewGRF sprite aligner (#10249)
Change: reset_engines console command now rerandomises introduction dates and reliability (#10220)
Change: Show error message on failed industry prospecting (#10202)
Fix: Local authority window rating list height ignored icon sizes (#10285)
Fix #10150: Town signs could be truncated when using custom fonts (#10283)
Fix #8971: Resize QueryStrings with interface scale change (#10281)
Fix #10274: Crash when rescanning scripts with GS selected (#10276)
Fix #10151: Use smaller padding for signs (#10272)
Fix #10263: [Script] Restore tile validation for commands (#10269)
Fix: Missing scrollbar for rail/roadtype dropdowns (#10264)
Fix #10260: Incorrect rect height drawing image in vehicle details (#10261)
Fix #10257: Incorrect catenary position on sloped bridge heads (#10258)
Fix: Vertically centre chat prompt (#10250)
Fix #10214: League and graph buttons in toolbar did not have a default action (#10246)
Fix #10242: Allow a space for text shadow when clipping text (#10243)
Fix #10206: Fully disable scripts in intro game (#10241)
Fix #10218: Don't try to create river tiles along incorrect slopes (#10235)
Fix #10208: [NewGRF] Allow using a specific underlay for road/tram tunnels (#10233)
Fix #10224: Don't change fast-forward mode while saving (#10230)
Fix #10147: Sound effect volume slider no longer set volume (#10228)
Fix #10223: Crash when vehicle cloning fails on order cloning (#10225)
Fix: Maximum space for engine preview image was never scaled (#10219)
Fix #10216: Crash when upgrading savegame with crashed vehicles (#10217)
Fix #10212: [Script] Nested ScriptAccounting scopes not restored properly (#10213)
Fix #10114: Incorrect drag-highlight position with non-power-of-2 scaling (#10211)
Fix #10198: Rearrange Intro GUI to make button rows narrower (#10203)
Fix: Missing extra padding when drawing tooltip text (#10201)
Fix: Bad alignment of button icons when using the original baseset (#10200)
Fix: Signal icons incorrectly positioned in UI (#10199)
Fix #10021: Object GUI resized when switching between different objects (#10196)
Fix #9720: Delay start of GS/AI to after loading of savegame (#9745)
13.0-beta2 (2022-11-27)
------------------------------------------------------------------------
Feature: Allow AI/GS to be fully modified in scenario editor (#10152)
Feature: Display power-to-weight ratio in ground vehicle details GUI (#10123)
Feature: Variable interface scaling (with chunky bevels!) (#10114)
Feature: Hotkey to honk a vehicle's horn (#10110)
Feature: Split AI/Game Script configuration windows and add them to world gen window (#10058)
Feature: [GS] Scriptable league tables (#10001)
Feature: Multi-track level crossings (#9931)
Feature: Improved local authority action window (#9928)
Feature: Automatic console command screenshot numbering with a filename ending in '#' (#9781)
Feature: Add buttons to toggle music in the Game Options menu (#9727)
Feature: Contextual actions for vehicles grouped by shared orders (#8425)
Feature: Add cargo filter support to vehicle list (#8308)
Feature: Show the cargoes the vehicles can carry in the vehicle list window (#8304)
Change: Allow building canal by area outside editor (#10173)
Change: Minor improvements to the new Finance GUI (#10168)
Change: Let AI developers edit non-editable AI/Game Script Parameters (#8895)
Change: Allow building docks on clearable watered object tiles (#8514)
Fix #8770: Center vehicle status bar icon (#10178)
Fix: Crash if error message window is too wide for screen. (#10172)
Fix #10155: Network games not syncing company settings properly (#10158)
Fix #10154: Network game desync related to setting a random company face (#10157)
Fix #10011: Incorrect infrastructure totals when overbuilding bay road stop (#10143)
Fix #10117: Object burst limit allowed one fewer object than the setting (#10120)
Fix #10023: Allow negative input in text fields when needed (#10112)
Fix #9908: Fix crash which could occur when a company was deleted when a depot window was open (#9912)
13.0-beta1 (2022-10-31)
------------------------------------------------------------------------
Feature: Airport construction GUI displays infrastructure cost (#10094)

View File

@@ -16,7 +16,7 @@ jobs:
runs-on: ubuntu-20.04
container:
# If you change this version, change the number in the cache step too.
image: emscripten/emsdk:2.0.31
image: emscripten/emsdk:3.1.28
steps:
- name: Checkout
@@ -26,7 +26,7 @@ jobs:
uses: actions/cache@v3
with:
path: /emsdk/upstream/emscripten/cache
key: 2.0.31-${{ runner.os }}
key: 3.1.28-${{ runner.os }}
- name: Patch Emscripten to support LZMA
run: |
@@ -162,7 +162,7 @@ jobs:
runs-on: macos-latest
env:
MACOSX_DEPLOYMENT_TARGET: 10.14
MACOSX_DEPLOYMENT_TARGET: 10.13
steps:
- name: Checkout

View File

@@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-20.04
container:
# If you change this version, change the number in the cache step too.
image: emscripten/emsdk:2.0.31
image: emscripten/emsdk:3.1.28
steps:
- name: Update deployment status to in progress
@@ -44,7 +44,7 @@ jobs:
uses: actions/cache@v3
with:
path: /emsdk/upstream/emscripten/cache
key: 2.0.31-${{ runner.os }}
key: 3.1.28-${{ runner.os }}
- name: Patch Emscripten to support LZMA
run: |

View File

@@ -469,7 +469,7 @@ jobs:
runs-on: macos-11
env:
MACOSX_DEPLOYMENT_TARGET: 10.14
MACOSX_DEPLOYMENT_TARGET: 10.13
steps:
- name: Download source

View File

@@ -1 +1 @@
13.0-beta1 20221031 0 c4e655b1d4fa83b8f192d2df0062f6dd7f346aad 1 0 2022
13.0-RC1 20230101 0 4b123394cf5102688d9635d2988a13dbc9018d4d 1 0 2023

View File

@@ -1 +1 @@
2022-11-01 19:19 UTC
2023-01-01 18:22 UTC

View File

@@ -1 +1 @@
13.0-beta1
13.0-RC1

View File

@@ -22,7 +22,7 @@ if (EMSCRIPTEN)
endif()
set(CMAKE_MODULE_PATH ${CMAKE_MODULE_PATH} "${CMAKE_SOURCE_DIR}/cmake")
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.14)
set(CMAKE_OSX_DEPLOYMENT_TARGET 10.13)
# Use GNUInstallDirs to allow customisation
# but set our own default data and bin dir

View File

@@ -10,6 +10,7 @@
- Peter Nelson (peter1138) - Spiritual descendant from newGRF gods (since 0.4.5)
- Remko Bijker (Rubidium) - Coder and way more (since 0.4.5)
- Patric Stout (TrueBrain) - NoProgrammer (since 0.3), sys op
- Tyler Trahan (2TallTyler) - General coding (since 13)
### Inactive Developers:

View File

@@ -1,3 +1,79 @@
13.0-RC1 (2023-01-01)
------------------------------------------------------------------------
Feature: 'font' console command to configure fonts within game (#10278)
Feature: Ctrl-click to bulk edit timetable speeds/waiting times (#10265)
Feature: [NewGRF] Vehicle variants in expandable purchase list (#10220)
Feature: Expand all towns in the scenario editor (#10215)
Add: [NewGRF] Slope-aware and roadtype-specific one-way sprites (#10282)
Change: Display text files in black (#10291)
Change: Make vehicle list dropdown buttons resize to fit strings (#10286)
Change: [NewGRF] Support flipping shorter engines without explicit support (#10262)
Change: Separate ground sprite from foundation sprite offsets (#10256)
Change: Vertically centre sprite font relative to TrueType font (#10254)
Change: [macOS] Set minimum macOS version to 10.13 (#10253)
Change: Use lowered not disabled widget for current vehicle details tab (#10252)
Change: Various improvements to NewGRF sprite aligner (#10249)
Change: reset_engines console command now rerandomises introduction dates and reliability (#10220)
Change: Show error message on failed industry prospecting (#10202)
Fix: Local authority window rating list height ignored icon sizes (#10285)
Fix #10150: Town signs could be truncated when using custom fonts (#10283)
Fix #8971: Resize QueryStrings with interface scale change (#10281)
Fix #10274: Crash when rescanning scripts with GS selected (#10276)
Fix #10151: Use smaller padding for signs (#10272)
Fix #10263: [Script] Restore tile validation for commands (#10269)
Fix: Missing scrollbar for rail/roadtype dropdowns (#10264)
Fix #10260: Incorrect rect height drawing image in vehicle details (#10261)
Fix #10257: Incorrect catenary position on sloped bridge heads (#10258)
Fix: Vertically centre chat prompt (#10250)
Fix #10214: League and graph buttons in toolbar did not have a default action (#10246)
Fix #10242: Allow a space for text shadow when clipping text (#10243)
Fix #10206: Fully disable scripts in intro game (#10241)
Fix #10218: Don't try to create river tiles along incorrect slopes (#10235)
Fix #10208: [NewGRF] Allow using a specific underlay for road/tram tunnels (#10233)
Fix #10224: Don't change fast-forward mode while saving (#10230)
Fix #10147: Sound effect volume slider no longer set volume (#10228)
Fix #10223: Crash when vehicle cloning fails on order cloning (#10225)
Fix: Maximum space for engine preview image was never scaled (#10219)
Fix #10216: Crash when upgrading savegame with crashed vehicles (#10217)
Fix #10212: [Script] Nested ScriptAccounting scopes not restored properly (#10213)
Fix #10114: Incorrect drag-highlight position with non-power-of-2 scaling (#10211)
Fix #10198: Rearrange Intro GUI to make button rows narrower (#10203)
Fix: Missing extra padding when drawing tooltip text (#10201)
Fix: Bad alignment of button icons when using the original baseset (#10200)
Fix: Signal icons incorrectly positioned in UI (#10199)
Fix #10021: Object GUI resized when switching between different objects (#10196)
Fix #9720: Delay start of GS/AI to after loading of savegame (#9745)
13.0-beta2 (2022-11-27)
------------------------------------------------------------------------
Feature: Allow AI/GS to be fully modified in scenario editor (#10152)
Feature: Display power-to-weight ratio in ground vehicle details GUI (#10123)
Feature: Variable interface scaling (with chunky bevels!) (#10114)
Feature: Hotkey to honk a vehicle's horn (#10110)
Feature: Split AI/Game Script configuration windows and add them to world gen window (#10058)
Feature: [GS] Scriptable league tables (#10001)
Feature: Multi-track level crossings (#9931)
Feature: Improved local authority action window (#9928)
Feature: Automatic console command screenshot numbering with a filename ending in '#' (#9781)
Feature: Add buttons to toggle music in the Game Options menu (#9727)
Feature: Contextual actions for vehicles grouped by shared orders (#8425)
Feature: Add cargo filter support to vehicle list (#8308)
Feature: Show the cargoes the vehicles can carry in the vehicle list window (#8304)
Change: Allow building canal by area outside editor (#10173)
Change: Minor improvements to the new Finance GUI (#10168)
Change: Let AI developers edit non-editable AI/Game Script Parameters (#8895)
Change: Allow building docks on clearable watered object tiles (#8514)
Fix #8770: Center vehicle status bar icon (#10178)
Fix: Crash if error message window is too wide for screen. (#10172)
Fix #10155: Network games not syncing company settings properly (#10158)
Fix #10154: Network game desync related to setting a random company face (#10157)
Fix #10011: Incorrect infrastructure totals when overbuilding bay road stop (#10143)
Fix #10117: Object burst limit allowed one fewer object than the setting (#10120)
Fix #10023: Allow negative input in text fields when needed (#10112)
Fix #9908: Fix crash which could occur when a company was deleted when a depot window was open (#9912)
13.0-beta1 (2022-10-31)
------------------------------------------------------------------------
Feature: Airport construction GUI displays infrastructure cost (#10094)

View File

@@ -44,8 +44,8 @@ macro(compile_flags)
"$<$<NOT:$<CONFIG:Debug>>:-fstack-protector>" # Prevent undefined references when _FORTIFY_SOURCE > 0
)
if(CMAKE_SIZEOF_VOID_P EQUAL 8)
add_link_options(
"$<$<CONFIG:Debug>:-Wl,--disable-dynamicbase,--disable-high-entropy-va,--default-image-base-low>" # ASLR somehow breaks linking for x64 Debug builds
add_compile_options(
"$<$<CONFIG:Debug>:-Wa,-mbig-obj>" # Switch to pe-bigobj-x86-64 as x64 Debug builds push pe-x86-64 to the limits (linking errors with ASLR, ...)
)
endif()
endif()
@@ -56,7 +56,7 @@ macro(compile_flags)
if(MSVC)
add_compile_options(/W3)
if(MSVC_VERSION GREATER 1929)
if(MSVC_VERSION GREATER 1929 AND CMAKE_CXX_COMPILER_ID STREQUAL "MSVC")
# Starting with version 19.30, there is an optimisation bug, see #9966 for details
# This flag disables the broken optimisation to work around the bug
add_compile_options(/d2ssa-rse-)

Binary file not shown.

View File

@@ -4,10 +4,24 @@
// See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
//
-1 * 0 0C "One way road graphics"
-1 * 3 05 09 06
-1 sprites/oneway.png 8bpp 34 8 24 16 -12 -8 normal
-1 sprites/oneway.png 8bpp 66 8 24 16 -12 -8 normal
-1 sprites/oneway.png 8bpp 98 8 24 16 -12 -8 normal
-1 sprites/oneway.png 8bpp 130 8 24 16 -12 -8 normal
-1 sprites/oneway.png 8bpp 162 8 24 16 -12 -8 normal
-1 sprites/oneway.png 8bpp 194 8 24 16 -12 -8 normal
-1 * 3 05 09 12
-1 sprites/oneway.png 8bpp 34 8 24 16 -10 -9 normal
-1 sprites/oneway.png 8bpp 66 8 24 16 -13 -7 normal
-1 sprites/oneway.png 8bpp 98 8 24 16 -12 -8 normal
-1 sprites/oneway.png 8bpp 130 8 24 16 -15 -10 normal
-1 sprites/oneway.png 8bpp 162 8 24 16 -12 -9 normal
-1 sprites/oneway.png 8bpp 194 8 24 16 -11 -8 normal
-1 sprites/oneway.png 8bpp 34 40 24 16 -13 -10 normal
-1 sprites/oneway.png 8bpp 66 40 24 16 -12 -8 normal
-1 sprites/oneway.png 8bpp 98 40 24 16 -12 -9 normal
-1 sprites/oneway.png 8bpp 130 40 24 16 -11 -8 normal
-1 sprites/oneway.png 8bpp 162 40 24 16 -9 -10 normal
-1 sprites/oneway.png 8bpp 194 40 24 16 -10 -9 normal
-1 sprites/oneway.png 8bpp 34 72 24 16 -8 -11 normal
-1 sprites/oneway.png 8bpp 66 72 24 16 -11 -5 normal
-1 sprites/oneway.png 8bpp 98 72 24 16 -12 -8 normal
-1 sprites/oneway.png 8bpp 130 72 24 16 -12 -5 normal
-1 sprites/oneway.png 8bpp 162 72 24 16 -14 -10 normal
-1 sprites/oneway.png 8bpp 194 72 24 16 -12 -8 normal

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 7.7 KiB

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,12 @@
// This file is part of OpenTTD.
// OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
// OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
// See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
//
-1 * 0 0C "Fix alignment of button icons."
// Fix alignment of button icons.
-1 * 11 0A 03 01 DC 02 01 E2 02 01 E6 02
-1 sprites/fix_gui_icons.png 8bpp 8 13 20 20 0 0 normal nocrop
-1 sprites/fix_gui_icons.png 8bpp 40 13 20 20 0 0 normal nocrop
-1 sprites/fix_gui_icons.png 8bpp 72 13 20 20 0 0 normal nocrop

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -83,3 +83,4 @@
#include "rivers/arctic.nfo"
#include "rivers/tropic.nfo"
#include "rivers/toyland.nfo"
#include "fix_gui_icons.nfo"

View File

@@ -1,4 +1,4 @@
FROM emscripten/emsdk:2.0.34
FROM emscripten/emsdk:3.1.28
COPY emsdk-liblzma.patch /
RUN cd /emsdk/upstream/emscripten && patch -p1 < /emsdk-liblzma.patch

View File

@@ -1,40 +1,38 @@
## How to build with Emscripten
Building with Emscripten works with emsdk 2.0.31 and above.
Please use docker with the supplied `Dockerfile` to build for emscripten.
It takes care of a few things:
- Use a version of emscripten we know works
- Patch in LibLZMA support (as this is not supported by upstream)
Currently there is no LibLZMA support upstream; for this we suggest to apply
the provided patch in this folder to your emsdk installation.
For convenience, a Dockerfile is supplied that does this patches for you
against upstream emsdk docker. Best way to use it:
Build the docker image:
First, build the docker image by navigating in the folder this `README.md` is in, and executing:
```
docker build -t emsdk-lzma .
```
Build the host tools first:
Next, navigate back to the root folder of this project.
Now we build the host tools first:
```
mkdir build-host
docker run -it --rm -v $(pwd):$(pwd) -u $(id -u):$(id -g) --workdir $(pwd)/build-host emsdk-lzma cmake .. -DOPTION_TOOLS_ONLY=ON
docker run -it --rm -v $(pwd):$(pwd) -u $(id -u):$(id -g) --workdir $(pwd)/build-host emsdk-lzma make -j5 tools
docker run -it --rm -v $(pwd):$(pwd) -u $(id -u):$(id -g) --workdir $(pwd)/build-host emsdk-lzma make -j$(nproc) tools
```
Next, build the game with emscripten:
Finally, we build the actual game:
```
mkdir build
docker run -it --rm -v $(pwd):$(pwd) -u $(id -u):$(id -g) --workdir $(pwd)/build emsdk-lzma emcmake cmake .. -DHOST_BINARY_DIR=../build-host -DCMAKE_BUILD_TYPE=Release -DOPTION_USE_ASSERTS=OFF
docker run -it --rm -v $(pwd):$(pwd) -u $(id -u):$(id -g) --workdir $(pwd)/build emsdk-lzma emmake make -j5
docker run -it --rm -v $(pwd):$(pwd) -u $(id -u):$(id -g) --workdir $(pwd)/build emsdk-lzma emmake make -j$(nproc)
```
And now you have in your build folder files like "openttd.html".
In the `build` folder you will now see `openttd.html`.
To run it locally, you would have to start a local webserver, like:
To run it locally, you would have to start a local webserver; something like:
```
cd build
python3 -m http.server
````
Now you can play the game via http://127.0.0.1:8000/openttd.html .
You can now play the game via http://127.0.0.1:8000/openttd.html .

View File

@@ -13,7 +13,7 @@ of emsdk.
diff --git a/tools/settings.py b/tools/settings.py
--- a/tools/settings.py
+++ b/tools/settings.py
@@ -38,6 +38,7 @@
@@ -40,6 +40,7 @@ PORTS_SETTINGS = {
'USE_SDL_NET',
'USE_SDL_GFX',
'USE_LIBJPEG',
@@ -24,24 +24,23 @@ diff --git a/tools/settings.py b/tools/settings.py
diff --git a/src/settings.js b/src/settings.js
--- a/src/settings.js
+++ b/src/settings.js
@@ -1382,8 +1382,12 @@ var USE_BZIP2 = 0;
// 1 = use libjpeg from emscripten-ports
// [link]
var USE_LIBJPEG = 0;
@@ -1450,6 +1450,10 @@ var USE_GIFLIB = false;
// [compile+link]
var USE_LIBJPEG = false;
+// 1 = use liblzma from emscripten-ports
+// [link]
+var USE_LIBLZMA = 0;
+// [compile+link]
+var USE_LIBLZMA = false;
+
// 1 = use libpng from emscripten-ports
// [link]
var USE_LIBPNG = 0;
// [compile+link]
var USE_LIBPNG = false;
diff --git a/tools/ports/liblzma.py b/tools/ports/liblzma.py
new file mode 100644
--- /dev/null
+++ b/tools/ports/liblzma.py
@@ -0,0 +1,160 @@
@@ -0,0 +1,151 @@
+# Copyright 2020 The Emscripten Authors. All rights reserved.
+# Emscripten is available under two separate licenses, the MIT license and the
+# University of Illinois/NCSA Open Source License. Both these licenses can be
@@ -52,8 +51,8 @@ new file mode 100644
+import logging
+from pathlib import Path
+
+VERSION = '5.2.5'
+HASH = '7443674247deda2935220fbc4dfc7665e5bb5a260be8ad858c8bd7d7b9f0f868f04ea45e62eb17c0a5e6a2de7c7500ad2d201e2d668c48ca29bd9eea5a73a3ce'
+VERSION = '5.4.0'
+HASH = '29b2cd25bb5b234b329ffe9547692d2c29be393db9d8d4ce70a66dfdaebd54433e79a89d80c57e58cd4559c3c68b9845507d5fedf3eec1c528a81e3d9ddbd811'
+
+
+def needed(settings):
@@ -61,40 +60,31 @@ new file mode 100644
+
+
+def get(ports, settings, shared):
+ ports.fetch_project('liblzma', 'https://tukaani.org/xz/xz-' + VERSION + '.tar.gz', 'xz-' + VERSION, sha512hash=HASH)
+ ports.fetch_project('liblzma', f'https://tukaani.org/xz/xz-{VERSION}.tar.gz', sha512hash=HASH)
+
+ def create(final):
+ logging.info('building port: liblzma')
+
+ ports.clear_project_build('liblzma')
+
+ source_path = os.path.join(ports.get_dir(), 'liblzma', 'xz-' + VERSION)
+ dest_path = os.path.join(ports.get_build_dir(), 'liblzma')
+
+ shared.try_delete(dest_path)
+ os.makedirs(dest_path)
+ shutil.rmtree(dest_path, ignore_errors=True)
+ shutil.copytree(source_path, dest_path)
+ source_path = os.path.join(ports.get_dir(), 'liblzma', f'xz-{VERSION}', 'src', 'liblzma')
+ ports.write_file(os.path.join(source_path, 'config.h'), config_h)
+ ports.install_headers(os.path.join(source_path, 'api'), pattern='lzma.h')
+ ports.install_headers(os.path.join(source_path, 'api', 'lzma'), pattern='*.h', target='lzma')
+
+ build_flags = ['-DHAVE_CONFIG_H', '-DTUKLIB_SYMBOL_PREFIX=lzma_', '-fvisibility=hidden']
+ exclude_dirs = ['xzdec', 'xz', 'lzmainfo']
+ exclude_files = ['crc32_small.c', 'crc64_small.c', 'crc32_tablegen.c', 'crc64_tablegen.c', 'price_tablegen.c', 'fastpos_tablegen.c'
+ exclude_files = ['crc32_small.c', 'crc64_small.c', 'crc32_tablegen.c', 'crc64_tablegen.c', 'price_tablegen.c', 'fastpos_tablegen.c',
+ 'tuklib_exit.c', 'tuklib_mbstr_fw.c', 'tuklib_mbstr_width.c', 'tuklib_open_stdxxx.c', 'tuklib_progname.c']
+ include_dirs_rel = ['../common', 'api', 'common', 'check', 'lz', 'rangecoder', 'lzma', 'delta', 'simple']
+ include_dirs_rel = ['../common', 'api', 'check', 'common', 'delta', 'lz', 'lzma', 'rangecoder', 'simple']
+
+ Path(dest_path, os.path.join('src', 'config.h')).write_text(config_h)
+ include_dirs = [os.path.join(source_path, p) for p in include_dirs_rel]
+ ports.build_port(source_path, final, 'liblzma', flags=build_flags, exclude_files=exclude_files, includes=include_dirs)
+
+ include_dirs = [os.path.join(dest_path, 'src', 'liblzma', p) for p in include_dirs_rel]
+ ports.build_port(os.path.join(dest_path, 'src'), final, flags=build_flags, exclude_dirs=exclude_dirs, exclude_files=exclude_files, includes=include_dirs)
+
+ ports.install_headers(os.path.join(dest_path, 'src', 'liblzma', 'api'), 'lzma.h')
+ ports.install_headers(os.path.join(dest_path, 'src', 'liblzma', 'api', 'lzma'), '*.h', 'lzma')
+
+ return [shared.Cache.get_lib('liblzma.a', create, what='port')]
+ return [shared.cache.get_lib('liblzma.a', create, what='port')]
+
+
+def clear(ports, settings, shared):
+ shared.Cache.erase_lib('liblzma.a')
+ shared.cache.erase_lib('liblzma.a')
+
+
+def process_args(ports):
@@ -105,7 +95,7 @@ new file mode 100644
+ return 'liblzma (USE_LIBLZMA=1; public domain)'
+
+
+config_h = r'''
+config_h = '''
+#define ASSUME_RAM 128
+#define ENABLE_NLS 1
+#define HAVE_CHECK_CRC32 1
@@ -177,9 +167,9 @@ new file mode 100644
+#define PACKAGE "xz"
+#define PACKAGE_BUGREPORT "lasse.collin@tukaani.org"
+#define PACKAGE_NAME "XZ Utils"
+#define PACKAGE_STRING "XZ Utils 5.2.5"
+#define PACKAGE_STRING "XZ Utils 5.4.0"
+#define PACKAGE_TARNAME "xz"
+#define PACKAGE_VERSION "5.2.5"
+#define PACKAGE_VERSION "5.4.0"
+#define SIZEOF_SIZE_T 4
+#define STDC_HEADERS 1
+#define TUKLIB_CPUCORES_SYSCONF 1
@@ -200,5 +190,5 @@ new file mode 100644
+#ifndef __EXTENSIONS__
+# define __EXTENSIONS__ 1
+#endif
+#define VERSION "5.2.5"
+#define VERSION "5.4.0"
+'''

View File

@@ -32,6 +32,6 @@
<key>NSHighResolutionCapable</key>
<string>True</string>
<key>LSMinimumSystemVersion</key>
<string>10.14.0</string>
<string>10.13.0</string>
</dict>
</plist>

View File

@@ -562,6 +562,25 @@ function Regression::Prices()
print(" BT_CLEAR_WATER: " + AITile.GetBuildCost(AITile.BT_CLEAR_WATER));
}
function Regression::Commands()
{
print("");
print("--Commands--");
print(" -Command accounting-");
local test = AITestMode();
local costs = AIAccounting();
AITile.DemolishTile(2834);
print(" Command cost: " + costs.GetCosts());
{
local inner = AIAccounting();
print(" New inner cost scope: " + costs.GetCosts());
AITile.DemolishTile(2835);
print(" Further command cost: " + costs.GetCosts());
}
print(" Saved cost of outer scope: " + costs.GetCosts());
}
function cost_callback(old_path, new_tile, new_direction, self) { if (old_path == null) return 0; return old_path.GetCost() + 1; }
function estimate_callback(tile, direction, goals, self) { return goals[0] - tile; }
function neighbours_callback(path, cur_tile, self) { return [[cur_tile + 1, 1]]; }
@@ -1684,6 +1703,7 @@ function Regression::Vehicle()
print(" BuildVehicle(): " + AIVehicle.BuildVehicle(33417, 153));
print(" IsValidVehicle(12): " + AIVehicle.IsValidVehicle(12));
print(" CloneVehicle(): " + AIVehicle.CloneVehicle(33417, 12, true));
print(" BuildVehicle(): " + AIVehicle.BuildVehicle(-1, 153));
local bank_after = AICompany.GetBankBalance(AICompany.COMPANY_SELF);
@@ -1940,6 +1960,7 @@ function Regression::Start()
/* Do this first as it gains maximum loan (which is faked to quite a lot). */
this.Company();
this.Commands();
this.Airport();
this.Bridge();
this.BridgeList();

View File

@@ -788,6 +788,13 @@ ERROR: IsEnd() is invalid as Begin() is never called
GetQuarterlyPerformanceRating(): 0
GetQuarterlyCompanyValue(): 0
--Commands--
-Command accounting-
Command cost: 7500
New inner cost scope: 0
Further command cost: 30
Saved cost of outer scope: 7500
--AIAirport--
IsHangarTile(): false
IsAirportTile(): false
@@ -9288,6 +9295,7 @@ ERROR: IsEnd() is invalid as Begin() is never called
BuildVehicle(): 12
IsValidVehicle(12): true
CloneVehicle(): 13
BuildVehicle(): 1048575
--Accounting--
GetCosts(): 11894
Should be: 11894

View File

@@ -450,7 +450,7 @@ void RefTable::Resize(SQUnsignedInteger size)
SQUnsignedInteger oldnumofslots = _numofslots;
AllocNodes(size);
//rehash
SQUnsignedInteger nfound = 0;
[[maybe_unused]] SQUnsignedInteger nfound = 0;
for(SQUnsignedInteger n = 0; n < oldnumofslots; n++) {
if(type(t->obj) != OT_NULL) {
//add back;

View File

@@ -217,6 +217,12 @@ add_files(
landscape_cmd.h
landscape_type.h
language.h
league_base.h
league_cmd.h
league_cmd.cpp
league_gui.h
league_gui.cpp
league_type.h
livery.h
main_gui.cpp
map.cpp

View File

@@ -128,11 +128,6 @@ public:
*/
static void Save(CompanyID company);
/**
* Load data for an AI from a savegame.
*/
static void Load(CompanyID company, int version);
/**
* Get the number of days before the next AI should start.
*/

View File

@@ -57,6 +57,8 @@
assert(c->ai_instance == nullptr);
c->ai_instance = new AIInstance();
c->ai_instance->Initialize(info);
c->ai_instance->LoadOnStack(config->GetToLoadData());
config->SetToLoadData(nullptr);
cur_company.Restore();
@@ -289,21 +291,6 @@
}
}
/* static */ void AI::Load(CompanyID company, int version)
{
if (!_networking || _network_server) {
Company *c = Company::GetIfValid(company);
assert(c != nullptr && c->ai_instance != nullptr);
Backup<CompanyID> cur_company(_current_company, company, FILE_LINE);
c->ai_instance->Load(version);
cur_company.Restore();
} else {
/* Read, but ignore, the load data */
AIInstance::LoadEmpty();
}
}
/* static */ int AI::GetStartNextTime()
{
/* Find the first company which doesn't exist yet */

View File

@@ -112,7 +112,7 @@ struct AIListWindow : public Window {
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
{
if (widget == WID_AIL_LIST) {
this->line_height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM;
this->line_height = FONT_HEIGHT_NORMAL + padding.height;
resize->width = 1;
resize->height = this->line_height;
@@ -125,45 +125,45 @@ struct AIListWindow : public Window {
switch (widget) {
case WID_AIL_LIST: {
/* Draw a list of all available AIs. */
int y = this->GetWidget<NWidgetBase>(WID_AIL_LIST)->pos_y;
Rect tr = r.Shrink(WidgetDimensions::scaled.matrix);
/* First AI in the list is hardcoded to random */
if (this->vscroll->IsVisible(0)) {
DrawString(r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_LEFT, y + WD_MATRIX_TOP, this->slot == OWNER_DEITY ? STR_AI_CONFIG_NONE : STR_AI_CONFIG_RANDOM_AI, this->selected == -1 ? TC_WHITE : TC_ORANGE);
y += this->line_height;
DrawString(tr, this->slot == OWNER_DEITY ? STR_AI_CONFIG_NONE : STR_AI_CONFIG_RANDOM_AI, this->selected == -1 ? TC_WHITE : TC_ORANGE);
tr.top += this->line_height;
}
int i = 0;
for (const auto &item : *this->info_list) {
i++;
if (this->vscroll->IsVisible(i)) {
DrawString(r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_RIGHT, y + WD_MATRIX_TOP, item.second->GetName(), (this->selected == i - 1) ? TC_WHITE : TC_ORANGE);
y += this->line_height;
DrawString(tr, item.second->GetName(), (this->selected == i - 1) ? TC_WHITE : TC_ORANGE);
tr.top += this->line_height;
}
}
break;
}
case WID_AIL_INFO_BG: {
AIInfo *selected_info = nullptr;
ScriptInfo *selected_info = nullptr;
int i = 0;
for (const auto &item : *this->info_list) {
i++;
if (this->selected == i - 1) selected_info = static_cast<AIInfo *>(item.second);
if (this->selected == i - 1) selected_info = static_cast<ScriptInfo *>(item.second);
}
/* Some info about the currently selected AI. */
if (selected_info != nullptr) {
int y = r.top + WD_FRAMERECT_TOP;
Rect tr = r.Shrink(WidgetDimensions::scaled.frametext, WidgetDimensions::scaled.framerect);
SetDParamStr(0, selected_info->GetAuthor());
DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, y, STR_AI_LIST_AUTHOR);
y += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL;
DrawString(tr, STR_AI_LIST_AUTHOR);
tr.top += FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal;
SetDParam(0, selected_info->GetVersion());
DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, y, STR_AI_LIST_VERSION);
y += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL;
DrawString(tr, STR_AI_LIST_VERSION);
tr.top += FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal;
if (selected_info->GetURL() != nullptr) {
SetDParamStr(0, selected_info->GetURL());
DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, y, STR_AI_LIST_URL);
y += FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL;
DrawString(tr, STR_AI_LIST_URL);
tr.top += FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal;
}
SetDParamStr(0, selected_info->GetDescription());
DrawStringMultiLine(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, y, r.bottom - WD_FRAMERECT_BOTTOM, STR_JUST_RAW_STRING, TC_WHITE);
DrawStringMultiLine(tr, STR_JUST_RAW_STRING, TC_WHITE);
}
break;
}
@@ -182,7 +182,7 @@ struct AIListWindow : public Window {
for (int i = 0; i < this->selected; i++) it++;
GetConfig(slot)->Change((*it).second->GetName(), (*it).second->GetVersion());
}
InvalidateWindowData(WC_GAME_OPTIONS, WN_GAME_OPTIONS_AI);
InvalidateWindowData(WC_GAME_OPTIONS, slot == OWNER_DEITY ? WN_GAME_OPTIONS_GS : WN_GAME_OPTIONS_AI);
InvalidateWindowClassesData(WC_AI_SETTINGS);
CloseWindowByClass(WC_QUERY_STRING);
InvalidateWindowClassesData(WC_TEXTFILE);
@@ -253,7 +253,7 @@ static const NWidgetPart _nested_ai_list_widgets[] = {
NWidget(WWT_MATRIX, COLOUR_MAUVE, WID_AIL_LIST), SetMinimalSize(188, 112), SetFill(1, 1), SetResize(1, 1), SetMatrixDataTip(1, 0, STR_AI_LIST_TOOLTIP), SetScrollbar(WID_AIL_SCROLLBAR),
NWidget(NWID_VSCROLLBAR, COLOUR_MAUVE, WID_AIL_SCROLLBAR),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_MAUVE, WID_AIL_INFO_BG), SetMinimalTextLines(8, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM), SetResize(1, 0),
NWidget(WWT_PANEL, COLOUR_MAUVE, WID_AIL_INFO_BG), SetMinimalTextLines(8, WidgetDimensions::unscaled.framerect.Vertical() + WidgetDimensions::unscaled.vsep_normal * 3), SetResize(1, 0),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
@@ -276,7 +276,7 @@ static WindowDesc _ai_list_desc(
* Open the AI list window to chose an AI for the given company slot.
* @param slot The slot to change the AI of.
*/
static void ShowAIListWindow(CompanyID slot)
void ShowAIListWindow(CompanyID slot)
{
CloseWindowByClass(WC_AI_LIST);
new AIListWindow(&_ai_list_desc, slot);
@@ -296,7 +296,7 @@ struct AISettingsWindow : public Window {
int clicked_row; ///< The clicked row of settings.
int line_height; ///< Height of a row in the matrix widget.
Scrollbar *vscroll; ///< Cache of the vertical scrollbar.
typedef std::vector<const ScriptConfigItem *> VisibleSettingsList;
typedef std::vector<const ScriptConfigItem *> VisibleSettingsList; ///< typdef for a vector of script settings
VisibleSettingsList visible_settings; ///< List of visible AI settings
/**
@@ -320,15 +320,6 @@ struct AISettingsWindow : public Window {
this->RebuildVisibleSettings();
}
void SetStringParameters(int widget) const override
{
switch (widget) {
case WID_AIS_CAPTION:
SetDParam(0, (this->slot == OWNER_DEITY) ? STR_AI_SETTINGS_CAPTION_GAMESCRIPT : STR_AI_SETTINGS_CAPTION_AI);
break;
}
}
/**
* Rebuilds the list of visible settings. AI settings with the flag
* AICONFIG_AI_DEVELOPER set will only be visible if the game setting
@@ -351,7 +342,7 @@ struct AISettingsWindow : public Window {
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
{
if (widget == WID_AIS_BACKGROUND) {
this->line_height = std::max(SETTING_BUTTON_HEIGHT, FONT_HEIGHT_NORMAL) + WD_MATRIX_TOP + WD_MATRIX_BOTTOM;
this->line_height = std::max(SETTING_BUTTON_HEIGHT, FONT_HEIGHT_NORMAL) + padding.height;
resize->width = 1;
resize->height = this->line_height;
@@ -368,11 +359,10 @@ struct AISettingsWindow : public Window {
int i = 0;
for (; !this->vscroll->IsVisible(i); i++) it++;
Rect ir = r.Shrink(WidgetDimensions::scaled.framerect);
bool rtl = _current_text_dir == TD_RTL;
uint buttons_left = rtl ? r.right - SETTING_BUTTON_WIDTH - 3 : r.left + 4;
uint text_left = r.left + (rtl ? WD_FRAMERECT_LEFT : SETTING_BUTTON_WIDTH + 8);
uint text_right = r.right - (rtl ? SETTING_BUTTON_WIDTH + 8 : WD_FRAMERECT_RIGHT);
Rect br = ir.WithWidth(SETTING_BUTTON_WIDTH, rtl);
Rect tr = ir.Indent(SETTING_BUTTON_WIDTH + WidgetDimensions::scaled.hsep_wide, rtl);
int y = r.top;
int button_y_offset = (this->line_height - SETTING_BUTTON_HEIGHT) / 2;
@@ -401,13 +391,13 @@ struct AISettingsWindow : public Window {
}
if ((config_item.flags & SCRIPTCONFIG_BOOLEAN) != 0) {
DrawBoolButton(buttons_left, y + button_y_offset, current_value != 0, editable);
DrawBoolButton(br.left, y + button_y_offset, current_value != 0, editable);
SetDParam(idx++, current_value == 0 ? STR_CONFIG_SETTING_OFF : STR_CONFIG_SETTING_ON);
} else {
if (config_item.complete_labels) {
DrawDropDownButton(buttons_left, y + button_y_offset, COLOUR_YELLOW, this->clicked_row == i && clicked_dropdown, editable);
DrawDropDownButton(br.left, y + button_y_offset, COLOUR_YELLOW, this->clicked_row == i && clicked_dropdown, editable);
} else {
DrawArrowButtons(buttons_left, y + button_y_offset, COLOUR_YELLOW, (this->clicked_button == i) ? 1 + (this->clicked_increase != rtl) : 0, editable && current_value > config_item.min_value, editable && current_value < config_item.max_value);
DrawArrowButtons(br.left, y + button_y_offset, COLOUR_YELLOW, (this->clicked_button == i) ? 1 + (this->clicked_increase != rtl) : 0, editable && current_value > config_item.min_value, editable && current_value < config_item.max_value);
}
if (config_item.labels != nullptr && config_item.labels->Contains(current_value)) {
SetDParam(idx++, STR_JUST_RAW_STRING);
@@ -418,7 +408,7 @@ struct AISettingsWindow : public Window {
}
}
DrawString(text_left, text_right, y + text_y_offset, str, colour);
DrawString(tr.left, tr.right, y + text_y_offset, str, colour);
y += this->line_height;
}
}
@@ -436,8 +426,8 @@ struct AISettingsWindow : public Window {
{
switch (widget) {
case WID_AIS_BACKGROUND: {
const NWidgetBase *wid = this->GetWidget<NWidgetBase>(WID_AIS_BACKGROUND);
int num = (pt.y - wid->pos_y) / this->line_height + this->vscroll->GetPosition();
Rect r = this->GetWidget<NWidgetBase>(widget)->GetCurrentRect().Shrink(WidgetDimensions::scaled.matrix, RectPadding::zero);
int num = (pt.y - r.top) / this->line_height + this->vscroll->GetPosition();
if (num >= (int)this->visible_settings.size()) break;
VisibleSettingsList::const_iterator it = this->visible_settings.begin();
@@ -454,9 +444,8 @@ struct AISettingsWindow : public Window {
bool bool_item = (config_item.flags & SCRIPTCONFIG_BOOLEAN) != 0;
int x = pt.x - wid->pos_x;
if (_current_text_dir == TD_RTL) x = wid->current_x - 1 - x;
x -= 4;
int x = pt.x - r.left;
if (_current_text_dir == TD_RTL) x = r.Width() - 1 - x;
/* One of the arrows is clicked (or green/red rect in case of bool value) */
int old_val = this->ai_config->GetSetting(config_item.name);
@@ -467,8 +456,7 @@ struct AISettingsWindow : public Window {
this->clicked_dropdown = false;
this->closing_dropdown = false;
} else {
const NWidgetBase *wid = this->GetWidget<NWidgetBase>(WID_AIS_BACKGROUND);
int rel_y = (pt.y - (int)wid->pos_y) % this->line_height;
int rel_y = (pt.y - r.top) % this->line_height;
Rect wi_rect;
wi_rect.left = pt.x - (_current_text_dir == TD_RTL ? SETTING_BUTTON_WIDTH - 1 - x : x);
@@ -476,7 +464,7 @@ struct AISettingsWindow : public Window {
wi_rect.top = pt.y - rel_y + (this->line_height - SETTING_BUTTON_HEIGHT) / 2;
wi_rect.bottom = wi_rect.top + SETTING_BUTTON_HEIGHT - 1;
/* For dropdowns we also have to check the y position thoroughly, the mouse may not above the just opening dropdown */
/* If the mouse is still held but dragged outside of the dropdown list, keep the dropdown open */
if (pt.y >= wi_rect.top && pt.y <= wi_rect.bottom) {
this->clicked_dropdown = true;
this->closing_dropdown = false;
@@ -533,24 +521,15 @@ struct AISettingsWindow : public Window {
void OnQueryTextFinished(char *str) override
{
if (StrEmpty(str)) return;
VisibleSettingsList::const_iterator it = this->visible_settings.begin();
for (int i = 0; i < this->clicked_row; i++) it++;
const ScriptConfigItem config_item = **it;
if (_game_mode == GM_NORMAL && ((this->slot == OWNER_DEITY) || Company::IsValidID(this->slot)) && (config_item.flags & SCRIPTCONFIG_INGAME) == 0) return;
int32 value = atoi(str);
this->ai_config->SetSetting(config_item.name, value);
this->SetDirty();
SetValue(value);
}
void OnDropdownSelect(int widget, int index) override
{
assert(this->clicked_dropdown);
VisibleSettingsList::const_iterator it = this->visible_settings.begin();
for (int i = 0; i < this->clicked_row; i++) it++;
const ScriptConfigItem config_item = **it;
if (_game_mode == GM_NORMAL && ((this->slot == OWNER_DEITY) || Company::IsValidID(this->slot)) && (config_item.flags & SCRIPTCONFIG_INGAME) == 0) return;
this->ai_config->SetSetting(config_item.name, index);
this->SetDirty();
SetValue(index);
}
void OnDropdownClose(Point pt, int widget, int index, bool instant_close) override
@@ -592,7 +571,21 @@ struct AISettingsWindow : public Window {
private:
bool IsEditableItem(const ScriptConfigItem &config_item) const
{
return _game_mode == GM_MENU || ((this->slot != OWNER_DEITY) && !Company::IsValidID(this->slot)) || (config_item.flags & SCRIPTCONFIG_INGAME) != 0;
return _game_mode == GM_MENU
|| _game_mode == GM_EDITOR
|| ((this->slot != OWNER_DEITY) && !Company::IsValidID(this->slot))
|| (config_item.flags & SCRIPTCONFIG_INGAME) != 0
|| _settings_client.gui.ai_developer_tools;
}
void SetValue(int value)
{
VisibleSettingsList::const_iterator it = this->visible_settings.begin();
for (int i = 0; i < this->clicked_row; i++) it++;
const ScriptConfigItem config_item = **it;
if (_game_mode == GM_NORMAL && ((this->slot == OWNER_DEITY) || Company::IsValidID(this->slot)) && (config_item.flags & SCRIPTCONFIG_INGAME) == 0) return;
this->ai_config->SetSetting(config_item.name, value);
this->SetDirty();
}
};
@@ -600,7 +593,7 @@ private:
static const NWidgetPart _nested_ai_settings_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_MAUVE),
NWidget(WWT_CAPTION, COLOUR_MAUVE, WID_AIS_CAPTION), SetDataTip(STR_AI_SETTINGS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
NWidget(WWT_CAPTION, COLOUR_MAUVE, WID_AIS_CAPTION), SetDataTip(STR_AI_SETTINGS_CAPTION_AI, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
NWidget(WWT_DEFSIZEBOX, COLOUR_MAUVE),
EndContainer(),
NWidget(NWID_HORIZONTAL),
@@ -680,7 +673,7 @@ void ShowScriptTextfileWindow(TextfileType file_type, CompanyID slot)
static const NWidgetPart _nested_ai_config_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_MAUVE),
NWidget(WWT_CAPTION, COLOUR_MAUVE), SetDataTip(STR_AI_CONFIG_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
NWidget(WWT_CAPTION, COLOUR_MAUVE), SetDataTip(STR_AI_CONFIG_CAPTION_AI, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_MAUVE, WID_AIC_BACKGROUND),
NWidget(NWID_VERTICAL), SetPIP(4, 4, 4),
@@ -688,7 +681,7 @@ static const NWidgetPart _nested_ai_config_widgets[] = {
NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_AIC_DECREASE), SetDataTip(AWV_DECREASE, STR_NULL),
NWidget(WWT_PUSHARROWBTN, COLOUR_YELLOW, WID_AIC_INCREASE), SetDataTip(AWV_INCREASE, STR_NULL),
NWidget(NWID_SPACER), SetMinimalSize(6, 0),
NWidget(WWT_TEXT, COLOUR_MAUVE, WID_AIC_NUMBER), SetDataTip(STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS, STR_NULL), SetFill(1, 0),
NWidget(WWT_TEXT, COLOUR_MAUVE, WID_AIC_NUMBER), SetDataTip(STR_AI_CONFIG_MAX_COMPETITORS, STR_NULL), SetFill(1, 0),
EndContainer(),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7),
NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_MOVE_UP), SetResize(1, 0), SetFill(1, 0), SetDataTip(STR_AI_CONFIG_MOVE_UP, STR_AI_CONFIG_MOVE_UP_TOOLTIP),
@@ -702,16 +695,13 @@ static const NWidgetPart _nested_ai_config_widgets[] = {
EndContainer(),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 9),
NWidget(WWT_FRAME, COLOUR_MAUVE), SetDataTip(STR_AI_CONFIG_GAMESCRIPT, STR_NULL), SetPadding(0, 5, 4, 5),
NWidget(WWT_MATRIX, COLOUR_MAUVE, WID_AIC_GAMELIST), SetMinimalSize(288, 14), SetFill(1, 0), SetMatrixDataTip(1, 1, STR_AI_CONFIG_GAMELIST_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7),
NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_CHANGE), SetFill(1, 0), SetMinimalSize(93, 0), SetDataTip(STR_AI_CONFIG_CHANGE, STR_AI_CONFIG_CHANGE_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_CHANGE), SetFill(1, 0), SetMinimalSize(93, 0), SetDataTip(STR_AI_CONFIG_CHANGE_AI, STR_AI_CONFIG_CHANGE_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_CONFIGURE), SetFill(1, 0), SetMinimalSize(93, 0), SetDataTip(STR_AI_CONFIG_CONFIGURE, STR_AI_CONFIG_CONFIGURE_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_CLOSE), SetFill(1, 0), SetMinimalSize(93, 0), SetDataTip(STR_AI_SETTINGS_CLOSE, STR_NULL),
NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_README, STR_NULL),
EndContainer(),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7),
NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_README, STR_NULL),
NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_CLOSE), SetFill(1, 0), SetMinimalSize(93, 0), SetDataTip(STR_AI_SETTINGS_CLOSE, STR_NULL),
NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_NULL),
NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_AIC_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_LICENCE, STR_NULL),
EndContainer(),
@@ -759,21 +749,6 @@ struct AIConfigWindow : public Window {
case WID_AIC_NUMBER:
SetDParam(0, GetGameSettings().difficulty.max_no_competitors);
break;
case WID_AIC_CHANGE:
switch (selected_slot) {
case OWNER_DEITY:
SetDParam(0, STR_AI_CONFIG_CHANGE_GAMESCRIPT);
break;
case INVALID_COMPANY:
SetDParam(0, STR_AI_CONFIG_CHANGE_NONE);
break;
default:
SetDParam(0, STR_AI_CONFIG_CHANGE_AI);
break;
}
break;
}
}
@@ -785,32 +760,11 @@ struct AIConfigWindow : public Window {
*size = maxdim(*size, NWidgetScrollbar::GetHorizontalDimension());
break;
case WID_AIC_GAMELIST:
this->line_height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM;
size->height = 1 * this->line_height;
break;
case WID_AIC_LIST:
this->line_height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM;
this->line_height = FONT_HEIGHT_NORMAL + padding.height;
resize->height = this->line_height;
size->height = 8 * this->line_height;
break;
case WID_AIC_CHANGE: {
SetDParam(0, STR_AI_CONFIG_CHANGE_GAMESCRIPT);
Dimension dim = GetStringBoundingBox(STR_AI_CONFIG_CHANGE);
SetDParam(0, STR_AI_CONFIG_CHANGE_NONE);
dim = maxdim(dim, GetStringBoundingBox(STR_AI_CONFIG_CHANGE));
SetDParam(0, STR_AI_CONFIG_CHANGE_AI);
dim = maxdim(dim, GetStringBoundingBox(STR_AI_CONFIG_CHANGE));
dim.width += padding.width;
dim.height += padding.height;
*size = maxdim(*size, dim);
break;
}
}
}
@@ -821,8 +775,6 @@ struct AIConfigWindow : public Window {
*/
static bool IsEditable(CompanyID slot)
{
if (slot == OWNER_DEITY) return _game_mode != GM_NORMAL || Game::GetInstance() != nullptr;
if (_game_mode != GM_NORMAL) {
return slot > 0 && slot <= GetGameSettings().difficulty.max_no_competitors;
}
@@ -838,22 +790,8 @@ struct AIConfigWindow : public Window {
void DrawWidget(const Rect &r, int widget) const override
{
switch (widget) {
case WID_AIC_GAMELIST: {
StringID text = STR_AI_CONFIG_NONE;
if (GameConfig::GetConfig()->GetInfo() != nullptr) {
SetDParamStr(0, GameConfig::GetConfig()->GetInfo()->GetName());
text = STR_JUST_RAW_STRING;
}
DrawString(r.left + 10, r.right - 10, r.top + WD_MATRIX_TOP, text,
(this->selected_slot == OWNER_DEITY) ? TC_WHITE : (IsEditable(OWNER_DEITY) ? TC_ORANGE : TC_SILVER));
break;
}
case WID_AIC_LIST: {
int y = r.top;
Rect tr = r.Shrink(WidgetDimensions::scaled.matrix);
for (int i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < MAX_COMPANIES; i++) {
StringID text;
@@ -865,9 +803,9 @@ struct AIConfigWindow : public Window {
} else {
text = STR_AI_CONFIG_RANDOM_AI;
}
DrawString(r.left + 10, r.right - 10, y + WD_MATRIX_TOP, text,
DrawString(tr, text,
(this->selected_slot == i) ? TC_WHITE : (IsEditable((CompanyID)i) ? TC_ORANGE : TC_SILVER));
y += this->line_height;
tr.top += this->line_height;
}
break;
}
@@ -896,13 +834,6 @@ struct AIConfigWindow : public Window {
break;
}
case WID_AIC_GAMELIST: {
this->selected_slot = OWNER_DEITY;
this->InvalidateData();
if (click_count > 1 && this->selected_slot != INVALID_COMPANY && _game_mode != GM_NORMAL) ShowAIListWindow((CompanyID)this->selected_slot);
break;
}
case WID_AIC_LIST: { // Select a slot
this->selected_slot = (CompanyID)this->vscroll->GetScrolledRowFromWidget(pt.y, this, widget);
this->InvalidateData();
@@ -944,7 +875,7 @@ struct AIConfigWindow : public Window {
if (!_network_available) {
ShowErrorMessage(STR_NETWORK_ERROR_NOTAVAILABLE, INVALID_STRING_ID, WL_ERROR);
} else {
ShowNetworkContentListWindow(nullptr, CONTENT_TYPE_AI, CONTENT_TYPE_GAME);
ShowNetworkContentListWindow(nullptr, CONTENT_TYPE_AI);
}
break;
}
@@ -965,10 +896,10 @@ struct AIConfigWindow : public Window {
this->SetWidgetDisabledState(WID_AIC_DECREASE, GetGameSettings().difficulty.max_no_competitors == 0);
this->SetWidgetDisabledState(WID_AIC_INCREASE, GetGameSettings().difficulty.max_no_competitors == MAX_COMPANIES - 1);
this->SetWidgetDisabledState(WID_AIC_CHANGE, (this->selected_slot == OWNER_DEITY && _game_mode == GM_NORMAL) || this->selected_slot == INVALID_COMPANY);
this->SetWidgetDisabledState(WID_AIC_CHANGE, this->selected_slot == INVALID_COMPANY);
this->SetWidgetDisabledState(WID_AIC_CONFIGURE, this->selected_slot == INVALID_COMPANY || GetConfig(this->selected_slot)->GetConfigList()->size() == 0);
this->SetWidgetDisabledState(WID_AIC_MOVE_UP, this->selected_slot == OWNER_DEITY || this->selected_slot == INVALID_COMPANY || !IsEditable((CompanyID)(this->selected_slot - 1)));
this->SetWidgetDisabledState(WID_AIC_MOVE_DOWN, this->selected_slot == OWNER_DEITY || this->selected_slot == INVALID_COMPANY || !IsEditable((CompanyID)(this->selected_slot + 1)));
this->SetWidgetDisabledState(WID_AIC_MOVE_UP, this->selected_slot == INVALID_COMPANY || !IsEditable((CompanyID)(this->selected_slot - 1)));
this->SetWidgetDisabledState(WID_AIC_MOVE_DOWN, this->selected_slot == INVALID_COMPANY || !IsEditable((CompanyID)(this->selected_slot + 1)));
for (TextfileType tft = TFT_BEGIN; tft < TFT_END; tft++) {
this->SetWidgetDisabledState(WID_AIC_TEXTFILE + tft, this->selected_slot == INVALID_COMPANY || (GetConfig(this->selected_slot)->GetTextfile(tft, this->selected_slot) == nullptr));
@@ -1008,9 +939,6 @@ static bool SetScriptButtonColour(NWidgetCore &button, bool dead, bool paused)
* Window with everything an AI prints via ScriptLog.
*/
struct AIDebugWindow : public Window {
static const int top_offset; ///< Offset of the text at the top of the WID_AID_LOG_PANEL.
static const int bottom_offset; ///< Offset of the text at the bottom of the WID_AID_LOG_PANEL.
static const uint MAX_BREAK_STR_STRING_LENGTH = 256; ///< Maximum length of the break string.
static CompanyID ai_debug_company; ///< The AI that is (was last) being debugged.
@@ -1114,8 +1042,8 @@ struct AIDebugWindow : public Window {
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
{
if (widget == WID_AID_LOG_PANEL) {
resize->height = FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL;
size->height = 14 * resize->height + this->top_offset + this->bottom_offset;
resize->height = FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal;
size->height = 14 * resize->height + WidgetDimensions::scaled.framerect.Vertical();
}
}
@@ -1229,7 +1157,8 @@ struct AIDebugWindow : public Window {
ScriptLog::LogData *log = this->GetLogPointer();
if (log == nullptr) return;
int y = this->top_offset;
Rect br = r.Shrink(WidgetDimensions::scaled.bevel);
Rect tr = r.Shrink(WidgetDimensions::scaled.framerect);
for (int i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < log->used; i++) {
int pos = (i + log->pos + 1 - log->used + log->count) % log->count;
if (log->lines[pos] == nullptr) break;
@@ -1246,12 +1175,12 @@ struct AIDebugWindow : public Window {
/* Check if the current line should be highlighted */
if (pos == this->highlight_row) {
GfxFillRect(r.left + 1, r.top + y, r.right - 1, r.top + y + this->resize.step_height - WD_PAR_VSEP_NORMAL, PC_BLACK);
GfxFillRect(br.left, tr.top, br.right, tr.top + this->resize.step_height - 1, PC_BLACK);
if (colour == TC_BLACK) colour = TC_WHITE; // Make black text readable by inverting it to white.
}
DrawString(r.left + 7, r.right - 7, r.top + y, log->lines[pos], colour, SA_LEFT | SA_FORCE);
y += this->resize.step_height;
DrawString(tr, log->lines[pos], colour, SA_LEFT | SA_FORCE);
tr.top += this->resize.step_height;
}
break;
}
@@ -1423,14 +1352,12 @@ struct AIDebugWindow : public Window {
void OnResize() override
{
this->vscroll->SetCapacityFromWidget(this, WID_AID_LOG_PANEL);
this->vscroll->SetCapacityFromWidget(this, WID_AID_LOG_PANEL, WidgetDimensions::scaled.framerect.Vertical());
}
static HotkeyList hotkeys;
};
const int AIDebugWindow::top_offset = WD_FRAMERECT_TOP + 2;
const int AIDebugWindow::bottom_offset = WD_FRAMERECT_BOTTOM;
CompanyID AIDebugWindow::ai_debug_company = INVALID_COMPANY;
char AIDebugWindow::break_string[MAX_BREAK_STR_STRING_LENGTH] = "";
bool AIDebugWindow::break_check_enabled = true;

View File

@@ -12,8 +12,10 @@
#include "../company_type.h"
void ShowAIListWindow(CompanyID slot);
Window* ShowAIDebugWindow(CompanyID show_company = INVALID_COMPANY);
void ShowAIConfigWindow();
void ShowScriptTextfileWindow(TextfileType file_type, CompanyID slot);
void ShowAIDebugWindowIfAIError();
void InitializeAIGui();

View File

@@ -61,6 +61,9 @@ void AIInstance::Died()
{
ScriptInstance::Died();
/* Intro is not supposed to use AI, but it may have 'dummy' AI which instant dies. */
if (_game_mode == GM_MENU) return;
ShowAIDebugWindow(_current_company);
const AIInfo *info = AIConfig::GetConfig(_current_company, AIConfig::SSS_FORCE_GAME)->GetInfo();

View File

@@ -10,6 +10,7 @@
#include "../stdafx.h"
#include "../debug.h"
#include "../network/network.h"
#include "../openttd.h"
#include "../core/random_func.hpp"
#include "../script/squirrel_class.hpp"
@@ -59,6 +60,11 @@ void AIScannerInfo::RegisterAPI(class Squirrel *engine)
AIInfo *AIScannerInfo::SelectRandomAI() const
{
if (_game_mode == GM_MENU) {
Debug(script, 0, "The intro game should not use AI, loading 'dummy' AI.");
return this->info_dummy;
}
uint num_random_ais = 0;
for (const auto &item : info_single_list) {
AIInfo *i = static_cast<AIInfo *>(item.second);

View File

@@ -231,7 +231,7 @@ void DrawAircraftEngine(int left, int right, int preferred_x, int y, EngineID en
VehicleSpriteSeq rotor_seq;
GetCustomRotorIcon(engine, image_type, &rotor_seq);
if (!rotor_seq.IsValid()) rotor_seq.Set(SPR_ROTOR_STOPPED);
rotor_seq.Draw(preferred_x, y - ScaleGUITrad(5), PAL_NONE, false);
rotor_seq.Draw(preferred_x, y - ScaleSpriteTrad(5), PAL_NONE, false);
}
}
@@ -252,8 +252,8 @@ void GetAircraftSpriteSize(EngineID engine, uint &width, uint &height, int &xoff
Rect rect;
seq.GetBounds(&rect);
width = UnScaleGUI(rect.right - rect.left + 1);
height = UnScaleGUI(rect.bottom - rect.top + 1);
width = UnScaleGUI(rect.Width());
height = UnScaleGUI(rect.Height());
xoffs = UnScaleGUI(rect.left);
yoffs = UnScaleGUI(rect.top);
}

View File

@@ -25,59 +25,58 @@
* Draw the details for the given vehicle at the given position
*
* @param v current vehicle
* @param left The left most coordinate to draw
* @param right The right most coordinate to draw
* @param y The y coordinate
* @param r the Rect to draw within
*/
void DrawAircraftDetails(const Aircraft *v, int left, int right, int y)
void DrawAircraftDetails(const Aircraft *v, const Rect &r)
{
int y_offset = (v->Next()->cargo_cap != 0) ? -(FONT_HEIGHT_NORMAL + 1): 0;
Money feeder_share = 0;
int y = r.top;
for (const Aircraft *u = v; u != nullptr; u = u->Next()) {
if (u->IsNormalAircraft()) {
SetDParam(0, u->engine_type);
SetDParam(1, u->build_year);
SetDParam(2, u->value);
DrawString(left, right, y, STR_VEHICLE_INFO_BUILT_VALUE);
DrawString(r.left, r.right, y, STR_VEHICLE_INFO_BUILT_VALUE);
y += FONT_HEIGHT_NORMAL;
SetDParam(0, u->cargo_type);
SetDParam(1, u->cargo_cap);
SetDParam(2, u->Next()->cargo_type);
SetDParam(3, u->Next()->cargo_cap);
SetDParam(4, GetCargoSubtypeText(u));
DrawString(left, right, y + FONT_HEIGHT_NORMAL, (u->Next()->cargo_cap != 0) ? STR_VEHICLE_INFO_CAPACITY_CAPACITY : STR_VEHICLE_INFO_CAPACITY);
DrawString(r.left, r.right, y, (u->Next()->cargo_cap != 0) ? STR_VEHICLE_INFO_CAPACITY_CAPACITY : STR_VEHICLE_INFO_CAPACITY);
y += FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal;
}
if (u->cargo_cap != 0) {
uint cargo_count = u->cargo.StoredCount();
y_offset += FONT_HEIGHT_NORMAL + 1;
if (cargo_count != 0) {
/* Cargo names (fix pluralness) */
SetDParam(0, u->cargo_type);
SetDParam(1, cargo_count);
SetDParam(2, u->cargo.Source());
DrawString(left, right, y + 2 * FONT_HEIGHT_NORMAL + 1 + y_offset, STR_VEHICLE_DETAILS_CARGO_FROM);
DrawString(r.left, r.right, y, STR_VEHICLE_DETAILS_CARGO_FROM);
y += FONT_HEIGHT_NORMAL;
feeder_share += u->cargo.FeederShare();
}
}
}
y += WidgetDimensions::scaled.vsep_normal;
SetDParam(0, feeder_share);
DrawString(left, right, y + 3 * FONT_HEIGHT_NORMAL + 3 + y_offset, STR_VEHICLE_INFO_FEEDER_CARGO_VALUE);
DrawString(r.left, r.right, y, STR_VEHICLE_INFO_FEEDER_CARGO_VALUE);
}
/**
* Draws an image of an aircraft
* @param v Front vehicle
* @param left The minimum horizontal position
* @param right The maximum horizontal position
* @param y Vertical position to draw at
* @param r Rect to draw at
* @param selection Selected vehicle to draw a frame around
*/
void DrawAircraftImage(const Vehicle *v, int left, int right, int y, VehicleID selection, EngineImageType image_type)
void DrawAircraftImage(const Vehicle *v, const Rect &r, VehicleID selection, EngineImageType image_type)
{
bool rtl = _current_text_dir == TD_RTL;
@@ -87,27 +86,29 @@ void DrawAircraftImage(const Vehicle *v, int left, int right, int y, VehicleID s
Rect rect;
seq.GetBounds(&rect);
int width = UnScaleGUI(rect.right - rect.left + 1);
int width = UnScaleGUI(rect.Width());
int x_offs = UnScaleGUI(rect.left);
int x = rtl ? right - width - x_offs : left - x_offs;
int x = rtl ? r.right - width - x_offs : r.left - x_offs;
/* This magic -1 offset is related to the sprite_y_offsets in build_vehicle_gui.cpp */
int y = ScaleSpriteTrad(-1) + CenterBounds(r.top, r.bottom, 0);
bool helicopter = v->subtype == AIR_HELICOPTER;
int y_offs = ScaleGUITrad(10);
int heli_offs = 0;
PaletteID pal = (v->vehstatus & VS_CRASHED) ? PALETTE_CRASH : GetVehiclePalette(v);
seq.Draw(x, y + y_offs, pal, (v->vehstatus & VS_CRASHED) != 0);
seq.Draw(x, y, pal, (v->vehstatus & VS_CRASHED) != 0);
if (helicopter) {
const Aircraft *a = Aircraft::From(v);
VehicleSpriteSeq rotor_seq;
GetCustomRotorSprite(a, image_type, &rotor_seq);
if (!rotor_seq.IsValid()) rotor_seq.Set(SPR_ROTOR_STOPPED);
heli_offs = ScaleGUITrad(5);
rotor_seq.Draw(x, y + y_offs - heli_offs, PAL_NONE, false);
heli_offs = ScaleSpriteTrad(5);
rotor_seq.Draw(x, y - heli_offs, PAL_NONE, false);
}
if (v->index == selection) {
x += x_offs;
y += UnScaleGUI(rect.top) + y_offs - heli_offs;
DrawFrameRect(x - 1, y - 1, x + width + 1, y + UnScaleGUI(rect.bottom - rect.top + 1) + heli_offs + 1, COLOUR_WHITE, FR_BORDERONLY);
y += UnScaleGUI(rect.top) - heli_offs;
Rect hr = {x, y, x + width - 1, y + UnScaleGUI(rect.Height()) + heli_offs - 1};
DrawFrameRect(hr.Expand(WidgetDimensions::scaled.bevel), COLOUR_WHITE, FR_BORDERONLY);
}
}

View File

@@ -340,10 +340,10 @@ public:
const AirportSpec *as = AirportSpec::Get(i);
if (!as->enabled) continue;
size->width = std::max(size->width, GetStringBoundingBox(as->name).width);
size->width = std::max(size->width, GetStringBoundingBox(as->name).width + padding.width);
}
this->line_height = FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM;
this->line_height = FONT_HEIGHT_NORMAL + padding.height;
size->height = 5 * this->line_height;
break;
}
@@ -356,8 +356,8 @@ public:
SpriteID sprite = GetCustomAirportSprite(as, layout);
if (sprite != 0) {
Dimension d = GetSpriteSize(sprite);
d.width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
d.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
d.width += WidgetDimensions::scaled.framerect.Horizontal();
d.height += WidgetDimensions::scaled.framerect.Vertical();
*size = maxdim(d, *size);
}
}
@@ -388,15 +388,17 @@ public:
{
switch (widget) {
case WID_AP_AIRPORT_LIST: {
int y = r.top;
Rect row = r.WithHeight(this->line_height).Shrink(WidgetDimensions::scaled.bevel);
Rect text = r.WithHeight(this->line_height).Shrink(WidgetDimensions::scaled.matrix);
AirportClass *apclass = AirportClass::Get(_selected_airport_class);
for (uint i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < apclass->GetSpecCount(); i++) {
const AirportSpec *as = apclass->GetSpec(i);
if (!as->IsAvailable()) {
GfxFillRect(r.left + 1, y + 1, r.right - 1, y + this->line_height - 2, PC_BLACK, FILLRECT_CHECKER);
GfxFillRect(row, PC_BLACK, FILLRECT_CHECKER);
}
DrawString(r.left + WD_MATRIX_LEFT, r.right - WD_MATRIX_RIGHT, y + WD_MATRIX_TOP, as->name, ((int)i == _selected_airport_index) ? TC_WHITE : TC_BLACK);
y += this->line_height;
DrawString(text, as->name, ((int)i == _selected_airport_index) ? TC_WHITE : TC_BLACK);
row = row.Translate(0, this->line_height);
text = text.Translate(0, this->line_height);
}
break;
}
@@ -404,7 +406,7 @@ public:
case WID_AP_AIRPORT_SPRITE:
if (this->preview_sprite != 0) {
Dimension d = GetSpriteSize(this->preview_sprite);
DrawSprite(this->preview_sprite, COMPANY_SPRITE_COLOUR(_local_company), (r.left + r.right - d.width) / 2, (r.top + r.bottom - d.height) / 2);
DrawSprite(this->preview_sprite, COMPANY_SPRITE_COLOUR(_local_company), CenterBounds(r.left, r.right, d.width), CenterBounds(r.top, r.bottom, d.height));
}
break;
@@ -426,7 +428,7 @@ public:
this->DrawWidgets();
Rect r = this->GetWidget<NWidgetBase>(WID_AP_ACCEPTANCE)->GetCurrentRect();
int top = r.top + ScaleGUITrad(WD_PAR_VSEP_NORMAL);
int top = r.top + WidgetDimensions::scaled.vsep_normal;
if (_selected_airport_index != -1) {
const AirportSpec *as = AirportClass::Get(_selected_airport_class)->GetSpec(_selected_airport_index);
@@ -437,19 +439,19 @@ public:
/* show the noise of the selected airport */
SetDParam(0, as->noise_level);
DrawString(r.left, r.right, top, STR_STATION_BUILD_NOISE);
top += FONT_HEIGHT_NORMAL + ScaleGUITrad(WD_PAR_VSEP_NORMAL);
top += FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal;
}
if (_settings_game.economy.infrastructure_maintenance) {
Money monthly = _price[PR_INFRASTRUCTURE_AIRPORT] * as->maintenance_cost >> 3;
SetDParam(0, monthly * 12);
DrawString(r.left, r.right, top, STR_STATION_BUILD_INFRASTRUCTURE_COST);
top += FONT_HEIGHT_NORMAL + ScaleGUITrad(WD_PAR_VSEP_NORMAL);
top += FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal;
}
/* strings such as 'Size' and 'Coverage Area' */
top = DrawStationCoverageAreaText(r.left, r.right, top, SCT_ALL, rad, false) + ScaleGUITrad(WD_PAR_VSEP_NORMAL);
top = DrawStationCoverageAreaText(r.left, r.right, top, SCT_ALL, rad, true) + ScaleGUITrad(WD_PAR_VSEP_NORMAL);
top = DrawStationCoverageAreaText(r.left, r.right, top, SCT_ALL, rad, false) + WidgetDimensions::scaled.vsep_normal;
top = DrawStationCoverageAreaText(r.left, r.right, top, SCT_ALL, rad, true) + WidgetDimensions::scaled.vsep_normal;
}
/* Resize background if the window is too small.
@@ -603,7 +605,7 @@ static const NWidgetPart _nested_build_airport_widgets[] = {
EndContainer(),
/* Bottom panel. */
NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_AP_BOTTOMPANEL),
NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetPadding(WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM, WD_FRAMERECT_LEFT), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL), SetFill(1, 0),
NWidget(WWT_LABEL, COLOUR_DARK_GREEN), SetPadding(WidgetDimensions::unscaled.framerect), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL), SetFill(1, 0),
NWidget(NWID_HORIZONTAL),
NWidget(NWID_SPACER), SetMinimalSize(14, 0), SetFill(1, 0),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
@@ -614,7 +616,7 @@ static const NWidgetPart _nested_build_airport_widgets[] = {
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(14, 0), SetFill(1, 0),
EndContainer(),
NWidget(WWT_EMPTY, COLOUR_DARK_GREEN, WID_AP_ACCEPTANCE), SetPadding(0, WD_FRAMERECT_RIGHT, 0, WD_FRAMERECT_LEFT), SetResize(0, 1), SetFill(1, 0),
NWidget(WWT_EMPTY, COLOUR_DARK_GREEN, WID_AP_ACCEPTANCE), SetPadding(WidgetDimensions::unscaled.framerect), SetResize(0, 1), SetFill(1, 0),
EndContainer(),
};

View File

@@ -33,11 +33,11 @@
#include "safeguards.h"
void DrawEngineList(VehicleType type, int x, int r, int y, const GUIEngineList *eng_list, uint16 min, uint16 max, EngineID selected_id, bool show_count, GroupID selected_group);
void DrawEngineList(VehicleType type, const Rect &r, const GUIEngineList &eng_list, uint16 min, uint16 max, EngineID selected_id, bool show_count, GroupID selected_group);
static bool EngineNumberSorter(const EngineID &a, const EngineID &b)
static bool EngineNumberSorter(const GUIEngineListItem &a, const GUIEngineListItem &b)
{
return Engine::Get(a)->list_position < Engine::Get(b)->list_position;
return Engine::Get(a.engine_id)->list_position < Engine::Get(b.engine_id)->list_position;
}
/**
@@ -113,6 +113,26 @@ class ReplaceVehicleWindow : public Window {
return true;
}
void AddChildren(const GUIEngineList &source, GUIEngineList &target, EngineID parent, int indent, int side)
{
for (const auto &item : source) {
if (item.variant_id != parent || item.engine_id == parent) continue;
const Engine *e = Engine::Get(item.engine_id);
EngineDisplayFlags flags = item.flags;
if (e->display_last_variant != INVALID_ENGINE) flags &= ~EngineDisplayFlags::Shaded;
target.emplace_back(e->display_last_variant == INVALID_ENGINE ? item.engine_id : e->display_last_variant, item.engine_id, flags, indent);
/* Add variants if not folded */
if ((item.flags & (EngineDisplayFlags::HasVariants | EngineDisplayFlags::IsFolded)) == EngineDisplayFlags::HasVariants) {
/* Add this engine again as a child */
if ((item.flags & EngineDisplayFlags::Shaded) == EngineDisplayFlags::None) {
target.emplace_back(item.engine_id, item.engine_id, EngineDisplayFlags::None, indent + 1);
}
AddChildren(source, target, item.engine_id, indent + 1, side);
}
}
}
/**
* Generate an engines list
@@ -120,12 +140,12 @@ class ReplaceVehicleWindow : public Window {
*/
void GenerateReplaceVehList(bool draw_left)
{
std::vector<EngineID> variants;
EngineID selected_engine = INVALID_ENGINE;
VehicleType type = (VehicleType)this->window_number;
byte side = draw_left ? 0 : 1;
GUIEngineList *list = &this->engines[side];
list->clear();
GUIEngineList list;
for (const Engine *e : Engine::IterateType(type)) {
if (!draw_left && !this->show_hidden_engines && e->IsHidden(_local_company)) continue;
@@ -155,15 +175,37 @@ class ReplaceVehicleWindow : public Window {
if (!CheckAutoreplaceValidity(this->sel_engine[0], eid, _local_company)) continue;
}
list->push_back(eid);
EngineDisplayFlags flags = (side == 0) ? EngineDisplayFlags::None : e->display_flags;
if (side == 1 && eid == this->sel_engine[0]) flags |= EngineDisplayFlags::Shaded;
list.emplace_back(eid, e->info.variant_id, flags, 0);
if (side == 1 && e->info.variant_id != INVALID_ENGINE) variants.push_back(e->info.variant_id);
if (eid == this->sel_engine[side]) selected_engine = eid; // The selected engine is still in the list
}
if (side == 1) {
/* ensure primary engine of variant group is in list */
for (const auto &variant : variants) {
if (std::find(list.begin(), list.end(), variant) == list.end()) {
const Engine *e = Engine::Get(variant);
list.emplace_back(variant, e->info.variant_id, e->display_flags | EngineDisplayFlags::Shaded, 0);
}
}
}
this->sel_engine[side] = selected_engine; // update which engine we selected (the same or none, if it's not in the list anymore)
if (draw_left) {
EngList_Sort(list, &EngineNumberSorter);
EngList_Sort(&list, &EngineNumberSorter);
} else {
_engine_sort_direction = this->descending_sort_order;
EngList_Sort(list, _engine_sort_functions[this->window_number][this->sort_criteria]);
EngList_Sort(&list, _engine_sort_functions[this->window_number][this->sort_criteria]);
}
this->engines[side].clear();
if (side == 1) {
AddChildren(list, this->engines[side], INVALID_ENGINE, 0, side);
} else {
this->engines[side].swap(list);
}
}
@@ -177,7 +219,7 @@ class ReplaceVehicleWindow : public Window {
this->GenerateReplaceVehList(true);
this->vscroll[0]->SetCount((uint)this->engines[0].size());
if (this->reset_sel_engine && this->sel_engine[0] == INVALID_ENGINE && this->engines[0].size() != 0) {
this->sel_engine[0] = this->engines[0][0];
this->sel_engine[0] = this->engines[0][0].engine_id;
}
}
@@ -198,8 +240,8 @@ class ReplaceVehicleWindow : public Window {
this->vscroll[1]->SetCount((uint)this->engines[1].size());
if (this->reset_sel_engine && this->sel_engine[1] != INVALID_ENGINE) {
int position = 0;
for (EngineID &eid : this->engines[1]) {
if (eid == this->sel_engine[1]) break;
for (const auto &item : this->engines[1]) {
if (item.engine_id == this->sel_engine[1]) break;
++position;
}
this->vscroll[1]->ScrollTowards(position);
@@ -304,8 +346,8 @@ public:
case WID_RV_INFO_TAB: {
Dimension d = GetStringBoundingBox(STR_REPLACE_NOT_REPLACING);
d = maxdim(d, GetStringBoundingBox(STR_REPLACE_NOT_REPLACING_VEHICLE_SELECTED));
d.width += WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT;
d.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
d.width += padding.width;
d.height += padding.height;
*size = maxdim(*size, d);
break;
}
@@ -422,7 +464,7 @@ public:
str = STR_REPLACE_NOT_REPLACING_VEHICLE_SELECTED;
}
DrawString(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, r.top + WD_FRAMERECT_TOP, str, TC_BLACK, SA_HOR_CENTER);
DrawString(r.Shrink(WidgetDimensions::scaled.frametext, WidgetDimensions::scaled.framerect), str, TC_BLACK, SA_HOR_CENTER);
break;
}
@@ -433,8 +475,7 @@ public:
EngineID end = static_cast<EngineID>(std::min<size_t>(this->vscroll[side]->GetCapacity() + start, this->engines[side].size()));
/* Do the actual drawing */
DrawEngineList((VehicleType)this->window_number, r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP,
&this->engines[side], start, end, this->sel_engine[side], side == 0, this->sel_group);
DrawEngineList((VehicleType)this->window_number, r, this->engines[side], start, end, this->sel_engine[side], side == 0, this->sel_group);
break;
}
}
@@ -485,10 +526,10 @@ public:
ted.cargo = e->GetDefaultCargoType();
ted.capacity = e->GetDisplayDefaultCapacity(&ted.mail_capacity);
NWidgetBase *nwi = this->GetWidget<NWidgetBase>(side == 0 ? WID_RV_LEFT_DETAILS : WID_RV_RIGHT_DETAILS);
int text_end = DrawVehiclePurchaseInfo(nwi->pos_x + WD_FRAMETEXT_LEFT, nwi->pos_x + nwi->current_x - WD_FRAMETEXT_RIGHT,
nwi->pos_y + WD_FRAMERECT_TOP, this->sel_engine[side], ted);
needed_height = std::max(needed_height, (text_end - (int)nwi->pos_y - WD_FRAMERECT_TOP) / FONT_HEIGHT_NORMAL);
const Rect r = this->GetWidget<NWidgetBase>(side == 0 ? WID_RV_LEFT_DETAILS : WID_RV_RIGHT_DETAILS)->GetCurrentRect()
.Shrink(WidgetDimensions::scaled.frametext, WidgetDimensions::scaled.framerect);
int text_end = DrawVehiclePurchaseInfo(r.left, r.right, r.top, this->sel_engine[side], ted);
needed_height = std::max(needed_height, (text_end - r.top) / FONT_HEIGHT_NORMAL);
}
}
if (needed_height != this->details_height) { // Details window are not high enough, enlarge them.
@@ -580,7 +621,22 @@ public:
uint i = this->vscroll[click_side]->GetScrolledRowFromWidget(pt.y, this, widget);
size_t engine_count = this->engines[click_side].size();
EngineID e = engine_count > i ? this->engines[click_side][i] : INVALID_ENGINE;
EngineID e = INVALID_ENGINE;
if (i < engine_count) {
const auto &item = this->engines[click_side][i];
const Rect r = this->GetWidget<NWidgetBase>(widget)->GetCurrentRect().Shrink(WidgetDimensions::scaled.matrix).WithWidth(WidgetDimensions::scaled.hsep_indent * (item.indent + 1), _current_text_dir == TD_RTL);
if ((item.flags & EngineDisplayFlags::HasVariants) != EngineDisplayFlags::None && IsInsideMM(r.left, r.right, pt.x)) {
/* toggle folded flag on engine */
assert(item.variant_id != INVALID_ENGINE);
Engine *engine = Engine::Get(item.variant_id);
engine->display_flags ^= EngineDisplayFlags::IsFolded;
InvalidateWindowData(WC_REPLACE_VEHICLE, (VehicleType)this->window_number, 0); // Update the autoreplace window
InvalidateWindowClassesData(WC_BUILD_VEHICLE); // The build windows needs updating as well
return;
}
if ((item.flags & EngineDisplayFlags::Shaded) == EngineDisplayFlags::None) e = item.engine_id;
}
/* If Ctrl is pressed on the left side and we don't have any engines of the selected type, stop autoreplacing.
* This is most common when we have finished autoreplacing the engine and want to remove it from the list. */

View File

@@ -62,8 +62,7 @@ struct BaseStation : StationPool::PoolItem<&_station_pool> {
Owner owner; ///< The owner of this station
StationFacility facilities; ///< The facilities that this station has
uint8 num_specs; ///< Number of specs in the speclist
StationSpecList *speclist; ///< List of station specs of this station
std::vector<StationSpecList> speclist; ///< List of rail station specs of this station.
Date build_date; ///< Date of construction

View File

@@ -58,8 +58,8 @@ public:
void Initialize(const Rect &r)
{
this->tile = TileXY(r.left, r.top);
this->w = r.right - r.left + 1;
this->h = r.bottom - r.top + 1;
this->w = r.Width();
this->h = r.Height();
this->data.clear();
this->data.resize(Index(w, h));
}

View File

@@ -1,5 +1,3 @@
/* $Id$ */
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.

View File

@@ -1,5 +1,3 @@
/* $Id$ */
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.

View File

@@ -101,14 +101,14 @@ public:
{
if (widget == WID_BEM_MESSAGE) {
*size = GetStringBoundingBox(STR_MISSING_GRAPHICS_ERROR);
size->height = GetStringHeight(STR_MISSING_GRAPHICS_ERROR, size->width - WD_FRAMETEXT_LEFT - WD_FRAMETEXT_RIGHT) + WD_FRAMETEXT_BOTTOM + WD_FRAMETEXT_TOP;
size->height = GetStringHeight(STR_MISSING_GRAPHICS_ERROR, size->width - WidgetDimensions::scaled.frametext.Horizontal()) + WidgetDimensions::scaled.frametext.Vertical();
}
}
void DrawWidget(const Rect &r, int widget) const override
{
if (widget == WID_BEM_MESSAGE) {
DrawStringMultiLine(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, r.top + WD_FRAMETEXT_TOP, r.bottom - WD_FRAMETEXT_BOTTOM, STR_MISSING_GRAPHICS_ERROR, TC_FROMSTRING, SA_CENTER);
DrawStringMultiLine(r.Shrink(WidgetDimensions::scaled.frametext), STR_MISSING_GRAPHICS_ERROR, TC_FROMSTRING, SA_CENTER);
}
}
@@ -123,8 +123,11 @@ public:
/** Nested widgets for the download window. */
static const NWidgetPart _nested_bootstrap_download_status_window_widgets[] = {
NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_CONTENT_DOWNLOAD_TITLE, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
NWidget(WWT_PANEL, COLOUR_GREY, WID_NCDS_BACKGROUND),
NWidget(NWID_SPACER), SetMinimalSize(350, 0), SetMinimalTextLines(3, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 30),
NWidget(WWT_PANEL, COLOUR_GREY),
NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0), SetPadding(WidgetDimensions::unscaled.modalpopup),
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_NCDS_PROGRESS_BAR), SetFill(1, 0),
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_NCDS_PROGRESS_TEXT), SetFill(1, 0), SetMinimalSize(350, 0),
EndContainer(),
EndContainer(),
};
@@ -214,15 +217,15 @@ public:
/* We cache the button size. This is safe as no reinit can happen here. */
if (this->button_size.width == 0) {
this->button_size = maxdim(GetStringBoundingBox(STR_MISSING_GRAPHICS_YES_DOWNLOAD), GetStringBoundingBox(STR_MISSING_GRAPHICS_NO_QUIT));
this->button_size.width += WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT;
this->button_size.height += WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM;
this->button_size.width += WidgetDimensions::scaled.frametext.Horizontal();
this->button_size.height += WidgetDimensions::scaled.frametext.Vertical();
}
switch (widget) {
case WID_BAFD_QUESTION:
/* The question is twice as wide as the buttons, and determine the height based on the width. */
size->width = this->button_size.width * 2;
size->height = GetStringHeight(STR_MISSING_GRAPHICS_SET_MESSAGE, size->width - WD_FRAMETEXT_LEFT - WD_FRAMETEXT_RIGHT) + WD_FRAMETEXT_BOTTOM + WD_FRAMETEXT_TOP;
size->height = GetStringHeight(STR_MISSING_GRAPHICS_SET_MESSAGE, size->width - WidgetDimensions::scaled.frametext.Horizontal()) + WidgetDimensions::scaled.frametext.Vertical();
break;
case WID_BAFD_YES:
@@ -236,7 +239,7 @@ public:
{
if (widget != 0) return;
DrawStringMultiLine(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, r.top + WD_FRAMETEXT_TOP, r.bottom - WD_FRAMETEXT_BOTTOM, STR_MISSING_GRAPHICS_SET_MESSAGE, TC_FROMSTRING, SA_CENTER);
DrawStringMultiLine(r.Shrink(WidgetDimensions::scaled.frametext), STR_MISSING_GRAPHICS_SET_MESSAGE, TC_FROMSTRING, SA_CENTER);
}
void OnClick(Point pt, int widget, int click_count) override

View File

@@ -194,10 +194,10 @@ public:
}
sprite_dim.height++; // Sprite is rendered one pixel down in the matrix field.
text_dim.height++; // Allowing the bottom row pixels to be rendered on the edge of the matrix field.
resize->height = std::max(sprite_dim.height, text_dim.height) + 2; // Max of both sizes + account for matrix edges.
resize->height = std::max(sprite_dim.height, text_dim.height) + padding.height; // Max of both sizes + account for matrix edges.
this->bridgetext_offset = WD_MATRIX_LEFT + sprite_dim.width + 1; // Left edge of text, 1 pixel distance from the sprite.
size->width = this->bridgetext_offset + text_dim.width + WD_MATRIX_RIGHT;
this->bridgetext_offset = sprite_dim.width + WidgetDimensions::scaled.hsep_normal; // Left edge of text, 1 pixel distance from the sprite.
size->width = this->bridgetext_offset + text_dim.width + padding.width;
size->height = 4 * resize->height; // Smallest bridge gui is 4 entries high in the matrix.
break;
}
@@ -222,7 +222,7 @@ public:
break;
case WID_BBS_BRIDGE_LIST: {
uint y = r.top;
Rect tr = r.WithHeight(this->resize.step_height).Shrink(WidgetDimensions::scaled.matrix);
for (int i = this->vscroll->GetPosition(); this->vscroll->IsVisible(i) && i < (int)this->bridges->size(); i++) {
const BridgeSpec *b = this->bridges->at(i).spec;
@@ -230,10 +230,10 @@ public:
SetDParam(1, b->speed);
SetDParam(0, b->material);
DrawSprite(b->sprite, b->pal, r.left + WD_MATRIX_LEFT, y + this->resize.step_height - 1 - GetSpriteSize(b->sprite).height);
DrawStringMultiLine(r.left + this->bridgetext_offset, r.right, y + 2, y + this->resize.step_height,
DrawSprite(b->sprite, b->pal, tr.left, tr.bottom - GetSpriteSize(b->sprite).height);
DrawStringMultiLine(tr.Indent(this->bridgetext_offset, false),
_game_mode == GM_EDITOR ? STR_SELECT_BRIDGE_SCENEDIT_INFO : STR_SELECT_BRIDGE_INFO);
y += this->resize.step_height;
tr = tr.Translate(0, this->resize.step_height);
}
break;
}

View File

@@ -33,6 +33,7 @@
#include "engine_cmd.h"
#include "train_cmd.h"
#include "vehicle_cmd.h"
#include "zoom_func.h"
#include "widgets/build_vehicle_widget.h"
@@ -47,7 +48,7 @@
*/
uint GetEngineListHeight(VehicleType type)
{
return std::max<uint>(FONT_HEIGHT_NORMAL + WD_MATRIX_TOP + WD_MATRIX_BOTTOM, GetVehicleImageCellSize(type, EIT_PURCHASE).height);
return std::max<uint>(FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.matrix.Vertical(), GetVehicleImageCellSize(type, EIT_PURCHASE).height);
}
static const NWidgetPart _nested_build_vehicle_widgets[] = {
@@ -105,9 +106,9 @@ static CargoID _engine_sort_last_cargo_criteria[] = {CF_ANY, CF_ANY, CF_ANY, CF_
* @param b second engine to compare
* @return for descending order: returns true if a < b. Vice versa for ascending order
*/
static bool EngineNumberSorter(const EngineID &a, const EngineID &b)
static bool EngineNumberSorter(const GUIEngineListItem &a, const GUIEngineListItem &b)
{
int r = Engine::Get(a)->list_position - Engine::Get(b)->list_position;
int r = Engine::Get(a.engine_id)->list_position - Engine::Get(b.engine_id)->list_position;
return _engine_sort_direction ? r > 0 : r < 0;
}
@@ -118,10 +119,10 @@ static bool EngineNumberSorter(const EngineID &a, const EngineID &b)
* @param b second engine to compare
* @return for descending order: returns true if a < b. Vice versa for ascending order
*/
static bool EngineIntroDateSorter(const EngineID &a, const EngineID &b)
static bool EngineIntroDateSorter(const GUIEngineListItem &a, const GUIEngineListItem &b)
{
const int va = Engine::Get(a)->intro_date;
const int vb = Engine::Get(b)->intro_date;
const int va = Engine::Get(a.engine_id)->intro_date;
const int vb = Engine::Get(b.engine_id)->intro_date;
const int r = va - vb;
/* Use EngineID to sort instead since we want consistent sorting */
@@ -138,19 +139,19 @@ static EngineID _last_engine[2] = { INVALID_ENGINE, INVALID_ENGINE };
* @param b second engine to compare
* @return for descending order: returns true if a < b. Vice versa for ascending order
*/
static bool EngineNameSorter(const EngineID &a, const EngineID &b)
static bool EngineNameSorter(const GUIEngineListItem &a, const GUIEngineListItem &b)
{
static char last_name[2][64] = { "", "" };
if (a != _last_engine[0]) {
_last_engine[0] = a;
SetDParam(0, a);
if (a.engine_id != _last_engine[0]) {
_last_engine[0] = a.engine_id;
SetDParam(0, a.engine_id);
GetString(last_name[0], STR_ENGINE_NAME, lastof(last_name[0]));
}
if (b != _last_engine[1]) {
_last_engine[1] = b;
SetDParam(0, b);
if (b.engine_id != _last_engine[1]) {
_last_engine[1] = b.engine_id;
SetDParam(0, b.engine_id);
GetString(last_name[1], STR_ENGINE_NAME, lastof(last_name[1]));
}
@@ -167,10 +168,10 @@ static bool EngineNameSorter(const EngineID &a, const EngineID &b)
* @param b second engine to compare
* @return for descending order: returns true if a < b. Vice versa for ascending order
*/
static bool EngineReliabilitySorter(const EngineID &a, const EngineID &b)
static bool EngineReliabilitySorter(const GUIEngineListItem &a, const GUIEngineListItem &b)
{
const int va = Engine::Get(a)->reliability;
const int vb = Engine::Get(b)->reliability;
const int va = Engine::Get(a.engine_id)->reliability;
const int vb = Engine::Get(b.engine_id)->reliability;
const int r = va - vb;
/* Use EngineID to sort instead since we want consistent sorting */
@@ -184,10 +185,10 @@ static bool EngineReliabilitySorter(const EngineID &a, const EngineID &b)
* @param b second engine to compare
* @return for descending order: returns true if a < b. Vice versa for ascending order
*/
static bool EngineCostSorter(const EngineID &a, const EngineID &b)
static bool EngineCostSorter(const GUIEngineListItem &a, const GUIEngineListItem &b)
{
Money va = Engine::Get(a)->GetCost();
Money vb = Engine::Get(b)->GetCost();
Money va = Engine::Get(a.engine_id)->GetCost();
Money vb = Engine::Get(b.engine_id)->GetCost();
int r = ClampToI32(va - vb);
/* Use EngineID to sort instead since we want consistent sorting */
@@ -201,10 +202,10 @@ static bool EngineCostSorter(const EngineID &a, const EngineID &b)
* @param b second engine to compare
* @return for descending order: returns true if a < b. Vice versa for ascending order
*/
static bool EngineSpeedSorter(const EngineID &a, const EngineID &b)
static bool EngineSpeedSorter(const GUIEngineListItem &a, const GUIEngineListItem &b)
{
int va = Engine::Get(a)->GetDisplayMaxSpeed();
int vb = Engine::Get(b)->GetDisplayMaxSpeed();
int va = Engine::Get(a.engine_id)->GetDisplayMaxSpeed();
int vb = Engine::Get(b.engine_id)->GetDisplayMaxSpeed();
int r = va - vb;
/* Use EngineID to sort instead since we want consistent sorting */
@@ -218,10 +219,10 @@ static bool EngineSpeedSorter(const EngineID &a, const EngineID &b)
* @param b second engine to compare
* @return for descending order: returns true if a < b. Vice versa for ascending order
*/
static bool EnginePowerSorter(const EngineID &a, const EngineID &b)
static bool EnginePowerSorter(const GUIEngineListItem &a, const GUIEngineListItem &b)
{
int va = Engine::Get(a)->GetPower();
int vb = Engine::Get(b)->GetPower();
int va = Engine::Get(a.engine_id)->GetPower();
int vb = Engine::Get(b.engine_id)->GetPower();
int r = va - vb;
/* Use EngineID to sort instead since we want consistent sorting */
@@ -235,10 +236,10 @@ static bool EnginePowerSorter(const EngineID &a, const EngineID &b)
* @param b second engine to compare
* @return for descending order: returns true if a < b. Vice versa for ascending order
*/
static bool EngineTractiveEffortSorter(const EngineID &a, const EngineID &b)
static bool EngineTractiveEffortSorter(const GUIEngineListItem &a, const GUIEngineListItem &b)
{
int va = Engine::Get(a)->GetDisplayMaxTractiveEffort();
int vb = Engine::Get(b)->GetDisplayMaxTractiveEffort();
int va = Engine::Get(a.engine_id)->GetDisplayMaxTractiveEffort();
int vb = Engine::Get(b.engine_id)->GetDisplayMaxTractiveEffort();
int r = va - vb;
/* Use EngineID to sort instead since we want consistent sorting */
@@ -252,10 +253,10 @@ static bool EngineTractiveEffortSorter(const EngineID &a, const EngineID &b)
* @param b second engine to compare
* @return for descending order: returns true if a < b. Vice versa for ascending order
*/
static bool EngineRunningCostSorter(const EngineID &a, const EngineID &b)
static bool EngineRunningCostSorter(const GUIEngineListItem &a, const GUIEngineListItem &b)
{
Money va = Engine::Get(a)->GetRunningCost();
Money vb = Engine::Get(b)->GetRunningCost();
Money va = Engine::Get(a.engine_id)->GetRunningCost();
Money vb = Engine::Get(b.engine_id)->GetRunningCost();
int r = ClampToI32(va - vb);
/* Use EngineID to sort instead since we want consistent sorting */
@@ -269,10 +270,10 @@ static bool EngineRunningCostSorter(const EngineID &a, const EngineID &b)
* @param b second engine to compare
* @return for descending order: returns true if a < b. Vice versa for ascending order
*/
static bool EnginePowerVsRunningCostSorter(const EngineID &a, const EngineID &b)
static bool EnginePowerVsRunningCostSorter(const GUIEngineListItem &a, const GUIEngineListItem &b)
{
const Engine *e_a = Engine::Get(a);
const Engine *e_b = Engine::Get(b);
const Engine *e_a = Engine::Get(a.engine_id);
const Engine *e_b = Engine::Get(b.engine_id);
uint p_a = e_a->GetPower();
uint p_b = e_b->GetPower();
Money r_a = e_a->GetRunningCost();
@@ -311,13 +312,13 @@ static bool EnginePowerVsRunningCostSorter(const EngineID &a, const EngineID &b)
* @param b second engine to compare
* @return for descending order: returns true if a < b. Vice versa for ascending order
*/
static bool TrainEngineCapacitySorter(const EngineID &a, const EngineID &b)
static bool TrainEngineCapacitySorter(const GUIEngineListItem &a, const GUIEngineListItem &b)
{
const RailVehicleInfo *rvi_a = RailVehInfo(a);
const RailVehicleInfo *rvi_b = RailVehInfo(b);
const RailVehicleInfo *rvi_a = RailVehInfo(a.engine_id);
const RailVehicleInfo *rvi_b = RailVehInfo(b.engine_id);
int va = GetTotalCapacityOfArticulatedParts(a) * (rvi_a->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1);
int vb = GetTotalCapacityOfArticulatedParts(b) * (rvi_b->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1);
int va = GetTotalCapacityOfArticulatedParts(a.engine_id) * (rvi_a->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1);
int vb = GetTotalCapacityOfArticulatedParts(b.engine_id) * (rvi_b->railveh_type == RAILVEH_MULTIHEAD ? 2 : 1);
int r = va - vb;
/* Use EngineID to sort instead since we want consistent sorting */
@@ -331,10 +332,10 @@ static bool TrainEngineCapacitySorter(const EngineID &a, const EngineID &b)
* @param b second engine to compare
* @return for descending order: returns true if a < b. Vice versa for ascending order
*/
static bool TrainEnginesThenWagonsSorter(const EngineID &a, const EngineID &b)
static bool TrainEnginesThenWagonsSorter(const GUIEngineListItem &a, const GUIEngineListItem &b)
{
int val_a = (RailVehInfo(a)->railveh_type == RAILVEH_WAGON ? 1 : 0);
int val_b = (RailVehInfo(b)->railveh_type == RAILVEH_WAGON ? 1 : 0);
int val_a = (RailVehInfo(a.engine_id)->railveh_type == RAILVEH_WAGON ? 1 : 0);
int val_b = (RailVehInfo(b.engine_id)->railveh_type == RAILVEH_WAGON ? 1 : 0);
int r = val_a - val_b;
/* Use EngineID to sort instead since we want consistent sorting */
@@ -350,10 +351,10 @@ static bool TrainEnginesThenWagonsSorter(const EngineID &a, const EngineID &b)
* @param b second engine to compare
* @return for descending order: returns true if a < b. Vice versa for ascending order
*/
static bool RoadVehEngineCapacitySorter(const EngineID &a, const EngineID &b)
static bool RoadVehEngineCapacitySorter(const GUIEngineListItem &a, const GUIEngineListItem &b)
{
int va = GetTotalCapacityOfArticulatedParts(a);
int vb = GetTotalCapacityOfArticulatedParts(b);
int va = GetTotalCapacityOfArticulatedParts(a.engine_id);
int vb = GetTotalCapacityOfArticulatedParts(b.engine_id);
int r = va - vb;
/* Use EngineID to sort instead since we want consistent sorting */
@@ -369,10 +370,10 @@ static bool RoadVehEngineCapacitySorter(const EngineID &a, const EngineID &b)
* @param b second engine to compare
* @return for descending order: returns true if a < b. Vice versa for ascending order
*/
static bool ShipEngineCapacitySorter(const EngineID &a, const EngineID &b)
static bool ShipEngineCapacitySorter(const GUIEngineListItem &a, const GUIEngineListItem &b)
{
const Engine *e_a = Engine::Get(a);
const Engine *e_b = Engine::Get(b);
const Engine *e_a = Engine::Get(a.engine_id);
const Engine *e_b = Engine::Get(b.engine_id);
int va = e_a->GetDisplayDefaultCapacity();
int vb = e_b->GetDisplayDefaultCapacity();
@@ -391,10 +392,10 @@ static bool ShipEngineCapacitySorter(const EngineID &a, const EngineID &b)
* @param b second engine to compare
* @return for descending order: returns true if a < b. Vice versa for ascending order
*/
static bool AircraftEngineCargoSorter(const EngineID &a, const EngineID &b)
static bool AircraftEngineCargoSorter(const GUIEngineListItem &a, const GUIEngineListItem &b)
{
const Engine *e_a = Engine::Get(a);
const Engine *e_b = Engine::Get(b);
const Engine *e_a = Engine::Get(a.engine_id);
const Engine *e_b = Engine::Get(b.engine_id);
uint16 mail_a, mail_b;
int va = e_a->GetDisplayDefaultCapacity(&mail_a);
@@ -419,10 +420,10 @@ static bool AircraftEngineCargoSorter(const EngineID &a, const EngineID &b)
* @param b second engine to compare
* @return for descending order: returns true if a < b. Vice versa for ascending order
*/
static bool AircraftRangeSorter(const EngineID &a, const EngineID &b)
static bool AircraftRangeSorter(const GUIEngineListItem &a, const GUIEngineListItem &b)
{
uint16 r_a = Engine::Get(a)->GetRange();
uint16 r_b = Engine::Get(b)->GetRange();
uint16 r_a = Engine::Get(a.engine_id)->GetRange();
uint16 r_b = Engine::Get(b.engine_id)->GetRange();
int r = r_a - r_b;
@@ -536,14 +537,14 @@ const StringID _engine_sort_listing[][12] = {{
}};
/** Filters vehicles by cargo and engine (in case of rail vehicle). */
static bool CDECL CargoAndEngineFilter(const EngineID *eid, const CargoID cid)
static bool CDECL CargoAndEngineFilter(const GUIEngineListItem *item, const CargoID cid)
{
if (cid == CF_ANY) {
return true;
} else if (cid == CF_ENGINES) {
return Engine::Get(*eid)->GetPower() != 0;
return Engine::Get(item->engine_id)->GetPower() != 0;
} else {
CargoTypes refit_mask = GetUnionOfArticulatedRefitMasks(*eid, true) & _standard_cargo_mask;
CargoTypes refit_mask = GetUnionOfArticulatedRefitMasks(item->engine_id, true) & _standard_cargo_mask;
return (cid == CF_NONE ? refit_mask == 0 : HasBit(refit_mask, cid));
}
}
@@ -590,7 +591,7 @@ static int DrawRailWagonPurchaseInfo(int left, int right, int y, EngineID engine
/* Wagon weight - (including cargo) */
uint weight = e->GetDisplayWeight();
SetDParam(0, weight);
uint cargo_weight = (e->CanCarryCargo() ? CargoSpec::Get(te.cargo)->weight * te.capacity / 16 : 0);
uint cargo_weight = (e->CanCarryCargo() ? CargoSpec::Get(te.cargo)->WeightOfNUnitsInTrain(te.capacity) : 0);
SetDParam(1, cargo_weight + weight);
DrawString(left, right, y, STR_PURCHASE_INFO_WEIGHT_CWEIGHT);
y += FONT_HEIGHT_NORMAL;
@@ -684,7 +685,7 @@ static int DrawRoadVehPurchaseInfo(int left, int right, int y, EngineID engine_n
/* Road vehicle weight - (including cargo) */
int16 weight = e->GetDisplayWeight();
SetDParam(0, weight);
uint cargo_weight = (e->CanCarryCargo() ? CargoSpec::Get(te.cargo)->weight * te.capacity / 16 : 0);
uint cargo_weight = (e->CanCarryCargo() ? CargoSpec::Get(te.cargo)->WeightOfNUnits(te.capacity) : 0);
SetDParam(1, cargo_weight + weight);
DrawString(left, right, y, STR_PURCHASE_INFO_WEIGHT_CWEIGHT);
y += FONT_HEIGHT_NORMAL;
@@ -953,9 +954,7 @@ int DrawVehiclePurchaseInfo(int left, int right, int y, EngineID engine_number,
/**
* Engine drawing loop
* @param type Type of vehicle (VEH_*)
* @param l The left most location of the list
* @param r The right most location of the list
* @param y The top most location of the list
* @param r The Rect of the list
* @param eng_list What engines to draw
* @param min where to start in the list
* @param max where in the list to end
@@ -963,21 +962,23 @@ int DrawVehiclePurchaseInfo(int left, int right, int y, EngineID engine_number,
* @param show_count Whether to show the amount of engines or not
* @param selected_group the group to list the engines of
*/
void DrawEngineList(VehicleType type, int l, int r, int y, const GUIEngineList *eng_list, uint16 min, uint16 max, EngineID selected_id, bool show_count, GroupID selected_group)
void DrawEngineList(VehicleType type, const Rect &r, const GUIEngineList &eng_list, uint16 min, uint16 max, EngineID selected_id, bool show_count, GroupID selected_group)
{
static const int sprite_y_offsets[] = { -1, -1, -2, -2 };
/* Obligatory sanity checks! */
assert(max <= eng_list->size());
assert(max <= eng_list.size());
bool rtl = _current_text_dir == TD_RTL;
int step_size = GetEngineListHeight(type);
int sprite_left = GetVehicleImageCellSize(type, EIT_PURCHASE).extend_left;
int sprite_right = GetVehicleImageCellSize(type, EIT_PURCHASE).extend_right;
int sprite_width = sprite_left + sprite_right;
int circle_width = std::max(GetScaledSpriteSize(SPR_CIRCLE_FOLDED).width, GetScaledSpriteSize(SPR_CIRCLE_UNFOLDED).width);
int linecolour = _colour_gradient[COLOUR_ORANGE][4];
int sprite_x = rtl ? r - sprite_right - 1 : l + sprite_left + 1;
int sprite_y_offset = sprite_y_offsets[type] + step_size / 2;
Rect ir = r.WithHeight(step_size).Shrink(WidgetDimensions::scaled.matrix);
int sprite_y_offset = ScaleSpriteTrad(sprite_y_offsets[type]) + ir.Height() / 2;
Dimension replace_icon = {0, 0};
int count_width = 0;
@@ -987,33 +988,51 @@ void DrawEngineList(VehicleType type, int l, int r, int y, const GUIEngineList *
count_width = GetStringBoundingBox(STR_TINY_BLACK_COMA).width;
}
int text_left = l + (rtl ? WD_FRAMERECT_LEFT + replace_icon.width + 8 + count_width : sprite_width + WD_FRAMETEXT_LEFT);
int text_right = r - (rtl ? sprite_width + WD_FRAMETEXT_RIGHT : WD_FRAMERECT_RIGHT + replace_icon.width + 8 + count_width);
int replace_icon_left = rtl ? l + WD_FRAMERECT_LEFT : r - WD_FRAMERECT_RIGHT - replace_icon.width;
int count_left = l;
int count_right = rtl ? text_left : r - WD_FRAMERECT_RIGHT - replace_icon.width - 8;
Rect tr = ir.Indent(circle_width + WidgetDimensions::scaled.hsep_normal + sprite_width + WidgetDimensions::scaled.hsep_wide, rtl); // Name position
Rect cr = tr.Indent(replace_icon.width + WidgetDimensions::scaled.hsep_wide, !rtl).WithWidth(count_width, !rtl); // Count position
Rect rr = tr.WithWidth(replace_icon.width, !rtl); // Replace icon position
if (show_count) tr = tr.Indent(count_width + WidgetDimensions::scaled.hsep_normal + replace_icon.width + WidgetDimensions::scaled.hsep_wide, !rtl);
int normal_text_y_offset = (step_size - FONT_HEIGHT_NORMAL) / 2;
int small_text_y_offset = step_size - FONT_HEIGHT_SMALL - WD_FRAMERECT_BOTTOM - 1;
int replace_icon_y_offset = (step_size - replace_icon.height) / 2 - 1;
int normal_text_y_offset = (ir.Height() - FONT_HEIGHT_NORMAL) / 2;
int small_text_y_offset = ir.Height() - FONT_HEIGHT_SMALL;
int replace_icon_y_offset = (ir.Height() - replace_icon.height) / 2;
int y = ir.top;
for (; min < max; min++, y += step_size) {
const EngineID engine = (*eng_list)[min];
const auto &item = eng_list[min];
uint indent = item.indent * WidgetDimensions::scaled.hsep_indent;
bool has_variants = (item.flags & EngineDisplayFlags::HasVariants) != EngineDisplayFlags::None;
bool is_folded = (item.flags & EngineDisplayFlags::IsFolded) != EngineDisplayFlags::None;
bool shaded = (item.flags & EngineDisplayFlags::Shaded) != EngineDisplayFlags::None;
/* Note: num_engines is only used in the autoreplace GUI, so it is correct to use _local_company here. */
const uint num_engines = GetGroupNumEngines(_local_company, selected_group, engine);
const uint num_engines = GetGroupNumEngines(_local_company, selected_group, item.engine_id);
const Engine *e = Engine::Get(engine);
const Engine *e = Engine::Get(item.engine_id);
bool hidden = HasBit(e->company_hidden, _local_company);
StringID str = hidden ? STR_HIDDEN_ENGINE_NAME : STR_ENGINE_NAME;
TextColour tc = (engine == selected_id) ? TC_WHITE : (TC_NO_SHADE | (hidden ? TC_GREY : TC_BLACK));
TextColour tc = (item.engine_id == selected_id) ? TC_WHITE : (TC_NO_SHADE | ((hidden | shaded) ? TC_GREY : TC_BLACK));
SetDParam(0, engine);
DrawString(text_left, text_right, y + normal_text_y_offset, str, tc);
DrawVehicleEngine(l, r, sprite_x, y + sprite_y_offset, engine, (show_count && num_engines == 0) ? PALETTE_CRASH : GetEnginePalette(engine, _local_company), EIT_PURCHASE);
SetDParam(0, item.engine_id);
Rect itr = tr.Indent(indent, rtl);
DrawString(itr.left, itr.right, y + normal_text_y_offset, str, tc);
int sprite_x = ir.Indent(indent + circle_width + WidgetDimensions::scaled.hsep_normal, rtl).WithWidth(sprite_width, rtl).left + sprite_left;
DrawVehicleEngine(r.left, r.right, sprite_x, y + sprite_y_offset, item.engine_id, (show_count && num_engines == 0) ? PALETTE_CRASH : GetEnginePalette(item.engine_id, _local_company), EIT_PURCHASE);
if (show_count) {
SetDParam(0, num_engines);
DrawString(count_left, count_right, y + small_text_y_offset, STR_TINY_BLACK_COMA, TC_FROMSTRING, SA_RIGHT | SA_FORCE);
if (EngineHasReplacementForCompany(Company::Get(_local_company), engine, selected_group)) DrawSprite(SPR_GROUP_REPLACE_ACTIVE, num_engines == 0 ? PALETTE_CRASH : PAL_NONE, replace_icon_left, y + replace_icon_y_offset);
DrawString(cr.left, cr.right, y + small_text_y_offset, STR_TINY_BLACK_COMA, TC_FROMSTRING, SA_RIGHT | SA_FORCE);
if (EngineHasReplacementForCompany(Company::Get(_local_company), item.engine_id, selected_group)) DrawSprite(SPR_GROUP_REPLACE_ACTIVE, num_engines == 0 ? PALETTE_CRASH : PAL_NONE, rr.left, y + replace_icon_y_offset);
}
if (has_variants) {
Rect fr = ir.Indent(indent, rtl).WithWidth(circle_width, rtl);
DrawSpriteIgnorePadding(is_folded ? SPR_CIRCLE_FOLDED : SPR_CIRCLE_UNFOLDED, PAL_NONE, {fr.left, y, fr.right, y + ir.Height() - 1}, false, SA_CENTER);
}
if (indent > 0) {
/* Draw tree lines */
Rect fr = ir.Indent(indent - WidgetDimensions::scaled.hsep_indent, rtl).WithWidth(circle_width, rtl);
int ycenter = y + normal_text_y_offset + FONT_HEIGHT_NORMAL / 2;
bool continues = (min + 1U) < eng_list.size() && eng_list[min + 1].indent == item.indent;
GfxDrawLine(fr.left + circle_width / 2, y - WidgetDimensions::scaled.matrix.top, fr.left + circle_width / 2, continues ? y - WidgetDimensions::scaled.matrix.top + step_size - 1 : ycenter, linecolour, WidgetDimensions::scaled.fullbevel.top);
GfxDrawLine(fr.left + circle_width / 2, ycenter, fr.right, ycenter, linecolour, WidgetDimensions::scaled.fullbevel.top);
}
}
}
@@ -1078,6 +1097,27 @@ struct BuildVehicleWindow : Window {
}
}
void AddChildren(const GUIEngineList &source, EngineID parent, int indent)
{
for (const auto &item : source) {
if (item.variant_id != parent || item.engine_id == parent) continue;
const Engine *e = Engine::Get(item.engine_id);
EngineDisplayFlags flags = item.flags;
if (e->display_last_variant != INVALID_ENGINE) flags &= ~EngineDisplayFlags::Shaded;
this->eng_list.emplace_back(e->display_last_variant == INVALID_ENGINE ? item.engine_id : e->display_last_variant, item.engine_id, flags, indent);
/* Add variants if not folded */
if ((item.flags & (EngineDisplayFlags::HasVariants | EngineDisplayFlags::IsFolded)) == EngineDisplayFlags::HasVariants) {
/* Add this engine again as a child */
if ((item.flags & EngineDisplayFlags::Shaded) == EngineDisplayFlags::None) {
this->eng_list.emplace_back(item.engine_id, item.engine_id, EngineDisplayFlags::None, indent + 1);
}
AddChildren(source, item.engine_id, indent + 1);
}
}
}
BuildVehicleWindow(WindowDesc *desc, TileIndex tile, VehicleType type) : Window(desc)
{
this->vehicle_type = type;
@@ -1125,7 +1165,7 @@ struct BuildVehicleWindow : Window {
this->GenerateBuildList(); // generate the list, since we need it in the next line
/* Select the first engine in the list as default when opening the window */
if (this->eng_list.size() > 0) {
this->SelectEngine(this->eng_list[0]);
this->SelectEngine(this->eng_list[0].engine_id);
} else {
this->SelectEngine(INVALID_ENGINE);
}
@@ -1257,7 +1297,7 @@ struct BuildVehicleWindow : Window {
if (0 == this->eng_list.size()) { // no engine passed through the filter, invalidate the previously selected engine
this->SelectEngine(INVALID_ENGINE);
} else if (std::find(this->eng_list.begin(), this->eng_list.end(), this->sel_engine) == this->eng_list.end()) { // previously selected engine didn't pass the filter, select the first engine of the list
this->SelectEngine(this->eng_list[0]);
this->SelectEngine(this->eng_list[0].engine_id);
}
}
@@ -1265,17 +1305,19 @@ struct BuildVehicleWindow : Window {
bool FilterSingleEngine(EngineID eid)
{
CargoID filter_type = this->cargo_filter[this->cargo_filter_criteria];
return CargoAndEngineFilter(&eid, filter_type);
GUIEngineListItem item = {eid, eid, EngineDisplayFlags::None, 0};
return CargoAndEngineFilter(&item, filter_type);
}
/* Figure out what train EngineIDs to put in the list */
void GenerateBuildTrainList()
void GenerateBuildTrainList(GUIEngineList &list)
{
std::vector<EngineID> variants;
EngineID sel_id = INVALID_ENGINE;
int num_engines = 0;
int num_wagons = 0;
this->eng_list.clear();
list.clear();
/* Make list of all available train engines and wagons.
* Also check to see if the previously selected engine is still available,
@@ -1292,7 +1334,7 @@ struct BuildVehicleWindow : Window {
/* Filter now! So num_engines and num_wagons is valid */
if (!FilterSingleEngine(eid)) continue;
this->eng_list.push_back(eid);
list.emplace_back(eid, e->info.variant_id, e->display_flags, 0);
if (rvi->railveh_type != RAILVEH_WAGON) {
num_engines++;
@@ -1300,9 +1342,18 @@ struct BuildVehicleWindow : Window {
num_wagons++;
}
if (e->info.variant_id != eid && e->info.variant_id != INVALID_ENGINE) variants.push_back(e->info.variant_id);
if (eid == this->sel_engine) sel_id = eid;
}
/* ensure primary engine of variant group is in list */
for (const auto &variant : variants) {
if (std::find(list.begin(), list.end(), variant) == list.end()) {
const Engine *e = Engine::Get(variant);
list.emplace_back(variant, e->info.variant_id, e->display_flags | EngineDisplayFlags::Shaded, 0);
}
}
this->SelectEngine(sel_id);
/* invalidate cached values for name sorter - engine names could change */
@@ -1310,14 +1361,14 @@ struct BuildVehicleWindow : Window {
/* make engines first, and then wagons, sorted by selected sort_criteria */
_engine_sort_direction = false;
EngList_Sort(&this->eng_list, TrainEnginesThenWagonsSorter);
EngList_Sort(&list, TrainEnginesThenWagonsSorter);
/* and then sort engines */
_engine_sort_direction = this->descending_sort_order;
EngList_SortPartial(&this->eng_list, _engine_sort_functions[0][this->sort_criteria], 0, num_engines);
EngList_SortPartial(&list, _engine_sort_functions[0][this->sort_criteria], 0, num_engines);
/* and finally sort wagons */
EngList_SortPartial(&this->eng_list, _engine_sort_functions[0][this->sort_criteria], num_engines, num_wagons);
EngList_SortPartial(&list, _engine_sort_functions[0][this->sort_criteria], num_engines, num_wagons);
}
/* Figure out what road vehicle EngineIDs to put in the list */
@@ -1333,7 +1384,7 @@ struct BuildVehicleWindow : Window {
if (!IsEngineBuildable(eid, VEH_ROAD, _local_company)) continue;
if (this->filter.roadtype != INVALID_ROADTYPE && !HasPowerOnRoad(e->u.road.roadtype, this->filter.roadtype)) continue;
this->eng_list.push_back(eid);
this->eng_list.emplace_back(eid, e->info.variant_id, e->display_flags, 0);
if (eid == this->sel_engine) sel_id = eid;
}
@@ -1350,7 +1401,7 @@ struct BuildVehicleWindow : Window {
if (!this->show_hidden_engines && e->IsHidden(_local_company)) continue;
EngineID eid = e->index;
if (!IsEngineBuildable(eid, VEH_SHIP, _local_company)) continue;
this->eng_list.push_back(eid);
this->eng_list.emplace_back(eid, e->info.variant_id, e->display_flags, 0);
if (eid == this->sel_engine) sel_id = eid;
}
@@ -1377,7 +1428,7 @@ struct BuildVehicleWindow : Window {
/* First VEH_END window_numbers are fake to allow a window open for all different types at once */
if (!this->listview_mode && !CanVehicleUseStation(eid, st)) continue;
this->eng_list.push_back(eid);
this->eng_list.emplace_back(eid, e->info.variant_id, e->display_flags, 0);
if (eid == this->sel_engine) sel_id = eid;
}
@@ -1392,13 +1443,18 @@ struct BuildVehicleWindow : Window {
/* Update filter type in case the road/railtype of the depot got converted */
this->UpdateFilterByTile();
this->eng_list.clear();
GUIEngineList list;
switch (this->vehicle_type) {
default: NOT_REACHED();
case VEH_TRAIN:
this->GenerateBuildTrainList();
this->GenerateBuildTrainList(list);
AddChildren(list, INVALID_ENGINE, 0);
this->eng_list.shrink_to_fit();
this->eng_list.RebuildDone();
return; // trains should not reach the last sorting
return;
case VEH_ROAD:
this->GenerateBuildRoadVehList();
break;
@@ -1412,9 +1468,23 @@ struct BuildVehicleWindow : Window {
this->FilterEngineList();
/* ensure primary engine of variant group is in list after filtering */
std::vector<EngineID> variants;
for (const auto &item : this->eng_list) {
if (item.engine_id != item.variant_id && item.variant_id != INVALID_ENGINE) variants.push_back(item.variant_id);
}
for (const auto &variant : variants) {
if (std::find(this->eng_list.begin(), this->eng_list.end(), variant) == this->eng_list.end()) {
const Engine *e = Engine::Get(variant);
this->eng_list.emplace_back(variant, e->info.variant_id, e->display_flags | EngineDisplayFlags::Shaded, 0);
}
}
_engine_sort_direction = this->descending_sort_order;
EngList_Sort(&this->eng_list, _engine_sort_functions[this->vehicle_type][this->sort_criteria]);
this->eng_list.swap(list);
AddChildren(list, INVALID_ENGINE, 0);
this->eng_list.shrink_to_fit();
this->eng_list.RebuildDone();
}
@@ -1440,7 +1510,23 @@ struct BuildVehicleWindow : Window {
case WID_BV_LIST: {
uint i = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_BV_LIST);
size_t num_items = this->eng_list.size();
this->SelectEngine((i < num_items) ? this->eng_list[i] : INVALID_ENGINE);
EngineID e = INVALID_ENGINE;
if (i < num_items) {
const auto &item = this->eng_list[i];
const Rect r = this->GetWidget<NWidgetBase>(widget)->GetCurrentRect().Shrink(WidgetDimensions::scaled.matrix).WithWidth(WidgetDimensions::scaled.hsep_indent * (item.indent + 1), _current_text_dir == TD_RTL);
if ((item.flags & EngineDisplayFlags::HasVariants) != EngineDisplayFlags::None && IsInsideMM(r.left, r.right, pt.x)) {
/* toggle folded flag on engine */
assert(item.variant_id != INVALID_ENGINE);
Engine *engine = Engine::Get(item.variant_id);
engine->display_flags ^= EngineDisplayFlags::IsFolded;
InvalidateWindowData(WC_REPLACE_VEHICLE, this->vehicle_type, 0); // Update the autoreplace window
InvalidateWindowClassesData(WC_BUILD_VEHICLE); // The build windows needs updating as well
return;
}
if ((item.flags & EngineDisplayFlags::Shaded) == EngineDisplayFlags::None) e = item.engine_id;
}
this->SelectEngine(e);
this->SetDirty();
if (_ctrl_pressed) {
this->OnClick(pt, WID_BV_SHOW_HIDE, 1);
@@ -1476,6 +1562,20 @@ struct BuildVehicleWindow : Window {
} else {
Command<CMD_BUILD_VEHICLE>::Post(GetCmdBuildVehMsg(this->vehicle_type), CcBuildPrimaryVehicle, this->window_number, sel_eng, true, cargo, INVALID_CLIENT_ID);
}
/* Update last used variant and refresh if necessary. */
bool refresh = false;
int recursion = 10; /* In case of infinite loop */
for (Engine *e = Engine::Get(sel_eng); recursion > 0; e = Engine::Get(e->info.variant_id), --recursion) {
refresh |= (e->display_last_variant != sel_eng);
e->display_last_variant = sel_eng;
if (e->info.variant_id == INVALID_ENGINE) break;
}
if (refresh) {
InvalidateWindowData(WC_REPLACE_VEHICLE, this->vehicle_type, 0); // Update the autoreplace window
InvalidateWindowClassesData(WC_BUILD_VEHICLE); // The build windows needs updating as well
return;
}
}
break;
}
@@ -1551,7 +1651,7 @@ struct BuildVehicleWindow : Window {
case WID_BV_LIST:
resize->height = GetEngineListHeight(this->vehicle_type);
size->height = 3 * resize->height;
size->width = std::max(size->width, GetVehicleImageCellSize(this->vehicle_type, EIT_PURCHASE).extend_left + GetVehicleImageCellSize(this->vehicle_type, EIT_PURCHASE).extend_right + 165);
size->width = std::max(size->width, GetVehicleImageCellSize(this->vehicle_type, EIT_PURCHASE).extend_left + GetVehicleImageCellSize(this->vehicle_type, EIT_PURCHASE).extend_right + 165) + padding.width;
break;
case WID_BV_PANEL:
@@ -1588,10 +1688,8 @@ struct BuildVehicleWindow : Window {
case WID_BV_LIST:
DrawEngineList(
this->vehicle_type,
r.left + WD_FRAMERECT_LEFT,
r.right - WD_FRAMERECT_RIGHT,
r.top + WD_FRAMERECT_TOP,
&this->eng_list,
r,
this->eng_list,
this->vscroll->GetPosition(),
static_cast<uint16>(std::min<size_t>(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->eng_list.size())),
this->sel_engine,
@@ -1622,10 +1720,9 @@ struct BuildVehicleWindow : Window {
int needed_height = this->details_height;
/* Draw details panels. */
if (this->sel_engine != INVALID_ENGINE) {
NWidgetBase *nwi = this->GetWidget<NWidgetBase>(WID_BV_PANEL);
int text_end = DrawVehiclePurchaseInfo(nwi->pos_x + WD_FRAMETEXT_LEFT, nwi->pos_x + nwi->current_x - WD_FRAMETEXT_RIGHT,
nwi->pos_y + WD_FRAMERECT_TOP, this->sel_engine, this->te);
needed_height = std::max(needed_height, (text_end - (int)nwi->pos_y - WD_FRAMERECT_TOP) / FONT_HEIGHT_NORMAL);
const Rect r = this->GetWidget<NWidgetBase>(WID_BV_PANEL)->GetCurrentRect().Shrink(WidgetDimensions::scaled.frametext, WidgetDimensions::scaled.framerect);
int text_end = DrawVehiclePurchaseInfo(r.left, r.right, r.top, this->sel_engine, this->te);
needed_height = std::max(needed_height, (text_end - r.top) / FONT_HEIGHT_NORMAL);
}
if (needed_height != this->details_height) { // Details window are not high enough, enlarge them.
int resize = needed_height - this->details_height;

View File

@@ -12,6 +12,7 @@
#include "newgrf_cargo.h"
#include "string_func.h"
#include "strings_func.h"
#include "settings_type.h"
#include "table/sprites.h"
#include "table/strings.h"
@@ -209,3 +210,8 @@ void InitializeSortedCargoSpecs()
_sorted_standard_cargo_specs = { _sorted_cargo_specs.data(), nb_standard_cargo };
}
uint64 CargoSpec::WeightOfNUnitsInTrain(uint32 n) const
{
if (this->is_freight) n *= _settings_game.vehicle.freight_trains;
return this->WeightOfNUnits(n);
}

View File

@@ -123,6 +123,13 @@ struct CargoSpec {
SpriteID GetCargoIcon() const;
inline uint64 WeightOfNUnits(uint32 n) const
{
return n * this->weight / 16u;
}
uint64 WeightOfNUnitsInTrain(uint32 n) const;
/**
* Iterator to iterate all valid CargoSpec
*/

View File

@@ -29,6 +29,7 @@
#include "newgrf.h"
#include "error.h"
#include "misc_cmd.h"
#include "core/geometry_func.hpp"
#include "widgets/cheat_widget.h"
@@ -207,7 +208,7 @@ static const NWidgetPart _nested_cheat_widgets[] = {
EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY, WID_C_PANEL), SetDataTip(0x0, STR_CHEATS_TOOLTIP), EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY),
NWidget(WWT_LABEL, COLOUR_GREY, WID_C_NOTE), SetFill(1, 1), SetDataTip(STR_CHEATS_NOTE, STR_NULL), SetPadding(WD_PAR_VSEP_NORMAL, 4, WD_PAR_VSEP_NORMAL, 4),
NWidget(WWT_LABEL, COLOUR_GREY, WID_C_NOTE), SetFill(1, 1), SetDataTip(STR_CHEATS_NOTE, STR_NULL), SetPadding(WidgetDimensions::unscaled.frametext),
EndContainer(),
};
@@ -216,39 +217,48 @@ struct CheatWindow : Window {
int clicked;
int clicked_widget;
uint line_height;
int box_width;
Dimension box; ///< Dimension of box sprite
Dimension icon; ///< Dimension of company icon sprite
CheatWindow(WindowDesc *desc) : Window(desc)
{
this->box_width = GetSpriteSize(SPR_BOX_EMPTY).width;
this->InitNested();
}
void OnInit() override
{
this->box = maxdim(GetSpriteSize(SPR_BOX_EMPTY), GetSpriteSize(SPR_BOX_CHECKED));
this->icon = GetSpriteSize(SPR_COMPANY_ICON);
}
void DrawWidget(const Rect &r, int widget) const override
{
if (widget != WID_C_PANEL) return;
int y = r.top + WD_FRAMERECT_TOP + WD_PAR_VSEP_NORMAL;
const Rect ir = r.Shrink(WidgetDimensions::scaled.framerect);
int y = ir.top;
bool rtl = _current_text_dir == TD_RTL;
uint box_left = rtl ? r.right - this->box_width - 5 : r.left + 5;
uint button_left = rtl ? r.right - this->box_width - 10 - SETTING_BUTTON_WIDTH : r.left + this->box_width + 10;
uint text_left = r.left + (rtl ? WD_FRAMERECT_LEFT : 20 + this->box_width + SETTING_BUTTON_WIDTH);
uint text_right = r.right - (rtl ? 20 + this->box_width + SETTING_BUTTON_WIDTH : WD_FRAMERECT_RIGHT);
uint box_left = rtl ? ir.right - this->box.width - WidgetDimensions::scaled.hsep_wide : ir.left + WidgetDimensions::scaled.hsep_wide;
uint button_left = rtl ? ir.right - this->box.width - WidgetDimensions::scaled.hsep_wide * 2 - SETTING_BUTTON_WIDTH : ir.left + this->box.width + WidgetDimensions::scaled.hsep_wide * 2;
uint text_left = ir.left + (rtl ? 0 : WidgetDimensions::scaled.hsep_wide * 4 + this->box.width + SETTING_BUTTON_WIDTH);
uint text_right = ir.right - (rtl ? WidgetDimensions::scaled.hsep_wide * 4 + this->box.width + SETTING_BUTTON_WIDTH : 0);
int text_y_offset = (this->line_height - FONT_HEIGHT_NORMAL) / 2;
int icon_y_offset = (this->line_height - SETTING_BUTTON_HEIGHT) / 2;
int box_y_offset = (this->line_height - this->box.height) / 2;
int button_y_offset = (this->line_height - SETTING_BUTTON_HEIGHT) / 2;
int icon_y_offset = (this->line_height - this->icon.height) / 2;
for (int i = 0; i != lengthof(_cheats_ui); i++) {
const CheatEntry *ce = &_cheats_ui[i];
DrawSprite((*ce->been_used) ? SPR_BOX_CHECKED : SPR_BOX_EMPTY, PAL_NONE, box_left, y + icon_y_offset + 2);
DrawSprite((*ce->been_used) ? SPR_BOX_CHECKED : SPR_BOX_EMPTY, PAL_NONE, box_left, y + box_y_offset);
switch (ce->type) {
case SLE_BOOL: {
bool on = (*(bool*)ce->variable);
DrawBoolButton(button_left, y + icon_y_offset, on, true);
DrawBoolButton(button_left, y + button_y_offset, on, true);
SetDParam(0, on ? STR_CONFIG_SETTING_ON : STR_CONFIG_SETTING_OFF);
break;
}
@@ -258,7 +268,7 @@ struct CheatWindow : Window {
char buf[512];
/* Draw [<][>] boxes for settings of an integer-type */
DrawArrowButtons(button_left, y + icon_y_offset, COLOUR_YELLOW, clicked - (i * 2), true, true);
DrawArrowButtons(button_left, y + button_y_offset, COLOUR_YELLOW, clicked - (i * 2), true, true);
switch (ce->str) {
/* Display date for change date cheat */
@@ -268,8 +278,8 @@ struct CheatWindow : Window {
case STR_CHEAT_CHANGE_COMPANY: {
SetDParam(0, val + 1);
GetString(buf, STR_CHEAT_CHANGE_COMPANY, lastof(buf));
uint offset = 10 + GetStringBoundingBox(buf).width;
DrawCompanyIcon(_local_company, rtl ? text_right - offset - 10 : text_left + offset, y + icon_y_offset + 2);
uint offset = WidgetDimensions::scaled.hsep_indent + GetStringBoundingBox(buf).width;
DrawCompanyIcon(_local_company, rtl ? text_right - offset - WidgetDimensions::scaled.hsep_indent : text_left + offset, y + icon_y_offset);
break;
}
@@ -311,7 +321,7 @@ struct CheatWindow : Window {
/* Draw coloured flag for change company cheat */
case STR_CHEAT_CHANGE_COMPANY:
SetDParamMaxValue(0, MAX_COMPANIES);
width = std::max(width, GetStringBoundingBox(ce->str).width + 10 + 10);
width = std::max(width, GetStringBoundingBox(ce->str).width + WidgetDimensions::scaled.hsep_wide * 4);
break;
default:
@@ -323,21 +333,21 @@ struct CheatWindow : Window {
}
}
this->line_height = std::max(GetSpriteSize(SPR_BOX_CHECKED).height, GetSpriteSize(SPR_BOX_EMPTY).height);
this->line_height = std::max(this->box.height, this->icon.height);
this->line_height = std::max<uint>(this->line_height, SETTING_BUTTON_HEIGHT);
this->line_height = std::max<uint>(this->line_height, FONT_HEIGHT_NORMAL) + WD_PAR_VSEP_NORMAL;
this->line_height = std::max<uint>(this->line_height, FONT_HEIGHT_NORMAL) + WidgetDimensions::scaled.framerect.Vertical();
size->width = width + 20 + this->box_width + SETTING_BUTTON_WIDTH /* stuff on the left */ + 10 /* extra spacing on right */;
size->height = WD_FRAMERECT_TOP + WD_PAR_VSEP_NORMAL + WD_FRAMERECT_BOTTOM + this->line_height * lengthof(_cheats_ui);
size->width = width + WidgetDimensions::scaled.hsep_wide * 4 + this->box.width + SETTING_BUTTON_WIDTH /* stuff on the left */ + WidgetDimensions::scaled.hsep_wide * 2 /* extra spacing on right */;
size->height = WidgetDimensions::scaled.framerect.Vertical() + this->line_height * lengthof(_cheats_ui);
}
void OnClick(Point pt, int widget, int click_count) override
{
const NWidgetBase *wid = this->GetWidget<NWidgetBase>(WID_C_PANEL);
uint btn = (pt.y - wid->pos_y - WD_FRAMERECT_TOP - WD_PAR_VSEP_NORMAL) / this->line_height;
int x = pt.x - wid->pos_x;
Rect r = this->GetWidget<NWidgetBase>(WID_C_PANEL)->GetCurrentRect().Shrink(WidgetDimensions::scaled.framerect);
uint btn = (pt.y - r.top) / this->line_height;
uint x = pt.x - r.left;
bool rtl = _current_text_dir == TD_RTL;
if (rtl) x = wid->current_x - x;
if (rtl) x = r.Width() - 1 - x;
if (btn >= lengthof(_cheats_ui)) return;
@@ -345,13 +355,13 @@ struct CheatWindow : Window {
int value = (int32)ReadValue(ce->variable, ce->type);
int oldvalue = value;
if (btn == CHT_CHANGE_DATE && x >= 20 + this->box_width + SETTING_BUTTON_WIDTH) {
if (btn == CHT_CHANGE_DATE && x >= WidgetDimensions::scaled.hsep_wide * 2 + this->box.width + SETTING_BUTTON_WIDTH) {
/* Click at the date text directly. */
clicked_widget = CHT_CHANGE_DATE;
SetDParam(0, value);
ShowQueryString(STR_JUST_INT, STR_CHEAT_CHANGE_DATE_QUERY_CAPT, 8, this, CS_NUMERAL, QSF_ACCEPT_UNCHANGED);
return;
} else if (btn == CHT_EDIT_MAX_HL && x >= 20 + this->box_width + SETTING_BUTTON_WIDTH) {
} else if (btn == CHT_EDIT_MAX_HL && x >= WidgetDimensions::scaled.hsep_wide * 2 + this->box.width + SETTING_BUTTON_WIDTH) {
clicked_widget = CHT_EDIT_MAX_HL;
SetDParam(0, value);
ShowQueryString(STR_JUST_INT, STR_CHEAT_EDIT_MAX_HL_QUERY_CAPT, 8, this, CS_NUMERAL, QSF_ACCEPT_UNCHANGED);
@@ -359,7 +369,7 @@ struct CheatWindow : Window {
}
/* Not clicking a button? */
if (!IsInsideMM(x, 10 + this->box_width, 10 + this->box_width + SETTING_BUTTON_WIDTH)) return;
if (!IsInsideMM(x, WidgetDimensions::scaled.hsep_wide * 2 + this->box.width, WidgetDimensions::scaled.hsep_wide * 2 + this->box.width + SETTING_BUTTON_WIDTH)) return;
*ce->been_used = true;
@@ -371,10 +381,10 @@ struct CheatWindow : Window {
default:
/* Take whatever the function returns */
value = ce->proc(value + ((x >= 10 + this->box_width + SETTING_BUTTON_WIDTH / 2) ? 1 : -1), (x >= 10 + this->box_width + SETTING_BUTTON_WIDTH / 2) ? 1 : -1);
value = ce->proc(value + ((x >= WidgetDimensions::scaled.hsep_wide * 2 + this->box.width + SETTING_BUTTON_WIDTH / 2) ? 1 : -1), (x >= WidgetDimensions::scaled.hsep_wide * 2 + this->box.width + SETTING_BUTTON_WIDTH / 2) ? 1 : -1);
/* The first cheat (money), doesn't return a different value. */
if (value != oldvalue || btn == CHT_MONEY) this->clicked = btn * 2 + 1 + ((x >= 10 + this->box_width + SETTING_BUTTON_WIDTH / 2) != rtl ? 1 : 0);
if (value != oldvalue || btn == CHT_MONEY) this->clicked = btn * 2 + 1 + ((x >= WidgetDimensions::scaled.hsep_wide * 2 + this->box.width + SETTING_BUTTON_WIDTH / 2) != rtl ? 1 : 0);
break;
}

View File

@@ -32,6 +32,7 @@
#include "goal_cmd.h"
#include "group_cmd.h"
#include "industry_cmd.h"
#include "league_cmd.h"
#include "landscape_cmd.h"
#include "misc_cmd.h"
#include "news_cmd.h"

View File

@@ -331,12 +331,19 @@ enum Commands : uint16 {
CMD_MOVE_ORDER, ///< move an order
CMD_CHANGE_TIMETABLE, ///< change the timetable for a vehicle
CMD_BULK_CHANGE_TIMETABLE, ///< change the timetable for all orders of a vehicle
CMD_SET_VEHICLE_ON_TIME, ///< set the vehicle on time feature (timetable)
CMD_AUTOFILL_TIMETABLE, ///< autofill the timetable
CMD_SET_TIMETABLE_START, ///< set the date that a timetable should start
CMD_OPEN_CLOSE_AIRPORT, ///< open/close an airport to incoming aircraft
CMD_CREATE_LEAGUE_TABLE, ///< create a new league table
CMD_CREATE_LEAGUE_TABLE_ELEMENT, ///< create a new element in a league table
CMD_UPDATE_LEAGUE_TABLE_ELEMENT_DATA, ///< update the data fields of a league table element
CMD_UPDATE_LEAGUE_TABLE_ELEMENT_SCORE, ///< update the score of a league table element
CMD_REMOVE_LEAGUE_TABLE_ELEMENT, ///< remove a league table element
CMD_END, ///< Must ALWAYS be on the end of this list!! (period)
};

View File

@@ -115,8 +115,11 @@ void SetLocalCompany(CompanyID new_company)
_current_company = _local_company = new_company;
/* Delete any construction windows... */
if (switching_company) CloseConstructionWindows();
if (switching_company) {
InvalidateWindowClassesData(WC_COMPANY);
/* Delete any construction windows... */
CloseConstructionWindows();
}
/* ... and redraw the whole screen. */
MarkWholeScreenDirty();
@@ -566,8 +569,8 @@ Company *DoStartupNewCompany(bool is_ai, CompanyID company = INVALID_COMPANY)
c->inaugurated_year = _cur_year;
/* If starting a player company in singleplayer and a favorite company manager face is selected, choose it. Otherwise, use a random face.
* In a network game, we'll choose the favorite face later in CmdCompanyCtrl to sync it to all clients, but we choose it here for the first (host) company. */
if (_company_manager_face != 0 && !is_ai) {
* In a network game, we'll choose the favorite face later in CmdCompanyCtrl to sync it to all clients. */
if (_company_manager_face != 0 && !is_ai && !_networking) {
c->face = _company_manager_face;
} else {
RandomCompanyManagerFaceBits(c->face, (GenderEthnicity)Random(), false, false);
@@ -889,8 +892,6 @@ CommandCost CmdCompanyCtrl(DoCommandFlag flags, CompanyCtrlAction cca, CompanyID
if (!(flags & DC_EXEC)) return CommandCost();
/* Delete any open window of the company */
CloseCompanyWindows(c->index);
CompanyNewsInformation *cni = new CompanyNewsInformation(c);
/* Show the bankrupt news */

View File

@@ -49,10 +49,6 @@
/** Company GUI constants. */
static const uint EXP_LINESPACE = 2; ///< Amount of vertical space for a horizontal (sub-)total line.
static const uint EXP_BLOCKSPACE = 10; ///< Amount of vertical space between two blocks of numbers.
static const int EXP_INDENT = 10; ///< Amount of horizontal space for an indented line.
static void DoSelectCompanyManagerFace(Window *parent);
static void ShowCompanyInfrastructure(CompanyID company);
@@ -122,15 +118,15 @@ static const ExpensesList _expenses_list_types[] = {
static uint GetTotalCategoriesHeight()
{
/* There's an empty line and blockspace on the year row */
uint total_height = FONT_HEIGHT_NORMAL + EXP_BLOCKSPACE;
uint total_height = FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_wide;
for (uint i = 0; i < lengthof(_expenses_list_types); i++) {
/* Title + expense list + total line + total + blockspace after category */
total_height += FONT_HEIGHT_NORMAL + _expenses_list_types[i].GetHeight() + EXP_LINESPACE + FONT_HEIGHT_NORMAL + EXP_BLOCKSPACE;
total_height += FONT_HEIGHT_NORMAL + _expenses_list_types[i].GetHeight() + WidgetDimensions::scaled.vsep_normal + FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_wide;
}
/* Total income */
total_height += EXP_LINESPACE + FONT_HEIGHT_NORMAL + EXP_BLOCKSPACE;
total_height += WidgetDimensions::scaled.vsep_normal + FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_wide;
return total_height;
}
@@ -148,7 +144,7 @@ static uint GetMaxCategoriesWidth()
/* Title of category */
max_width = std::max(max_width, GetStringBoundingBox(STR_FINANCES_REVENUE_TITLE + i).width);
/* Entries in category */
max_width = std::max(max_width, _expenses_list_types[i].GetListWidth());
max_width = std::max(max_width, _expenses_list_types[i].GetListWidth() + WidgetDimensions::scaled.hsep_indent);
}
return max_width;
@@ -159,16 +155,15 @@ static uint GetMaxCategoriesWidth()
*/
static void DrawCategory(const Rect &r, int start_y, ExpensesList list)
{
int offs_left = _current_text_dir == TD_LTR ? EXP_INDENT : 0;
int offs_right = _current_text_dir == TD_LTR ? 0 : EXP_INDENT;
Rect tr = r.Indent(WidgetDimensions::scaled.hsep_indent, _current_text_dir == TD_RTL);
int y = start_y;
tr.top = start_y;
ExpensesType et;
for (uint i = 0; i < list.length; i++) {
et = list.et[i];
DrawString(r.left + offs_left, r.right - offs_right, y, STR_FINANCES_SECTION_CONSTRUCTION + et);
y += FONT_HEIGHT_NORMAL;
DrawString(tr, STR_FINANCES_SECTION_CONSTRUCTION + et);
tr.top += FONT_HEIGHT_NORMAL;
}
}
@@ -180,7 +175,7 @@ static void DrawCategory(const Rect &r, int start_y, ExpensesList list)
static void DrawCategories(const Rect &r)
{
/* Start with an empty space in the year row, plus the blockspace under the year. */
int y = r.top + FONT_HEIGHT_NORMAL + EXP_BLOCKSPACE;
int y = r.top + FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_wide;
for (uint i = 0; i < lengthof(_expenses_list_types); i++) {
/* Draw category title and advance y */
@@ -191,16 +186,20 @@ static void DrawCategories(const Rect &r)
DrawCategory(r, y, _expenses_list_types[i]);
y += _expenses_list_types[i].GetHeight();
/* Advance y by the height of the total and associated total line */
y += EXP_LINESPACE + FONT_HEIGHT_NORMAL;
/* Advance y by the height of the horizontal line between amounts and subtotal */
y += WidgetDimensions::scaled.vsep_normal;
/* Draw category total and advance y */
DrawString(r.left, r.right, y, STR_FINANCES_TOTAL_CAPTION, TC_FROMSTRING, SA_RIGHT);
y += FONT_HEIGHT_NORMAL;
/* Advance y by a blockspace after this category block */
y += EXP_BLOCKSPACE;
y += WidgetDimensions::scaled.vsep_wide;
}
/* Draw total profit/loss */
y += EXP_LINESPACE;
DrawString(r.left, r.right, y, STR_FINANCES_NET_PROFIT, TC_FROMSTRING, SA_LEFT);
y += WidgetDimensions::scaled.vsep_normal;
DrawString(r.left, r.right, y, STR_FINANCES_PROFIT, TC_FROMSTRING, SA_LEFT);
}
/**
@@ -244,7 +243,7 @@ static Money DrawYearCategory (const Rect &r, int start_y, ExpensesList list, co
/* Draw the total at the bottom of the category. */
GfxFillRect(r.left, y, r.right, y, PC_BLACK);
y += EXP_LINESPACE;
y += WidgetDimensions::scaled.vsep_normal;
if (sum != 0) DrawPrice(sum, r.left, r.right, y, TC_WHITE);
/* Return the sum for the yearly total. */
@@ -267,19 +266,19 @@ static void DrawYearColumn(const Rect &r, int year, const Money (*tbl)[EXPENSES_
/* Year header */
SetDParam(0, year);
DrawString(r.left, r.right, y, STR_FINANCES_YEAR, TC_FROMSTRING, SA_RIGHT, true);
y += FONT_HEIGHT_NORMAL + EXP_BLOCKSPACE;
y += FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_wide;
/* Categories */
for (uint i = 0; i < lengthof(_expenses_list_types); i++) {
y += FONT_HEIGHT_NORMAL;
sum += DrawYearCategory(r, y, _expenses_list_types[i], tbl);
/* Expense list + expense category title + expense category total + blockspace after category */
y += _expenses_list_types[i].GetHeight() + EXP_LINESPACE + FONT_HEIGHT_NORMAL + EXP_BLOCKSPACE;
y += _expenses_list_types[i].GetHeight() + WidgetDimensions::scaled.vsep_normal + FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_wide;
}
/* Total income. */
GfxFillRect(r.left, y, r.right, y, PC_BLACK);
y += EXP_LINESPACE;
y += WidgetDimensions::scaled.vsep_normal;
DrawPrice(sum, r.left, r.right, y, TC_WHITE);
}
@@ -293,7 +292,7 @@ static const NWidgetPart _nested_company_finances_widgets[] = {
EndContainer(),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_CF_SEL_PANEL),
NWidget(WWT_PANEL, COLOUR_GREY),
NWidget(NWID_HORIZONTAL), SetPadding(WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM, WD_FRAMERECT_LEFT), SetPIP(0, 9, 0),
NWidget(NWID_HORIZONTAL), SetPadding(WidgetDimensions::unscaled.framerect), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0),
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CF_EXPS_CATEGORY), SetMinimalSize(120, 0), SetFill(0, 0),
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CF_EXPS_PRICE1), SetMinimalSize(86, 0), SetFill(0, 0),
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CF_EXPS_PRICE2), SetMinimalSize(86, 0), SetFill(0, 0),
@@ -302,7 +301,7 @@ static const NWidgetPart _nested_company_finances_widgets[] = {
EndContainer(),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY),
NWidget(NWID_HORIZONTAL), SetPadding(WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM, WD_FRAMERECT_LEFT),
NWidget(NWID_HORIZONTAL), SetPadding(WidgetDimensions::unscaled.framerect),
NWidget(NWID_VERTICAL), // Vertical column with 'bank balance', 'loan'
NWidget(WWT_TEXT, COLOUR_GREY), SetDataTip(STR_FINANCES_OWN_FUNDS_TITLE, STR_NULL), SetFill(1, 0),
NWidget(WWT_TEXT, COLOUR_GREY), SetDataTip(STR_FINANCES_LOAN_TITLE, STR_NULL), SetFill(1, 0),
@@ -315,7 +314,7 @@ static const NWidgetPart _nested_company_finances_widgets[] = {
NWidget(WWT_TEXT, COLOUR_GREY, WID_CF_OWN_VALUE), SetDataTip(STR_FINANCES_TOTAL_CURRENCY, STR_NULL), SetAlignment(SA_VERT_CENTER | SA_RIGHT),
NWidget(WWT_TEXT, COLOUR_GREY, WID_CF_LOAN_VALUE), SetDataTip(STR_FINANCES_TOTAL_CURRENCY, STR_NULL), SetAlignment(SA_VERT_CENTER | SA_RIGHT),
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CF_BALANCE_LINE), SetMinimalSize(0, 2), SetFill(1, 0),
NWidget(WWT_TEXT, COLOUR_GREY, WID_CF_BALANCE_VALUE), SetDataTip(STR_FINANCES_TOTAL_CURRENCY, STR_NULL), SetAlignment(SA_VERT_CENTER | SA_RIGHT),
NWidget(WWT_TEXT, COLOUR_GREY, WID_CF_BALANCE_VALUE), SetDataTip(STR_FINANCES_BANK_BALANCE, STR_NULL), SetAlignment(SA_VERT_CENTER | SA_RIGHT),
EndContainer(),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_CF_SEL_MAXLOAN),
NWidget(NWID_HORIZONTAL),
@@ -603,23 +602,20 @@ public:
return true;
}
void Draw(int left, int right, int top, int bottom, bool sel, Colours bg_colour) const override
void Draw(const Rect &r, bool sel, Colours bg_colour) const override
{
bool rtl = _current_text_dir == TD_RTL;
int height = bottom - top;
int icon_y_offset = height / 2;
int text_y_offset = (height - FONT_HEIGHT_NORMAL) / 2 + 1;
int icon_y = CenterBounds(r.top, r.bottom, 0);
int text_y = CenterBounds(r.top, r.bottom, FONT_HEIGHT_NORMAL);
Rect tr = r.Shrink(WidgetDimensions::scaled.dropdowntext);
DrawSprite(SPR_VEH_BUS_SIDE_VIEW, PALETTE_RECOLOUR_START + (this->result % COLOUR_END),
rtl ? right - 2 - ScaleGUITrad(14) : left + ScaleGUITrad(14) + 2,
top + icon_y_offset);
DrawString(rtl ? left + 2 : left + ScaleGUITrad(28) + 4,
rtl ? right - ScaleGUITrad(28) - 4 : right - 2,
top + text_y_offset, this->String(), sel ? TC_WHITE : TC_BLACK);
rtl ? tr.right - ScaleGUITrad(14) : tr.left + ScaleGUITrad(14),
icon_y);
tr = tr.Indent(ScaleGUITrad(28) + WidgetDimensions::scaled.hsep_normal, rtl);
DrawString(tr.left, tr.right, text_y, this->String(), sel ? TC_WHITE : TC_BLACK);
}
};
static const int LEVEL_WIDTH = 10; ///< Indenting width of a sub-group in pixels
typedef GUIList<const Group*> GUIGroupList;
/** Company livery colour scheme window. */
@@ -824,14 +820,14 @@ public:
}
}
size->width = std::max(size->width, 5 + d.width + WD_FRAMERECT_RIGHT);
size->width = std::max(size->width, 5 + d.width + padding.width);
break;
}
case WID_SCL_MATRIX: {
/* 11 items in the default rail class */
this->square = GetSpriteSize(SPR_SQUARE);
this->line_height = std::max(this->square.height, (uint)FONT_HEIGHT_NORMAL) + 4;
this->line_height = std::max(this->square.height, (uint)FONT_HEIGHT_NORMAL) + padding.height;
size->height = 11 * this->line_height;
resize->width = 1;
@@ -848,7 +844,7 @@ public:
case WID_SCL_PRI_COL_DROPDOWN: {
this->square = GetSpriteSize(SPR_SQUARE);
int string_padding = this->square.width + NWidgetScrollbar::GetVerticalDimension().width + 10;
int string_padding = this->square.width + WidgetDimensions::scaled.hsep_normal + padding.width;
for (const StringID *id = _colour_dropdown; id != endof(_colour_dropdown); id++) {
size->width = std::max(size->width, GetStringBoundingBox(*id).width + string_padding);
}
@@ -918,40 +914,41 @@ public:
bool rtl = _current_text_dir == TD_RTL;
/* Horizontal coordinates of scheme name column. */
/* Coordinates of scheme name column. */
const NWidgetBase *nwi = this->GetWidget<NWidgetBase>(WID_SCL_SPACER_DROPDOWN);
int sch_left = nwi->pos_x;
int sch_right = sch_left + nwi->current_x - 1;
/* Horizontal coordinates of first dropdown. */
Rect sch = nwi->GetCurrentRect().Shrink(WidgetDimensions::scaled.framerect);
/* Coordinates of first dropdown. */
nwi = this->GetWidget<NWidgetBase>(WID_SCL_PRI_COL_DROPDOWN);
int pri_left = nwi->pos_x;
int pri_right = pri_left + nwi->current_x - 1;
/* Horizontal coordinates of second dropdown. */
Rect pri = nwi->GetCurrentRect().Shrink(WidgetDimensions::scaled.framerect);
/* Coordinates of second dropdown. */
nwi = this->GetWidget<NWidgetBase>(WID_SCL_SEC_COL_DROPDOWN);
int sec_left = nwi->pos_x;
int sec_right = sec_left + nwi->current_x - 1;
Rect sec = nwi->GetCurrentRect().Shrink(WidgetDimensions::scaled.framerect);
int text_left = (rtl ? (uint)WD_FRAMERECT_LEFT : (this->square.width + 5));
int text_right = (rtl ? (this->square.width + 5) : (uint)WD_FRAMERECT_RIGHT);
Rect pri_squ = pri.WithWidth(this->square.width, rtl);
Rect sec_squ = sec.WithWidth(this->square.width, rtl);
int square_offs = (this->line_height - this->square.height) / 2 + 1;
int text_offs = (this->line_height - FONT_HEIGHT_NORMAL) / 2 + 1;
pri = pri.Indent(this->square.width + WidgetDimensions::scaled.hsep_normal, rtl);
sec = sec.Indent(this->square.width + WidgetDimensions::scaled.hsep_normal, rtl);
int y = r.top;
Rect ir = r.WithHeight(this->resize.step_height).Shrink(WidgetDimensions::scaled.matrix);
int square_offs = (ir.Height() - this->square.height) / 2;
int text_offs = (ir.Height() - FONT_HEIGHT_NORMAL) / 2;
int y = ir.top;
/* Helper function to draw livery info. */
auto draw_livery = [&](StringID str, const Livery &liv, bool sel, bool def, int indent) {
/* Livery Label. */
DrawString(sch_left + WD_FRAMERECT_LEFT + (rtl ? 0 : indent), sch_right - WD_FRAMERECT_RIGHT - (rtl ? indent : 0), y + text_offs, str, sel ? TC_WHITE : TC_BLACK);
DrawString(sch.left + (rtl ? 0 : indent), sch.right - (rtl ? indent : 0), y + text_offs, str, sel ? TC_WHITE : TC_BLACK);
/* Text below the first dropdown. */
DrawSprite(SPR_SQUARE, GENERAL_SPRITE_COLOUR(liv.colour1), (rtl ? pri_right - (this->square.width + 5) + WD_FRAMERECT_RIGHT : pri_left) + WD_FRAMERECT_LEFT, y + square_offs);
DrawString(pri_left + text_left, pri_right - text_right, y + text_offs, (def || HasBit(liv.in_use, 0)) ? STR_COLOUR_DARK_BLUE + liv.colour1 : STR_COLOUR_DEFAULT, sel ? TC_WHITE : TC_GOLD);
DrawSprite(SPR_SQUARE, GENERAL_SPRITE_COLOUR(liv.colour1), pri_squ.left, y + square_offs);
DrawString(pri.left, pri.right, y + text_offs, (def || HasBit(liv.in_use, 0)) ? STR_COLOUR_DARK_BLUE + liv.colour1 : STR_COLOUR_DEFAULT, sel ? TC_WHITE : TC_GOLD);
/* Text below the second dropdown. */
if (sec_right > sec_left) { // Second dropdown has non-zero size.
DrawSprite(SPR_SQUARE, GENERAL_SPRITE_COLOUR(liv.colour2), (rtl ? sec_right - (this->square.width + 5) + WD_FRAMERECT_RIGHT : sec_left) + WD_FRAMERECT_LEFT, y + square_offs);
DrawString(sec_left + text_left, sec_right - text_right, y + text_offs, (def || HasBit(liv.in_use, 1)) ? STR_COLOUR_DARK_BLUE + liv.colour2 : STR_COLOUR_DEFAULT, sel ? TC_WHITE : TC_GOLD);
if (sec.right > sec.left) { // Second dropdown has non-zero size.
DrawSprite(SPR_SQUARE, GENERAL_SPRITE_COLOUR(liv.colour2), sec_squ.left, y + square_offs);
DrawString(sec.left, sec.right, y + text_offs, (def || HasBit(liv.in_use, 1)) ? STR_COLOUR_DARK_BLUE + liv.colour2 : STR_COLOUR_DEFAULT, sel ? TC_WHITE : TC_GOLD);
}
y += this->line_height;
@@ -971,7 +968,7 @@ public:
for (uint i = this->vscroll->GetPosition(); i < max; ++i) {
const Group *g = this->groups[i];
SetDParam(0, g->index);
draw_livery(STR_GROUP_NAME, g->livery, this->sel == g->index, false, this->indents[i] * LEVEL_WIDTH);
draw_livery(STR_GROUP_NAME, g->livery, this->sel == g->index, false, this->indents[i] * WidgetDimensions::scaled.hsep_indent);
}
}
}
@@ -1269,81 +1266,81 @@ static const NWidgetPart _nested_select_company_manager_face_widgets[] = {
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 4),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_HAS_MOUSTACHE_EARRING_TEXT), SetFill(1, 0), SetPadding(0, WD_FRAMERECT_RIGHT, 0, WD_FRAMERECT_LEFT),
NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_HAS_MOUSTACHE_EARRING_TEXT), SetFill(1, 0), SetPadding(WidgetDimensions::unscaled.framerect),
SetDataTip(STR_FACE_EYECOLOUR, STR_NULL), SetTextColour(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_HAS_MOUSTACHE_EARRING), SetDataTip(STR_WHITE_STRING, STR_FACE_MOUSTACHE_EARRING_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_HAS_GLASSES_TEXT), SetFill(1, 0), SetPadding(0, WD_FRAMERECT_RIGHT, 0, WD_FRAMERECT_LEFT),
NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_HAS_GLASSES_TEXT), SetFill(1, 0), SetPadding(WidgetDimensions::unscaled.framerect),
SetDataTip(STR_FACE_GLASSES, STR_NULL), SetTextColour(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_HAS_GLASSES), SetDataTip(STR_WHITE_STRING, STR_FACE_GLASSES_TOOLTIP),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 2), SetFill(1, 0),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_HAIR_TEXT), SetFill(1, 0), SetPadding(0, WD_FRAMERECT_RIGHT, 0, WD_FRAMERECT_LEFT),
NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_HAIR_TEXT), SetFill(1, 0), SetPadding(WidgetDimensions::unscaled.framerect),
SetDataTip(STR_FACE_HAIR, STR_NULL), SetTextColour(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_HAIR_L), SetDataTip(AWV_DECREASE, STR_FACE_HAIR_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_HAIR), SetDataTip(STR_WHITE_STRING, STR_FACE_HAIR_TOOLTIP),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_HAIR_R), SetDataTip(AWV_INCREASE, STR_FACE_HAIR_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_EYEBROWS_TEXT), SetFill(1, 0), SetPadding(0, WD_FRAMERECT_RIGHT, 0, WD_FRAMERECT_LEFT),
NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_EYEBROWS_TEXT), SetFill(1, 0), SetPadding(WidgetDimensions::unscaled.framerect),
SetDataTip(STR_FACE_EYEBROWS, STR_NULL), SetTextColour(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_EYEBROWS_L), SetDataTip(AWV_DECREASE, STR_FACE_EYEBROWS_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_EYEBROWS), SetDataTip(STR_WHITE_STRING, STR_FACE_EYEBROWS_TOOLTIP),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_EYEBROWS_R), SetDataTip(AWV_INCREASE, STR_FACE_EYEBROWS_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_EYECOLOUR_TEXT), SetFill(1, 0), SetPadding(0, WD_FRAMERECT_RIGHT, 0, WD_FRAMERECT_LEFT),
NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_EYECOLOUR_TEXT), SetFill(1, 0), SetPadding(WidgetDimensions::unscaled.framerect),
SetDataTip(STR_FACE_EYECOLOUR, STR_NULL), SetTextColour(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_EYECOLOUR_L), SetDataTip(AWV_DECREASE, STR_FACE_EYECOLOUR_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_EYECOLOUR), SetDataTip(STR_WHITE_STRING, STR_FACE_EYECOLOUR_TOOLTIP),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_EYECOLOUR_R), SetDataTip(AWV_INCREASE, STR_FACE_EYECOLOUR_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_GLASSES_TEXT), SetFill(1, 0), SetPadding(0, WD_FRAMERECT_RIGHT, 0, WD_FRAMERECT_LEFT),
NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_GLASSES_TEXT), SetFill(1, 0), SetPadding(WidgetDimensions::unscaled.framerect),
SetDataTip(STR_FACE_GLASSES, STR_NULL), SetTextColour(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_GLASSES_L), SetDataTip(AWV_DECREASE, STR_FACE_GLASSES_TOOLTIP_2),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_GLASSES), SetDataTip(STR_WHITE_STRING, STR_FACE_GLASSES_TOOLTIP_2),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_GLASSES_R), SetDataTip(AWV_INCREASE, STR_FACE_GLASSES_TOOLTIP_2),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_NOSE_TEXT), SetFill(1, 0), SetPadding(0, WD_FRAMERECT_RIGHT, 0, WD_FRAMERECT_LEFT),
NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_NOSE_TEXT), SetFill(1, 0), SetPadding(WidgetDimensions::unscaled.framerect),
SetDataTip(STR_FACE_NOSE, STR_NULL), SetTextColour(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_NOSE_L), SetDataTip(AWV_DECREASE, STR_FACE_NOSE_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_NOSE), SetDataTip(STR_WHITE_STRING, STR_FACE_NOSE_TOOLTIP),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_NOSE_R), SetDataTip(AWV_INCREASE, STR_FACE_NOSE_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_LIPS_MOUSTACHE_TEXT), SetFill(1, 0), SetPadding(0, WD_FRAMERECT_RIGHT, 0, WD_FRAMERECT_LEFT),
NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_LIPS_MOUSTACHE_TEXT), SetFill(1, 0), SetPadding(WidgetDimensions::unscaled.framerect),
SetDataTip(STR_FACE_MOUSTACHE, STR_NULL), SetTextColour(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_LIPS_MOUSTACHE_L), SetDataTip(AWV_DECREASE, STR_FACE_LIPS_MOUSTACHE_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_LIPS_MOUSTACHE), SetDataTip(STR_WHITE_STRING, STR_FACE_LIPS_MOUSTACHE_TOOLTIP),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_LIPS_MOUSTACHE_R), SetDataTip(AWV_INCREASE, STR_FACE_LIPS_MOUSTACHE_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_CHIN_TEXT), SetFill(1, 0), SetPadding(0, WD_FRAMERECT_RIGHT, 0, WD_FRAMERECT_LEFT),
NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_CHIN_TEXT), SetFill(1, 0), SetPadding(WidgetDimensions::unscaled.framerect),
SetDataTip(STR_FACE_CHIN, STR_NULL), SetTextColour(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_CHIN_L), SetDataTip(AWV_DECREASE, STR_FACE_CHIN_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_CHIN), SetDataTip(STR_WHITE_STRING, STR_FACE_CHIN_TOOLTIP),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_CHIN_R), SetDataTip(AWV_INCREASE, STR_FACE_CHIN_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_JACKET_TEXT), SetFill(1, 0), SetPadding(0, WD_FRAMERECT_RIGHT, 0, WD_FRAMERECT_LEFT),
NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_JACKET_TEXT), SetFill(1, 0), SetPadding(WidgetDimensions::unscaled.framerect),
SetDataTip(STR_FACE_JACKET, STR_NULL), SetTextColour(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_JACKET_L), SetDataTip(AWV_DECREASE, STR_FACE_JACKET_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_JACKET), SetDataTip(STR_WHITE_STRING, STR_FACE_JACKET_TOOLTIP),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_JACKET_R), SetDataTip(AWV_INCREASE, STR_FACE_JACKET_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_COLLAR_TEXT), SetFill(1, 0), SetPadding(0, WD_FRAMERECT_RIGHT, 0, WD_FRAMERECT_LEFT),
NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_COLLAR_TEXT), SetFill(1, 0), SetPadding(WidgetDimensions::unscaled.framerect),
SetDataTip(STR_FACE_COLLAR, STR_NULL), SetTextColour(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_COLLAR_L), SetDataTip(AWV_DECREASE, STR_FACE_COLLAR_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_COLLAR), SetDataTip(STR_WHITE_STRING, STR_FACE_COLLAR_TOOLTIP),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_COLLAR_R), SetDataTip(AWV_INCREASE, STR_FACE_COLLAR_TOOLTIP),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_TIE_EARRING_TEXT), SetFill(1, 0), SetPadding(0, WD_FRAMERECT_RIGHT, 0, WD_FRAMERECT_LEFT),
NWidget(WWT_TEXT, INVALID_COLOUR, WID_SCMF_TIE_EARRING_TEXT), SetFill(1, 0), SetPadding(WidgetDimensions::unscaled.framerect),
SetDataTip(STR_FACE_EARRING, STR_NULL), SetTextColour(TC_GOLD), SetAlignment(SA_VERT_CENTER | SA_RIGHT),
NWidget(WWT_PUSHARROWBTN, COLOUR_GREY, WID_SCMF_TIE_EARRING_L), SetDataTip(AWV_DECREASE, STR_FACE_TIE_EARRING_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_SCMF_TIE_EARRING), SetDataTip(STR_WHITE_STRING, STR_FACE_TIE_EARRING_TOOLTIP),
@@ -1447,17 +1444,17 @@ public:
{
/* Size of the boolean yes/no button. */
Dimension yesno_dim = maxdim(GetStringBoundingBox(STR_FACE_YES), GetStringBoundingBox(STR_FACE_NO));
yesno_dim.width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
yesno_dim.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
yesno_dim.width += WidgetDimensions::scaled.framerect.Horizontal();
yesno_dim.height += WidgetDimensions::scaled.framerect.Vertical();
/* Size of the number button + arrows. */
Dimension number_dim = {0, 0};
for (int val = 1; val <= 12; val++) {
SetDParam(0, val);
number_dim = maxdim(number_dim, GetStringBoundingBox(STR_JUST_INT));
}
uint arrows_width = GetSpriteSize(SPR_ARROW_LEFT).width + GetSpriteSize(SPR_ARROW_RIGHT).width + 2 * (WD_IMGBTN_LEFT + WD_IMGBTN_RIGHT);
number_dim.width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT + arrows_width;
number_dim.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
uint arrows_width = GetSpriteSize(SPR_ARROW_LEFT).width + GetSpriteSize(SPR_ARROW_RIGHT).width + 2 * (WidgetDimensions::scaled.imgbtn.Horizontal());
number_dim.width += WidgetDimensions::scaled.framerect.Horizontal() + arrows_width;
number_dim.height += WidgetDimensions::scaled.framerect.Vertical();
/* Compute width of both buttons. */
yesno_dim.width = std::max(yesno_dim.width, number_dim.width);
number_dim.width = yesno_dim.width - arrows_width;
@@ -1796,28 +1793,28 @@ static const NWidgetPart _nested_company_infrastructure_widgets[] = {
NWidget(WWT_STICKYBOX, COLOUR_GREY),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY),
NWidget(NWID_VERTICAL), SetPIP(WD_FRAMERECT_TOP, 4, WD_FRAMETEXT_BOTTOM),
NWidget(NWID_HORIZONTAL), SetPIP(2, 4, 2),
NWidget(NWID_VERTICAL), SetPadding(WidgetDimensions::unscaled.framerect), SetPIP(0, WidgetDimensions::unscaled.vsep_normal, 0),
NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0),
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_RAIL_DESC), SetMinimalTextLines(2, 0), SetFill(1, 0),
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_RAIL_COUNT), SetMinimalTextLines(2, 0), SetFill(0, 1),
EndContainer(),
NWidget(NWID_HORIZONTAL), SetPIP(2, 4, 2),
NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0),
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_ROAD_DESC), SetMinimalTextLines(2, 0), SetFill(1, 0),
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_ROAD_COUNT), SetMinimalTextLines(2, 0), SetFill(0, 1),
EndContainer(),
NWidget(NWID_HORIZONTAL), SetPIP(2, 4, 2),
NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0),
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_TRAM_DESC), SetMinimalTextLines(2, 0), SetFill(1, 0),
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_TRAM_COUNT), SetMinimalTextLines(2, 0), SetFill(0, 1),
EndContainer(),
NWidget(NWID_HORIZONTAL), SetPIP(2, 4, 2),
NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0),
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_WATER_DESC), SetMinimalTextLines(2, 0), SetFill(1, 0),
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_WATER_COUNT), SetMinimalTextLines(2, 0), SetFill(0, 1),
EndContainer(),
NWidget(NWID_HORIZONTAL), SetPIP(2, 4, 2),
NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0),
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_STATION_DESC), SetMinimalTextLines(3, 0), SetFill(1, 0),
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_STATION_COUNT), SetMinimalTextLines(3, 0), SetFill(0, 1),
EndContainer(),
NWidget(NWID_HORIZONTAL), SetPIP(2, 4, 2),
NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0),
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_TOTAL_DESC), SetFill(1, 0),
NWidget(WWT_EMPTY, COLOUR_GREY, WID_CI_TOTAL), SetFill(0, 1),
EndContainer(),
@@ -1918,12 +1915,12 @@ struct CompanyInfrastructureWindow : Window
if (HasBit(this->railtypes, rt)) {
lines++;
SetDParam(0, GetRailTypeInfo(rt)->strings.name);
size->width = std::max(size->width, GetStringBoundingBox(STR_WHITE_STRING).width + WD_FRAMERECT_LEFT);
size->width = std::max(size->width, GetStringBoundingBox(STR_WHITE_STRING).width + WidgetDimensions::scaled.hsep_indent);
}
}
if (this->railtypes != RAILTYPES_NONE) {
lines++;
size->width = std::max(size->width, GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS).width + WD_FRAMERECT_LEFT);
size->width = std::max(size->width, GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS).width + WidgetDimensions::scaled.hsep_indent);
}
size->height = std::max(size->height, lines * FONT_HEIGHT_NORMAL);
@@ -1940,7 +1937,7 @@ struct CompanyInfrastructureWindow : Window
if (HasBit(this->roadtypes, rt) && RoadTypeIsRoad(rt) == (widget == WID_CI_ROAD_DESC)) {
lines++;
SetDParam(0, GetRoadTypeInfo(rt)->strings.name);
size->width = std::max(size->width, GetStringBoundingBox(STR_WHITE_STRING).width + WD_FRAMERECT_LEFT);
size->width = std::max(size->width, GetStringBoundingBox(STR_WHITE_STRING).width + WidgetDimensions::scaled.hsep_indent);
}
}
@@ -1950,13 +1947,13 @@ struct CompanyInfrastructureWindow : Window
case WID_CI_WATER_DESC:
size->width = std::max(size->width, GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT).width);
size->width = std::max(size->width, GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS).width + WD_FRAMERECT_LEFT);
size->width = std::max(size->width, GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS).width + WidgetDimensions::scaled.hsep_indent);
break;
case WID_CI_STATION_DESC:
size->width = std::max(size->width, GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT).width);
size->width = std::max(size->width, GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_STATIONS).width + WD_FRAMERECT_LEFT);
size->width = std::max(size->width, GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_AIRPORTS).width + WD_FRAMERECT_LEFT);
size->width = std::max(size->width, GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_STATIONS).width + WidgetDimensions::scaled.hsep_indent);
size->width = std::max(size->width, GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_AIRPORTS).width + WidgetDimensions::scaled.hsep_indent);
break;
case WID_CI_RAIL_COUNT:
@@ -1990,11 +1987,11 @@ struct CompanyInfrastructureWindow : Window
max_cost = std::max(max_cost, AirportMaintenanceCost(c->index));
SetDParamMaxValue(0, max_val);
uint count_width = GetStringBoundingBox(STR_WHITE_COMMA).width + 20; // Reserve some wiggle room
uint count_width = GetStringBoundingBox(STR_WHITE_COMMA).width + WidgetDimensions::scaled.hsep_indent; // Reserve some wiggle room
if (_settings_game.economy.infrastructure_maintenance) {
SetDParamMaxValue(0, this->GetTotalMaintenanceCost() * 12); // Convert to per year
this->total_width = GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL).width + 20;
this->total_width = GetStringBoundingBox(STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL).width + WidgetDimensions::scaled.hsep_indent * 2;
size->width = std::max(size->width, this->total_width);
SetDParamMaxValue(0, max_cost * 12); // Convert to per year
@@ -2005,7 +2002,7 @@ struct CompanyInfrastructureWindow : Window
/* Set height of the total line. */
if (widget == WID_CI_TOTAL) {
size->height = _settings_game.economy.infrastructure_maintenance ? std::max(size->height, EXP_LINESPACE + FONT_HEIGHT_NORMAL) : 0;
size->height = _settings_game.economy.infrastructure_maintenance ? std::max<uint>(size->height, WidgetDimensions::scaled.vsep_normal + FONT_HEIGHT_NORMAL) : 0;
}
break;
}
@@ -2026,19 +2023,18 @@ struct CompanyInfrastructureWindow : Window
if (_settings_game.economy.infrastructure_maintenance) {
SetDParam(0, monthly_cost * 12); // Convert to per year
int left = _current_text_dir == TD_RTL ? r.right - this->total_width : r.left;
DrawString(left, left + this->total_width, y, STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL, TC_FROMSTRING, SA_RIGHT);
Rect tr = r.WithWidth(this->total_width, _current_text_dir == TD_RTL);
DrawString(tr.left, tr.right, y, STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL, TC_FROMSTRING, SA_RIGHT);
}
}
void DrawWidget(const Rect &r, int widget) const override
{
const Company *c = Company::Get((CompanyID)this->window_number);
int y = r.top;
int offs_left = _current_text_dir == TD_LTR ? WD_FRAMERECT_LEFT : 0;
int offs_right = _current_text_dir == TD_LTR ? 0 : WD_FRAMERECT_LEFT;
Rect ir = r.Indent(WidgetDimensions::scaled.hsep_indent, _current_text_dir == TD_RTL);
switch (widget) {
case WID_CI_RAIL_DESC:
DrawString(r.left, r.right, y, STR_COMPANY_INFRASTRUCTURE_VIEW_RAIL_SECT);
@@ -2048,13 +2044,13 @@ struct CompanyInfrastructureWindow : Window
for (const auto &rt : _sorted_railtypes) {
if (HasBit(this->railtypes, rt)) {
SetDParam(0, GetRailTypeInfo(rt)->strings.name);
DrawString(r.left + offs_left, r.right - offs_right, y += FONT_HEIGHT_NORMAL, STR_WHITE_STRING);
DrawString(ir.left, ir.right, y += FONT_HEIGHT_NORMAL, STR_WHITE_STRING);
}
}
DrawString(r.left + offs_left, r.right - offs_right, y += FONT_HEIGHT_NORMAL, STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS);
DrawString(ir.left, ir.right, y += FONT_HEIGHT_NORMAL, STR_COMPANY_INFRASTRUCTURE_VIEW_SIGNALS);
} else {
/* No valid railtype. */
DrawString(r.left + offs_left, r.right - offs_right, y += FONT_HEIGHT_NORMAL, STR_COMPANY_VIEW_INFRASTRUCTURE_NONE);
DrawString(ir.left, ir.right, y += FONT_HEIGHT_NORMAL, STR_COMPANY_VIEW_INFRASTRUCTURE_NONE);
}
break;
@@ -2081,7 +2077,7 @@ struct CompanyInfrastructureWindow : Window
for (const auto &rt : _sorted_roadtypes) {
if (HasBit(this->roadtypes, rt) && RoadTypeIsRoad(rt) == (widget == WID_CI_ROAD_DESC)) {
SetDParam(0, GetRoadTypeInfo(rt)->strings.name);
DrawString(r.left + offs_left, r.right - offs_right, y += FONT_HEIGHT_NORMAL, STR_WHITE_STRING);
DrawString(ir.left, ir.right, y += FONT_HEIGHT_NORMAL, STR_WHITE_STRING);
}
}
@@ -2101,7 +2097,7 @@ struct CompanyInfrastructureWindow : Window
case WID_CI_WATER_DESC:
DrawString(r.left, r.right, y, STR_COMPANY_INFRASTRUCTURE_VIEW_WATER_SECT);
DrawString(r.left + offs_left, r.right - offs_right, y += FONT_HEIGHT_NORMAL, STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS);
DrawString(ir.left, ir.right, y += FONT_HEIGHT_NORMAL, STR_COMPANY_INFRASTRUCTURE_VIEW_CANALS);
break;
case WID_CI_WATER_COUNT:
@@ -2110,18 +2106,18 @@ struct CompanyInfrastructureWindow : Window
case WID_CI_TOTAL:
if (_settings_game.economy.infrastructure_maintenance) {
int left = _current_text_dir == TD_RTL ? r.right - this->total_width : r.left;
GfxFillRect(left, y, left + this->total_width, y, PC_WHITE);
y += EXP_LINESPACE;
Rect tr = r.WithWidth(this->total_width, _current_text_dir == TD_RTL);
GfxFillRect(tr.left, y, tr.right, y, PC_WHITE);
y += WidgetDimensions::scaled.vsep_normal;
SetDParam(0, this->GetTotalMaintenanceCost() * 12); // Convert to per year
DrawString(left, left + this->total_width, y, STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL, TC_FROMSTRING, SA_RIGHT);
DrawString(tr.left, tr.right, y, STR_COMPANY_INFRASTRUCTURE_VIEW_TOTAL, TC_FROMSTRING, SA_RIGHT);
}
break;
case WID_CI_STATION_DESC:
DrawString(r.left, r.right, y, STR_COMPANY_INFRASTRUCTURE_VIEW_STATION_SECT);
DrawString(r.left + offs_left, r.right - offs_right, y += FONT_HEIGHT_NORMAL, STR_COMPANY_INFRASTRUCTURE_VIEW_STATIONS);
DrawString(r.left + offs_left, r.right - offs_right, y += FONT_HEIGHT_NORMAL, STR_COMPANY_INFRASTRUCTURE_VIEW_AIRPORTS);
DrawString(ir.left, ir.right, y += FONT_HEIGHT_NORMAL, STR_COMPANY_INFRASTRUCTURE_VIEW_STATIONS);
DrawString(ir.left, ir.right, y += FONT_HEIGHT_NORMAL, STR_COMPANY_INFRASTRUCTURE_VIEW_AIRPORTS);
break;
case WID_CI_STATION_COUNT:
@@ -2466,7 +2462,7 @@ struct CompanyWindow : Window
Point offset;
Dimension d = GetSpriteSize(SPR_VEH_BUS_SW_VIEW, &offset);
d.height -= offset.y;
DrawSprite(SPR_VEH_BUS_SW_VIEW, COMPANY_SPRITE_COLOUR(c->index), r.left - offset.x, (r.top + r.bottom - d.height) / 2 - offset.y);
DrawSprite(SPR_VEH_BUS_SW_VIEW, COMPANY_SPRITE_COLOUR(c->index), r.left - offset.x, CenterBounds(r.top, r.bottom, d.height) - offset.y);
break;
}

View File

@@ -23,6 +23,7 @@
#include "settings_func.h"
#include "fios.h"
#include "fileio_func.h"
#include "fontcache.h"
#include "screenshot.h"
#include "genworld.h"
#include "strings_func.h"
@@ -1495,6 +1496,7 @@ DEF_CONSOLE_CMD(ConScreenShot)
IConsolePrint(CC_HELP, " 'minimap' makes a top-viewed minimap screenshot of the whole world which represents one tile by one pixel.");
IConsolePrint(CC_HELP, " 'no_con' hides the console to create the screenshot (only useful in combination with 'viewport').");
IConsolePrint(CC_HELP, " 'size' sets the width and height of the viewport to make a screenshot of (only useful in combination with 'normal' or 'big').");
IConsolePrint(CC_HELP, " A filename ending in # will prevent overwriting existing files and will number files counting upwards.");
return true;
}
@@ -1983,6 +1985,82 @@ DEF_CONSOLE_CMD(ConContent)
}
#endif /* defined(WITH_ZLIB) */
DEF_CONSOLE_CMD(ConFont)
{
if (argc == 0) {
IConsolePrint(CC_HELP, "Manage the fonts configuration.");
IConsolePrint(CC_HELP, "Usage 'font'.");
IConsolePrint(CC_HELP, " Print out the fonts configuration.");
IConsolePrint(CC_HELP, "Usage 'font [medium|small|large|mono] [<name>] [<size>] [aa|noaa]'.");
IConsolePrint(CC_HELP, " Change the configuration for a font.");
IConsolePrint(CC_HELP, " Omitting an argument will keep the current value.");
IConsolePrint(CC_HELP, " Set <name> to \"\" for the sprite font (size and aa have no effect on sprite font).");
return true;
}
FontSize argfs;
for (argfs = FS_BEGIN; argfs < FS_END; argfs++) {
if (argc > 1 && strcasecmp(argv[1], FontSizeToName(argfs)) == 0) break;
}
/* First argument must be a FontSize. */
if (argc > 1 && argfs == FS_END) return false;
if (argc > 2) {
FontCacheSubSetting *setting = GetFontCacheSubSetting(argfs);
std::string font = setting->font;
uint size = setting->size;
bool aa = setting->aa;
byte arg_index = 2;
if (argc > arg_index) {
/* We may encounter "aa" or "noaa" but it must be the last argument. */
if (strcasecmp(argv[arg_index], "aa") == 0 || strcasecmp(argv[arg_index], "noaa") == 0) {
aa = strncasecmp(argv[arg_index++], "no", 2) != 0;
if (argc > arg_index) return false;
} else {
/* For <name> we want a string. */
uint v;
if (!GetArgumentInteger(&v, argv[arg_index])) {
font = argv[arg_index++];
}
}
}
if (argc > arg_index) {
/* For <size> we want a number. */
uint v;
if (GetArgumentInteger(&v, argv[arg_index])) {
size = v;
arg_index++;
}
}
if (argc > arg_index) {
/* Last argument must be "aa" or "noaa". */
if (strcasecmp(argv[arg_index], "aa") != 0 && strcasecmp(argv[arg_index], "noaa") != 0) return false;
aa = strncasecmp(argv[arg_index++], "no", 2) != 0;
if (argc > arg_index) return false;
}
SetFont(argfs, font, size, aa);
}
for (FontSize fs = FS_BEGIN; fs < FS_END; fs++) {
FontCache *fc = FontCache::Get(fs);
FontCacheSubSetting *setting = GetFontCacheSubSetting(fs);
/* Make sure all non sprite fonts are loaded. */
if (!setting->font.empty() && !fc->HasParent()) {
InitFontCache(fs == FS_MONO);
fc = FontCache::Get(fs);
}
IConsolePrint(CC_DEFAULT, "{}: \"{}\" {} {} [\"{}\" {} {}]", FontSizeToName(fs), fc->GetFontName(), fc->GetFontSize(), GetFontAAState(fs), setting->font, setting->size, setting->aa);
}
return true;
}
DEF_CONSOLE_CMD(ConSetting)
{
if (argc == 0) {
@@ -2481,6 +2559,7 @@ void IConsoleStdLibRegister()
IConsole::CmdRegister("cd", ConChangeDirectory);
IConsole::CmdRegister("pwd", ConPrintWorkingDirectory);
IConsole::CmdRegister("clear", ConClearBuffer);
IConsole::CmdRegister("font", ConFont);
IConsole::CmdRegister("setting", ConSetting);
IConsole::CmdRegister("setting_newgame", ConSettingNewgame);
IConsole::CmdRegister("list_settings", ConListSettings);

View File

@@ -31,7 +31,6 @@
#include "safeguards.h"
static const uint ICON_HISTORY_SIZE = 20;
static const uint ICON_LINE_SPACING = 2;
static const uint ICON_RIGHT_BORDERWIDTH = 10;
static const uint ICON_BOTTOM_BORDERWIDTH = 12;
@@ -121,14 +120,18 @@ struct IConsoleWindow : Window
IConsoleWindow() : Window(&_console_window_desc)
{
_iconsole_mode = ICONSOLE_OPENED;
this->line_height = FONT_HEIGHT_NORMAL + ICON_LINE_SPACING;
this->line_offset = GetStringBoundingBox("] ").width + 5;
this->InitNested(0);
this->truncate_timer.SetInterval(3000);
ResizeWindow(this, _screen.width, _screen.height / 3);
}
void OnInit() override
{
this->line_height = FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.hsep_normal;
this->line_offset = GetStringBoundingBox("] ").width + WidgetDimensions::scaled.frametext.left;
}
void Close() override
{
_iconsole_mode = ICONSOLE_CLOSED;
@@ -156,20 +159,20 @@ struct IConsoleWindow : Window
void OnPaint() override
{
const int right = this->width - 5;
const int right = this->width - WidgetDimensions::scaled.frametext.right;
GfxFillRect(0, 0, this->width - 1, this->height - 1, PC_BLACK);
int ypos = this->height - this->line_height;
for (size_t line_index = IConsoleWindow::scroll; line_index < _iconsole_buffer.size(); line_index++) {
const IConsoleLine &print = _iconsole_buffer[line_index];
SetDParamStr(0, print.buffer);
ypos = DrawStringMultiLine(5, right, -this->line_height, ypos, STR_JUST_RAW_STRING, print.colour, SA_LEFT | SA_BOTTOM | SA_FORCE) - ICON_LINE_SPACING;
ypos = DrawStringMultiLine(WidgetDimensions::scaled.frametext.left, right, -this->line_height, ypos, STR_JUST_RAW_STRING, print.colour, SA_LEFT | SA_BOTTOM | SA_FORCE) - WidgetDimensions::scaled.hsep_normal;
if (ypos < 0) break;
}
/* If the text is longer than the window, don't show the starting ']' */
int delta = this->width - this->line_offset - _iconsole_cmdline.pixels - ICON_RIGHT_BORDERWIDTH;
if (delta > 0) {
DrawString(5, right, this->height - this->line_height, "]", (TextColour)CC_COMMAND, SA_LEFT | SA_FORCE);
DrawString(WidgetDimensions::scaled.frametext.left, right, this->height - this->line_height, "]", (TextColour)CC_COMMAND, SA_LEFT | SA_FORCE);
delta = 0;
}

View File

@@ -48,3 +48,5 @@ Rect BoundingRect(const Rect &r1, const Rect &r2)
return r;
}
const RectPadding RectPadding::zero = {0, 0, 0, 0};

View File

@@ -43,12 +43,182 @@ struct Dimension {
}
};
/** Padding dimensions to apply to each side of a Rect. */
struct RectPadding {
uint8 left;
uint8 top;
uint8 right;
uint8 bottom;
static const RectPadding zero;
/**
* Get total horizontal padding of RectPadding.
* @return total horizontal padding.
*/
inline uint Horizontal() const { return this->left + this->right; }
/**
* Get total vertical padding of RectPadding.
* @return total vertical padding.
*/
inline uint Vertical() const { return this->top + this->bottom; }
};
/** Specification of a rectangle with absolute coordinates of all edges */
struct Rect {
int left;
int top;
int right;
int bottom;
/**
* Get width of Rect.
* @return width of Rect.
*/
inline int Width() const { return this->right - this->left + 1; }
/**
* Get height of Rect.
* @return height of Rect.
*/
inline int Height() const { return this->bottom - this->top + 1; }
/**
* Copy and shrink Rect by s pixels.
* @param s number of pixels to remove from each side of Rect.
* @return the new smaller Rect.
*/
[[nodiscard]] inline Rect Shrink(int s) const
{
return {this->left + s, this->top + s, this->right - s, this->bottom - s};
}
/**
* Copy and shrink Rect by h horizontal and v vertical pixels.
* @param h number of pixels to remove from left and right sides.
* @param v number of pixels to remove from top and bottom sides.
* @return the new smaller Rect.
*/
[[nodiscard]] inline Rect Shrink(int h, int v) const
{
return {this->left + h, this->top + v, this->right - h, this->bottom - v};
}
/**
* Copy and shrink Rect by pixels.
* @param left number of pixels to remove from left side.
* @param top number of pixels to remove from top side.
* @param right number of pixels to remove from right side.
* @param bottom number of pixels to remove from bottom side.
* @return the new smaller Rect.
*/
[[nodiscard]] inline Rect Shrink(int left, int top, int right, int bottom) const
{
return {this->left + left, this->top + top, this->right - right, this->bottom - bottom};
}
/**
* Copy and shrink Rect by a RectPadding.
* @param other RectPadding to remove from each side of Rect.
* @return the new smaller Rect.
*/
[[nodiscard]] inline Rect Shrink(const RectPadding &other) const
{
return {this->left + other.left, this->top + other.top, this->right - other.right, this->bottom - other.bottom};
}
/**
* Copy and shrink Rect by a different horizontal and vertical RectPadding.
* @param horz RectPadding to remove from left and right of Rect.
* @param vert RectPadding to remove from top and bottom of Rect.
* @return the new smaller Rect.
*/
[[nodiscard]] inline Rect Shrink(const RectPadding &horz, const RectPadding &vert) const
{
return {this->left + horz.left, this->top + vert.top, this->right - horz.right, this->bottom - vert.bottom};
}
/**
* Copy and expand Rect by s pixels.
* @param s number of pixels to add to each side of Rect.
* @return the new larger Rect.
*/
[[nodiscard]] inline Rect Expand(int s) const
{
return this->Shrink(-s);
}
/**
* Copy and expand Rect by a RectPadding.
* @param other RectPadding to add to each side of Rect.
* @return the new larger Rect.
*/
[[nodiscard]] inline Rect Expand(const RectPadding &other) const
{
return {this->left - other.left, this->top - other.top, this->right + other.right, this->bottom + other.bottom};
}
/**
* Copy and translate Rect by x,y pixels.
* @param x number of pixels to move horizontally.
* @param y number of pixels to move vertically.
* @return the new translated Rect.
*/
[[nodiscard]] inline Rect Translate(int x, int y) const
{
return {this->left + x, this->top + y, this->right + x, this->bottom + y};
}
/**
* Copy Rect and set its width.
* @param width width in pixels for new Rect.
* @param end if set, set width at end of Rect, i.e. on right.
* @return the new resized Rect.
*/
[[nodiscard]] inline Rect WithWidth(int width, bool end) const
{
return end
? Rect {this->right - width + 1, this->top, this->right, this->bottom}
: Rect {this->left, this->top, this->left + width - 1, this->bottom};
}
/**
* Copy Rect and indent it from its position.
* @param indent offset in pixels for new Rect.
* @param end if set, set indent at end of Rect, i.e. on right.
* @return the new resized Rect.
*/
[[nodiscard]] inline Rect Indent(int indent, bool end) const
{
return end
? Rect {this->left, this->top, this->right - indent, this->bottom}
: Rect {this->left + indent, this->top, this->right, this->bottom};
}
/**
* Copy Rect and set its height.
* @param width height in pixels for new Rect.
* @param end if set, set height at end of Rect, i.e. at bottom.
* @return the new resized Rect.
*/
[[nodiscard]] inline Rect WithHeight(int height, bool end = false) const
{
return end
? Rect {this->left, this->bottom - height + 1, this->right, this->bottom}
: Rect {this->left, this->top, this->right, this->top + height - 1};
}
/**
* Test if a point falls inside this Rect.
* @param pt the point to test.
* @return true iif the point falls inside the Rect.
*/
inline bool Contains(const Point &pt) const
{
/* This is a local version of IsInsideMM, to avoid including math_func everywhere. */
return (uint)(pt.x - this->left) < (uint)(this->right - this->left) && (uint)(pt.y - this->top) < (uint)(this->bottom - this->top);
}
};
/**

View File

@@ -24,11 +24,14 @@
#include "tilehighlight_func.h"
#include "window_gui.h"
#include "vehiclelist.h"
#include "vehicle_func.h"
#include "order_backup.h"
#include "zoom_func.h"
#include "error.h"
#include "depot_cmd.h"
#include "train_cmd.h"
#include "vehicle_cmd.h"
#include "core/geometry_func.hpp"
#include "widgets/depot_widget.h"
@@ -190,17 +193,17 @@ static void InitBlocksizeForVehicles(VehicleType type, EngineImageType image_typ
if ((int)x + x_offs > max_extend_right) max_extend_right = x + x_offs;
}
int min_extend = ScaleGUITrad(16);
int max_extend = ScaleGUITrad(98);
int min_extend = ScaleSpriteTrad(16);
int max_extend = ScaleSpriteTrad(98);
switch (image_type) {
case EIT_IN_DEPOT:
_base_block_sizes_depot[type].height = std::max<uint>(ScaleGUITrad(GetVehicleHeight(type)), max_height);
_base_block_sizes_depot[type].height = std::max<uint>(ScaleSpriteTrad(GetVehicleHeight(type)), max_height);
_base_block_sizes_depot[type].extend_left = Clamp(max_extend_left, min_extend, max_extend);
_base_block_sizes_depot[type].extend_right = Clamp(max_extend_right, min_extend, max_extend);
break;
case EIT_PURCHASE:
_base_block_sizes_purchase[type].height = std::max<uint>(ScaleGUITrad(GetVehicleHeight(type)), max_height);
_base_block_sizes_purchase[type].height = std::max<uint>(ScaleSpriteTrad(GetVehicleHeight(type)), max_height);
_base_block_sizes_purchase[type].extend_left = Clamp(max_extend_left, min_extend, max_extend);
_base_block_sizes_purchase[type].extend_right = Clamp(max_extend_right, min_extend, max_extend);
break;
@@ -303,18 +306,15 @@ struct DepotWindow : Window {
/**
* Draw a vehicle in the depot window in the box with the top left corner at x,y.
* @param v Vehicle to draw.
* @param left Left side of the box to draw in.
* @param right Right side of the box to draw in.
* @param y Top of the box to draw in.
* @param r Rect to draw in.
*/
void DrawVehicleInDepot(const Vehicle *v, int left, int right, int y) const
void DrawVehicleInDepot(const Vehicle *v, const Rect &r) const
{
bool free_wagon = false;
int sprite_y = y + (this->resize.step_height - ScaleGUITrad(GetVehicleHeight(v->type))) / 2;
bool rtl = _current_text_dir == TD_RTL;
int image_left = rtl ? left + this->count_width : left + this->header_width;
int image_right = rtl ? right - this->header_width : right - this->count_width;
Rect text = r.Shrink(RectPadding::zero, WidgetDimensions::scaled.matrix); /* Ract for text elements, horizontal is already applied. */
Rect image = r.Indent(this->header_width, rtl).Indent(this->count_width, !rtl); /* Rect for vehicle images */
switch (v->type) {
case VEH_TRAIN: {
@@ -322,45 +322,45 @@ struct DepotWindow : Window {
free_wagon = u->IsFreeWagon();
uint x_space = free_wagon ?
ScaleGUITrad(_consistent_train_width != 0 ? _consistent_train_width : TRAININFO_DEFAULT_VEHICLE_WIDTH) :
ScaleSpriteTrad(_consistent_train_width != 0 ? _consistent_train_width : TRAININFO_DEFAULT_VEHICLE_WIDTH) :
0;
DrawTrainImage(u, image_left + (rtl ? 0 : x_space), image_right - (rtl ? x_space : 0), sprite_y - 1,
this->sel, EIT_IN_DEPOT, free_wagon ? 0 : this->hscroll->GetPosition(), this->vehicle_over);
DrawTrainImage(u, image.Indent(x_space, rtl), this->sel, EIT_IN_DEPOT, free_wagon ? 0 : this->hscroll->GetPosition(), this->vehicle_over);
/* Length of consist in tiles with 1 fractional digit (rounded up) */
SetDParam(0, CeilDiv(u->gcache.cached_total_length * 10, TILE_SIZE));
SetDParam(1, 1);
DrawString(rtl ? left + WD_FRAMERECT_LEFT : right - this->count_width, rtl ? left + this->count_width : right - WD_FRAMERECT_RIGHT, y + (this->resize.step_height - FONT_HEIGHT_SMALL) / 2, STR_TINY_BLACK_DECIMAL, TC_FROMSTRING, SA_RIGHT); // Draw the counter
Rect count = text.WithWidth(this->count_width - WidgetDimensions::scaled.hsep_normal, !rtl);
DrawString(count.left, count.right, count.bottom - FONT_HEIGHT_SMALL + 1, STR_TINY_BLACK_DECIMAL, TC_FROMSTRING, SA_RIGHT); // Draw the counter
break;
}
case VEH_ROAD: DrawRoadVehImage( v, image_left, image_right, sprite_y, this->sel, EIT_IN_DEPOT); break;
case VEH_SHIP: DrawShipImage( v, image_left, image_right, sprite_y, this->sel, EIT_IN_DEPOT); break;
case VEH_AIRCRAFT: DrawAircraftImage(v, image_left, image_right, sprite_y, this->sel, EIT_IN_DEPOT); break;
case VEH_ROAD: DrawRoadVehImage( v, image, this->sel, EIT_IN_DEPOT); break;
case VEH_SHIP: DrawShipImage( v, image, this->sel, EIT_IN_DEPOT); break;
case VEH_AIRCRAFT: DrawAircraftImage(v, image, this->sel, EIT_IN_DEPOT); break;
default: NOT_REACHED();
}
uint diff_x, diff_y;
if (v->IsGroundVehicle()) {
/* Arrange unitnumber and flag horizontally */
diff_x = this->flag_width + WD_FRAMERECT_LEFT;
diff_y = (this->resize.step_height - this->flag_height) / 2 - 2;
diff_x = this->flag_size.width + WidgetDimensions::scaled.hsep_normal;
diff_y = WidgetDimensions::scaled.matrix.top;
} else {
/* Arrange unitnumber and flag vertically */
diff_x = WD_FRAMERECT_LEFT;
diff_y = FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL;
diff_x = 0;
diff_y = WidgetDimensions::scaled.matrix.top + FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal;
}
int text_left = rtl ? right - this->header_width - 1 : left + diff_x;
int text_right = rtl ? right - diff_x : left + this->header_width - 1;
text = text.WithWidth(this->header_width - WidgetDimensions::scaled.hsep_normal, rtl).WithHeight(FONT_HEIGHT_NORMAL).Indent(diff_x, rtl);
if (free_wagon) {
DrawString(text_left, text_right, y + 2, STR_DEPOT_NO_ENGINE);
DrawString(text, STR_DEPOT_NO_ENGINE);
} else {
DrawSprite((v->vehstatus & VS_STOPPED) ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, PAL_NONE, rtl ? right - this->flag_width : left + WD_FRAMERECT_LEFT, y + diff_y);
Rect flag = r.WithWidth(this->flag_size.width, rtl).WithHeight(this->flag_size.height).Translate(0, diff_y);
DrawSpriteIgnorePadding((v->vehstatus & VS_STOPPED) ? SPR_FLAG_VEH_STOPPED : SPR_FLAG_VEH_RUNNING, PAL_NONE, flag, false, SA_CENTER);
SetDParam(0, v->unitnumber);
DrawString(text_left, text_right, y + 2, (uint16)(v->max_age - DAYS_IN_LEAP_YEAR) >= v->age ? STR_BLACK_COMMA : STR_RED_COMMA);
DrawString(text, (uint16)(v->max_age - DAYS_IN_LEAP_YEAR) >= v->age ? STR_BLACK_COMMA : STR_RED_COMMA);
}
}
@@ -373,24 +373,28 @@ struct DepotWindow : Window {
/* Set the row and number of boxes in each row based on the number of boxes drawn in the matrix */
const NWidgetCore *wid = this->GetWidget<NWidgetCore>(WID_D_MATRIX);
/* Set up rect for each cell */
Rect ir = r.WithHeight(this->resize.step_height);
if (this->num_columns != 1) ir = ir.WithWidth(this->resize.step_width, rtl);
ir = ir.Shrink(WidgetDimensions::scaled.framerect, RectPadding::zero);
/* Draw vertical separators at whole tiles.
* This only works in two cases:
* - All vehicles use VEHICLEINFO_FULL_VEHICLE_WIDTH as reference width.
* - All vehicles are 8/8. This cannot be checked for NewGRF, so instead we check for "all vehicles are original vehicles".
*/
if (this->type == VEH_TRAIN && _consistent_train_width != 0) {
int w = ScaleGUITrad(2 * _consistent_train_width);
int w = ScaleSpriteTrad(2 * _consistent_train_width);
int col = _colour_gradient[wid->colour][4];
int image_left = rtl ? r.left + this->count_width : r.left + this->header_width;
int image_right = rtl ? r.right - this->header_width : r.right - this->count_width;
Rect image = ir.Indent(this->header_width, rtl).Indent(this->count_width, !rtl);
int first_line = w + (-this->hscroll->GetPosition()) % w;
if (rtl) {
for (int x = image_right - first_line; x >= image_left; x -= w) {
GfxDrawLine(x, r.top, x, r.bottom, col, 1, 3);
for (int x = image.right - first_line; x >= image.left; x -= w) {
GfxDrawLine(x, r.top, x, r.bottom, col, ScaleGUITrad(1), ScaleGUITrad(3));
}
} else {
for (int x = image_left + first_line; x <= image_right; x += w) {
GfxDrawLine(x, r.top, x, r.bottom, col, 1, 3);
for (int x = image.left + first_line; x <= image.right; x += w) {
GfxDrawLine(x, r.top, x, r.bottom, col, ScaleGUITrad(1), ScaleGUITrad(3));
}
}
}
@@ -399,26 +403,22 @@ struct DepotWindow : Window {
uint num = this->vscroll->GetPosition() * this->num_columns;
uint maxval = static_cast<uint>(std::min<size_t>(this->vehicle_list.size(), num + (rows_in_display * this->num_columns)));
int y;
for (y = r.top + 1; num < maxval; y += this->resize.step_height) { // Draw the rows
for (; num < maxval; ir = ir.Translate(0, this->resize.step_height)) { // Draw the rows
Rect cell = ir; /* Keep track of horizontal cells */
for (uint i = 0; i < this->num_columns && num < maxval; i++, num++) {
/* Draw all vehicles in the current row */
const Vehicle *v = this->vehicle_list[num];
if (this->num_columns == 1) {
this->DrawVehicleInDepot(v, r.left, r.right, y);
} else {
int x = r.left + (rtl ? (this->num_columns - i - 1) : i) * this->resize.step_width;
this->DrawVehicleInDepot(v, x, x + this->resize.step_width - 1, y);
}
this->DrawVehicleInDepot(v, cell);
cell = cell.Translate(rtl ? -(int)this->resize.step_width : (int)this->resize.step_width, 0);
}
}
maxval = static_cast<uint>(std::min<size_t>(this->vehicle_list.size() + this->wagon_list.size(), (this->vscroll->GetPosition() * this->num_columns) + (rows_in_display * this->num_columns)));
/* Draw the train wagons without an engine in front. */
for (; num < maxval; num++, y += this->resize.step_height) {
for (; num < maxval; num++, ir = ir.Translate(0, this->resize.step_height)) {
const Vehicle *v = this->wagon_list[num - this->vehicle_list.size()];
this->DrawVehicleInDepot(v, r.left, r.right, y);
this->DrawVehicleInDepot(v, ir);
}
}
@@ -484,7 +484,7 @@ struct DepotWindow : Window {
pos -= (uint)this->vehicle_list.size();
*veh = this->wagon_list[pos];
/* free wagons don't have an initial loco. */
x -= ScaleGUITrad(VEHICLEINFO_FULL_VEHICLE_WIDTH);
x -= ScaleSpriteTrad(VEHICLEINFO_FULL_VEHICLE_WIDTH);
wagon = true;
}
@@ -501,12 +501,12 @@ struct DepotWindow : Window {
FALLTHROUGH;
case VEH_ROAD:
if (xm <= this->flag_width) return MODE_START_STOP;
if (xm <= this->flag_size.width) return MODE_START_STOP;
break;
case VEH_SHIP:
case VEH_AIRCRAFT:
if (xm <= this->flag_width && ym >= (uint)(FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL)) return MODE_START_STOP;
if (xm <= this->flag_size.width && ym >= (uint)(FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal)) return MODE_START_STOP;
break;
default: NOT_REACHED();
@@ -643,10 +643,16 @@ struct DepotWindow : Window {
}
}
uint count_width;
uint header_width;
uint flag_width;
uint flag_height;
uint count_width; ///< Width of length count, including separator.
uint header_width; ///< Width of unit number and flag, including separator.
Dimension flag_size; ///< Size of start/stop flag.
VehicleCellSize cell_size; ///< Vehicle sprite cell size.
void OnInit() override
{
this->cell_size = GetVehicleImageCellSize(this->type, EIT_IN_DEPOT);
this->flag_size = maxdim(GetScaledSpriteSize(SPR_FLAG_VEH_STOPPED), GetScaledSpriteSize(SPR_FLAG_VEH_RUNNING));
}
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
{
@@ -657,33 +663,30 @@ struct DepotWindow : Window {
if (this->type == VEH_TRAIN) {
SetDParamMaxValue(0, 1000, 0, FS_SMALL);
SetDParam(1, 1);
this->count_width = GetStringBoundingBox(STR_TINY_BLACK_DECIMAL).width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
this->count_width = GetStringBoundingBox(STR_TINY_BLACK_DECIMAL).width + WidgetDimensions::scaled.hsep_normal;
} else {
this->count_width = 0;
}
SetDParamMaxDigits(0, this->unitnumber_digits);
Dimension unumber = GetStringBoundingBox(STR_BLACK_COMMA);
const Sprite *spr = GetSprite(SPR_FLAG_VEH_STOPPED, ST_NORMAL);
this->flag_width = UnScaleGUI(spr->width) + WD_FRAMERECT_RIGHT;
this->flag_height = UnScaleGUI(spr->height);
if (this->type == VEH_TRAIN || this->type == VEH_ROAD) {
min_height = std::max<uint>(unumber.height + WD_MATRIX_TOP, UnScaleGUI(spr->height));
this->header_width = unumber.width + this->flag_width + WD_FRAMERECT_LEFT;
min_height = std::max<uint>(unumber.height, this->flag_size.height);
this->header_width = unumber.width + WidgetDimensions::scaled.hsep_normal + this->flag_size.width + WidgetDimensions::scaled.hsep_normal;
} else {
min_height = unumber.height + UnScaleGUI(spr->height) + WD_MATRIX_TOP + WD_PAR_VSEP_NORMAL + WD_MATRIX_BOTTOM;
this->header_width = std::max<uint>(unumber.width, this->flag_width) + WD_FRAMERECT_RIGHT;
min_height = unumber.height + WidgetDimensions::scaled.vsep_normal + this->flag_size.height;
this->header_width = std::max<uint>(unumber.width, this->flag_size.width) + WidgetDimensions::scaled.hsep_normal;
}
int base_width = this->count_width + this->header_width;
int base_width = this->count_width + this->header_width + padding.width;
resize->height = std::max<uint>(GetVehicleImageCellSize(this->type, EIT_IN_DEPOT).height, min_height);
resize->height = std::max<uint>(this->cell_size.height, min_height + padding.height);
if (this->type == VEH_TRAIN) {
resize->width = 1;
size->width = base_width + 2 * ScaleGUITrad(29); // about 2 parts
size->width = base_width + 2 * ScaleSpriteTrad(29); // about 2 parts
size->height = resize->height * 6;
} else {
resize->width = base_width + GetVehicleImageCellSize(this->type, EIT_IN_DEPOT).extend_left + GetVehicleImageCellSize(this->type, EIT_IN_DEPOT).extend_right;
resize->width = base_width + this->cell_size.extend_left + this->cell_size.extend_right;
size->width = resize->width * (this->type == VEH_ROAD ? 5 : 3);
size->height = resize->height * (this->type == VEH_ROAD ? 5 : 3);
}
@@ -723,7 +726,7 @@ struct DepotWindow : Window {
/* determine amount of items for scroller */
if (this->type == VEH_TRAIN) {
uint max_width = ScaleGUITrad(VEHICLEINFO_FULL_VEHICLE_WIDTH);
uint max_width = ScaleSpriteTrad(VEHICLEINFO_FULL_VEHICLE_WIDTH);
for (uint num = 0; num < this->vehicle_list.size(); num++) {
uint width = 0;
for (const Train *v = Train::From(this->vehicle_list[num]); v != nullptr; v = v->Next()) {
@@ -734,7 +737,7 @@ struct DepotWindow : Window {
/* Always have 1 empty row, so people can change the setting of the train */
this->vscroll->SetCount((uint)this->vehicle_list.size() + (uint)this->wagon_list.size() + 1);
/* Always make it longer than the longest train, so you can attach vehicles at the end, and also see the next vertical tile separator line */
this->hscroll->SetCount(max_width + ScaleGUITrad(2 * VEHICLEINFO_FULL_VEHICLE_WIDTH + 1));
this->hscroll->SetCount(max_width + ScaleSpriteTrad(2 * VEHICLEINFO_FULL_VEHICLE_WIDTH + 1));
} else {
this->vscroll->SetCount(CeilDiv((uint)this->vehicle_list.size(), this->num_columns));
}
@@ -916,6 +919,49 @@ struct DepotWindow : Window {
return true;
}
/**
* Clones a vehicle from a vehicle list. If this doesn't make sense (because not all vehicles in the list have the same orders), then it displays an error.
* @return This always returns true, which indicates that the contextual action handled the mouse click.
* Note that it's correct behaviour to always handle the click even though an error is displayed,
* because users aren't going to expect the default action to be performed just because they overlooked that cloning doesn't make sense.
*/
bool OnVehicleSelect(VehicleList::const_iterator begin, VehicleList::const_iterator end) override
{
if (!_ctrl_pressed) {
/* If CTRL is not pressed: If all the vehicles in this list have the same orders, then copy orders */
if (AllEqual(begin, end, [](const Vehicle *v1, const Vehicle *v2) {
return VehiclesHaveSameEngineList(v1, v2);
})) {
if (AllEqual(begin, end, [](const Vehicle *v1, const Vehicle *v2) {
return VehiclesHaveSameOrderList(v1, v2);
})) {
OnVehicleSelect(*begin);
} else {
ShowErrorMessage(STR_ERROR_CAN_T_BUY_TRAIN + (*begin)->type, STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST, WL_INFO);
}
} else {
ShowErrorMessage(STR_ERROR_CAN_T_BUY_TRAIN + (*begin)->type, STR_ERROR_CAN_T_CLONE_VEHICLE_LIST, WL_INFO);
}
} else {
/* If CTRL is pressed: If all the vehicles in this list share orders, then copy orders */
if (AllEqual(begin, end, [](const Vehicle *v1, const Vehicle *v2) {
return VehiclesHaveSameEngineList(v1, v2);
})) {
if (AllEqual(begin, end, [](const Vehicle *v1, const Vehicle *v2) {
return v1->FirstShared() == v2->FirstShared();
})) {
OnVehicleSelect(*begin);
} else {
ShowErrorMessage(STR_ERROR_CAN_T_BUY_TRAIN + (*begin)->type, STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST, WL_INFO);
}
} else {
ShowErrorMessage(STR_ERROR_CAN_T_BUY_TRAIN + (*begin)->type, STR_ERROR_CAN_T_CLONE_VEHICLE_LIST, WL_INFO);
}
}
return true;
}
void OnPlaceObjectAbort() override
{
/* abort clone */

View File

@@ -192,7 +192,7 @@ struct BuildDocksToolbarWindow : Window {
{
switch (this->last_clicked_widget) {
case WID_DT_CANAL: // Build canal button
VpStartPlaceSizing(tile, (_game_mode == GM_EDITOR) ? VPM_X_AND_Y : VPM_X_OR_Y, DDSP_CREATE_WATER);
VpStartPlaceSizing(tile, VPM_X_AND_Y, DDSP_CREATE_WATER);
break;
case WID_DT_LOCK: // Build lock button
@@ -447,9 +447,9 @@ public:
/* strings such as 'Size' and 'Coverage Area' */
Rect r = this->GetWidget<NWidgetBase>(BDSW_ACCEPTANCE)->GetCurrentRect();
int top = r.top + ScaleGUITrad(WD_PAR_VSEP_NORMAL);
top = DrawStationCoverageAreaText(r.left, r.right, top, SCT_ALL, rad, false) + ScaleGUITrad(WD_PAR_VSEP_NORMAL);
top = DrawStationCoverageAreaText(r.left, r.right, top, SCT_ALL, rad, true) + ScaleGUITrad(WD_PAR_VSEP_NORMAL);
int top = r.top + WidgetDimensions::scaled.vsep_normal;
top = DrawStationCoverageAreaText(r.left, r.right, top, SCT_ALL, rad, false) + WidgetDimensions::scaled.vsep_normal;
top = DrawStationCoverageAreaText(r.left, r.right, top, SCT_ALL, rad, true) + WidgetDimensions::scaled.vsep_normal;
/* Resize background if the window is too small.
* Never make the window smaller to avoid oscillating if the size change affects the acceptance.
* (This is the case, if making the window bigger moves the mouse into the window.) */
@@ -486,12 +486,12 @@ static const NWidgetPart _nested_build_dock_station_widgets[] = {
NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_STATION_BUILD_DOCK_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_DARK_GREEN, BDSW_BACKGROUND),
NWidget(WWT_LABEL, COLOUR_DARK_GREEN, BDSW_INFO), SetPadding(WD_FRAMERECT_TOP, WD_FRAMERECT_RIGHT, WD_FRAMERECT_BOTTOM, WD_FRAMERECT_LEFT), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL), SetFill(1, 0),
NWidget(WWT_LABEL, COLOUR_DARK_GREEN, BDSW_INFO), SetPadding(WidgetDimensions::unscaled.framerect), SetDataTip(STR_STATION_BUILD_COVERAGE_AREA_TITLE, STR_NULL), SetFill(1, 0),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(14, 0, 14),
NWidget(WWT_TEXTBTN, COLOUR_GREY, BDSW_LT_OFF), SetMinimalSize(60, 12), SetFill(1, 0), SetDataTip(STR_STATION_BUILD_COVERAGE_OFF, STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP),
NWidget(WWT_TEXTBTN, COLOUR_GREY, BDSW_LT_ON), SetMinimalSize(60, 12), SetFill(1, 0), SetDataTip(STR_STATION_BUILD_COVERAGE_ON, STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP),
EndContainer(),
NWidget(WWT_EMPTY, COLOUR_GREY, BDSW_ACCEPTANCE), SetPadding(0, WD_FRAMERECT_RIGHT, 0, WD_FRAMERECT_LEFT), SetResize(0, 1),
NWidget(WWT_EMPTY, COLOUR_GREY, BDSW_ACCEPTANCE), SetPadding(WidgetDimensions::unscaled.framerect), SetResize(0, 1),
EndContainer(),
};
@@ -531,25 +531,35 @@ public:
switch (widget) {
case WID_BDD_X:
case WID_BDD_Y:
size->width = ScaleGUITrad(96) + 2;
size->height = ScaleGUITrad(64) + 2;
size->width = ScaleGUITrad(96) + WidgetDimensions::scaled.fullbevel.Horizontal();
size->height = ScaleGUITrad(64) + WidgetDimensions::scaled.fullbevel.Vertical();
break;
}
}
void OnPaint() override
void DrawWidget(const Rect &r, int widget) const override
{
this->DrawWidgets();
DrawPixelInfo tmp_dpi;
int x1 = ScaleGUITrad(63) + 1;
int x2 = ScaleGUITrad(31) + 1;
int y1 = ScaleGUITrad(17) + 1;
int y2 = ScaleGUITrad(33) + 1;
switch (widget) {
case WID_BDD_X:
case WID_BDD_Y: {
Axis axis = widget == WID_BDD_X ? AXIS_X : AXIS_Y;
DrawShipDepotSprite(this->GetWidget<NWidgetBase>(WID_BDD_X)->pos_x + x1, this->GetWidget<NWidgetBase>(WID_BDD_X)->pos_y + y1, AXIS_X, DEPOT_PART_NORTH);
DrawShipDepotSprite(this->GetWidget<NWidgetBase>(WID_BDD_X)->pos_x + x2, this->GetWidget<NWidgetBase>(WID_BDD_X)->pos_y + y2, AXIS_X, DEPOT_PART_SOUTH);
DrawShipDepotSprite(this->GetWidget<NWidgetBase>(WID_BDD_Y)->pos_x + x2, this->GetWidget<NWidgetBase>(WID_BDD_Y)->pos_y + y1, AXIS_Y, DEPOT_PART_NORTH);
DrawShipDepotSprite(this->GetWidget<NWidgetBase>(WID_BDD_Y)->pos_x + x1, this->GetWidget<NWidgetBase>(WID_BDD_Y)->pos_y + y2, AXIS_Y, DEPOT_PART_SOUTH);
if (FillDrawPixelInfo(&tmp_dpi, r.left, r.top, r.Width(), r.Height())) {
DrawPixelInfo *old_dpi = _cur_dpi;
_cur_dpi = &tmp_dpi;
int x = (r.Width() - ScaleSpriteTrad(96)) / 2;
int y = (r.Height() - ScaleSpriteTrad(64)) / 2;
int x1 = ScaleSpriteTrad(63);
int x2 = ScaleSpriteTrad(31);
DrawShipDepotSprite(x + (axis == AXIS_X ? x1 : x2), y + ScaleSpriteTrad(17), axis, DEPOT_PART_NORTH);
DrawShipDepotSprite(x + (axis == AXIS_X ? x2 : x1), y + ScaleSpriteTrad(33), axis, DEPOT_PART_SOUTH);
_cur_dpi = old_dpi;
}
break;
}
}
}
void OnClick(Point pt, int widget, int click_count) override
@@ -574,17 +584,14 @@ static const NWidgetPart _nested_build_docks_depot_widgets[] = {
NWidget(WWT_CAPTION, COLOUR_DARK_GREEN), SetDataTip(STR_DEPOT_BUILD_SHIP_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_DARK_GREEN, WID_BDD_BACKGROUND),
NWidget(NWID_SPACER), SetMinimalSize(0, 3),
NWidget(NWID_HORIZONTAL_LTR),
NWidget(NWID_SPACER), SetMinimalSize(3, 0),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BDD_X), SetMinimalSize(98, 66), SetDataTip(0x0, STR_DEPOT_BUILD_SHIP_ORIENTATION_TOOLTIP),
NWidget(NWID_HORIZONTAL), SetPadding(3),
NWidget(NWID_SPACER), SetFill(1, 0),
NWidget(NWID_HORIZONTAL_LTR), SetPIP(0, 2, 0),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BDD_X), SetMinimalSize(98, 66), SetDataTip(0x0, STR_DEPOT_BUILD_SHIP_ORIENTATION_TOOLTIP), EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BDD_Y), SetMinimalSize(98, 66), SetDataTip(0x0, STR_DEPOT_BUILD_SHIP_ORIENTATION_TOOLTIP), EndContainer(),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(2, 0),
NWidget(WWT_PANEL, COLOUR_GREY, WID_BDD_Y), SetMinimalSize(98, 66), SetDataTip(0x0, STR_DEPOT_BUILD_SHIP_ORIENTATION_TOOLTIP),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(3, 0),
NWidget(NWID_SPACER), SetFill(1, 0),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 3),
EndContainer(),
};

View File

@@ -103,6 +103,8 @@ Economy _economy;
Prices _price;
static PriceMultipliers _price_base_multiplier;
extern int GetAmountOwnedBy(const Company *c, Owner owner);
/**
* Calculate the value of the company. That is the value of all
* assets (vehicles, stations, shares) and money minus the loan,
@@ -117,18 +119,12 @@ Money CalculateCompanyValue(const Company *c, bool including_loan)
Money owned_shares_value = 0;
for (const Company *co : Company::Iterate()) {
uint8 shares_owned = 0;
int shares_owned = GetAmountOwnedBy(co, c->index);
for (uint8 i = 0; i < 4; i++) {
if (co->share_owners[i] == c->index) {
shares_owned++;
}
}
owned_shares_value += (CalculateCompanyValueExcludingShares(co) / 4) * shares_owned;
if (shares_owned > 0) owned_shares_value += (CalculateCompanyValueExcludingShares(co) / 4) * shares_owned;
}
return std::max<Money>(owned_shares_value + CalculateCompanyValueExcludingShares(c), 1);
return owned_shares_value + CalculateCompanyValueExcludingShares(c);
}
Money CalculateCompanyValueExcludingShares(const Company *c, bool including_loan)
@@ -2030,8 +2026,6 @@ static void DoAcquireCompany(Company *c)
delete c;
}
extern int GetAmountOwnedBy(const Company *c, Owner owner);
/**
* Acquire shares in an opposing company.
* @param flags type of operation

View File

@@ -485,10 +485,11 @@ static void DrawRailCatenaryRailway(const TileInfo *ti)
/*
* The "wire"-sprite position is inside the tile, i.e. 0 <= sss->?_offset < TILE_SIZE.
* Therefore it is safe to use GetSlopePixelZ() for the elevation.
* Also note that the result of GetSlopePixelZ() is very special for bridge-ramps.
* Also note that the result of GetSlopePixelZ() is very special for bridge-ramps, so we round the result up or
* down to the nearest full height change.
*/
AddSortableSpriteToDraw(wire_base + sss->image_offset, PAL_NONE, ti->x + sss->x_offset, ti->y + sss->y_offset,
sss->x_size, sss->y_size, sss->z_size, GetSlopePixelZ(ti->x + sss->x_offset, ti->y + sss->y_offset) + sss->z_offset,
sss->x_size, sss->y_size, sss->z_size, (GetSlopePixelZ(ti->x + sss->x_offset, ti->y + sss->y_offset) + 4) / 8 * 8 + sss->z_offset,
IsTransparencySet(TO_CATENARY));
}
}

View File

@@ -73,6 +73,7 @@ Engine::Engine(VehicleType type, EngineID base)
this->grf_prop.local_id = base;
this->list_position = base;
this->preview_company = INVALID_COMPANY;
this->display_last_variant = INVALID_ENGINE;
/* Check if this base engine is within the original engine data range */
if (base >= _engine_counts[type]) {
@@ -93,6 +94,8 @@ Engine::Engine(VehicleType type, EngineID base)
}
/* Set cargo aging period to the default value. */
this->info.cargo_age_period = CARGO_AGING_TICKS;
/* Not a variant */
this->info.variant_id = INVALID_ENGINE;
return;
}
@@ -535,7 +538,7 @@ void SetupEngines()
_engine_pool.CleanPool();
assert(_engine_mngr.size() >= _engine_mngr.NUM_DEFAULT_ENGINES);
uint index = 0;
[[maybe_unused]] uint index = 0;
for (const EngineIDMapping &eid : _engine_mngr) {
/* Assert is safe; there won't be more than 256 original vehicles
* in any case, and we just cleaned the pool. */
@@ -559,13 +562,32 @@ static bool IsWagon(EngineID index)
return e->type == VEH_TRAIN && e->u.rail.railveh_type == RAILVEH_WAGON;
}
/**
* Ensure engine is not set as the last used variant for any other engine.
* @param engine_id Engine being removed.
* @param type Type of engine.
*/
static void ClearLastVariant(EngineID engine_id, VehicleType type)
{
for (Engine *e : Engine::IterateType(type)) {
if (e->display_last_variant == engine_id) e->display_last_variant = INVALID_ENGINE;
}
}
/**
* Update #Engine::reliability and (if needed) update the engine GUIs.
* @param e %Engine to update.
*/
static void CalcEngineReliability(Engine *e)
void CalcEngineReliability(Engine *e, bool new_month)
{
uint age = e->age;
/* Get source engine for reliability age. This is normally our engine unless variant reliability syncing is requested. */
Engine *re = e;
while (re->info.variant_id != INVALID_ENGINE && re->info.variant_id != re->index && (re->info.extra_flags & ExtraEngineFlags::SyncReliability) != ExtraEngineFlags::None) {
re = Engine::Get(re->info.variant_id);
}
uint age = re->age;
if (new_month && re->index > e->index && age != MAX_DAY) age++; /* parent variant's age has not yet updated. */
/* Check for early retirement */
if (e->company_avail != 0 && !_settings_game.vehicle.never_expire_vehicles && e->info.base_life != 0xFF) {
@@ -574,6 +596,7 @@ static void CalcEngineReliability(Engine *e)
if (retire_early != 0 && age >= retire_early_max_age) {
/* Early retirement is enabled and we're past the date... */
e->company_avail = 0;
ClearLastVariant(e->index, e->type);
AddRemoveEngineFromAutoreplaceAndBuildWindows(e->type);
}
}
@@ -594,10 +617,10 @@ static void CalcEngineReliability(Engine *e)
e->company_avail = 0;
e->reliability = e->reliability_final;
/* Kick this engine out of the lists */
ClearLastVariant(e->index, e->type);
AddRemoveEngineFromAutoreplaceAndBuildWindows(e->type);
}
SetWindowClassesDirty(WC_BUILD_VEHICLE); // Update to show the new reliability
SetWindowClassesDirty(WC_REPLACE_VEHICLE);
}
/** Compute the value for #_year_engine_aging_stops. */
@@ -625,8 +648,9 @@ void SetYearEngineAgingStops()
* Start/initialise one engine.
* @param e The engine to initialise.
* @param aging_date The date used for age calculations.
* @param seed Random seed.
*/
void StartupOneEngine(Engine *e, Date aging_date)
void StartupOneEngine(Engine *e, Date aging_date, uint32 seed)
{
const EngineInfo *ei = &e->info;
@@ -639,7 +663,7 @@ void StartupOneEngine(Engine *e, Date aging_date)
* Make sure they use the same randomisation of the date. */
SavedRandomSeeds saved_seeds;
SaveRandomSeeds(&saved_seeds);
SetRandomSeed(_settings_game.game_creation.generation_seed ^
SetRandomSeed(_settings_game.game_creation.generation_seed ^ seed ^
ei->base_intro ^
e->type ^
e->GetGRFID());
@@ -655,7 +679,17 @@ void StartupOneEngine(Engine *e, Date aging_date)
e->flags |= ENGINE_AVAILABLE;
}
RestoreRandomSeeds(saved_seeds);
/* Get parent variant index for syncing reliability via random seed. */
const Engine *re = e;
while (re->info.variant_id != INVALID_ENGINE && re->info.variant_id != re->index && (re->info.extra_flags & ExtraEngineFlags::SyncReliability) != ExtraEngineFlags::None) {
re = Engine::Get(re->info.variant_id);
}
SetRandomSeed(_settings_game.game_creation.generation_seed ^ seed ^
(re->index << 16) ^ (re->info.base_intro << 12) ^ (re->info.decay_speed << 8) ^
(re->info.lifelength << 4) ^ re->info.retire_early ^
e->type ^
e->GetGRFID());
r = Random();
e->reliability_start = GB(r, 16, 14) + 0x7AE0;
@@ -667,9 +701,9 @@ void StartupOneEngine(Engine *e, Date aging_date)
e->duration_phase_2 = GB(r, 5, 4) + ei->base_life * 12 - 96;
e->duration_phase_3 = GB(r, 9, 7) + 120;
e->reliability_spd_dec = ei->decay_speed << 2;
RestoreRandomSeeds(saved_seeds);
CalcEngineReliability(e);
e->reliability_spd_dec = ei->decay_speed << 2;
/* prevent certain engines from ever appearing. */
if (!HasBit(ei->climates, _settings_game.game_creation.landscape)) {
@@ -686,9 +720,13 @@ void StartupEngines()
{
/* Aging of vehicles stops, so account for that when starting late */
const Date aging_date = std::min(_date, ConvertYMDToDate(_year_engine_aging_stops, 0, 1));
uint32 seed = Random();
for (Engine *e : Engine::Iterate()) {
StartupOneEngine(e, aging_date);
StartupOneEngine(e, aging_date, seed);
}
for (Engine *e : Engine::Iterate()) {
CalcEngineReliability(e, false);
}
/* Update the bitmasks for the vehicle lists */
@@ -699,6 +737,9 @@ void StartupEngines()
/* Invalidate any open purchase lists */
InvalidateWindowClassesData(WC_BUILD_VEHICLE);
SetWindowClassesDirty(WC_BUILD_VEHICLE);
SetWindowClassesDirty(WC_REPLACE_VEHICLE);
}
/**
@@ -747,6 +788,7 @@ static void DisableEngineForCompany(EngineID eid, CompanyID company)
}
if (company == _local_company) {
ClearLastVariant(e->index, e->type);
AddRemoveEngineFromAutoreplaceAndBuildWindows(e->type);
}
}
@@ -755,8 +797,9 @@ static void DisableEngineForCompany(EngineID eid, CompanyID company)
* Company \a company accepts engine \a eid for preview.
* @param eid Engine being accepted (is under preview).
* @param company Current company previewing the engine.
* @param recursion_depth Recursion depth to avoid infinite loop.
*/
static void AcceptEnginePreview(EngineID eid, CompanyID company)
static void AcceptEnginePreview(EngineID eid, CompanyID company, int recursion_depth = 0)
{
Engine *e = Engine::Get(eid);
@@ -771,6 +814,16 @@ static void AcceptEnginePreview(EngineID eid, CompanyID company)
* we have to use the GUI-scope scheduling of InvalidateWindowData.
*/
InvalidateWindowData(WC_ENGINE_PREVIEW, eid);
/* Don't search for variants to include if we are 10 levels deep already. */
if (recursion_depth >= 10) return;
/* Find variants to be included in preview. */
for (Engine *ve : Engine::IterateType(e->type)) {
if (ve->index != eid && ve->info.variant_id == eid && (ve->info.extra_flags & ExtraEngineFlags::JoinPreview) != ExtraEngineFlags::None) {
AcceptEnginePreview(ve->index, company, recursion_depth + 1);
}
}
}
/**
@@ -994,7 +1047,7 @@ static void NewVehicleAvailable(Engine *e)
if (!IsVehicleTypeDisabled(e->type, true)) AI::BroadcastNewEvent(new ScriptEventEngineAvailable(index));
/* Only provide the "New Vehicle available" news paper entry, if engine can be built. */
if (!IsVehicleTypeDisabled(e->type, false)) {
if (!IsVehicleTypeDisabled(e->type, false) && (e->info.extra_flags & ExtraEngineFlags::NoNews) == ExtraEngineFlags::None) {
SetDParam(0, GetEngineCategoryName(index));
SetDParam(1, index);
AddNewsItem(STR_NEWS_NEW_VEHICLE_NOW_AVAILABLE_WITH_TYPE, NT_NEW_VEHICLES, NF_VEHICLE, NR_ENGINE, index);
@@ -1013,11 +1066,13 @@ static void NewVehicleAvailable(Engine *e)
void EnginesMonthlyLoop()
{
if (_cur_year < _year_engine_aging_stops) {
bool refresh = false;
for (Engine *e : Engine::Iterate()) {
/* Age the vehicle */
if ((e->flags & ENGINE_AVAILABLE) && e->age != MAX_DAY) {
e->age++;
CalcEngineReliability(e);
CalcEngineReliability(e, true);
refresh = true;
}
/* Do not introduce invalid engines */
@@ -1036,6 +1091,9 @@ void EnginesMonthlyLoop()
/* Do not introduce new rail wagons */
if (IsWagon(e->index)) continue;
/* Engine has no preview */
if ((e->info.extra_flags & ExtraEngineFlags::NoPreview) != ExtraEngineFlags::None) continue;
/* Show preview dialog to one of the companies. */
e->flags |= ENGINE_EXCLUSIVE_PREVIEW;
e->preview_company = INVALID_COMPANY;
@@ -1044,6 +1102,11 @@ void EnginesMonthlyLoop()
}
InvalidateWindowClassesData(WC_BUILD_VEHICLE); // rebuild the purchase list (esp. when sorted by reliability)
if (refresh) {
SetWindowClassesDirty(WC_BUILD_VEHICLE);
SetWindowClassesDirty(WC_REPLACE_VEHICLE);
}
}
}

View File

@@ -21,6 +21,15 @@ struct WagonOverride {
const SpriteGroup *group;
};
/** Flags used client-side in the purchase/autorenew engine list. */
enum class EngineDisplayFlags : byte {
None = 0, ///< No flag set.
HasVariants = (1U << 0), ///< Set if engine has variants.
IsFolded = (1U << 1), ///< Set if display of variants should be folded (hidden).
Shaded = (1U << 2), ///< Set if engine should be masked.
};
DECLARE_ENUM_AS_BIT_SET(EngineDisplayFlags)
typedef Pool<Engine, EngineID, 64, 64000> EnginePool;
extern EnginePool _engine_pool;
@@ -45,6 +54,9 @@ struct Engine : EnginePool::PoolItem<&_engine_pool> {
uint8 original_image_index; ///< Original vehicle image index, thus the image index of the overridden vehicle
VehicleType type; ///< %Vehicle type, ie #VEH_ROAD, #VEH_TRAIN, etc.
EngineDisplayFlags display_flags; ///< NOSAVE client-side-only display flags for build engine list.
EngineID display_last_variant; ///< NOSAVE client-side-only last variant selected.
EngineInfo info;
union {

View File

@@ -26,7 +26,8 @@ bool IsEngineBuildable(EngineID engine, VehicleType type, CompanyID company);
bool IsEngineRefittable(EngineID engine);
void GetArticulatedVehicleCargoesAndRefits(EngineID engine, CargoArray *cargoes, CargoTypes *refits, CargoID cargo_type, uint cargo_capacity);
void SetYearEngineAgingStops();
void StartupOneEngine(Engine *e, Date aging_date);
void CalcEngineReliability(Engine *e, bool new_month);
void StartupOneEngine(Engine *e, Date aging_date, uint32 seed);
uint GetTotalCapacityOfArticulatedParts(EngineID engine);

View File

@@ -24,6 +24,7 @@
#include "ship.h"
#include "aircraft.h"
#include "engine_cmd.h"
#include "zoom_func.h"
#include "widgets/engine_widget.h"
@@ -94,11 +95,11 @@ struct EnginePreviewWindow : Window {
case VEH_SHIP: GetShipSpriteSize( engine, x, y, x_offs, y_offs, image_type); break;
case VEH_AIRCRAFT: GetAircraftSpriteSize(engine, x, y, x_offs, y_offs, image_type); break;
}
this->vehicle_space = std::max<int>(40, y - y_offs);
this->vehicle_space = std::max<int>(ScaleSpriteTrad(40), y - y_offs);
size->width = std::max(size->width, x - x_offs);
SetDParam(0, GetEngineCategoryName(engine));
size->height = GetStringHeight(STR_ENGINE_PREVIEW_MESSAGE, size->width) + WD_PAR_VSEP_WIDE + FONT_HEIGHT_NORMAL + this->vehicle_space;
size->height = GetStringHeight(STR_ENGINE_PREVIEW_MESSAGE, size->width) + WidgetDimensions::scaled.vsep_wide + FONT_HEIGHT_NORMAL + this->vehicle_space;
SetDParam(0, engine);
size->height += GetStringHeight(GetEngineInfoString(engine), size->width);
}
@@ -109,17 +110,16 @@ struct EnginePreviewWindow : Window {
EngineID engine = this->window_number;
SetDParam(0, GetEngineCategoryName(engine));
int y = r.top + GetStringHeight(STR_ENGINE_PREVIEW_MESSAGE, r.right - r.left + 1);
y = DrawStringMultiLine(r.left, r.right, r.top, y, STR_ENGINE_PREVIEW_MESSAGE, TC_FROMSTRING, SA_CENTER) + WD_PAR_VSEP_WIDE;
int y = DrawStringMultiLine(r, STR_ENGINE_PREVIEW_MESSAGE, TC_FROMSTRING, SA_HOR_CENTER | SA_TOP) + WidgetDimensions::scaled.vsep_wide;
SetDParam(0, engine);
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_ENGINE_NAME, TC_BLACK, SA_HOR_CENTER);
DrawString(r.left, r.right, y, STR_ENGINE_NAME, TC_BLACK, SA_HOR_CENTER);
y += FONT_HEIGHT_NORMAL;
DrawVehicleEngine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, this->width >> 1, y + this->vehicle_space / 2, engine, GetEnginePalette(engine, _local_company), EIT_PREVIEW);
DrawVehicleEngine(r.left, r.right, this->width >> 1, y + this->vehicle_space / 2, engine, GetEnginePalette(engine, _local_company), EIT_PREVIEW);
y += this->vehicle_space;
DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, r.bottom, GetEngineInfoString(engine), TC_FROMSTRING, SA_CENTER);
DrawStringMultiLine(r.left, r.right, y, r.bottom, GetEngineInfoString(engine), TC_FROMSTRING, SA_CENTER);
}
void OnClick(Point pt, int widget, int click_count) override

View File

@@ -14,10 +14,23 @@
#include "sortlist_type.h"
#include "gfx_type.h"
#include "vehicle_type.h"
#include "engine_base.h"
typedef GUIList<EngineID, CargoID> GUIEngineList;
struct GUIEngineListItem {
EngineID engine_id; ///< Engine to display in build purchase list
EngineID variant_id; ///< Variant group of the engine.
EngineDisplayFlags flags; ///< Flags for toggling/drawing (un)folded status and controlling indentation.
int8 indent; ///< Display indentation level.
typedef bool EngList_SortTypeFunction(const EngineID&, const EngineID&); ///< argument type for #EngList_Sort.
GUIEngineListItem(EngineID engine_id, EngineID variant_id, EngineDisplayFlags flags, int indent) : engine_id(engine_id), variant_id(variant_id), flags(flags), indent(indent) {}
/* Used when searching list only by engine_id. */
bool operator == (const EngineID &other) const { return this->engine_id == other; }
};
typedef GUIList<GUIEngineListItem, CargoID> GUIEngineList;
typedef bool EngList_SortTypeFunction(const GUIEngineListItem&, const GUIEngineListItem&); ///< argument type for #EngList_Sort.
void EngList_Sort(GUIEngineList *el, EngList_SortTypeFunction compare);
void EngList_SortPartial(GUIEngineList *el, EngList_SortTypeFunction compare, uint begin, uint num_items);

View File

@@ -126,6 +126,15 @@ struct RoadVehicleInfo {
RoadType roadtype; ///< Road type
};
enum class ExtraEngineFlags : uint32 {
None = 0,
NoNews = (1U << 0), ///< No 'new vehicle' news will be generated.
NoPreview = (1U << 1), ///< No exclusive preview will be offered.
JoinPreview = (1U << 2), ///< Engine will join exclusive preview with variant parent.
SyncReliability = (1U << 3), ///< Engine reliability will be synced with variant parent.
};
DECLARE_ENUM_AS_BIT_SET(ExtraEngineFlags);
/**
* Information about a vehicle
* @see table/engines.h
@@ -145,6 +154,8 @@ struct EngineInfo {
int8 retire_early; ///< Number of years early to retire vehicle
StringID string_id; ///< Default name of engine
uint16 cargo_age_period; ///< Number of ticks before carried cargo is aged.
EngineID variant_id; ///< Engine variant ID. If set, will be treated specially in purchase lists.
ExtraEngineFlags extra_flags;
};
/**
@@ -155,7 +166,7 @@ enum EngineMiscFlags {
EF_ROAD_TRAM = 0, ///< Road vehicle is a tram/light rail vehicle
EF_USES_2CC = 1, ///< Vehicle uses two company colours
EF_RAIL_IS_MU = 2, ///< Rail vehicle is a multiple-unit (DMU/EMU)
EF_RAIL_FLIPS = 3, ///< Rail vehicle can be flipped in the depot
EF_RAIL_FLIPS = 3, ///< Rail vehicle has old depot-flip handling
EF_AUTO_REFIT = 4, ///< Automatic refitting is allowed
EF_NO_DEFAULT_CARGO_MULTIPLIER = 5, ///< Use the new capacity algorithm. The default cargotype of the vehicle does not affect capacity multipliers. CB 15 is also called in purchase list.
EF_NO_BREAKDOWN_SMOKE = 6, ///< Do not show black smoke during a breakdown.

View File

@@ -35,7 +35,7 @@ static const NWidgetPart _nested_errmsg_widgets[] = {
NWidget(WWT_CAPTION, COLOUR_RED, WID_EM_CAPTION), SetDataTip(STR_ERROR_MESSAGE_CAPTION, STR_NULL),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_RED),
NWidget(WWT_EMPTY, COLOUR_RED, WID_EM_MESSAGE), SetPadding(0, 2, 0, 2), SetMinimalSize(236, 32),
NWidget(WWT_EMPTY, COLOUR_RED, WID_EM_MESSAGE), SetPadding(WidgetDimensions::unscaled.modalpopup), SetFill(1, 0), SetMinimalSize(236, 0),
EndContainer(),
};
@@ -52,9 +52,9 @@ static const NWidgetPart _nested_errmsg_face_widgets[] = {
NWidget(WWT_CAPTION, COLOUR_RED, WID_EM_CAPTION), SetDataTip(STR_ERROR_MESSAGE_CAPTION_OTHER_COMPANY, STR_NULL),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_RED),
NWidget(NWID_HORIZONTAL), SetPIP(2, 1, 2),
NWidget(WWT_EMPTY, COLOUR_RED, WID_EM_FACE), SetMinimalSize(92, 119), SetFill(0, 1), SetPadding(2, 0, 1, 0),
NWidget(WWT_EMPTY, COLOUR_RED, WID_EM_MESSAGE), SetFill(0, 1), SetMinimalSize(238, 123),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_EMPTY, COLOUR_RED, WID_EM_FACE), SetPadding(2, 0, 2, 2), SetFill(0, 1), SetMinimalSize(92, 119),
NWidget(WWT_EMPTY, COLOUR_RED, WID_EM_MESSAGE), SetPadding(WidgetDimensions::unscaled.modalpopup), SetFill(1, 1), SetMinimalSize(236, 0),
EndContainer(),
EndContainer(),
};
@@ -200,14 +200,13 @@ public:
CopyInDParam(0, this->decode_params, lengthof(this->decode_params));
if (this->textref_stack_size > 0) StartTextRefStackUsage(this->textref_stack_grffile, this->textref_stack_size, this->textref_stack);
int text_width = std::max(0, (int)size->width - WD_FRAMETEXT_LEFT - WD_FRAMETEXT_RIGHT);
this->height_summary = GetStringHeight(this->summary_msg, text_width);
this->height_detailed = (this->detailed_msg == INVALID_STRING_ID) ? 0 : GetStringHeight(this->detailed_msg, text_width);
this->height_summary = GetStringHeight(this->summary_msg, size->width);
this->height_detailed = (this->detailed_msg == INVALID_STRING_ID) ? 0 : GetStringHeight(this->detailed_msg, size->width);
if (this->textref_stack_size > 0) StopTextRefStackUsage();
uint panel_height = WD_FRAMERECT_TOP + this->height_summary + WD_FRAMERECT_BOTTOM;
if (this->detailed_msg != INVALID_STRING_ID) panel_height += this->height_detailed + WD_PAR_VSEP_WIDE;
uint panel_height = this->height_summary;
if (this->detailed_msg != INVALID_STRING_ID) panel_height += this->height_detailed + WidgetDimensions::scaled.vsep_wide;
size->height = std::max(size->height, panel_height);
break;
@@ -246,8 +245,8 @@ public:
pt.y = UnScaleByZoom(pt.y - vp->virtual_top, vp->zoom) + vp->top;
pt.y = (pt.y < (_screen.height >> 1)) ? scr_bot - sm_height : scr_top;
} else {
pt.x = Clamp(UnScaleByZoom(pt.x - vp->virtual_left, vp->zoom) + vp->left - (sm_width / 2), 0, _screen.width - sm_width);
pt.y = Clamp(UnScaleByZoom(pt.y - vp->virtual_top, vp->zoom) + vp->top - (sm_height / 2), scr_top, scr_bot - sm_height);
pt.x = std::min(std::max(UnScaleByZoom(pt.x - vp->virtual_left, vp->zoom) + vp->left - (sm_width / 2), 0), _screen.width - sm_width);
pt.y = std::min(std::max(UnScaleByZoom(pt.y - vp->virtual_top, vp->zoom) + vp->top - (sm_height / 2), scr_top), scr_bot - sm_height);
}
return pt;
}
@@ -282,19 +281,14 @@ public:
if (this->textref_stack_size > 0) StartTextRefStackUsage(this->textref_stack_grffile, this->textref_stack_size, this->textref_stack);
if (this->detailed_msg == INVALID_STRING_ID) {
DrawStringMultiLine(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, r.top + WD_FRAMERECT_TOP, r.bottom - WD_FRAMERECT_BOTTOM,
this->summary_msg, TC_FROMSTRING, SA_CENTER);
DrawStringMultiLine(r, this->summary_msg, TC_FROMSTRING, SA_CENTER);
} else {
int extra = (r.bottom - r.top + 1 - this->height_summary - this->height_detailed - WD_PAR_VSEP_WIDE) / 2;
/* Extra space when message is shorter than company face window */
int extra = (r.Height() - this->height_summary - this->height_detailed - WidgetDimensions::scaled.vsep_wide) / 2;
/* Note: NewGRF supplied error message often do not start with a colour code, so default to white. */
int top = r.top + WD_FRAMERECT_TOP;
int bottom = top + this->height_summary + extra;
DrawStringMultiLine(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, top, bottom, this->summary_msg, TC_WHITE, SA_CENTER);
bottom = r.bottom - WD_FRAMERECT_BOTTOM;
top = bottom - this->height_detailed - extra;
DrawStringMultiLine(r.left + WD_FRAMETEXT_LEFT, r.right - WD_FRAMETEXT_RIGHT, top, bottom, this->detailed_msg, TC_WHITE, SA_CENTER);
DrawStringMultiLine(r.WithHeight(this->height_summary + extra, false), this->summary_msg, TC_WHITE, SA_CENTER);
DrawStringMultiLine(r.WithHeight(this->height_detailed + extra, true), this->detailed_msg, TC_WHITE, SA_CENTER);
}
if (this->textref_stack_size > 0) StopTextRefStackUsage();

View File

@@ -418,7 +418,7 @@ uint TarScanner::DoScan(Subdirectory sd)
/* static */ uint TarScanner::DoScan(TarScanner::Mode mode)
{
Debug(misc, 1, "Scanning for tars");
Debug(misc, 2, "Scanning for tars");
TarScanner fs;
uint num = 0;
if (mode & TarScanner::BASESET) {
@@ -439,7 +439,7 @@ uint TarScanner::DoScan(Subdirectory sd)
num += fs.DoScan(SCENARIO_DIR);
num += fs.DoScan(HEIGHTMAP_DIR);
}
Debug(misc, 1, "Scan complete, found {} files", num);
Debug(misc, 2, "Scan complete, found {} files", num);
return num;
}
@@ -571,7 +571,7 @@ bool TarScanner::AddFile(const std::string &filename, size_t basepath_length, co
/* Only allow relative links */
if (link[0] == PATHSEPCHAR) {
Debug(misc, 1, "Ignoring absolute link in tar: {} -> {}", name, link);
Debug(misc, 5, "Ignoring absolute link in tar: {} -> {}", name, link);
break;
}
@@ -597,7 +597,7 @@ bool TarScanner::AddFile(const std::string &filename, size_t basepath_length, co
} else if (strcmp(pos, "..") == 0) {
/* level up */
if (dest[0] == '\0') {
Debug(misc, 1, "Ignoring link pointing outside of data directory: {} -> {}", name, link);
Debug(misc, 5, "Ignoring link pointing outside of data directory: {} -> {}", name, link);
break;
}
@@ -652,7 +652,7 @@ bool TarScanner::AddFile(const std::string &filename, size_t basepath_length, co
pos += skip;
}
Debug(misc, 1, "Found tar '{}' with {} new files", filename, num);
Debug(misc, 4, "Found tar '{}' with {} new files", filename, num);
fclose(f);
/* Resolve file links and store directory links.
@@ -690,7 +690,7 @@ bool ExtractTar(const std::string &tar_filename, Subdirectory subdir)
/* The file doesn't have a sub directory! */
if (dirname.empty()) {
Debug(misc, 1, "Extracting {} failed; archive rejected, the contents must be in a sub directory", tar_filename);
Debug(misc, 3, "Extracting {} failed; archive rejected, the contents must be in a sub directory", tar_filename);
return false;
}
@@ -987,7 +987,7 @@ void DeterminePaths(const char *exe, bool only_local_path)
for (Searchpath sp : _valid_searchpaths) {
if (sp == SP_WORKING_DIR && !_do_scan_working_directory) continue;
Debug(misc, 4, "{} added as search path", _searchpaths[sp]);
Debug(misc, 3, "{} added as search path", _searchpaths[sp]);
}
std::string config_dir;
@@ -1020,7 +1020,7 @@ void DeterminePaths(const char *exe, bool only_local_path)
_config_file = config_dir + "openttd.cfg";
}
Debug(misc, 3, "{} found as config directory", config_dir);
Debug(misc, 1, "{} found as config directory", config_dir);
_highscore_file = config_dir + "hs.dat";
extern std::string _hotkeys_file;
@@ -1056,7 +1056,7 @@ void DeterminePaths(const char *exe, bool only_local_path)
FioCreateDirectory(_personal_dir);
#endif
Debug(misc, 3, "{} found as personal directory", _personal_dir);
Debug(misc, 1, "{} found as personal directory", _personal_dir);
static const Subdirectory default_subdirs[] = {
SAVE_DIR, AUTOSAVE_DIR, SCENARIO_DIR, HEIGHTMAP_DIR, BASESET_DIR, NEWGRF_DIR, AI_DIR, AI_LIBRARY_DIR, GAME_DIR, GAME_LIBRARY_DIR, SCREENSHOT_DIR
@@ -1068,7 +1068,7 @@ void DeterminePaths(const char *exe, bool only_local_path)
/* If we have network we make a directory for the autodownloading of content */
_searchpaths[SP_AUTODOWNLOAD_DIR] = _personal_dir + "content_download" PATHSEP;
Debug(misc, 4, "{} added as search path", _searchpaths[SP_AUTODOWNLOAD_DIR]);
Debug(misc, 3, "{} added as search path", _searchpaths[SP_AUTODOWNLOAD_DIR]);
FioCreateDirectory(_searchpaths[SP_AUTODOWNLOAD_DIR]);
FillValidSearchPaths(only_local_path);

View File

@@ -83,8 +83,8 @@ static const NWidgetPart _nested_load_dialog_widgets[] = {
NWidget(NWID_VERTICAL),
/* Filter box with label */
NWidget(WWT_PANEL, COLOUR_GREY), SetFill(1, 1), SetResize(1, 1),
NWidget(NWID_HORIZONTAL), SetPadding(WD_FRAMERECT_TOP, 0, WD_FRAMERECT_BOTTOM, 0),
SetPIP(WD_FRAMETEXT_LEFT, WD_FRAMETEXT_RIGHT, 0),
NWidget(NWID_HORIZONTAL), SetPadding(WidgetDimensions::unscaled.framerect.top, 0, WidgetDimensions::unscaled.framerect.bottom, 0),
SetPIP(WidgetDimensions::unscaled.frametext.left, WidgetDimensions::unscaled.frametext.right, 0),
NWidget(WWT_TEXT, COLOUR_GREY), SetFill(0, 1), SetDataTip(STR_SAVELOAD_FILTER_TITLE , STR_NULL),
NWidget(WWT_EDITBOX, COLOUR_GREY, WID_SL_FILTER), SetFill(1, 0), SetMinimalSize(50, 12), SetResize(1, 0),
SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP),
@@ -141,8 +141,8 @@ static const NWidgetPart _nested_load_heightmap_dialog_widgets[] = {
/* Filter box with label */
NWidget(WWT_PANEL, COLOUR_GREY), SetFill(1, 1), SetResize(1, 1),
NWidget(NWID_HORIZONTAL), SetPadding(WD_FRAMERECT_TOP, 0, WD_FRAMERECT_BOTTOM, 0),
SetPIP(WD_FRAMETEXT_LEFT, WD_FRAMETEXT_RIGHT, 0),
NWidget(NWID_HORIZONTAL), SetPadding(WidgetDimensions::unscaled.framerect.top, 0, WidgetDimensions::unscaled.framerect.bottom, 0),
SetPIP(WidgetDimensions::unscaled.frametext.left, WidgetDimensions::unscaled.frametext.right, 0),
NWidget(WWT_TEXT, COLOUR_GREY), SetFill(0, 1), SetDataTip(STR_SAVELOAD_FILTER_TITLE , STR_NULL),
NWidget(WWT_EDITBOX, COLOUR_GREY, WID_SL_FILTER), SetFill(1, 0), SetMinimalSize(50, 12), SetResize(1, 0),
SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP),
@@ -188,8 +188,8 @@ static const NWidgetPart _nested_save_dialog_widgets[] = {
NWidget(NWID_VERTICAL),
/* Filter box with label */
NWidget(WWT_PANEL, COLOUR_GREY), SetFill(1, 1), SetResize(1, 1),
NWidget(NWID_HORIZONTAL), SetPadding(WD_FRAMERECT_TOP, 0, WD_FRAMERECT_BOTTOM, 0),
SetPIP(WD_FRAMETEXT_LEFT, WD_FRAMETEXT_RIGHT, 0),
NWidget(NWID_HORIZONTAL), SetPadding(WidgetDimensions::unscaled.framerect.top, 0, WidgetDimensions::unscaled.framerect.bottom, 0),
SetPIP(WidgetDimensions::unscaled.frametext.left, WidgetDimensions::unscaled.frametext.right, 0),
NWidget(WWT_TEXT, COLOUR_GREY), SetFill(0, 1), SetDataTip(STR_SAVELOAD_FILTER_TITLE , STR_NULL),
NWidget(WWT_EDITBOX, COLOUR_GREY, WID_SL_FILTER), SetFill(1, 0), SetMinimalSize(50, 12), SetResize(1, 0),
SetDataTip(STR_LIST_FILTER_OSKTITLE, STR_LIST_FILTER_TOOLTIP),
@@ -223,10 +223,10 @@ static const NWidgetPart _nested_save_dialog_widgets[] = {
EndContainer(),
/* Right side : game details */
NWidget(WWT_PANEL, COLOUR_GREY),
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_SL_DETAILS), SetResize(1, 1), SetFill(1, 1),
NWidget(NWID_VERTICAL),
NWidget(WWT_PANEL, COLOUR_GREY, WID_SL_DETAILS), SetResize(1, 1), SetFill(1, 1), EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(NWID_SPACER), SetResize(1, 0), SetFill(1, 1),
NWidget(WWT_PANEL, COLOUR_GREY), SetResize(1, 0), SetFill(1, 1), EndContainer(),
NWidget(WWT_RESIZEBOX, COLOUR_GREY),
EndContainer(),
EndContainer(),
@@ -437,18 +437,21 @@ public:
_fios_path_changed = false;
}
Rect ir = r.Shrink(WidgetDimensions::scaled.framerect);
if (str != STR_ERROR_UNABLE_TO_READ_DRIVE) SetDParam(0, tot);
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + FONT_HEIGHT_NORMAL + WD_FRAMERECT_TOP, str);
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, r.top + WD_FRAMERECT_TOP, path, TC_BLACK);
DrawString(ir.left, ir.right, ir.top + FONT_HEIGHT_NORMAL, str);
DrawString(ir.left, ir.right, ir.top, path, TC_BLACK);
break;
}
case WID_SL_DRIVES_DIRECTORIES_LIST: {
GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.bottom - 1, PC_BLACK);
const Rect br = r.Shrink(WidgetDimensions::scaled.bevel);
GfxFillRect(br, PC_BLACK);
uint y = r.top + WD_FRAMERECT_TOP;
Rect tr = r.Shrink(WidgetDimensions::scaled.inset).WithHeight(this->resize.step_height);
uint scroll_pos = this->vscroll->GetPosition();
for (uint row = 0; row < this->fios_items.size(); row++) {
for (uint row = 0; row < this->fios_items.size() && tr.top < br.bottom; row++) {
if (!this->fios_items_shown[row]) {
/* The current item is filtered out : we do not show it */
scroll_pos++;
@@ -458,107 +461,117 @@ public:
const FiosItem *item = &this->fios_items[row];
if (item == this->selected) {
GfxFillRect(r.left + 1, y, r.right - 1, y + this->resize.step_height - 1, PC_DARK_BLUE);
GfxFillRect(br.left, tr.top, br.right, tr.bottom, PC_DARK_BLUE);
} else if (item == this->highlighted) {
GfxFillRect(r.left + 1, y, r.right - 1, y + this->resize.step_height - 1, PC_VERY_DARK_BLUE);
GfxFillRect(br.left, tr.top, br.right, tr.bottom, PC_VERY_DARK_BLUE);
}
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, item->title, _fios_colours[GetDetailedFileType(item->type)]);
y += this->resize.step_height;
if (y >= this->vscroll->GetCapacity() * this->resize.step_height + r.top + WD_FRAMERECT_TOP) break;
DrawString(tr, item->title, _fios_colours[GetDetailedFileType(item->type)]);
tr = tr.Translate(0, this->resize.step_height);
}
break;
}
case WID_SL_DETAILS: {
GfxFillRect(r.left + 1, r.top + 1, r.right - 1, r.top + FONT_HEIGHT_NORMAL * 2 + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM, PC_GREY);
DrawString(r.left, r.right, r.top + FONT_HEIGHT_NORMAL / 2 + WD_FRAMERECT_TOP, STR_SAVELOAD_DETAIL_CAPTION, TC_FROMSTRING, SA_HOR_CENTER);
if (this->selected == nullptr) break;
uint y = r.top + FONT_HEIGHT_NORMAL * 2 + WD_PAR_VSEP_NORMAL + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
uint y_max = r.bottom - FONT_HEIGHT_NORMAL - WD_FRAMERECT_BOTTOM;
if (y > y_max) break;
if (!_load_check_data.checkable) {
/* Old savegame, no information available */
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_SAVELOAD_DETAIL_NOT_AVAILABLE);
y += FONT_HEIGHT_NORMAL;
} else if (_load_check_data.error != INVALID_STRING_ID) {
/* Incompatible / broken savegame */
SetDParamStr(0, _load_check_data.error_data);
y = DrawStringMultiLine(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT,
y, r.bottom - WD_FRAMERECT_BOTTOM, _load_check_data.error, TC_RED);
} else {
/* Mapsize */
SetDParam(0, _load_check_data.map_size_x);
SetDParam(1, _load_check_data.map_size_y);
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_MAP_SIZE);
y += FONT_HEIGHT_NORMAL;
if (y > y_max) break;
/* Climate */
byte landscape = _load_check_data.settings.game_creation.landscape;
if (landscape < NUM_LANDSCAPE) {
SetDParam(0, STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE + landscape);
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_LANDSCAPE);
y += FONT_HEIGHT_NORMAL;
}
y += WD_PAR_VSEP_NORMAL;
if (y > y_max) break;
/* Start date (if available) */
if (_load_check_data.settings.game_creation.starting_year != 0) {
SetDParam(0, ConvertYMDToDate(_load_check_data.settings.game_creation.starting_year, 0, 1));
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_START_DATE);
y += FONT_HEIGHT_NORMAL;
}
if (y > y_max) break;
/* Hide current date for scenarios */
if (this->abstract_filetype != FT_SCENARIO) {
/* Current date */
SetDParam(0, _load_check_data.current_date);
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_NETWORK_SERVER_LIST_CURRENT_DATE);
y += FONT_HEIGHT_NORMAL;
}
/* Hide the NewGRF stuff when saving. We also hide the button. */
if (this->fop == SLO_LOAD && (this->abstract_filetype == FT_SAVEGAME || this->abstract_filetype == FT_SCENARIO)) {
y += WD_PAR_VSEP_NORMAL;
if (y > y_max) break;
/* NewGrf compatibility */
SetDParam(0, _load_check_data.grfconfig == nullptr ? STR_NEWGRF_LIST_NONE :
STR_NEWGRF_LIST_ALL_FOUND + _load_check_data.grf_compatibility);
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_SAVELOAD_DETAIL_GRFSTATUS);
y += FONT_HEIGHT_NORMAL;
}
if (y > y_max) break;
/* Hide the company stuff for scenarios */
if (this->abstract_filetype != FT_SCENARIO) {
y += FONT_HEIGHT_NORMAL;
if (y > y_max) break;
/* Companies / AIs */
for (auto &pair : _load_check_data.companies) {
SetDParam(0, pair.first + 1);
const CompanyProperties &c = *pair.second;
if (!c.name.empty()) {
SetDParam(1, STR_JUST_RAW_STRING);
SetDParamStr(2, c.name);
} else {
SetDParam(1, c.name_1);
SetDParam(2, c.name_2);
}
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_SAVELOAD_DETAIL_COMPANY_INDEX);
y += FONT_HEIGHT_NORMAL;
if (y > y_max) break;
}
}
}
case WID_SL_DETAILS:
this->DrawDetails(r);
break;
}
}
void DrawDetails(const Rect &r) const
{
/* Header panel */
int HEADER_HEIGHT = FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.frametext.Vertical();
Rect hr = r.WithHeight(HEADER_HEIGHT).Shrink(WidgetDimensions::scaled.frametext);
Rect tr = r.Shrink(WidgetDimensions::scaled.frametext);
tr.top += HEADER_HEIGHT;
/* Create the nice grayish rectangle at the details top */
GfxFillRect(r.WithHeight(HEADER_HEIGHT).Shrink(WidgetDimensions::scaled.bevel.left, WidgetDimensions::scaled.bevel.top, WidgetDimensions::scaled.bevel.right, 0), PC_GREY);
DrawString(hr.left, hr.right, hr.top, STR_SAVELOAD_DETAIL_CAPTION, TC_FROMSTRING, SA_HOR_CENTER);
if (this->selected == nullptr) return;
/* Details panel */
tr.bottom -= FONT_HEIGHT_NORMAL - 1;
if (tr.top > tr.bottom) return;
if (!_load_check_data.checkable) {
/* Old savegame, no information available */
DrawString(tr, STR_SAVELOAD_DETAIL_NOT_AVAILABLE);
tr.top += FONT_HEIGHT_NORMAL;
} else if (_load_check_data.error != INVALID_STRING_ID) {
/* Incompatible / broken savegame */
SetDParamStr(0, _load_check_data.error_data);
tr.top = DrawStringMultiLine(tr, _load_check_data.error, TC_RED);
} else {
/* Mapsize */
SetDParam(0, _load_check_data.map_size_x);
SetDParam(1, _load_check_data.map_size_y);
DrawString(tr, STR_NETWORK_SERVER_LIST_MAP_SIZE);
tr.top += FONT_HEIGHT_NORMAL;
if (tr.top > tr.bottom) return;
/* Climate */
byte landscape = _load_check_data.settings.game_creation.landscape;
if (landscape < NUM_LANDSCAPE) {
SetDParam(0, STR_CLIMATE_TEMPERATE_LANDSCAPE + landscape);
DrawString(tr, STR_NETWORK_SERVER_LIST_LANDSCAPE);
tr.top += FONT_HEIGHT_NORMAL;
}
tr.top += WidgetDimensions::scaled.vsep_normal;
if (tr.top > tr.bottom) return;
/* Start date (if available) */
if (_load_check_data.settings.game_creation.starting_year != 0) {
SetDParam(0, ConvertYMDToDate(_load_check_data.settings.game_creation.starting_year, 0, 1));
DrawString(tr, STR_NETWORK_SERVER_LIST_START_DATE);
tr.top += FONT_HEIGHT_NORMAL;
}
if (tr.top > tr.bottom) return;
/* Hide current date for scenarios */
if (this->abstract_filetype != FT_SCENARIO) {
/* Current date */
SetDParam(0, _load_check_data.current_date);
DrawString(tr, STR_NETWORK_SERVER_LIST_CURRENT_DATE);
tr.top += FONT_HEIGHT_NORMAL;
}
/* Hide the NewGRF stuff when saving. We also hide the button. */
if (this->fop == SLO_LOAD && (this->abstract_filetype == FT_SAVEGAME || this->abstract_filetype == FT_SCENARIO)) {
tr.top += WidgetDimensions::scaled.vsep_normal;
if (tr.top > tr.bottom) return;
/* NewGrf compatibility */
SetDParam(0, _load_check_data.grfconfig == nullptr ? STR_NEWGRF_LIST_NONE :
STR_NEWGRF_LIST_ALL_FOUND + _load_check_data.grf_compatibility);
DrawString(tr, STR_SAVELOAD_DETAIL_GRFSTATUS);
tr.top += FONT_HEIGHT_NORMAL;
}
if (tr.top > tr.bottom) return;
/* Hide the company stuff for scenarios */
if (this->abstract_filetype != FT_SCENARIO) {
tr.top += WidgetDimensions::scaled.vsep_wide;
if (tr.top > tr.bottom) return;
/* Companies / AIs */
for (auto &pair : _load_check_data.companies) {
SetDParam(0, pair.first + 1);
const CompanyProperties &c = *pair.second;
if (!c.name.empty()) {
SetDParam(1, STR_JUST_RAW_STRING);
SetDParamStr(2, c.name);
} else {
SetDParam(1, c.name_1);
SetDParam(2, c.name_2);
}
DrawString(tr, STR_SAVELOAD_DETAIL_COMPANY_INDEX);
tr.top += FONT_HEIGHT_NORMAL;
if (tr.top > tr.bottom) break;
}
}
}
}
@@ -567,12 +580,12 @@ public:
{
switch (widget) {
case WID_SL_BACKGROUND:
size->height = 2 * FONT_HEIGHT_NORMAL + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
size->height = 2 * FONT_HEIGHT_NORMAL + padding.height;
break;
case WID_SL_DRIVES_DIRECTORIES_LIST:
resize->height = FONT_HEIGHT_NORMAL;
size->height = resize->height * 10 + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
size->height = resize->height * 10 + padding.height;
break;
case WID_SL_SORT_BYNAME:
case WID_SL_SORT_BYDATE: {
@@ -652,7 +665,7 @@ public:
break;
case WID_SL_DRIVES_DIRECTORIES_LIST: { // Click the listbox
int y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SL_DRIVES_DIRECTORIES_LIST, WD_FRAMERECT_TOP);
int y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SL_DRIVES_DIRECTORIES_LIST, WidgetDimensions::scaled.inset.top);
if (y == INT_MAX) return;
/* Get the corresponding non-filtered out item from the list */
@@ -732,7 +745,7 @@ public:
void OnMouseOver(Point pt, int widget) override
{
if (widget == WID_SL_DRIVES_DIRECTORIES_LIST) {
int y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SL_DRIVES_DIRECTORIES_LIST, WD_FRAMERECT_TOP);
int y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_SL_DRIVES_DIRECTORIES_LIST, WidgetDimensions::scaled.inset.top);
if (y == INT_MAX) return;
/* Get the corresponding non-filtered out item from the list */

View File

@@ -13,6 +13,11 @@
#include "blitter/factory.hpp"
#include "gfx_layout.h"
#include "fontcache/spritefontcache.h"
#include "openttd.h"
#include "settings_func.h"
#include "strings_func.h"
#include "viewport_func.h"
#include "window_func.h"
#include "safeguards.h"
@@ -70,15 +75,51 @@ bool GetFontAAState(FontSize size, bool check_blitter)
/* AA is only supported for 32 bpp */
if (check_blitter && BlitterFactory::GetCurrentBlitter()->GetScreenDepth() != 32) return false;
switch (size) {
default: NOT_REACHED();
case FS_NORMAL: return _fcsettings.medium.aa;
case FS_SMALL: return _fcsettings.small.aa;
case FS_LARGE: return _fcsettings.large.aa;
case FS_MONO: return _fcsettings.mono.aa;
}
return GetFontCacheSubSetting(size)->aa;
}
void SetFont(FontSize fontsize, const std::string& font, uint size, bool aa)
{
FontCacheSubSetting *setting = GetFontCacheSubSetting(fontsize);
bool changed = false;
if (setting->font != font) {
setting->font = font;
changed = true;
}
if (setting->size != size) {
setting->size = size;
changed = true;
}
if (setting->aa != aa) {
setting->aa = aa;
changed = true;
}
if (!changed) return;
if (fontsize != FS_MONO) {
/* Try to reload only the modified font. */
FontCacheSettings backup = _fcsettings;
for (FontSize fs = FS_BEGIN; fs < FS_END; fs++) {
if (fs == fontsize) continue;
FontCache *fc = FontCache::Get(fs);
GetFontCacheSubSetting(fs)->font = fc->HasParent() ? fc->GetFontName() : "";
}
CheckForMissingGlyphs();
_fcsettings = backup;
} else {
InitFontCache(true);
}
LoadStringWidthTable();
UpdateAllVirtCoords();
ReInitAllWindows(true);
if (_save_config) SaveToConfig();
}
/**
* (Re)initialize the font cache related things, i.e. load the non-sprite fonts.

View File

@@ -29,12 +29,12 @@ protected:
int descender; ///< The descender value of the font.
int units_per_em; ///< The units per EM value of the font.
static int GetDefaultFontHeight(FontSize fs);
public:
FontCache(FontSize fs);
virtual ~FontCache();
static int GetDefaultFontHeight(FontSize fs);
/**
* Get the FontSize of the font.
* @return The FontSize.
@@ -218,10 +218,27 @@ struct FontCacheSettings {
extern FontCacheSettings _fcsettings;
/**
* Get the settings of a given font size.
* @param fs The font size to look up.
* @return The settings.
*/
static inline FontCacheSubSetting *GetFontCacheSubSetting(FontSize fs)
{
switch (fs) {
default: NOT_REACHED();
case FS_SMALL: return &_fcsettings.small;
case FS_NORMAL: return &_fcsettings.medium;
case FS_LARGE: return &_fcsettings.large;
case FS_MONO: return &_fcsettings.mono;
}
}
void InitFontCache(bool monospace);
void UninitFontCache();
bool HasAntialiasedFonts();
bool GetFontAAState(FontSize size, bool check_blitter = true);
void SetFont(FontSize fontsize, const std::string &font, uint size, bool aa);
#endif /* FONTCACHE_H */

View File

@@ -65,18 +65,19 @@ void FreeTypeFontCache::SetFontSize(FontSize fs, FT_Face face, int pixels)
{
if (pixels == 0) {
/* Try to determine a good height based on the minimal height recommended by the font. */
int scaled_height = ScaleFontTrad(this->GetDefaultFontHeight(this->fs));
int scaled_height = ScaleGUITrad(FontCache::GetDefaultFontHeight(this->fs));
pixels = scaled_height;
TT_Header *head = (TT_Header *)FT_Get_Sfnt_Table(this->face, ft_sfnt_head);
if (head != nullptr) {
/* Font height is minimum height plus the difference between the default
* height for this font size and the small size. */
int diff = scaled_height - ScaleFontTrad(this->GetDefaultFontHeight(FS_SMALL));
pixels = Clamp(std::min<uint>(head->Lowest_Rec_PPEM, MAX_FONT_MIN_REC_SIZE) + diff, scaled_height, MAX_FONT_SIZE);
int diff = scaled_height - ScaleGUITrad(FontCache::GetDefaultFontHeight(FS_SMALL));
/* Clamp() is not used as scaled_height could be greater than MAX_FONT_SIZE, which is not permitted in Clamp(). */
pixels = std::min(std::max(std::min<int>(head->Lowest_Rec_PPEM, MAX_FONT_MIN_REC_SIZE) + diff, scaled_height), MAX_FONT_SIZE);
}
} else {
pixels = ScaleFontTrad(pixels);
pixels = ScaleGUITrad(pixels);
}
this->used_size = pixels;
@@ -121,14 +122,7 @@ void FreeTypeFontCache::SetFontSize(FontSize fs, FT_Face face, int pixels)
*/
void LoadFreeTypeFont(FontSize fs)
{
FontCacheSubSetting *settings = nullptr;
switch (fs) {
default: NOT_REACHED();
case FS_SMALL: settings = &_fcsettings.small; break;
case FS_NORMAL: settings = &_fcsettings.medium; break;
case FS_LARGE: settings = &_fcsettings.large; break;
case FS_MONO: settings = &_fcsettings.mono; break;
}
FontCacheSubSetting *settings = GetFontCacheSubSetting(fs);
if (settings->font.empty()) return;
@@ -196,8 +190,7 @@ void LoadFreeTypeFont(FontSize fs)
FT_Done_Face(face);
static const char *SIZE_TO_NAME[] = { "medium", "small", "large", "mono" };
ShowInfoF("Unable to use '%s' for %s font, FreeType reported error 0x%X, using sprite font instead", font_name, SIZE_TO_NAME[fs], error);
ShowInfoF("Unable to use '%s' for %s font, FreeType reported error 0x%X, using sprite font instead", font_name, FontSizeToName(fs), error);
return;
found_face:
@@ -237,9 +230,10 @@ const Sprite *FreeTypeFontCache::InternalGetGlyph(GlyphID key, bool aa)
/* Despite requesting a normal glyph, FreeType may have returned a bitmap */
aa = (slot->bitmap.pixel_mode == FT_PIXEL_MODE_GRAY);
/* Add 1 pixel for the shadow on the medium font. Our sprite must be at least 1x1 pixel */
uint width = std::max(1U, (uint)slot->bitmap.width + (this->fs == FS_NORMAL));
uint height = std::max(1U, (uint)slot->bitmap.rows + (this->fs == FS_NORMAL));
/* Add 1 scaled pixel for the shadow on the medium font. Our sprite must be at least 1x1 pixel */
uint shadow = (this->fs == FS_NORMAL) ? ScaleGUITrad(1) : 0;
uint width = std::max(1U, (uint)slot->bitmap.width + shadow);
uint height = std::max(1U, (uint)slot->bitmap.rows + shadow);
/* Limit glyph size to prevent overflows later on. */
if (width > MAX_GLYPH_DIM || height > MAX_GLYPH_DIM) usererror("Font glyph is too large");
@@ -259,8 +253,8 @@ const Sprite *FreeTypeFontCache::InternalGetGlyph(GlyphID key, bool aa)
for (uint y = 0; y < (uint)slot->bitmap.rows; y++) {
for (uint x = 0; x < (uint)slot->bitmap.width; x++) {
if (HasBit(slot->bitmap.buffer[(x / 8) + y * slot->bitmap.pitch], 7 - (x % 8))) {
sprite.data[1 + x + (1 + y) * sprite.width].m = SHADOW_COLOUR;
sprite.data[1 + x + (1 + y) * sprite.width].a = 0xFF;
sprite.data[shadow + x + (shadow + y) * sprite.width].m = SHADOW_COLOUR;
sprite.data[shadow + x + (shadow + y) * sprite.width].a = 0xFF;
}
}
}

View File

@@ -28,7 +28,8 @@ static const int ASCII_LETTERSTART = 32; ///< First printable ASCII letter.
SpriteFontCache::SpriteFontCache(FontSize fs) : FontCache(fs), glyph_to_spriteid_map(nullptr)
{
this->InitializeUnicodeGlyphMap();
this->height = ScaleFontTrad(this->GetDefaultFontHeight(this->fs));
this->height = ScaleGUITrad(FontCache::GetDefaultFontHeight(this->fs));
this->ascender = (this->height - ScaleSpriteTrad(FontCache::GetDefaultFontHeight(this->fs))) / 2;
}
/**
@@ -104,7 +105,8 @@ void SpriteFontCache::ClearGlyphToSpriteMap()
void SpriteFontCache::ClearFontCache()
{
Layouter::ResetFontCache(this->fs);
this->height = ScaleFontTrad(this->GetDefaultFontHeight(this->fs));
this->height = ScaleGUITrad(FontCache::GetDefaultFontHeight(this->fs));
this->ascender = (this->height - ScaleSpriteTrad(FontCache::GetDefaultFontHeight(this->fs))) / 2;
}
const Sprite *SpriteFontCache::GetGlyph(GlyphID key)
@@ -118,7 +120,7 @@ uint SpriteFontCache::GetGlyphWidth(GlyphID key)
{
SpriteID sprite = this->GetUnicodeGlyph(key);
if (sprite == 0) sprite = this->GetUnicodeGlyph('?');
return SpriteExists(sprite) ? GetSprite(sprite, ST_FONT)->width + ScaleFontTrad(this->fs != FS_NORMAL ? 1 : 0) : 0;
return SpriteExists(sprite) ? GetSprite(sprite, ST_FONT)->width + ScaleSpriteTrad(this->fs != FS_NORMAL ? 1 : 0) : 0;
}
bool SpriteFontCache::GetDrawGlyphShadow()

View File

@@ -25,8 +25,16 @@
#include "game/game_instance.hpp"
#include "widgets/framerate_widget.h"
#include <atomic>
#include <mutex>
#include <vector>
#include "safeguards.h"
static std::mutex _sound_perf_lock;
static std::atomic<bool> _sound_perf_pending;
static std::vector<TimingMeasurement> _sound_perf_measurements;
/**
* Private declarations for performance measurement implementation
@@ -251,6 +259,20 @@ PerformanceMeasurer::~PerformanceMeasurer()
return;
}
}
if (this->elem == PFE_SOUND) {
/* PFE_SOUND measurements are made from the mixer thread.
* _pf_data cannot be concurrently accessed from the mixer thread
* and the main thread, so store the measurement results in a
* mutex-protected queue which is drained by the main thread.
* See: ProcessPendingPerformanceMeasurements() */
TimingMeasurement end = GetPerformanceTimer();
std::lock_guard lk(_sound_perf_lock);
if (_sound_perf_measurements.size() >= NUM_FRAMERATE_POINTS * 2) return;
_sound_perf_measurements.push_back(this->start_time);
_sound_perf_measurements.push_back(end);
_sound_perf_pending.store(true, std::memory_order_release);
return;
}
_pf_data[this->elem].Add(this->start_time, GetPerformanceTimer());
}
@@ -358,7 +380,7 @@ static const NWidgetPart _framerate_window_widgets[] = {
NWidget(WWT_STICKYBOX, COLOUR_GREY),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY),
NWidget(NWID_VERTICAL), SetPadding(6), SetPIP(0, 3, 0),
NWidget(NWID_VERTICAL), SetPadding(WidgetDimensions::unscaled.frametext), SetPIP(0, WidgetDimensions::unscaled.vsep_normal, 0),
NWidget(WWT_TEXT, COLOUR_GREY, WID_FRW_RATE_GAMELOOP), SetDataTip(STR_FRAMERATE_RATE_GAMELOOP, STR_FRAMERATE_RATE_GAMELOOP_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
NWidget(WWT_TEXT, COLOUR_GREY, WID_FRW_RATE_DRAWING), SetDataTip(STR_FRAMERATE_RATE_BLITTER, STR_FRAMERATE_RATE_BLITTER_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
NWidget(WWT_TEXT, COLOUR_GREY, WID_FRW_RATE_FACTOR), SetDataTip(STR_FRAMERATE_SPEED_FACTOR, STR_FRAMERATE_SPEED_FACTOR_TOOLTIP), SetFill(1, 0), SetResize(1, 0),
@@ -366,8 +388,8 @@ static const NWidgetPart _framerate_window_widgets[] = {
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_PANEL, COLOUR_GREY),
NWidget(NWID_VERTICAL), SetPadding(6), SetPIP(0, 3, 0),
NWidget(NWID_HORIZONTAL), SetPIP(0, 8, 0),
NWidget(NWID_VERTICAL), SetPadding(WidgetDimensions::unscaled.frametext), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0),
NWidget(NWID_HORIZONTAL), SetPIP(0, WidgetDimensions::unscaled.hsep_wide, 0),
NWidget(WWT_EMPTY, COLOUR_GREY, WID_FRW_TIMES_NAMES), SetScrollbar(WID_FRW_SCROLLBAR),
NWidget(WWT_EMPTY, COLOUR_GREY, WID_FRW_TIMES_CURRENT), SetScrollbar(WID_FRW_SCROLLBAR),
NWidget(WWT_EMPTY, COLOUR_GREY, WID_FRW_TIMES_AVERAGE), SetScrollbar(WID_FRW_SCROLLBAR),
@@ -425,7 +447,6 @@ struct FramerateWindow : Window {
CachedDecimal times_shortterm[PFE_MAX]; ///< cached short term average times
CachedDecimal times_longterm[PFE_MAX]; ///< cached long term average times
static constexpr int VSPACING = 3; ///< space between column heading and values
static constexpr int MIN_ELEMENTS = 5; ///< smallest number of elements to display
FramerateWindow(WindowDesc *desc, WindowNumber number) : Window(desc)
@@ -545,7 +566,7 @@ struct FramerateWindow : Window {
case WID_FRW_TIMES_NAMES: {
size->width = 0;
size->height = FONT_HEIGHT_NORMAL + VSPACING + MIN_ELEMENTS * FONT_HEIGHT_NORMAL;
size->height = FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal + MIN_ELEMENTS * FONT_HEIGHT_NORMAL;
resize->width = 0;
resize->height = FONT_HEIGHT_NORMAL;
for (PerformanceElement e : DISPLAY_ORDER_PFE) {
@@ -571,7 +592,7 @@ struct FramerateWindow : Window {
SetDParam(1, 2);
Dimension item_size = GetStringBoundingBox(STR_FRAMERATE_MS_GOOD);
size->width = std::max(size->width, item_size.width);
size->height += FONT_HEIGHT_NORMAL * MIN_ELEMENTS + VSPACING;
size->height += FONT_HEIGHT_NORMAL * MIN_ELEMENTS + WidgetDimensions::scaled.vsep_normal;
resize->width = 0;
resize->height = FONT_HEIGHT_NORMAL;
break;
@@ -587,7 +608,7 @@ struct FramerateWindow : Window {
int drawable = this->num_displayed;
int y = r.top;
DrawString(r.left, r.right, y, heading_str, TC_FROMSTRING, SA_CENTER, true);
y += FONT_HEIGHT_NORMAL + VSPACING;
y += FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal;
for (PerformanceElement e : DISPLAY_ORDER_PFE) {
if (_pf_data[e].num_valid == 0) continue;
if (skip > 0) {
@@ -609,7 +630,7 @@ struct FramerateWindow : Window {
int drawable = this->num_displayed;
int y = r.top;
DrawString(r.left, r.right, y, STR_FRAMERATE_MEMORYUSE, TC_FROMSTRING, SA_CENTER, true);
y += FONT_HEIGHT_NORMAL + VSPACING;
y += FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal;
for (PerformanceElement e : DISPLAY_ORDER_PFE) {
if (_pf_data[e].num_valid == 0) continue;
if (skip > 0) {
@@ -641,7 +662,7 @@ struct FramerateWindow : Window {
const Scrollbar *sb = this->GetScrollbar(WID_FRW_SCROLLBAR);
uint16 skip = sb->GetPosition();
int drawable = this->num_displayed;
int y = r.top + FONT_HEIGHT_NORMAL + VSPACING; // first line contains headings in the value columns
int y = r.top + FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal; // first line contains headings in the value columns
for (PerformanceElement e : DISPLAY_ORDER_PFE) {
if (_pf_data[e].num_valid == 0) continue;
if (skip > 0) {
@@ -683,7 +704,7 @@ struct FramerateWindow : Window {
case WID_FRW_TIMES_AVERAGE: {
/* Open time graph windows when clicking detail measurement lines */
const Scrollbar *sb = this->GetScrollbar(WID_FRW_SCROLLBAR);
int line = sb->GetScrolledRowFromWidget(pt.y, this, widget, VSPACING + FONT_HEIGHT_NORMAL);
int line = sb->GetScrolledRowFromWidget(pt.y, this, widget, WidgetDimensions::scaled.vsep_normal + FONT_HEIGHT_NORMAL);
if (line != INT_MAX) {
line++;
/* Find the visible line that was clicked */
@@ -703,7 +724,7 @@ struct FramerateWindow : Window {
void OnResize() override
{
auto *wid = this->GetWidget<NWidgetResizeBase>(WID_FRW_TIMES_NAMES);
this->num_displayed = (wid->current_y - wid->min_y - VSPACING) / FONT_HEIGHT_NORMAL - 1; // subtract 1 for headings
this->num_displayed = (wid->current_y - wid->min_y - WidgetDimensions::scaled.vsep_normal) / FONT_HEIGHT_NORMAL - 1; // subtract 1 for headings
this->GetScrollbar(WID_FRW_SCROLLBAR)->SetCapacity(this->num_displayed);
}
};
@@ -1079,3 +1100,22 @@ void ConPrintFramerate()
IConsolePrint(CC_ERROR, "No performance measurements have been taken yet.");
}
}
/**
* This drains the PFE_SOUND measurement data queue into _pf_data.
* PFE_SOUND measurements are made by the mixer thread and so cannot be stored
* into _pf_data directly, because this would not be thread safe and would violate
* the invariants of the FPS and frame graph windows.
* @see PerformanceMeasurement::~PerformanceMeasurement()
*/
void ProcessPendingPerformanceMeasurements()
{
if (_sound_perf_pending.load(std::memory_order_acquire)) {
std::lock_guard lk(_sound_perf_lock);
for (size_t i = 0; i < _sound_perf_measurements.size(); i += 2) {
_pf_data[PFE_SOUND].Add(_sound_perf_measurements[i], _sound_perf_measurements[i + 1]);
}
_sound_perf_measurements.clear();
_sound_perf_pending.store(false, std::memory_order_relaxed);
}
}

View File

@@ -3,6 +3,8 @@ add_files(
game_config.cpp
game_config.hpp
game_core.cpp
game_gui.cpp
game_gui.hpp
game_info.cpp
game_info.hpp
game_instance.cpp

View File

@@ -87,11 +87,6 @@ public:
*/
static void Save();
/**
* Load data for a GameScript from a savegame.
*/
static void Load(int version);
/** Wrapper function for GameScanner::GetConsoleList */
static std::string GetConsoleList(bool newest_only = false);
/** Wrapper function for GameScanner::GetConsoleLibraryList */

View File

@@ -88,6 +88,8 @@
Game::info = info;
Game::instance = new GameInstance();
Game::instance->Initialize(info);
Game::instance->LoadOnStack(config->GetToLoadData());
config->SetToLoadData(nullptr);
cur_company.Restore();
@@ -199,6 +201,7 @@
InvalidateWindowData(WC_AI_LIST, 0, 1);
SetWindowClassesDirty(WC_AI_DEBUG);
InvalidateWindowClassesData(WC_AI_SETTINGS);
InvalidateWindowClassesData(WC_GAME_OPTIONS);
}
@@ -213,18 +216,6 @@
}
}
/* static */ void Game::Load(int version)
{
if (Game::instance != nullptr && (!_networking || _network_server)) {
Backup<CompanyID> cur_company(_current_company, OWNER_DEITY, FILE_LINE);
Game::instance->Load(version);
cur_company.Restore();
} else {
/* Read, but ignore, the load data */
GameInstance::LoadEmpty();
}
}
/* static */ std::string Game::GetConsoleList(bool newest_only)
{
return Game::scanner_info->GetConsoleList(newest_only);

465
src/game/game_gui.cpp Normal file
View File

@@ -0,0 +1,465 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can 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 <http://www.gnu.org/licenses/>.
*/
/** @file game_gui.cpp %Window for configuring the Game Script */
#include "../stdafx.h"
#include "../table/sprites.h"
#include "../error.h"
#include "../settings_gui.h"
#include "../querystring_gui.h"
#include "../stringfilter_type.h"
#include "../company_base.h"
#include "../company_gui.h"
#include "../strings_func.h"
#include "../window_func.h"
#include "../window_type.h"
#include "../gfx_func.h"
#include "../command_func.h"
#include "../network/network.h"
#include "../settings_func.h"
#include "../network/network_content.h"
#include "../textfile_gui.h"
#include "../widgets/dropdown_type.h"
#include "../widgets/dropdown_func.h"
#include "../hotkeys.h"
#include "../core/geometry_func.hpp"
#include "../guitimer_func.h"
#include "../company_cmd.h"
#include "../misc_cmd.h"
#include "game_gui.hpp"
#include "../ai/ai_config.hpp"
#include "../ai/ai_gui.hpp"
#include "../widgets/game_widget.h"
#include "../table/strings.h"
#include "../game/game.hpp"
#include "../game/game_config.hpp"
#include "../game/game_info.hpp"
#include "../game/game_instance.hpp"
#include "../safeguards.h"
/** Widgets for the configure GS window. */
static const NWidgetPart _nested_gs_config_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_MAUVE),
NWidget(WWT_CAPTION, COLOUR_MAUVE), SetDataTip(STR_AI_CONFIG_CAPTION_GAMESCRIPT, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
NWidget(WWT_DEFSIZEBOX, COLOUR_MAUVE),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_MAUVE, WID_GSC_BACKGROUND), SetFill(1, 0), SetResize(1, 0),
NWidget(NWID_SPACER), SetMinimalSize(0, 3), SetFill(1, 0), SetResize(1, 0),
NWidget(WWT_FRAME, COLOUR_MAUVE), SetDataTip(STR_AI_CONFIG_GAMESCRIPT, STR_NULL), SetFill(1, 0), SetResize(1, 0), SetPadding(0, 5, 4, 5),
NWidget(WWT_MATRIX, COLOUR_MAUVE, WID_GSC_GSLIST), SetMinimalSize(288, 14), SetFill(1, 0), SetResize(1, 0), SetMatrixDataTip(1, 1, STR_AI_CONFIG_GAMELIST_TOOLTIP),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 6), SetFill(1, 0), SetResize(1, 0),
NWidget(WWT_FRAME, COLOUR_MAUVE), SetDataTip(STR_AI_CONFIG_GAMESCRIPT_PARAM, STR_NULL), SetFill(1, 0), SetResize(1, 0), SetPadding(0, 5, 4, 5),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_MATRIX, COLOUR_MAUVE, WID_GSC_SETTINGS), SetFill(1, 0), SetResize(1, 1), SetMinimalSize(188, 182), SetMatrixDataTip(1, 0, STR_NULL), SetScrollbar(WID_GSC_SCROLLBAR),
NWidget(NWID_VSCROLLBAR, COLOUR_MAUVE, WID_GSC_SCROLLBAR),
EndContainer(),
EndContainer(),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7),
NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GSC_CHANGE), SetFill(1, 0), SetResize(1, 0), SetMinimalSize(93, 0), SetDataTip(STR_AI_CONFIG_CHANGE_GAMESCRIPT, STR_AI_CONFIG_CHANGE_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GSC_TEXTFILE + TFT_README), SetFill(1, 0), SetResize(1, 0), SetMinimalSize(93, 0), SetDataTip(STR_TEXTFILE_VIEW_README, STR_NULL),
EndContainer(),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(7, 0, 7),
NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GSC_TEXTFILE + TFT_CHANGELOG), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_CHANGELOG, STR_NULL),
NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GSC_TEXTFILE + TFT_LICENSE), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_TEXTFILE_VIEW_LICENCE, STR_NULL),
EndContainer(),
NWidget(WWT_PUSHTXTBTN, COLOUR_YELLOW, WID_GSC_CONTENT_DOWNLOAD), SetFill(1, 0), SetResize(1, 0), SetMinimalSize(279, 0), SetPadding(0, 7, 9, 7), SetDataTip(STR_INTRO_ONLINE_CONTENT, STR_INTRO_TOOLTIP_ONLINE_CONTENT),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(WWT_PUSHTXTBTN, COLOUR_MAUVE, WID_GSC_ACCEPT), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_AI_SETTINGS_CLOSE, STR_NULL),
NWidget(WWT_PUSHTXTBTN, COLOUR_MAUVE, WID_GSC_RESET), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_AI_SETTINGS_RESET, STR_NULL),
EndContainer(),
NWidget(WWT_RESIZEBOX, COLOUR_MAUVE),
EndContainer(),
};
/** Window definition for the configure GS window. */
static WindowDesc _gs_config_desc(
WDP_CENTER, "settings_gs_config", 500, 350,
WC_GAME_OPTIONS, WC_NONE,
0,
_nested_gs_config_widgets, lengthof(_nested_gs_config_widgets)
);
/**
* Window to configure which GSs will start.
*/
struct GSConfigWindow : public Window {
ScriptConfig* gs_config; ///< The configuration we're modifying.
int line_height; ///< Height of a single GS-name line.
int clicked_button; ///< The button we clicked.
bool clicked_increase; ///< Whether we clicked the increase or decrease button.
bool clicked_dropdown; ///< Whether the dropdown is open.
bool closing_dropdown; ///< True, if the dropdown list is currently closing.
GUITimer timeout; ///< Timeout for unclicking the button.
int clicked_row; ///< The clicked row of settings.
Scrollbar* vscroll; ///< Cache of the vertical scrollbar.
typedef std::vector<const ScriptConfigItem*> VisibleSettingsList; ///< typdef for a vector of script settings
VisibleSettingsList visible_settings; ///< List of visible GS settings
GSConfigWindow() : Window(&_gs_config_desc),
clicked_button(-1),
clicked_dropdown(false),
closing_dropdown(false),
timeout(0)
{
this->gs_config = GameConfig::GetConfig();
this->CreateNestedTree(); // Initializes 'this->line_height' as a side effect.
this->vscroll = this->GetScrollbar(WID_GSC_SCROLLBAR);
this->FinishInitNested(WN_GAME_OPTIONS_GS);
this->OnInvalidateData(0);
this->RebuildVisibleSettings();
}
void Close() override
{
CloseWindowByClass(WC_AI_LIST);
this->Window::Close();
}
/**
* Rebuilds the list of visible settings. GS settings with the flag
* GSCONFIG_GS_DEVELOPER set will only be visible if the game setting
* gui.ai_developer_tools is enabled.
*/
void RebuildVisibleSettings()
{
visible_settings.clear();
for (const auto& item : *this->gs_config->GetConfigList()) {
bool no_hide = (item.flags & SCRIPTCONFIG_DEVELOPER) == 0;
if (no_hide || _settings_client.gui.ai_developer_tools) {
visible_settings.push_back(&item);
}
}
this->vscroll->SetCount((int)this->visible_settings.size());
}
void UpdateWidgetSize(int widget, Dimension* size, const Dimension& padding, Dimension* fill, Dimension* resize) override
{
switch (widget) {
case WID_GSC_SETTINGS:
this->line_height = std::max(SETTING_BUTTON_HEIGHT, FONT_HEIGHT_NORMAL) + padding.height;
resize->width = 1;
resize->height = this->line_height;
size->height = 5 * this->line_height;
break;
case WID_GSC_GSLIST:
this->line_height = FONT_HEIGHT_NORMAL + padding.height;
size->height = 1 * this->line_height;
break;
}
}
/**
* Can the GS config be edited?
* @return True if the given GS Config slot can be edited, otherwise false.
*/
static bool IsEditable()
{
return _game_mode != GM_NORMAL || Game::GetInstance() != nullptr;
}
void DrawWidget(const Rect& r, int widget) const override
{
switch (widget) {
case WID_GSC_GSLIST: {
StringID text = STR_AI_CONFIG_NONE;
if (GameConfig::GetConfig()->GetInfo() != nullptr) {
SetDParamStr(0, GameConfig::GetConfig()->GetInfo()->GetName());
text = STR_JUST_RAW_STRING;
}
/* There is only one slot, unlike with the GS GUI, so it should never be white */
DrawString(r.Shrink(WidgetDimensions::scaled.matrix), text, (IsEditable() ? TC_ORANGE : TC_SILVER));
break;
}
case WID_GSC_SETTINGS: {
ScriptConfig* config = this->gs_config;
VisibleSettingsList::const_iterator it = this->visible_settings.begin();
int i = 0;
for (; !this->vscroll->IsVisible(i); i++) it++;
Rect ir = r.Shrink(WidgetDimensions::scaled.framerect);
bool rtl = _current_text_dir == TD_RTL;
Rect br = ir.WithWidth(SETTING_BUTTON_WIDTH, rtl);
Rect tr = ir.Indent(SETTING_BUTTON_WIDTH + WidgetDimensions::scaled.hsep_wide, rtl);
int y = r.top;
int button_y_offset = (this->line_height - SETTING_BUTTON_HEIGHT) / 2;
int text_y_offset = (this->line_height - FONT_HEIGHT_NORMAL) / 2;
for (; this->vscroll->IsVisible(i) && it != visible_settings.end(); i++, it++) {
const ScriptConfigItem& config_item = **it;
int current_value = config->GetSetting((config_item).name);
bool editable = this->IsEditableItem(config_item);
StringID str;
TextColour colour;
uint idx = 0;
if (StrEmpty(config_item.description)) {
if (!strcmp(config_item.name, "start_date")) {
/* Build-in translation */
str = STR_AI_SETTINGS_START_DELAY;
colour = TC_LIGHT_BLUE;
} else {
str = STR_JUST_STRING;
colour = TC_ORANGE;
}
} else {
str = STR_AI_SETTINGS_SETTING;
colour = TC_LIGHT_BLUE;
SetDParamStr(idx++, config_item.description);
}
if ((config_item.flags & SCRIPTCONFIG_BOOLEAN) != 0) {
DrawBoolButton(br.left, y + button_y_offset, current_value != 0, editable);
SetDParam(idx++, current_value == 0 ? STR_CONFIG_SETTING_OFF : STR_CONFIG_SETTING_ON);
} else {
if (config_item.complete_labels) {
DrawDropDownButton(br.left, y + button_y_offset, COLOUR_YELLOW, this->clicked_row == i && clicked_dropdown, editable);
} else {
DrawArrowButtons(br.left, y + button_y_offset, COLOUR_YELLOW, (this->clicked_button == i) ? 1 + (this->clicked_increase != rtl) : 0, editable && current_value > config_item.min_value, editable && current_value < config_item.max_value);
}
if (config_item.labels != nullptr && config_item.labels->Contains(current_value)) {
SetDParam(idx++, STR_JUST_RAW_STRING);
SetDParamStr(idx++, config_item.labels->Find(current_value)->second);
} else {
SetDParam(idx++, STR_JUST_INT);
SetDParam(idx++, current_value);
}
}
DrawString(tr.left, tr.right, y + text_y_offset, str, colour);
y += this->line_height;
}
break;
}
}
}
void OnPaint() override
{
if (this->closing_dropdown) {
this->closing_dropdown = false;
this->clicked_dropdown = false;
}
this->DrawWidgets();
}
void OnClick(Point pt, int widget, int click_count) override
{
if (widget >= WID_GSC_TEXTFILE && widget < WID_GSC_TEXTFILE + TFT_END) {
if (GameConfig::GetConfig() == nullptr) return;
ShowScriptTextfileWindow((TextfileType)(widget - WID_GSC_TEXTFILE), (CompanyID)OWNER_DEITY);
return;
}
switch (widget) {
case WID_GSC_GSLIST: {
this->InvalidateData();
if (click_count > 1 && _game_mode != GM_NORMAL) ShowAIListWindow((CompanyID)OWNER_DEITY);
break;
}
case WID_GSC_CHANGE: // choose other Game Script
ShowAIListWindow((CompanyID)OWNER_DEITY);
break;
case WID_GSC_CONTENT_DOWNLOAD:
if (!_network_available) {
ShowErrorMessage(STR_NETWORK_ERROR_NOTAVAILABLE, INVALID_STRING_ID, WL_ERROR);
} else {
ShowNetworkContentListWindow(nullptr, CONTENT_TYPE_GAME);
}
break;
case WID_GSC_SETTINGS: {
Rect r = this->GetWidget<NWidgetBase>(widget)->GetCurrentRect().Shrink(WidgetDimensions::scaled.matrix, RectPadding::zero);
int num = (pt.y - r.top) / this->line_height + this->vscroll->GetPosition();
if (num >= (int)this->visible_settings.size()) break;
VisibleSettingsList::const_iterator it = this->visible_settings.begin();
for (int i = 0; i < num; i++) it++;
const ScriptConfigItem config_item = **it;
if (!this->IsEditableItem(config_item)) return;
if (this->clicked_row != num) {
this->CloseChildWindows(WC_QUERY_STRING);
HideDropDownMenu(this);
this->clicked_row = num;
this->clicked_dropdown = false;
}
bool bool_item = (config_item.flags & SCRIPTCONFIG_BOOLEAN) != 0;
int x = pt.x - r.left;
if (_current_text_dir == TD_RTL) x = r.Width() - 1 - x;
/* One of the arrows is clicked (or green/red rect in case of bool value) */
int old_val = this->gs_config->GetSetting(config_item.name);
if (!bool_item && IsInsideMM(x, 0, SETTING_BUTTON_WIDTH) && config_item.complete_labels) {
if (this->clicked_dropdown) {
/* unclick the dropdown */
HideDropDownMenu(this);
this->clicked_dropdown = false;
this->closing_dropdown = false;
} else {
int rel_y = (pt.y - r.top) % this->line_height;
Rect wi_rect;
wi_rect.left = pt.x - (_current_text_dir == TD_RTL ? SETTING_BUTTON_WIDTH - 1 - x : x);
wi_rect.right = wi_rect.left + SETTING_BUTTON_WIDTH - 1;
wi_rect.top = pt.y - rel_y + (this->line_height - SETTING_BUTTON_HEIGHT) / 2;
wi_rect.bottom = wi_rect.top + SETTING_BUTTON_HEIGHT - 1;
/* If the mouse is still held but dragged outside of the dropdown list, keep the dropdown open */
if (pt.y >= wi_rect.top && pt.y <= wi_rect.bottom) {
this->clicked_dropdown = true;
this->closing_dropdown = false;
DropDownList list;
for (int i = config_item.min_value; i <= config_item.max_value; i++) {
list.emplace_back(new DropDownListCharStringItem(config_item.labels->Find(i)->second, i, false));
}
ShowDropDownListAt(this, std::move(list), old_val, -1, wi_rect, COLOUR_ORANGE, true);
}
}
} else if (IsInsideMM(x, 0, SETTING_BUTTON_WIDTH)) {
int new_val = old_val;
if (bool_item) {
new_val = !new_val;
} else if (x >= SETTING_BUTTON_WIDTH / 2) {
/* Increase button clicked */
new_val += config_item.step_size;
if (new_val > config_item.max_value) new_val = config_item.max_value;
this->clicked_increase = true;
} else {
/* Decrease button clicked */
new_val -= config_item.step_size;
if (new_val < config_item.min_value) new_val = config_item.min_value;
this->clicked_increase = false;
}
if (new_val != old_val) {
this->gs_config->SetSetting(config_item.name, new_val);
this->clicked_button = num;
this->timeout.SetInterval(150);
}
} else if (!bool_item && !config_item.complete_labels) {
/* Display a query box so users can enter a custom value. */
SetDParam(0, old_val);
ShowQueryString(STR_JUST_INT, STR_CONFIG_SETTING_QUERY_CAPTION, 10, this, CS_NUMERAL, QSF_NONE);
}
this->SetDirty();
break;
}
case WID_GSC_ACCEPT:
this->Close();
break;
case WID_GSC_RESET:
this->gs_config->ResetEditableSettings(_game_mode == GM_MENU);
this->SetDirty();
break;
}
}
void OnQueryTextFinished(char* str) override
{
if (StrEmpty(str)) return;
int32 value = atoi(str);
SetValue(value);
}
void OnDropdownSelect(int widget, int index) override
{
assert(this->clicked_dropdown);
SetValue(index);
}
void OnDropdownClose(Point pt, int widget, int index, bool instant_close) override
{
/* We cannot raise the dropdown button just yet. OnClick needs some hint, whether
* the same dropdown button was clicked again, and then not open the dropdown again.
* So, we only remember that it was closed, and process it on the next OnPaint, which is
* after OnClick. */
assert(this->clicked_dropdown);
this->closing_dropdown = true;
this->SetDirty();
}
void OnResize() override
{
this->vscroll->SetCapacityFromWidget(this, WID_GSC_SETTINGS);
}
void OnRealtimeTick(uint delta_ms) override
{
if (this->timeout.Elapsed(delta_ms)) {
this->clicked_button = -1;
this->SetDirty();
}
}
/**
* Some data on this window has become invalid.
* @param data Information about the changed data.
* @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details.
*/
void OnInvalidateData(int data = 0, bool gui_scope = true) override
{
if (!gui_scope) return;
this->SetWidgetDisabledState(WID_GSC_CHANGE, (_game_mode == GM_NORMAL) || !IsEditable());
for (TextfileType tft = TFT_BEGIN; tft < TFT_END; tft++) {
this->SetWidgetDisabledState(WID_GSC_TEXTFILE + tft, GameConfig::GetConfig()->GetTextfile(tft, (CompanyID)OWNER_DEITY) == nullptr);
}
this->RebuildVisibleSettings();
HideDropDownMenu(this);
this->CloseChildWindows(WC_QUERY_STRING);
}
private:
bool IsEditableItem(const ScriptConfigItem &config_item) const
{
return _game_mode == GM_MENU
|| _game_mode == GM_EDITOR
|| (config_item.flags & SCRIPTCONFIG_INGAME) != 0
|| _settings_client.gui.ai_developer_tools;
}
void SetValue(int value)
{
VisibleSettingsList::const_iterator it = this->visible_settings.begin();
for (int i = 0; i < this->clicked_row; i++) it++;
const ScriptConfigItem config_item = **it;
if (_game_mode == GM_NORMAL && (config_item.flags & SCRIPTCONFIG_INGAME) == 0) return;
this->gs_config->SetSetting(config_item.name, value);
this->SetDirty();
}
};
/** Open the GS config window. */
void ShowGSConfigWindow()
{
CloseWindowByClass(WC_GAME_OPTIONS);
new GSConfigWindow();
}

15
src/game/game_gui.hpp Normal file
View File

@@ -0,0 +1,15 @@
/*
* This file is part of OpenTTD.
* OpenTTD is free software; you can redistribute itand /or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
* See the GNU General Public License for more details.You should have received a copy of the GNU General Public License along with OpenTTD.If not, see < http://www.gnu.org/licenses/>.
*/
/** @file game_gui.hpp %Window for configuring the Games */
#ifndef GAME_GUI_HPP
#define GAME_GUI_HPP
void ShowGSConfigWindow();
#endif /* AI_GUI_HPP */

View File

@@ -30,6 +30,8 @@
#include "newgrf_townname.h"
#include "townname_type.h"
#include "video/video_driver.hpp"
#include "ai/ai_gui.hpp"
#include "game/game_gui.hpp"
#include "widgets/genworld_widget.h"
@@ -86,38 +88,42 @@ static const NWidgetPart _nested_generate_landscape_widgets[] = {
NWidget(NWID_SPACER), SetFill(1, 0),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 11),
/* Generation options. */
NWidget(NWID_HORIZONTAL), SetPIP(10, 5, 10),
NWidget(NWID_HORIZONTAL), SetPIP(0, 3, 0),
/* Left column with labels. */
NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(0, 4, 0),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_MAPSIZE, STR_MAPGEN_MAPSIZE_TOOLTIP), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_LAND_GENERATOR, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_TERRAIN_TYPE, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_VARIETY, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_QUANTITY_OF_SEA_LAKES, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_NUMBER_OF_TOWNS, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_NUMBER_OF_INDUSTRIES, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_BORDER_TYPE, STR_NULL), SetFill(1, 1),
EndContainer(),
/* Widgets at the right of the labels. */
NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(0, 4, 0),
/* Mapsize X * Y. */
NWidget(NWID_HORIZONTAL), SetPIP(0, 4, 0),
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_MAPSIZE_X_PULLDOWN), SetDataTip(STR_JUST_INT, STR_MAPGEN_MAPSIZE_TOOLTIP), SetFill(1, 0),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_BY, STR_NULL), SetPadding(1, 0, 0, 0), SetFill(1, 1),
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_MAPSIZE_Y_PULLDOWN), SetDataTip(STR_JUST_INT, STR_MAPGEN_MAPSIZE_TOOLTIP), SetFill(1, 0),
/* Left half (land generation options) */
NWidget(NWID_VERTICAL),
NWidget(NWID_HORIZONTAL), SetPIP(0, 3, 0),
/* Labels on the left side (global column 1). */
NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(0, 4, 0),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_MAPSIZE, STR_MAPGEN_MAPSIZE_TOOLTIP), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_LAND_GENERATOR, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_TERRAIN_TYPE, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_VARIETY, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_SMOOTHNESS, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_QUANTITY_OF_RIVERS, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_BORDER_TYPE, STR_NULL), SetFill(1, 1),
EndContainer(),
/* Widgets on the right side (global column 2). */
NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(0, 4, 0),
/* Mapsize X * Y. */
NWidget(NWID_HORIZONTAL), SetPIP(0, 4, 0),
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_MAPSIZE_X_PULLDOWN), SetDataTip(STR_JUST_INT, STR_MAPGEN_MAPSIZE_TOOLTIP), SetFill(1, 0),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_BY, STR_NULL), SetPadding(1, 0, 0, 0), SetFill(1, 1),
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_MAPSIZE_Y_PULLDOWN), SetDataTip(STR_JUST_INT, STR_MAPGEN_MAPSIZE_TOOLTIP), SetFill(1, 0),
EndContainer(),
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_LANDSCAPE_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TERRAIN_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_VARIETY_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_SMOOTHNESS_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_RIVER_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_BORDERS_RANDOM), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
EndContainer(),
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_LANDSCAPE_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TERRAIN_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_VARIETY_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_WATER_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TOWN_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_INDUSTRY_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_BORDERS_RANDOM), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
EndContainer(),
EndContainer(),
NWidget(NWID_VERTICAL), SetPIP(0, 4, 0),
/* Right half (all other options) */
NWidget(NWID_VERTICAL),
NWidget(NWID_HORIZONTAL), SetPIP(0, 3, 0),
/* Labels on the left side (global column 3). */
NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(0, 4, 0),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GL_CLIMATE_SEL_LABEL),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_SNOW_COVERAGE, STR_NULL), SetFill(1, 1),
@@ -125,11 +131,14 @@ static const NWidgetPart _nested_generate_landscape_widgets[] = {
NWidget(NWID_SPACER),
EndContainer(),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_DATE, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_SMOOTHNESS, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_QUANTITY_OF_RIVERS, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_GAME_OPTIONS_TOWN_NAMES_FRAME, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_TOWN_NAME_LABEL, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_NUMBER_OF_TOWNS, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_NUMBER_OF_INDUSTRIES, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_SEA_LEVEL, STR_NULL), SetFill(1, 1),
EndContainer(),
/* Widgets on the right side (global column 4). */
NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(0, 4, 0),
/* Climate selector. */
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GL_CLIMATE_SEL_SELECTOR),
/* Snow coverage. */
NWidget(NWID_HORIZONTAL),
@@ -143,7 +152,7 @@ static const NWidgetPart _nested_generate_landscape_widgets[] = {
NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_DESERT_COVERAGE_TEXT), SetDataTip(STR_MAPGEN_DESERT_COVERAGE_TEXT, STR_NULL), SetFill(1, 0),
NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_DESERT_COVERAGE_UP), SetDataTip(SPR_ARROW_UP, STR_MAPGEN_DESERT_COVERAGE_UP), SetFill(0, 1),
EndContainer(),
/* Temperate/Toyland spacer */
/* Temperate/Toyland spacer. */
NWidget(NWID_SPACER),
EndContainer(),
/* Starting date. */
@@ -152,12 +161,12 @@ static const NWidgetPart _nested_generate_landscape_widgets[] = {
NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_START_DATE_TEXT), SetDataTip(STR_BLACK_DATE_LONG, STR_NULL), SetFill(1, 0),
NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_START_DATE_UP), SetDataTip(SPR_ARROW_UP, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_FORWARD), SetFill(0, 1),
EndContainer(),
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_SMOOTHNESS_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_RIVER_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TOWNNAME_DROPDOWN), SetDataTip(STR_BLACK_STRING, STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP), SetFill(1, 0),
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TOWNNAME_DROPDOWN), SetDataTip(STR_BLACK_STRING, STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP), SetFill(1, 0),
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TOWN_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_INDUSTRY_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_WATER_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
EndContainer(),
EndContainer(),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_GL_GENERATE_BUTTON), SetMinimalSize(84, 0), SetDataTip(STR_MAPGEN_GENERATE, STR_NULL), SetFill(1, 1),
EndContainer(),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 4),
@@ -186,6 +195,16 @@ static const NWidgetPart _nested_generate_landscape_widgets[] = {
NWidget(NWID_SPACER), SetFill(1, 1),
EndContainer(),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 6), SetFill(1, 1),
/* AI, GS, and NewGRF settings */
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(10, 0, 10),
NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_AI_BUTTON), SetMinimalSize(0, 24), SetDataTip(STR_MAPGEN_AI_SETTINGS, STR_MAPGEN_AI_SETTINGS_TOOLTIP), SetFill(1, 0),
NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_GS_BUTTON), SetMinimalSize(0, 24), SetDataTip(STR_MAPGEN_GS_SETTINGS, STR_MAPGEN_GS_SETTINGS_TOOLTIP), SetFill(1, 0),
NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_NEWGRF_BUTTON), SetMinimalSize(0, 24), SetDataTip(STR_MAPGEN_NEWGRF_SETTINGS, STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP), SetFill(1, 0),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 7), SetFill(1, 1),
/* Generate */
NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_GL_GENERATE_BUTTON), SetMinimalSize(84, 36), SetDataTip(STR_MAPGEN_GENERATE, STR_NULL), SetPadding(0, 10, 0, 10), SetFill(1, 1),
NWidget(NWID_SPACER), SetMinimalSize(0, 9), SetFill(1, 1),
EndContainer(),
};
@@ -212,21 +231,24 @@ static const NWidgetPart _nested_heightmap_load_widgets[] = {
NWidget(NWID_SPACER), SetFill(1, 0),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 11), SetFill(0, 1),
/* Generation options. */
NWidget(NWID_HORIZONTAL), SetPIP(10, 3, 10),
/* Labels at the left side. */
/* Left half labels (global column 1) and heightmap name label */
NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(0, 4, 0),
/* Heightmap name label. */
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_HEIGHTMAP_NAME, STR_NULL), SetFill(1, 1),
/* Land generation option labels */
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_HEIGHTMAP_SIZE_LABEL, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_MAPSIZE, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_HEIGHTMAP_ROTATION, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_NUMBER_OF_TOWNS, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_NUMBER_OF_INDUSTRIES, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_HEIGHTMAP_HEIGHT, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_QUANTITY_OF_RIVERS, STR_NULL), SetFill(1, 1),
EndContainer(),
/* Widgets at the right of the labels. */
/* All other columns. */
NWidget(NWID_VERTICAL), SetPIP(0, 4, 0),
NWidget(WWT_TEXT, COLOUR_ORANGE, WID_GL_HEIGHTMAP_NAME_TEXT), SetTextColour(TC_ORANGE), SetDataTip(STR_JUST_RAW_STRING, STR_EMPTY), SetFill(1, 0),
NWidget(NWID_HORIZONTAL), SetPIP(0, 5, 0),
/* Left half widgets (global column 2) */
NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(0, 4, 0),
NWidget(WWT_TEXT, COLOUR_ORANGE, WID_GL_HEIGHTMAP_SIZE_TEXT), SetDataTip(STR_MAPGEN_HEIGHTMAP_SIZE, STR_NULL), SetFill(1, 0),
/* Mapsize X * Y. */
@@ -236,54 +258,72 @@ static const NWidgetPart _nested_heightmap_load_widgets[] = {
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_MAPSIZE_Y_PULLDOWN), SetDataTip(STR_JUST_INT, STR_NULL), SetFill(1, 0),
EndContainer(),
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_HEIGHTMAP_ROTATION_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TOWN_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_INDUSTRY_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
/* Heightmap highest peak. */
NWidget(NWID_HORIZONTAL),
NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_HEIGHTMAP_HEIGHT_DOWN), SetDataTip(SPR_ARROW_DOWN, STR_MAPGEN_HEIGHTMAP_HEIGHT_DOWN), SetFill(0, 1),
NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_HEIGHTMAP_HEIGHT_TEXT), SetDataTip(STR_BLACK_INT, STR_NULL), SetFill(1, 0),
NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_HEIGHTMAP_HEIGHT_UP), SetDataTip(SPR_ARROW_UP, STR_MAPGEN_HEIGHTMAP_HEIGHT_UP), SetFill(0, 1),
EndContainer(),
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_RIVER_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
EndContainer(),
NWidget(NWID_VERTICAL), SetPIP(0, 4, 0),
NWidget(NWID_HORIZONTAL), SetPIP(0, 3, 0),
/* Right half labels (global column 3) */
NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(0, 4, 0),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_HEIGHTMAP_HEIGHT, STR_NULL), SetFill(1, 1),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GL_CLIMATE_SEL_LABEL),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_SNOW_COVERAGE, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_DESERT_COVERAGE, STR_NULL), SetFill(1, 1),
NWidget(NWID_SPACER),
EndContainer(),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_DATE, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_GAME_OPTIONS_TOWN_NAMES_FRAME, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_TOWN_NAME_LABEL, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_NUMBER_OF_TOWNS, STR_NULL), SetFill(1, 1),
NWidget(WWT_TEXT, COLOUR_ORANGE), SetDataTip(STR_MAPGEN_NUMBER_OF_INDUSTRIES, STR_NULL), SetFill(1, 1),
EndContainer(),
/* Right half widgets (global column 4) */
NWidget(NWID_VERTICAL, NC_EQUALSIZE), SetPIP(0, 4, 0),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_HEIGHTMAP_HEIGHT_DOWN), SetDataTip(SPR_ARROW_DOWN, STR_MAPGEN_HEIGHTMAP_HEIGHT_DOWN), SetFill(0, 1),
NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_HEIGHTMAP_HEIGHT_TEXT), SetDataTip(STR_BLACK_INT, STR_NULL), SetFill(1, 0),
NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_HEIGHTMAP_HEIGHT_UP), SetDataTip(SPR_ARROW_UP, STR_MAPGEN_HEIGHTMAP_HEIGHT_UP), SetFill(0, 1),
EndContainer(),
/* Climate selector. */
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GL_CLIMATE_SEL_SELECTOR),
/* Snow coverage. */
NWidget(NWID_HORIZONTAL),
NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_SNOW_COVERAGE_DOWN), SetDataTip(SPR_ARROW_DOWN, STR_MAPGEN_SNOW_COVERAGE_DOWN), SetFill(0, 1),
NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_SNOW_COVERAGE_TEXT), SetDataTip(STR_MAPGEN_SNOW_COVERAGE_TEXT, STR_NULL), SetFill(1, 0),
NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_SNOW_COVERAGE_UP), SetDataTip(SPR_ARROW_UP, STR_MAPGEN_SNOW_COVERAGE_UP), SetFill(0, 1),
EndContainer(),
/* Desert coverage. */
NWidget(NWID_HORIZONTAL),
NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_DESERT_COVERAGE_DOWN), SetDataTip(SPR_ARROW_DOWN, STR_MAPGEN_DESERT_COVERAGE_DOWN), SetFill(0, 1),
NWidget(WWT_TEXTBTN, COLOUR_ORANGE, WID_GL_DESERT_COVERAGE_TEXT), SetDataTip(STR_MAPGEN_DESERT_COVERAGE_TEXT, STR_NULL), SetFill(1, 0),
NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_DESERT_COVERAGE_UP), SetDataTip(SPR_ARROW_UP, STR_MAPGEN_DESERT_COVERAGE_UP), SetFill(0, 1),
EndContainer(),
/* Temperate/Toyland spacer. */
NWidget(NWID_SPACER),
EndContainer(),
/* Starting date. */
NWidget(NWID_HORIZONTAL),
NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_START_DATE_DOWN), SetDataTip(SPR_ARROW_DOWN, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_BACKWARD), SetFill(0, 1),
NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_START_DATE_TEXT), SetDataTip(STR_BLACK_DATE_LONG, STR_NULL), SetFill(1, 0),
NWidget(WWT_IMGBTN, COLOUR_ORANGE, WID_GL_START_DATE_UP), SetDataTip(SPR_ARROW_UP, STR_SCENEDIT_TOOLBAR_TOOLTIP_MOVE_THE_STARTING_DATE_FORWARD), SetFill(0, 1),
EndContainer(),
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TOWNNAME_DROPDOWN), SetDataTip(STR_BLACK_STRING, STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP), SetFill(1, 0),
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TOWNNAME_DROPDOWN), SetDataTip(STR_BLACK_STRING, STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP), SetFill(1, 0),
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_TOWN_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
NWidget(WWT_DROPDOWN, COLOUR_ORANGE, WID_GL_INDUSTRY_PULLDOWN), SetDataTip(STR_JUST_STRING, STR_NULL), SetFill(1, 0),
EndContainer(),
EndContainer(),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_GL_GENERATE_BUTTON), SetMinimalSize(84, 0), SetDataTip(STR_MAPGEN_GENERATE, STR_NULL), SetFill(1, 1),
EndContainer(),
EndContainer(),
EndContainer(),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 6), SetFill(1, 1),
/* AI, GS, and NewGRF settings */
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE), SetPIP(10, 0, 10),
NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_AI_BUTTON), SetMinimalSize(0, 24), SetDataTip(STR_MAPGEN_AI_SETTINGS, STR_MAPGEN_AI_SETTINGS_TOOLTIP), SetFill(1, 0),
NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_GS_BUTTON), SetMinimalSize(0, 24), SetDataTip(STR_MAPGEN_GS_SETTINGS, STR_MAPGEN_GS_SETTINGS_TOOLTIP), SetFill(1, 0),
NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_GL_NEWGRF_BUTTON), SetMinimalSize(0, 24), SetDataTip(STR_MAPGEN_NEWGRF_SETTINGS, STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP), SetFill(1, 0),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 7), SetFill(1, 1),
/* Generate */
NWidget(WWT_PUSHTXTBTN, COLOUR_GREEN, WID_GL_GENERATE_BUTTON), SetMinimalSize(84, 36), SetDataTip(STR_MAPGEN_GENERATE, STR_NULL), SetPadding(0, 10, 0, 10), SetFill(1, 1),
NWidget(NWID_SPACER), SetMinimalSize(0, 9), SetFill(1, 1),
EndContainer(),
};
@@ -344,7 +384,7 @@ static DropDownList BuildTownNameDropDown()
/* Add and sort original townnames generators */
for (uint i = 0; i < BUILTIN_TOWNNAME_GENERATOR_COUNT; i++) {
list.emplace_back(new DropDownListStringItem(STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH + i, i, false));
list.emplace_back(new DropDownListStringItem(STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH + i, i, false));
}
std::sort(list.begin() + newgrf_size, list.end(), DropDownListStringItem::NatSortFunc);
@@ -415,7 +455,7 @@ struct GenerateLandscapeWindow : public Window {
case WID_GL_TOWNNAME_DROPDOWN: {
uint gen = _settings_newgame.game_creation.town_name;
StringID name = gen < BUILTIN_TOWNNAME_GENERATOR_COUNT ?
STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH + gen :
STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH + gen :
GetGRFTownNameName(gen - BUILTIN_TOWNNAME_GENERATOR_COUNT);
SetDParam(0, name);
break;
@@ -622,7 +662,7 @@ struct GenerateLandscapeWindow : public Window {
}
}
size->width += padding.width;
size->height = std::max(size->height, (uint)(FONT_HEIGHT_NORMAL + WD_DROPDOWNTEXT_TOP + WD_DROPDOWNTEXT_BOTTOM));
size->height = std::max(size->height, (uint)(FONT_HEIGHT_NORMAL + padding.height));
}
void OnClick(Point pt, int widget, int click_count) override
@@ -815,6 +855,18 @@ struct GenerateLandscapeWindow : public Window {
_settings_newgame.game_creation.water_borders = (_settings_newgame.game_creation.water_borders == BORDERS_RANDOM) ? 0 : BORDERS_RANDOM;
this->InvalidateData();
break;
case WID_GL_AI_BUTTON: ///< AI Settings
ShowAIConfigWindow();
break;
case WID_GL_GS_BUTTON: ///< Game Script Settings
ShowGSConfigWindow();
break;
case WID_GL_NEWGRF_BUTTON: ///< NewGRF Settings
ShowNewGRFSettings(true, true, false, &_grfconfig_newgame);
break;
}
}
@@ -882,7 +934,7 @@ struct GenerateLandscapeWindow : public Window {
if ((uint)index == CUSTOM_SEA_LEVEL_NUMBER_DIFFICULTY) {
this->widget_id = widget;
SetDParam(0, _settings_newgame.game_creation.custom_sea_level);
ShowQueryString(STR_JUST_INT, STR_MAPGEN_QUANTITY_OF_SEA_LAKES, 3, this, CS_NUMERAL, QSF_NONE);
ShowQueryString(STR_JUST_INT, STR_MAPGEN_SEA_LEVEL, 3, this, CS_NUMERAL, QSF_NONE);
}
_settings_newgame.difficulty.quantity_sea_lakes = index;
break;
@@ -1270,12 +1322,10 @@ void ShowCreateScenario()
static const NWidgetPart _nested_generate_progress_widgets[] = {
NWidget(WWT_CAPTION, COLOUR_GREY), SetDataTip(STR_GENERATION_WORLD, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
NWidget(WWT_PANEL, COLOUR_GREY),
NWidget(NWID_HORIZONTAL), SetPIP(20, 0, 20),
NWidget(NWID_VERTICAL), SetPIP(11, 8, 11),
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GP_PROGRESS_BAR), SetFill(1, 0),
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GP_PROGRESS_TEXT), SetFill(1, 0),
NWidget(WWT_TEXTBTN, COLOUR_WHITE, WID_GP_ABORT), SetDataTip(STR_GENERATION_ABORT, STR_NULL), SetFill(1, 0),
EndContainer(),
NWidget(NWID_VERTICAL), SetPIP(0, WidgetDimensions::unscaled.vsep_wide, 0), SetPadding(WidgetDimensions::unscaled.modalpopup),
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GP_PROGRESS_BAR), SetFill(1, 0),
NWidget(WWT_EMPTY, INVALID_COLOUR, WID_GP_PROGRESS_TEXT), SetFill(1, 0),
NWidget(WWT_TEXTBTN, COLOUR_WHITE, WID_GP_ABORT), SetDataTip(STR_GENERATION_ABORT, STR_NULL), SetFill(1, 0),
EndContainer(),
EndContainer(),
};
@@ -1353,8 +1403,8 @@ struct GenerateProgressWindow : public Window {
SetDParamMaxValue(0, 100);
*size = GetStringBoundingBox(STR_GENERATION_PROGRESS);
/* We need some spacing for the 'border' */
size->height += 8;
size->width += 8;
size->height += WidgetDimensions::scaled.frametext.Horizontal();
size->width += WidgetDimensions::scaled.frametext.Vertical();
break;
}
@@ -1362,7 +1412,7 @@ struct GenerateProgressWindow : public Window {
for (uint i = 0; i < GWP_CLASS_COUNT; i++) {
size->width = std::max(size->width, GetStringBoundingBox(_generation_class_table[i]).width);
}
size->height = FONT_HEIGHT_NORMAL * 2 + WD_PAR_VSEP_NORMAL;
size->height = FONT_HEIGHT_NORMAL * 2 + WidgetDimensions::scaled.vsep_normal;
break;
}
}
@@ -1370,13 +1420,15 @@ struct GenerateProgressWindow : public Window {
void DrawWidget(const Rect &r, int widget) const override
{
switch (widget) {
case WID_GP_PROGRESS_BAR:
case WID_GP_PROGRESS_BAR: {
/* Draw the % complete with a bar and a text */
DrawFrameRect(r.left, r.top, r.right, r.bottom, COLOUR_GREY, FR_BORDERONLY);
DrawFrameRect(r.left + 1, r.top + 1, (int)((r.right - r.left - 2) * _gws.percent / 100) + r.left + 1, r.bottom - 1, COLOUR_MAUVE, FR_NONE);
DrawFrameRect(r, COLOUR_GREY, FR_BORDERONLY | FR_LOWERED);
Rect br = r.Shrink(WidgetDimensions::scaled.bevel);
DrawFrameRect(br.WithWidth(br.Width() * _gws.percent / 100, false), COLOUR_MAUVE, FR_NONE);
SetDParam(0, _gws.percent);
DrawString(r.left, r.right, r.top + 5, STR_GENERATION_PROGRESS, TC_FROMSTRING, SA_HOR_CENTER);
DrawString(br.left, br.right, CenterBounds(br.top, br.bottom, FONT_HEIGHT_NORMAL), STR_GENERATION_PROGRESS, TC_FROMSTRING, SA_HOR_CENTER);
break;
}
case WID_GP_PROGRESS_TEXT:
/* Tell which class we are generating */
@@ -1385,7 +1437,7 @@ struct GenerateProgressWindow : public Window {
/* And say where we are in that class */
SetDParam(0, _gws.current);
SetDParam(1, _gws.total);
DrawString(r.left, r.right, r.top + FONT_HEIGHT_NORMAL + WD_PAR_VSEP_NORMAL, STR_GENERATION_PROGRESS_NUM, TC_FROMSTRING, SA_HOR_CENTER);
DrawString(r.left, r.right, r.top + FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_normal, STR_GENERATION_PROGRESS_NUM, TC_FROMSTRING, SA_HOR_CENTER);
}
}
};

View File

@@ -61,12 +61,9 @@ static void GfxMainBlitter(const Sprite *sprite, int x, int y, BlitterMode mode,
static ReusableBuffer<uint8> _cursor_backup;
ZoomLevel _gui_zoom; ///< GUI Zoom level
ZoomLevel _font_zoom; ///< Font Zoom level
int8 _gui_zoom_cfg; ///< GUI zoom level in config.
int8 _font_zoom_cfg; ///< Font zoom level in config.
ZoomLevel _gui_zoom = ZOOM_LVL_OUT_4X; ///< GUI Zoom level
int _gui_scale = MIN_INTERFACE_SCALE; ///< GUI scale, 100 is 100%.
int _gui_scale_cfg; ///< GUI scale in config.
/**
* The rect for repaint.
@@ -564,6 +561,8 @@ static int DrawLayoutLine(const ParagraphLayouter::Line &line, int y, int left,
NOT_REACHED();
}
const uint shadow_offset = ScaleGUITrad(1);
TextColour colour = TC_BLACK;
bool draw_shadow = false;
for (int run_index = 0; run_index < line.CountRuns(); run_index++) {
@@ -599,7 +598,7 @@ static int DrawLayoutLine(const ParagraphLayouter::Line &line, int y, int left,
if (draw_shadow && (glyph & SPRITE_GLYPH) == 0) {
SetColourRemap(TC_BLACK);
GfxMainBlitter(sprite, begin_x + 1, top + 1, BM_COLOUR_REMAP);
GfxMainBlitter(sprite, begin_x + shadow_offset, top + shadow_offset, BM_COLOUR_REMAP);
SetColourRemap(colour);
}
GfxMainBlitter(sprite, begin_x, top, BM_COLOUR_REMAP);
@@ -611,7 +610,7 @@ static int DrawLayoutLine(const ParagraphLayouter::Line &line, int y, int left,
for (int i = 0; i < 3; i++, x += dot_width) {
if (draw_shadow) {
SetColourRemap(TC_BLACK);
GfxMainBlitter(dot_sprite, x + 1, y + 1, BM_COLOUR_REMAP);
GfxMainBlitter(dot_sprite, x + shadow_offset, y + shadow_offset, BM_COLOUR_REMAP);
SetColourRemap(colour);
}
GfxMainBlitter(dot_sprite, x, y, BM_COLOUR_REMAP);
@@ -915,12 +914,27 @@ Dimension GetStringBoundingBox(const std::string &str, FontSize start_fontsize)
* @param strid String to examine.
* @return Width and height of the bounding box for the string in pixels.
*/
Dimension GetStringBoundingBox(StringID strid)
Dimension GetStringBoundingBox(StringID strid, FontSize start_fontsize)
{
char buffer[DRAW_STRING_BUFFER];
GetString(buffer, strid, lastof(buffer));
return GetStringBoundingBox(buffer);
return GetStringBoundingBox(buffer, start_fontsize);
}
/**
* Get maximum width of a list of strings.
* @param list List of strings, terminated with INVALID_STRING_ID.
* @param fontsize Font size to use.
* @return Width of longest string within the list.
*/
uint GetStringListWidth(const StringID *list, FontSize fontsize)
{
uint width = 0;
for (const StringID *str = list; *str != INVALID_STRING_ID; str++) {
width = std::max(width, GetStringBoundingBox(*str, fontsize).width);
}
return width;
}
/**
@@ -2026,48 +2040,52 @@ void SortResolutions()
void UpdateGUIZoom()
{
/* Determine real GUI zoom to use. */
if (_gui_zoom_cfg == ZOOM_LVL_CFG_AUTO) {
_gui_zoom = static_cast<ZoomLevel>(Clamp(VideoDriver::GetInstance()->GetSuggestedUIZoom(), _settings_client.gui.zoom_min, _settings_client.gui.zoom_max));
if (_gui_scale_cfg == -1) {
_gui_scale = VideoDriver::GetInstance()->GetSuggestedUIScale();
} else {
/* Ensure the gui_zoom is clamped between min/max. Change the
* _gui_zoom_cfg if it isn't, as this is used to visually show the
* selection in the Game Options. */
_gui_zoom_cfg = Clamp(_gui_zoom_cfg, _settings_client.gui.zoom_min, _settings_client.gui.zoom_max);
_gui_zoom = static_cast<ZoomLevel>(_gui_zoom_cfg);
_gui_scale = Clamp(_gui_scale_cfg, MIN_INTERFACE_SCALE, MAX_INTERFACE_SCALE);
}
/* Determine real font zoom to use. */
if (_font_zoom_cfg == ZOOM_LVL_CFG_AUTO) {
_font_zoom = static_cast<ZoomLevel>(VideoDriver::GetInstance()->GetSuggestedUIZoom());
} else {
_font_zoom = static_cast<ZoomLevel>(_font_zoom_cfg);
}
int8 new_zoom = ScaleGUITrad(1) <= 1 ? ZOOM_LVL_OUT_4X : ScaleGUITrad(1) >= 4 ? ZOOM_LVL_MIN : ZOOM_LVL_OUT_2X;
/* Ensure the gui_zoom is clamped between min/max. */
new_zoom = Clamp(new_zoom, _settings_client.gui.zoom_min, _settings_client.gui.zoom_max);
_gui_zoom = static_cast<ZoomLevel>(new_zoom);
}
/**
* Resolve GUI zoom level and adjust GUI to new zoom, if auto-suggestion is requested.
* @param automatic Set if the change is occuring due to OS DPI scaling being changed.
* @returns true when the zoom level has changed, caller must call ReInitAllWindows(true)
* after resizing the application's window/buffer.
*/
bool AdjustGUIZoom()
bool AdjustGUIZoom(bool automatic)
{
auto old_zoom = _gui_zoom;
ZoomLevel old_zoom = _gui_zoom;
int old_scale = _gui_scale;
UpdateGUIZoom();
if (old_zoom == _gui_zoom) return false;
GfxClearSpriteCache();
VideoDriver::GetInstance()->ClearSystemSprites();
if (old_scale == _gui_scale) return false;
/* Reload sprites if sprite zoom level has changed. */
if (old_zoom != _gui_zoom) {
GfxClearSpriteCache();
VideoDriver::GetInstance()->ClearSystemSprites();
UpdateCursorSize();
}
ClearFontCache();
GfxClearSpriteCache();
LoadStringWidthTable();
UpdateAllVirtCoords();
/* Adjust all window sizes to match the new zoom level, so that they don't appear
to move around when the application is moved to a screen with different DPI. */
auto zoom_shift = old_zoom - _gui_zoom;
for (Window *w : Window::Iterate()) {
w->left = AdjustByZoom(w->left, zoom_shift);
w->top = AdjustByZoom(w->top, zoom_shift);
w->width = AdjustByZoom(w->width, zoom_shift);
w->height = AdjustByZoom(w->height, zoom_shift);
if (automatic) {
w->left = (w->left * _gui_scale) / old_scale;
w->top = (w->top * _gui_scale) / old_scale;
w->width = (w->width * _gui_scale) / old_scale;
w->height = (w->height * _gui_scale) / old_scale;
}
if (w->viewport != nullptr) {
w->viewport->zoom = Clamp(ZoomLevel(w->viewport->zoom - zoom_shift), _settings_client.gui.zoom_min, _settings_client.gui.zoom_max);
}

View File

@@ -79,8 +79,7 @@ void ChangeGameSpeed(bool enable_fast_forward);
void DrawMouseCursor();
void ScreenSizeChanged();
void GameSizeChanged();
void UpdateGUIZoom();
bool AdjustGUIZoom();
bool AdjustGUIZoom(bool automatic);
void UndrawMouseCursor();
/** Size of the buffer used for drawing strings. */
@@ -90,8 +89,10 @@ void RedrawScreenRect(int left, int top, int right, int bottom);
void GfxScroll(int left, int top, int width, int height, int xo, int yo);
Dimension GetSpriteSize(SpriteID sprid, Point *offset = nullptr, ZoomLevel zoom = ZOOM_LVL_GUI);
Dimension GetScaledSpriteSize(SpriteID sprid); /* widget.cpp */
void DrawSpriteViewport(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub = nullptr);
void DrawSprite(SpriteID img, PaletteID pal, int x, int y, const SubSprite *sub = nullptr, ZoomLevel zoom = ZOOM_LVL_GUI);
void DrawSpriteIgnorePadding(SpriteID img, PaletteID pal, const Rect &r, bool clicked, StringAlignment align); /* widget.cpp */
std::unique_ptr<uint32[]> DrawSpriteToRgbaBuffer(SpriteID spriteId, ZoomLevel zoom = ZOOM_LVL_GUI);
int DrawString(int left, int right, int top, const char *str, TextColour colour = TC_FROMSTRING, StringAlignment align = SA_LEFT, bool underline = false, FontSize fontsize = FS_NORMAL);
@@ -108,9 +109,46 @@ void GfxFillPolygon(const std::vector<Point> &shape, int colour, FillRectMode mo
void GfxDrawLine(int left, int top, int right, int bottom, int colour, int width = 1, int dash = 0);
void DrawBox(int x, int y, int dx1, int dy1, int dx2, int dy2, int dx3, int dy3);
/* Versions of DrawString/DrawStringMultiLine that accept a Rect instead of separate left, right, top and bottom parameters. */
static inline int DrawString(const Rect &r, const char *str, TextColour colour = TC_FROMSTRING, StringAlignment align = SA_LEFT, bool underline = false, FontSize fontsize = FS_NORMAL)
{
return DrawString(r.left, r.right, r.top, str, colour, align, underline, fontsize);
}
static inline int DrawString(const Rect &r, const std::string &str, TextColour colour = TC_FROMSTRING, StringAlignment align = SA_LEFT, bool underline = false, FontSize fontsize = FS_NORMAL)
{
return DrawString(r.left, r.right, r.top, str, colour, align, underline, fontsize);
}
static inline int DrawString(const Rect &r, StringID str, TextColour colour = TC_FROMSTRING, StringAlignment align = SA_LEFT, bool underline = false, FontSize fontsize = FS_NORMAL)
{
return DrawString(r.left, r.right, r.top, str, colour, align, underline, fontsize);
}
static inline int DrawStringMultiLine(const Rect &r, const char *str, TextColour colour = TC_FROMSTRING, StringAlignment align = (SA_TOP | SA_LEFT), bool underline = false, FontSize fontsize = FS_NORMAL)
{
return DrawStringMultiLine(r.left, r.right, r.top, r.bottom, str, colour, align, underline, fontsize);
}
static inline int DrawStringMultiLine(const Rect &r, const std::string &str, TextColour colour = TC_FROMSTRING, StringAlignment align = (SA_TOP | SA_LEFT), bool underline = false, FontSize fontsize = FS_NORMAL)
{
return DrawStringMultiLine(r.left, r.right, r.top, r.bottom, str, colour, align, underline, fontsize);
}
static inline int DrawStringMultiLine(const Rect &r, StringID str, TextColour colour = TC_FROMSTRING, StringAlignment align = (SA_TOP | SA_LEFT), bool underline = false, FontSize fontsize = FS_NORMAL)
{
return DrawStringMultiLine(r.left, r.right, r.top, r.bottom, str, colour, align, underline, fontsize);
}
static inline void GfxFillRect(const Rect &r, int colour, FillRectMode mode = FILLRECT_OPAQUE)
{
GfxFillRect(r.left, r.top, r.right, r.bottom, colour, mode);
}
Dimension GetStringBoundingBox(const char *str, FontSize start_fontsize = FS_NORMAL);
Dimension GetStringBoundingBox(const std::string &str, FontSize start_fontsize = FS_NORMAL);
Dimension GetStringBoundingBox(StringID strid);
Dimension GetStringBoundingBox(StringID strid, FontSize start_fontsize = FS_NORMAL);
uint GetStringListWidth(const StringID *list, FontSize fontsize = FS_NORMAL);
int GetStringHeight(const char *str, int maxw, FontSize fontsize = FS_NORMAL);
int GetStringHeight(StringID str, int maxw);
int GetStringLineCount(StringID str, int maxw);
@@ -139,7 +177,7 @@ bool FillDrawPixelInfo(DrawPixelInfo *n, int left, int top, int width, int heigh
*/
static inline int CenterBounds(int min, int max, int size)
{
return min + (max - min - size + 1) / 2;
return (min + max - size + 1) / 2;
}
/* window.cpp */

View File

@@ -11,6 +11,7 @@
#include "gfx_layout.h"
#include "string_func.h"
#include "strings_func.h"
#include "zoom_func.h"
#include "debug.h"
#include "table/control_codes.h"
@@ -333,18 +334,25 @@ public:
FallbackParagraphLayout::FallbackVisualRun::FallbackVisualRun(Font *font, const WChar *chars, int char_count, int x) :
font(font), glyph_count(char_count)
{
const bool isbuiltin = font->fc->IsBuiltInFont();
this->glyphs = MallocT<GlyphID>(this->glyph_count);
this->glyph_to_char = MallocT<int>(this->glyph_count);
/* Positions contains the location of the begin of each of the glyphs, and the end of the last one. */
this->positions = MallocT<float>(this->glyph_count * 2 + 2);
this->positions[0] = x;
this->positions[1] = 0;
for (int i = 0; i < this->glyph_count; i++) {
this->glyphs[i] = font->fc->MapCharToGlyph(chars[i]);
if (isbuiltin) {
this->positions[2 * i + 1] = font->fc->GetAscender(); // Apply sprite font's ascender.
} else if (chars[i] >= SCC_SPRITE_START && chars[i] <= SCC_SPRITE_END) {
this->positions[2 * i + 1] = (font->fc->GetHeight() - ScaleSpriteTrad(FontCache::GetDefaultFontHeight(font->fc->GetSize()))) / 2; // Align sprite font to centre
} else {
this->positions[2 * i + 1] = 0; // No ascender adjustment.
}
this->positions[2 * i + 2] = this->positions[2 * i] + font->fc->GetGlyphWidth(this->glyphs[i]);
this->positions[2 * i + 3] = 0;
this->glyph_to_char[i] = i;
}
}

View File

@@ -214,6 +214,13 @@ enum FontSize {
};
DECLARE_POSTFIX_INCREMENT(FontSize)
static inline const char *FontSizeToName(FontSize fs)
{
static const char *SIZE_TO_NAME[] = { "medium", "small", "large", "mono" };
assert(fs < FS_END);
return SIZE_TO_NAME[fs];
}
/**
* Used to only draw a part of the sprite.
* Draw the subsprite in the rect (sprite_x_offset + left, sprite_y_offset + top) to (sprite_x_offset + right, sprite_y_offset + bottom).

View File

@@ -76,7 +76,7 @@ struct GoalListWindow : public Window {
break;
case WID_GOAL_LIST: {
int y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_GOAL_LIST, WD_FRAMERECT_TOP);
int y = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_GOAL_LIST, WidgetDimensions::scaled.framerect.top);
for (const Goal *s : Goal::Iterate()) {
if (s->company == this->window_number) {
if (y == 0) {
@@ -174,11 +174,12 @@ struct GoalListWindow : public Window {
if (widget != WID_GOAL_LIST) return;
Dimension d = GetStringBoundingBox(STR_GOALS_NONE);
resize->width = 1;
resize->height = d.height;
d.height *= 5;
d.width += padding.width + WD_FRAMERECT_RIGHT + WD_FRAMERECT_LEFT;
d.height += padding.height + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
d.width += WidgetDimensions::scaled.framerect.Horizontal();
d.height += WidgetDimensions::scaled.framerect.Vertical();
*size = maxdim(*size, d);
}
@@ -192,9 +193,7 @@ struct GoalListWindow : public Window {
void DrawListColumn(GoalColumn column, NWidgetBase *wid, uint progress_col_width) const
{
/* Get column draw area. */
int y = wid->pos_y + WD_FRAMERECT_TOP;
int x = wid->pos_x + WD_FRAMERECT_LEFT;
int right = x + wid->current_x - WD_FRAMERECT_RIGHT;
Rect r = wid->GetCurrentRect().Shrink(WidgetDimensions::scaled.framerect);
bool rtl = _current_text_dir == TD_RTL;
int pos = -this->vscroll->GetPosition();
@@ -208,8 +207,8 @@ struct GoalListWindow : public Window {
case GC_GOAL: {
/* Display the goal. */
SetDParamStr(0, s->text);
uint width_reduction = progress_col_width > 0 ? progress_col_width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT : 0;
DrawString(x + (rtl ? width_reduction : 0), right - (rtl ? 0 : width_reduction), y + pos * FONT_HEIGHT_NORMAL, STR_GOALS_TEXT);
uint width_reduction = progress_col_width > 0 ? progress_col_width + WidgetDimensions::scaled.framerect.Horizontal() : 0;
DrawString(r.Indent(width_reduction, !rtl), STR_GOALS_TEXT);
break;
}
@@ -217,12 +216,11 @@ struct GoalListWindow : public Window {
if (s->progress != nullptr) {
SetDParamStr(0, s->progress);
StringID str = s->completed ? STR_GOALS_PROGRESS_COMPLETE : STR_GOALS_PROGRESS;
int progress_x = x;
int progress_right = rtl ? x + progress_col_width : right;
DrawString(progress_x, progress_right, y + pos * FONT_HEIGHT_NORMAL, str, TC_FROMSTRING, SA_RIGHT | SA_FORCE);
DrawString(r.WithWidth(progress_col_width, !rtl), str, TC_FROMSTRING, SA_RIGHT | SA_FORCE);
}
break;
}
r.top += FONT_HEIGHT_NORMAL;
}
pos++;
num++;
@@ -231,9 +229,8 @@ struct GoalListWindow : public Window {
if (num == 0) {
if (column == GC_GOAL && IsInsideMM(pos, 0, cap)) {
DrawString(x, right, y + pos * FONT_HEIGHT_NORMAL, STR_GOALS_NONE);
DrawString(r, STR_GOALS_NONE);
}
pos++;
}
}
@@ -265,7 +262,7 @@ struct GoalListWindow : public Window {
void OnResize() override
{
this->vscroll->SetCapacityFromWidget(this, WID_GOAL_LIST);
this->vscroll->SetCapacityFromWidget(this, WID_GOAL_LIST, WidgetDimensions::scaled.framerect.Vertical());
}
/**
@@ -289,16 +286,15 @@ static const NWidgetPart _nested_goals_list_widgets[] = {
NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
NWidget(WWT_CAPTION, COLOUR_BROWN, WID_GOAL_CAPTION), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
NWidget(NWID_SELECTION, INVALID_COLOUR, WID_GOAL_SELECT_BUTTONS),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_GOAL_GLOBAL_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_GOALS_GLOBAL_BUTTON, STR_GOALS_GLOBAL_BUTTON_HELPTEXT),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_GOAL_COMPANY_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_GOALS_COMPANY_BUTTON, STR_GOALS_COMPANY_BUTTON_HELPTEXT),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_GOAL_GLOBAL_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WidgetDimensions::unscaled.captiontext.Vertical()), SetDataTip(STR_GOALS_GLOBAL_BUTTON, STR_GOALS_GLOBAL_BUTTON_HELPTEXT),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_GOAL_COMPANY_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WidgetDimensions::unscaled.captiontext.Vertical()), SetDataTip(STR_GOALS_COMPANY_BUTTON, STR_GOALS_COMPANY_BUTTON_HELPTEXT),
EndContainer(),
NWidget(WWT_SHADEBOX, COLOUR_BROWN),
NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
NWidget(WWT_STICKYBOX, COLOUR_BROWN),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_PANEL, COLOUR_BROWN), SetDataTip(0x0, STR_GOALS_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER), SetScrollbar(WID_GOAL_SCROLLBAR),
NWidget(WWT_EMPTY, COLOUR_GREY, WID_GOAL_LIST), SetResize(1, 1), SetMinimalTextLines(2, 0), SetFill(1, 1), SetPadding(WD_FRAMERECT_TOP, 2, WD_FRAMETEXT_BOTTOM, 2),
NWidget(WWT_PANEL, COLOUR_BROWN, WID_GOAL_LIST), SetDataTip(0x0, STR_GOALS_TOOLTIP_CLICK_ON_SERVICE_TO_CENTER), SetScrollbar(WID_GOAL_SCROLLBAR), SetResize(1, 1), SetMinimalTextLines(2, 0),
EndContainer(),
NWidget(NWID_VERTICAL),
NWidget(NWID_VSCROLLBAR, COLOUR_BROWN, WID_GOAL_SCROLLBAR),
@@ -404,7 +400,7 @@ struct GoalQuestionWindow : public Window {
if (widget != WID_GQ_QUESTION) return;
SetDParamStr(0, this->question);
size->height = GetStringHeight(STR_JUST_RAW_STRING, size->width) + WD_PAR_VSEP_WIDE;
size->height = GetStringHeight(STR_JUST_RAW_STRING, size->width) + WidgetDimensions::scaled.vsep_wide;
}
void DrawWidget(const Rect &r, int widget) const override
@@ -412,7 +408,7 @@ struct GoalQuestionWindow : public Window {
if (widget != WID_GQ_QUESTION) return;
SetDParamStr(0, this->question);
DrawStringMultiLine(r.left, r.right, r.top, UINT16_MAX, STR_JUST_RAW_STRING, this->colour, SA_TOP | SA_HOR_CENTER);
DrawStringMultiLine(r, STR_JUST_RAW_STRING, this->colour, SA_TOP | SA_HOR_CENTER);
}
};

View File

@@ -18,7 +18,6 @@
#include "window_func.h"
#include "date_func.h"
#include "gfx_func.h"
#include "sortlist_type.h"
#include "core/geometry_func.hpp"
#include "currency.h"
#include "zoom_func.h"
@@ -65,12 +64,14 @@ struct GraphLegendWindow : Window {
bool rtl = _current_text_dir == TD_RTL;
const Rect ir = r.Shrink(WidgetDimensions::scaled.framerect);
Dimension d = GetSpriteSize(SPR_COMPANY_ICON);
DrawCompanyIcon(cid, rtl ? r.right - d.width - ScaleGUITrad(2) : r.left + ScaleGUITrad(2), CenterBounds(r.top, r.bottom, d.height));
DrawCompanyIcon(cid, rtl ? ir.right - d.width : ir.left, CenterBounds(ir.top, ir.bottom, d.height));
const Rect tr = ir.Indent(d.width + WidgetDimensions::scaled.hsep_normal, rtl);
SetDParam(0, cid);
SetDParam(1, cid);
DrawString(r.left + (rtl ? (uint)WD_FRAMERECT_LEFT : (d.width + ScaleGUITrad(4))), r.right - (rtl ? (d.width + ScaleGUITrad(4)) : (uint)WD_FRAMERECT_RIGHT), CenterBounds(r.top, r.bottom, FONT_HEIGHT_NORMAL), STR_COMPANY_NAME_COMPANY_NUM, HasBit(_legend_excluded_companies, cid) ? TC_BLACK : TC_WHITE);
DrawString(tr.left, tr.right, CenterBounds(tr.top, tr.bottom, FONT_HEIGHT_NORMAL), STR_COMPANY_NAME_COMPANY_NUM, HasBit(_legend_excluded_companies, cid) ? TC_BLACK : TC_WHITE);
}
void OnClick(Point pt, int widget, int click_count) override
@@ -116,8 +117,8 @@ static NWidgetBase *MakeNWidgetCompanyLines(int *biggest_index)
for (int widnum = WID_GL_FIRST_COMPANY; widnum <= WID_GL_LAST_COMPANY; widnum++) {
NWidgetBackground *panel = new NWidgetBackground(WWT_PANEL, COLOUR_BROWN, widnum);
panel->SetMinimalSize(246, sprite_height + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM);
panel->SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM, FS_NORMAL);
panel->SetMinimalSize(246, sprite_height + WidgetDimensions::unscaled.framerect.Vertical());
panel->SetMinimalTextLines(1, WidgetDimensions::unscaled.framerect.Vertical(), FS_NORMAL);
panel->SetFill(1, 1);
panel->SetDataTip(0x0, STR_GRAPH_KEY_COMPANY_SELECTION_TOOLTIP);
vert->Add(panel);
@@ -297,15 +298,15 @@ protected:
/* Rect r will be adjusted to contain just the graph, with labels being
* placed outside the area. */
r.top += 5 + GetCharacterHeight(FS_SMALL) / 2;
r.bottom -= (this->month == 0xFF ? 1 : 2) * GetCharacterHeight(FS_SMALL) + 4;
r.left += 9;
r.right -= 5;
r.top += ScaleGUITrad(5) + GetCharacterHeight(FS_SMALL) / 2;
r.bottom -= (this->month == 0xFF ? 1 : 2) * GetCharacterHeight(FS_SMALL) + ScaleGUITrad(4);
r.left += ScaleGUITrad(9);
r.right -= ScaleGUITrad(5);
/* Initial number of horizontal lines. */
int num_hori_lines = 160 / MIN_GRID_PIXEL_SIZE;
int num_hori_lines = 160 / ScaleGUITrad(MIN_GRID_PIXEL_SIZE);
/* For the rest of the height, the number of horizontal lines will increase more slowly. */
int resize = (r.bottom - r.top - 160) / (2 * MIN_GRID_PIXEL_SIZE);
int resize = (r.bottom - r.top - 160) / (2 * ScaleGUITrad(MIN_GRID_PIXEL_SIZE));
if (resize > 0) num_hori_lines += resize;
interval = GetValuesInterval(num_hori_lines);
@@ -343,7 +344,7 @@ protected:
y = r.bottom;
for (int i = 0; i < (num_hori_lines + 1); i++) {
GfxFillRect(r.left - 3, y, r.left - 1, y, GRAPH_AXIS_LINE_COLOUR);
GfxFillRect(r.left - ScaleGUITrad(3), y, r.left - 1, y, GRAPH_AXIS_LINE_COLOUR);
GfxFillRect(r.left, y, r.right, y, GRAPH_GRID_COLOUR);
y -= y_sep;
}
@@ -370,7 +371,7 @@ protected:
for (int i = 0; i < (num_hori_lines + 1); i++) {
SetDParam(0, this->format_str_y_axis);
SetDParam(1, y_label);
DrawString(r.left - label_width - 4, r.left - 4, y, STR_GRAPH_Y_LABEL, GRAPH_AXIS_LABEL_COLOUR, SA_RIGHT);
DrawString(r.left - label_width - ScaleGUITrad(4), r.left - ScaleGUITrad(4), y, STR_GRAPH_Y_LABEL, GRAPH_AXIS_LABEL_COLOUR, SA_RIGHT);
y_label -= y_label_separation;
y += y_sep;
@@ -379,7 +380,7 @@ protected:
/* Draw x-axis labels and markings for graphs based on financial quarters and years. */
if (this->month != 0xFF) {
x = r.left;
y = r.bottom + 2;
y = r.bottom + ScaleGUITrad(2);
byte month = this->month;
Year year = this->year;
for (int i = 0; i < this->num_on_x_axis; i++) {
@@ -400,7 +401,7 @@ protected:
} else {
/* Draw x-axis labels for graphs not based on quarterly performance (cargo payment rates). */
x = r.left;
y = r.bottom + 2;
y = r.bottom + ScaleGUITrad(2);
uint16 label = this->x_values_start;
for (int i = 0; i < this->num_on_x_axis; i++) {
@@ -520,8 +521,8 @@ public:
SetDParam(1, INT64_MAX);
uint y_label_width = GetStringBoundingBox(STR_GRAPH_Y_LABEL).width;
size->width = std::max<uint>(size->width, 5 + y_label_width + this->num_on_x_axis * (x_label_width + 5) + 9);
size->height = std::max<uint>(size->height, 5 + (1 + MIN_GRAPH_NUM_LINES_Y * 2 + (this->month != 0xFF ? 3 : 1)) * FONT_HEIGHT_SMALL + 4);
size->width = std::max<uint>(size->width, ScaleGUITrad(5) + y_label_width + this->num_on_x_axis * (x_label_width + ScaleGUITrad(5)) + ScaleGUITrad(9));
size->height = std::max<uint>(size->height, ScaleGUITrad(5) + (1 + MIN_GRAPH_NUM_LINES_Y * 2 + (this->month != 0xFF ? 3 : 1)) * FONT_HEIGHT_SMALL + ScaleGUITrad(4));
size->height = std::max<uint>(size->height, size->width / 3);
}
@@ -634,7 +635,7 @@ static const NWidgetPart _nested_operating_profit_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_GRAPH_OPERATING_PROFIT_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CV_KEY_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CV_KEY_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WidgetDimensions::unscaled.framerect.Vertical() + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP),
NWidget(WWT_SHADEBOX, COLOUR_BROWN),
NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
NWidget(WWT_STICKYBOX, COLOUR_BROWN),
@@ -685,7 +686,7 @@ static const NWidgetPart _nested_income_graph_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_GRAPH_INCOME_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CV_KEY_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CV_KEY_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WidgetDimensions::unscaled.framerect.Vertical() + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP),
NWidget(WWT_SHADEBOX, COLOUR_BROWN),
NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
NWidget(WWT_STICKYBOX, COLOUR_BROWN),
@@ -734,7 +735,7 @@ static const NWidgetPart _nested_delivered_cargo_graph_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_GRAPH_CARGO_DELIVERED_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CV_KEY_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CV_KEY_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WidgetDimensions::unscaled.framerect.Vertical() + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP),
NWidget(WWT_SHADEBOX, COLOUR_BROWN),
NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
NWidget(WWT_STICKYBOX, COLOUR_BROWN),
@@ -789,8 +790,8 @@ static const NWidgetPart _nested_performance_history_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_GRAPH_COMPANY_PERFORMANCE_RATINGS_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_PHG_DETAILED_PERFORMANCE), SetMinimalSize(50, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_PERFORMANCE_DETAIL_KEY, STR_GRAPH_PERFORMANCE_DETAIL_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_PHG_KEY), SetMinimalSize(50, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_PHG_DETAILED_PERFORMANCE), SetMinimalSize(50, 0), SetMinimalTextLines(1, WidgetDimensions::unscaled.framerect.Vertical() + 2), SetDataTip(STR_PERFORMANCE_DETAIL_KEY, STR_GRAPH_PERFORMANCE_DETAIL_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_PHG_KEY), SetMinimalSize(50, 0), SetMinimalTextLines(1, WidgetDimensions::unscaled.framerect.Vertical() + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP),
NWidget(WWT_SHADEBOX, COLOUR_BROWN),
NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
NWidget(WWT_STICKYBOX, COLOUR_BROWN),
@@ -839,7 +840,7 @@ static const NWidgetPart _nested_company_value_graph_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_GRAPH_COMPANY_VALUES_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CV_KEY_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP),
NWidget(WWT_PUSHTXTBTN, COLOUR_BROWN, WID_CV_KEY_BUTTON), SetMinimalSize(50, 0), SetMinimalTextLines(1, WidgetDimensions::unscaled.framerect.Vertical() + 2), SetDataTip(STR_GRAPH_KEY_BUTTON, STR_GRAPH_KEY_TOOLTIP),
NWidget(WWT_SHADEBOX, COLOUR_BROWN),
NWidget(WWT_DEFSIZEBOX, COLOUR_BROWN),
NWidget(WWT_STICKYBOX, COLOUR_BROWN),
@@ -898,7 +899,7 @@ struct PaymentRatesGraphWindow : BaseGraphWindow {
void OnInit() override
{
/* Width of the legend blob. */
this->legend_width = (FONT_HEIGHT_SMALL - ScaleFontTrad(1)) * 8 / 5;
this->legend_width = (FONT_HEIGHT_SMALL - ScaleGUITrad(1)) * 8 / 5;
}
void UpdateExcludedData()
@@ -922,9 +923,9 @@ struct PaymentRatesGraphWindow : BaseGraphWindow {
for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
SetDParam(0, cs->name);
Dimension d = GetStringBoundingBox(STR_GRAPH_CARGO_PAYMENT_CARGO);
d.width += this->legend_width + 4; // colour field
d.width += WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
d.height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
d.width += this->legend_width + WidgetDimensions::scaled.hsep_normal; // colour field
d.width += WidgetDimensions::scaled.framerect.Horizontal();
d.height += WidgetDimensions::scaled.framerect.Vertical();
*size = maxdim(d, *size);
}
@@ -943,32 +944,31 @@ struct PaymentRatesGraphWindow : BaseGraphWindow {
bool rtl = _current_text_dir == TD_RTL;
int x = r.left + WD_FRAMERECT_LEFT;
int y = r.top;
uint row_height = FONT_HEIGHT_SMALL;
int padding = ScaleFontTrad(1);
int pos = this->vscroll->GetPosition();
int max = pos + this->vscroll->GetCapacity();
Rect line = r.WithHeight(this->line_height);
for (const CargoSpec *cs : _sorted_standard_cargo_specs) {
if (pos-- > 0) continue;
if (--max < 0) break;
bool lowered = !HasBit(_legend_excluded_cargo, cs->Index());
/* Redraw box if lowered */
if (lowered) DrawFrameRect(r.left, y, r.right, y + this->line_height - 1, COLOUR_BROWN, FR_LOWERED);
/* Redraw frame if lowered */
if (lowered) DrawFrameRect(line, COLOUR_BROWN, FR_LOWERED);
byte clk_dif = lowered ? 1 : 0;
int rect_x = clk_dif + (rtl ? r.right - this->legend_width - WD_FRAMERECT_RIGHT : r.left + WD_FRAMERECT_LEFT);
const Rect text = line.Shrink(WidgetDimensions::scaled.framerect).Translate(lowered ? WidgetDimensions::scaled.pressed : 0, lowered ? WidgetDimensions::scaled.pressed : 0);
GfxFillRect(rect_x, y + padding + clk_dif, rect_x + this->legend_width, y + row_height - 1 + clk_dif, PC_BLACK);
GfxFillRect(rect_x + 1, y + padding + 1 + clk_dif, rect_x + this->legend_width - 1, y + row_height - 2 + clk_dif, cs->legend_colour);
/* Cargo-colour box with outline */
const Rect cargo = text.WithWidth(this->legend_width, rtl);
GfxFillRect(cargo, PC_BLACK);
GfxFillRect(cargo.Shrink(WidgetDimensions::scaled.bevel), cs->legend_colour);
/* Cargo name */
SetDParam(0, cs->name);
DrawString(rtl ? r.left : x + this->legend_width + 4 + clk_dif, (rtl ? r.right - this->legend_width - 4 + clk_dif : r.right), y + clk_dif, STR_GRAPH_CARGO_PAYMENT_CARGO);
DrawString(text.Indent(this->legend_width + WidgetDimensions::scaled.hsep_normal, rtl), STR_GRAPH_CARGO_PAYMENT_CARGO);
y += this->line_height;
line = line.Translate(0, this->line_height);
}
}
@@ -1078,7 +1078,7 @@ static const NWidgetPart _nested_cargo_payment_rates_widgets[] = {
NWidget(NWID_SPACER), SetMinimalSize(5, 0), SetFill(0, 1), SetResize(0, 1),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(NWID_SPACER), SetMinimalSize(WD_RESIZEBOX_WIDTH, 0), SetFill(1, 0), SetResize(1, 0),
NWidget(NWID_SPACER), SetMinimalSize(12, 0), SetFill(1, 0), SetResize(1, 0),
NWidget(WWT_TEXT, COLOUR_BROWN, WID_CPR_FOOTER), SetMinimalSize(0, 6), SetPadding(2, 0, 2, 0), SetDataTip(STR_GRAPH_CARGO_PAYMENT_RATES_X_LABEL, STR_NULL),
NWidget(NWID_SPACER), SetFill(1, 0), SetResize(1, 0),
NWidget(WWT_RESIZEBOX, COLOUR_BROWN, WID_CPR_RESIZE),
@@ -1099,192 +1099,6 @@ void ShowCargoPaymentRates()
AllocateWindowDescFront<PaymentRatesGraphWindow>(&_cargo_payment_rates_desc, 0);
}
/************************/
/* COMPANY LEAGUE TABLE */
/************************/
static const StringID _performance_titles[] = {
STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_ENGINEER,
STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_ENGINEER,
STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_TRAFFIC_MANAGER,
STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_TRAFFIC_MANAGER,
STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_TRANSPORT_COORDINATOR,
STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_TRANSPORT_COORDINATOR,
STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_ROUTE_SUPERVISOR,
STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_ROUTE_SUPERVISOR,
STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_DIRECTOR,
STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_DIRECTOR,
STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_CHIEF_EXECUTIVE,
STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_CHIEF_EXECUTIVE,
STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_CHAIRMAN,
STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_CHAIRMAN,
STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_PRESIDENT,
STR_COMPANY_LEAGUE_PERFORMANCE_TITLE_TYCOON,
};
static inline StringID GetPerformanceTitleFromValue(uint value)
{
return _performance_titles[std::min(value, 1000u) >> 6];
}
class CompanyLeagueWindow : public Window {
private:
GUIList<const Company*> companies;
uint ordinal_width; ///< The width of the ordinal number
uint text_width; ///< The width of the actual text
uint icon_width; ///< The width of the company icon
int line_height; ///< Height of the text lines
/**
* (Re)Build the company league list
*/
void BuildCompanyList()
{
if (!this->companies.NeedRebuild()) return;
this->companies.clear();
for (const Company *c : Company::Iterate()) {
this->companies.push_back(c);
}
this->companies.shrink_to_fit();
this->companies.RebuildDone();
}
/** Sort the company league by performance history */
static bool PerformanceSorter(const Company * const &c1, const Company * const &c2)
{
return c2->old_economy[0].performance_history < c1->old_economy[0].performance_history;
}
public:
CompanyLeagueWindow(WindowDesc *desc, WindowNumber window_number) : Window(desc)
{
this->InitNested(window_number);
this->companies.ForceRebuild();
this->companies.NeedResort();
}
void OnPaint() override
{
this->BuildCompanyList();
this->companies.Sort(&PerformanceSorter);
this->DrawWidgets();
}
void DrawWidget(const Rect &r, int widget) const override
{
if (widget != WID_CL_BACKGROUND) return;
int icon_y_offset = 1 + (FONT_HEIGHT_NORMAL - this->line_height) / 2;
uint y = r.top + WD_FRAMERECT_TOP - icon_y_offset;
bool rtl = _current_text_dir == TD_RTL;
uint ordinal_left = rtl ? r.right - WD_FRAMERECT_LEFT - this->ordinal_width : r.left + WD_FRAMERECT_LEFT;
uint ordinal_right = rtl ? r.right - WD_FRAMERECT_LEFT : r.left + WD_FRAMERECT_LEFT + this->ordinal_width;
uint icon_left = r.left + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT + (rtl ? this->text_width : this->ordinal_width);
uint text_left = rtl ? r.left + WD_FRAMERECT_LEFT : r.right - WD_FRAMERECT_LEFT - this->text_width;
uint text_right = rtl ? r.left + WD_FRAMERECT_LEFT + this->text_width : r.right - WD_FRAMERECT_LEFT;
for (uint i = 0; i != this->companies.size(); i++) {
const Company *c = this->companies[i];
DrawString(ordinal_left, ordinal_right, y, i + STR_ORDINAL_NUMBER_1ST, i == 0 ? TC_WHITE : TC_YELLOW);
DrawCompanyIcon(c->index, icon_left, y + icon_y_offset);
SetDParam(0, c->index);
SetDParam(1, c->index);
SetDParam(2, GetPerformanceTitleFromValue(c->old_economy[0].performance_history));
DrawString(text_left, text_right, y, STR_COMPANY_LEAGUE_COMPANY_NAME);
y += this->line_height;
}
}
void UpdateWidgetSize(int widget, Dimension *size, const Dimension &padding, Dimension *fill, Dimension *resize) override
{
if (widget != WID_CL_BACKGROUND) return;
this->ordinal_width = 0;
for (uint i = 0; i < MAX_COMPANIES; i++) {
this->ordinal_width = std::max(this->ordinal_width, GetStringBoundingBox(STR_ORDINAL_NUMBER_1ST + i).width);
}
this->ordinal_width += 5; // Keep some extra spacing
uint widest_width = 0;
uint widest_title = 0;
for (uint i = 0; i < lengthof(_performance_titles); i++) {
uint width = GetStringBoundingBox(_performance_titles[i]).width;
if (width > widest_width) {
widest_title = i;
widest_width = width;
}
}
Dimension d = GetSpriteSize(SPR_COMPANY_ICON);
this->icon_width = d.width + 2;
this->line_height = std::max<int>(d.height + 2, FONT_HEIGHT_NORMAL);
for (const Company *c : Company::Iterate()) {
SetDParam(0, c->index);
SetDParam(1, c->index);
SetDParam(2, _performance_titles[widest_title]);
widest_width = std::max(widest_width, GetStringBoundingBox(STR_COMPANY_LEAGUE_COMPANY_NAME).width);
}
this->text_width = widest_width + 30; // Keep some extra spacing
size->width = WD_FRAMERECT_LEFT + this->ordinal_width + WD_FRAMERECT_RIGHT + this->icon_width + WD_FRAMERECT_LEFT + this->text_width + WD_FRAMERECT_RIGHT;
size->height = WD_FRAMERECT_TOP + this->line_height * MAX_COMPANIES + WD_FRAMERECT_BOTTOM;
}
void OnGameTick() override
{
if (this->companies.NeedResort()) {
this->SetDirty();
}
}
/**
* Some data on this window has become invalid.
* @param data Information about the changed data.
* @param gui_scope Whether the call is done from GUI scope. You may not do everything when not in GUI scope. See #InvalidateWindowData() for details.
*/
void OnInvalidateData(int data = 0, bool gui_scope = true) override
{
if (data == 0) {
/* This needs to be done in command-scope to enforce rebuilding before resorting invalid data */
this->companies.ForceRebuild();
} else {
this->companies.ForceResort();
}
}
};
static const NWidgetPart _nested_company_league_widgets[] = {
NWidget(NWID_HORIZONTAL),
NWidget(WWT_CLOSEBOX, COLOUR_BROWN),
NWidget(WWT_CAPTION, COLOUR_BROWN), SetDataTip(STR_COMPANY_LEAGUE_TABLE_CAPTION, STR_TOOLTIP_WINDOW_TITLE_DRAG_THIS),
NWidget(WWT_SHADEBOX, COLOUR_BROWN),
NWidget(WWT_STICKYBOX, COLOUR_BROWN),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_BROWN, WID_CL_BACKGROUND), SetMinimalSize(400, 0), SetMinimalTextLines(15, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM),
};
static WindowDesc _company_league_desc(
WDP_AUTO, "league", 0, 0,
WC_COMPANY_LEAGUE, WC_NONE,
0,
_nested_company_league_widgets, lengthof(_nested_company_league_widgets)
);
void ShowCompanyLeagueTable()
{
AllocateWindowDescFront<CompanyLeagueWindow>(&_company_league_desc, 0);
}
/*****************************/
/* PERFORMANCE RATING DETAIL */
/*****************************/
@@ -1325,18 +1139,18 @@ struct PerformanceRatingDetailWindow : Window {
{
switch (widget) {
case WID_PRD_SCORE_FIRST:
this->bar_height = FONT_HEIGHT_NORMAL + 4;
size->height = this->bar_height + 2 * WD_MATRIX_TOP;
this->bar_height = FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.fullbevel.Vertical();
size->height = this->bar_height + WidgetDimensions::scaled.matrix.Vertical();
uint score_info_width = 0;
for (uint i = SCORE_BEGIN; i < SCORE_END; i++) {
score_info_width = std::max(score_info_width, GetStringBoundingBox(STR_PERFORMANCE_DETAIL_VEHICLES + i).width);
}
SetDParamMaxValue(0, 1000);
score_info_width += GetStringBoundingBox(STR_BLACK_COMMA).width + WD_FRAMERECT_LEFT;
score_info_width += GetStringBoundingBox(STR_BLACK_COMMA).width + WidgetDimensions::scaled.hsep_wide;
SetDParamMaxValue(0, 100);
this->bar_width = GetStringBoundingBox(STR_PERFORMANCE_DETAIL_PERCENT).width + 20; // Wide bars!
this->bar_width = GetStringBoundingBox(STR_PERFORMANCE_DETAIL_PERCENT).width + WidgetDimensions::scaled.hsep_indent * 2; // Wide bars!
/* At this number we are roughly at the max; it can become wider,
* but then you need at 1000 times more money. At that time you're
@@ -1362,9 +1176,9 @@ struct PerformanceRatingDetailWindow : Window {
SetDParam(1, max);
uint score_detail_width = GetStringBoundingBox(STR_PERFORMANCE_DETAIL_AMOUNT_CURRENCY).width;
size->width = 7 + score_info_width + 5 + this->bar_width + 5 + score_detail_width + 7;
uint left = 7;
uint right = size->width - 7;
size->width = WidgetDimensions::scaled.frametext.Horizontal() + score_info_width + WidgetDimensions::scaled.hsep_wide + this->bar_width + WidgetDimensions::scaled.hsep_wide + score_detail_width;
uint left = WidgetDimensions::scaled.frametext.left;
uint right = size->width - WidgetDimensions::scaled.frametext.right;
bool rtl = _current_text_dir == TD_RTL;
this->score_info_left = rtl ? right - score_info_width : left;
@@ -1373,8 +1187,8 @@ struct PerformanceRatingDetailWindow : Window {
this->score_detail_left = rtl ? left : right - score_detail_width;
this->score_detail_right = rtl ? left + score_detail_width : right;
this->bar_left = left + (rtl ? score_detail_width : score_info_width) + 5;
this->bar_right = this->bar_left + this->bar_width;
this->bar_left = left + (rtl ? score_detail_width : score_info_width) + WidgetDimensions::scaled.hsep_wide;
this->bar_right = this->bar_left + this->bar_width - 1;
break;
}
}
@@ -1387,9 +1201,9 @@ struct PerformanceRatingDetailWindow : Window {
if (IsInsideMM(widget, WID_PRD_COMPANY_FIRST, WID_PRD_COMPANY_LAST + 1)) {
if (this->IsWidgetDisabled(widget)) return;
CompanyID cid = (CompanyID)(widget - WID_PRD_COMPANY_FIRST);
int offset = (cid == this->company) ? 1 : 0;
int offset = (cid == this->company) ? WidgetDimensions::scaled.pressed : 0;
Dimension sprite_size = GetSpriteSize(SPR_COMPANY_ICON);
DrawCompanyIcon(cid, (r.left + r.right - sprite_size.width) / 2 + offset, (r.top + r.bottom - sprite_size.height) / 2 + offset);
DrawCompanyIcon(cid, CenterBounds(r.left, r.right, sprite_size.width) + offset, CenterBounds(r.top, r.bottom, sprite_size.height) + offset);
return;
}
@@ -1412,8 +1226,8 @@ struct PerformanceRatingDetailWindow : Window {
needed = SCORE_MAX;
}
uint bar_top = r.top + WD_MATRIX_TOP;
uint text_top = bar_top + 2;
uint bar_top = CenterBounds(r.top, r.bottom, this->bar_height);
uint text_top = CenterBounds(r.top, r.bottom, FONT_HEIGHT_NORMAL);
DrawString(this->score_info_left, this->score_info_right, text_top, STR_PERFORMANCE_DETAIL_VEHICLES + score_type);
@@ -1431,8 +1245,8 @@ struct PerformanceRatingDetailWindow : Window {
}
/* Draw the bar */
if (x != this->bar_left) GfxFillRect(this->bar_left, bar_top, x, bar_top + this->bar_height, rtl ? colour_notdone : colour_done);
if (x != this->bar_right) GfxFillRect(x, bar_top, this->bar_right, bar_top + this->bar_height, rtl ? colour_done : colour_notdone);
if (x != this->bar_left) GfxFillRect(this->bar_left, bar_top, x, bar_top + this->bar_height - 1, rtl ? colour_notdone : colour_done);
if (x != this->bar_right) GfxFillRect(x, bar_top, this->bar_right, bar_top + this->bar_height - 1, rtl ? colour_done : colour_notdone);
/* Draw it */
SetDParam(0, Clamp<int64>(val, 0, needed) * 100 / needed);
@@ -1563,7 +1377,7 @@ static const NWidgetPart _nested_performance_rating_detail_widgets[] = {
NWidget(WWT_STICKYBOX, COLOUR_BROWN),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_BROWN),
NWidgetFunction(MakeCompanyButtonRowsGraphGUI), SetPadding(0, 1, 1, 2),
NWidgetFunction(MakeCompanyButtonRowsGraphGUI), SetPadding(2),
EndContainer(),
NWidgetFunction(MakePerformanceDetailPanels),
};

View File

@@ -16,7 +16,6 @@ void ShowDeliveredCargoGraph();
void ShowPerformanceHistoryGraph();
void ShowCompanyValueGraph();
void ShowCargoPaymentRates();
void ShowCompanyLeagueTable();
void ShowPerformanceRatingDetail();
#endif /* GRAPH_GUI_H */

View File

@@ -27,6 +27,7 @@
#include "gui.h"
#include "group_cmd.h"
#include "vehicle_cmd.h"
#include "gfx_func.h"
#include "widgets/group_widget.h"
@@ -34,8 +35,6 @@
#include "safeguards.h"
static const int LEVEL_WIDTH = 10; ///< Indenting width of a sub-group in pixels
typedef GUIList<const Group*> GUIGroupList;
static const NWidgetPart _nested_group_widgets[] = {
@@ -56,7 +55,7 @@ static const NWidgetPart _nested_group_widgets[] = {
SetFill(1, 0), SetResize(0, 1), SetScrollbar(WID_GL_LIST_GROUP_SCROLLBAR),
NWidget(NWID_VSCROLLBAR, COLOUR_GREY, WID_GL_LIST_GROUP_SCROLLBAR),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY, WID_GL_INFO), SetFill(1, 1), SetMinimalTextLines(3, WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM), EndContainer(),
NWidget(WWT_PANEL, COLOUR_GREY, WID_GL_INFO), SetFill(1, 1), SetMinimalTextLines(3, WidgetDimensions::unscaled.framerect.Vertical()), EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_PUSHIMGBTN, COLOUR_GREY, WID_GL_CREATE_GROUP),
SetDataTip(SPR_GROUP_CREATE_TRAIN, STR_GROUP_CREATE_TOOLTIP),
@@ -74,14 +73,21 @@ static const NWidgetPart _nested_group_widgets[] = {
/* right part */
NWidget(NWID_VERTICAL),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GL_GROUP_BY_ORDER), SetMinimalSize(81, 12), SetDataTip(STR_STATION_VIEW_GROUP, STR_TOOLTIP_GROUP_ORDER),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GL_GROUP_BY_DROPDOWN), SetMinimalSize(167, 12), SetDataTip(0x0, STR_TOOLTIP_GROUP_ORDER),
NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(12, 12), SetResize(1, 0), EndContainer(),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GL_SORT_BY_ORDER), SetMinimalSize(81, 12), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GL_SORT_BY_DROPDOWN), SetMinimalSize(167, 12), SetDataTip(0x0, STR_TOOLTIP_SORT_CRITERIA),
NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(12, 12), SetResize(1, 0), EndContainer(),
NWidget(NWID_VERTICAL),
NWidget(WWT_TEXTBTN, COLOUR_GREY, WID_GL_GROUP_BY_ORDER), SetFill(1, 0), SetMinimalSize(0, 12), SetDataTip(STR_STATION_VIEW_GROUP, STR_TOOLTIP_GROUP_ORDER),
NWidget(WWT_PUSHTXTBTN, COLOUR_GREY, WID_GL_SORT_BY_ORDER), SetFill(1, 0), SetMinimalSize(0, 12), SetDataTip(STR_BUTTON_SORT_BY, STR_TOOLTIP_SORT_ORDER),
EndContainer(),
NWidget(NWID_VERTICAL),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GL_GROUP_BY_DROPDOWN), SetFill(1, 0), SetMinimalSize(0, 12), SetDataTip(0x0, STR_TOOLTIP_GROUP_ORDER),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GL_SORT_BY_DROPDOWN), SetFill(1, 0), SetMinimalSize(0, 12), SetDataTip(0x0, STR_TOOLTIP_SORT_CRITERIA),
EndContainer(),
NWidget(NWID_VERTICAL),
NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(0, 12), SetResize(1, 0), EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_DROPDOWN, COLOUR_GREY, WID_GL_FILTER_BY_CARGO), SetMinimalSize(0, 12), SetDataTip(STR_JUST_STRING, STR_TOOLTIP_FILTER_CRITERIA),
NWidget(WWT_PANEL, COLOUR_GREY), SetMinimalSize(0, 12), SetResize(1, 0), EndContainer(),
EndContainer(),
EndContainer(),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_MATRIX, COLOUR_GREY, WID_GL_LIST_VEHICLE), SetMinimalSize(248, 0), SetMatrixDataTip(1, 0, STR_NULL), SetResize(1, 1), SetFill(1, 0), SetScrollbar(WID_GL_LIST_VEHICLE_SCROLLBAR),
@@ -118,7 +124,6 @@ private:
VGC_END
};
VehicleID vehicle_sel; ///< Selected vehicle
GroupID group_sel; ///< Selected group (for drag/drop)
GroupID group_rename; ///< Group being renamed, INVALID_GROUP if none
GroupID group_over; ///< Group over which a vehicle is dragged, INVALID_GROUP if none
@@ -207,7 +212,7 @@ private:
this->tiny_step_height = this->column_size[VGC_FOLD].height;
this->column_size[VGC_NAME] = maxdim(GetStringBoundingBox(STR_GROUP_DEFAULT_TRAINS + this->vli.vtype), GetStringBoundingBox(STR_GROUP_ALL_TRAINS + this->vli.vtype));
this->column_size[VGC_NAME].width = std::max(170u, this->column_size[VGC_NAME].width);
this->column_size[VGC_NAME].width = std::max(170u, this->column_size[VGC_NAME].width) + WidgetDimensions::scaled.hsep_indent;
this->tiny_step_height = std::max(this->tiny_step_height, this->column_size[VGC_NAME].height);
this->column_size[VGC_PROTECT] = GetSpriteSize(SPR_GROUP_REPLACE_PROTECT);
@@ -231,16 +236,16 @@ private:
this->column_size[VGC_NUMBER] = GetStringBoundingBox(STR_GROUP_COUNT_WITH_SUBGROUP);
this->tiny_step_height = std::max(this->tiny_step_height, this->column_size[VGC_NUMBER].height);
this->tiny_step_height += WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
this->tiny_step_height += WidgetDimensions::scaled.framerect.Vertical();
return WD_FRAMERECT_LEFT + 8 +
this->column_size[VGC_FOLD].width + 2 +
this->column_size[VGC_NAME].width + 8 +
this->column_size[VGC_PROTECT].width + 2 +
this->column_size[VGC_AUTOREPLACE].width + 2 +
this->column_size[VGC_PROFIT].width + 2 +
this->column_size[VGC_NUMBER].width + 2 +
WD_FRAMERECT_RIGHT;
return WidgetDimensions::scaled.framerect.left +
this->column_size[VGC_FOLD].width + WidgetDimensions::scaled.hsep_normal +
this->column_size[VGC_NAME].width + WidgetDimensions::scaled.hsep_wide +
this->column_size[VGC_PROTECT].width + WidgetDimensions::scaled.hsep_normal +
this->column_size[VGC_AUTOREPLACE].width + WidgetDimensions::scaled.hsep_normal +
this->column_size[VGC_PROFIT].width + WidgetDimensions::scaled.hsep_normal +
this->column_size[VGC_NUMBER].width +
WidgetDimensions::scaled.framerect.right;
}
/**
@@ -257,7 +262,7 @@ private:
{
/* Highlight the group if a vehicle is dragged over it */
if (g_id == this->group_over) {
GfxFillRect(left + WD_FRAMERECT_LEFT, y + WD_FRAMERECT_TOP + 1, right - WD_FRAMERECT_RIGHT, y + this->tiny_step_height - WD_FRAMERECT_BOTTOM - 1, _colour_gradient[COLOUR_GREY][7]);
GfxFillRect(left + WidgetDimensions::scaled.bevel.left, y + WidgetDimensions::scaled.framerect.top, right - WidgetDimensions::scaled.bevel.right, y + this->tiny_step_height - 1 - WidgetDimensions::scaled.framerect.bottom, _colour_gradient[COLOUR_GREY][7]);
}
if (g_id == NEW_GROUP) return;
@@ -268,7 +273,7 @@ private:
bool rtl = _current_text_dir == TD_RTL;
/* draw fold / unfold button */
int x = rtl ? right - WD_FRAMERECT_RIGHT - 8 - this->column_size[VGC_FOLD].width + 1 : left + WD_FRAMERECT_LEFT + 8;
int x = rtl ? right - WidgetDimensions::scaled.framerect.right - this->column_size[VGC_FOLD].width + 1 : left + WidgetDimensions::scaled.framerect.left;
if (has_children) {
DrawSprite(Group::Get(g_id)->folded ? SPR_CIRCLE_FOLDED : SPR_CIRCLE_UNFOLDED, PAL_NONE, rtl ? x - indent : x + indent, y + (this->tiny_step_height - this->column_size[VGC_FOLD].height) / 2);
}
@@ -283,19 +288,19 @@ private:
SetDParam(0, g_id);
str = STR_GROUP_NAME;
}
x = rtl ? x - 2 - this->column_size[VGC_NAME].width : x + 2 + this->column_size[VGC_FOLD].width;
x = rtl ? x - WidgetDimensions::scaled.hsep_normal - this->column_size[VGC_NAME].width : x + WidgetDimensions::scaled.hsep_normal + this->column_size[VGC_FOLD].width;
DrawString(x + (rtl ? 0 : indent), x + this->column_size[VGC_NAME].width - 1 - (rtl ? indent : 0), y + (this->tiny_step_height - this->column_size[VGC_NAME].height) / 2, str, colour);
/* draw autoreplace protection */
x = rtl ? x - 8 - this->column_size[VGC_PROTECT].width : x + 8 + this->column_size[VGC_NAME].width;
x = rtl ? x - WidgetDimensions::scaled.hsep_wide - this->column_size[VGC_PROTECT].width : x + WidgetDimensions::scaled.hsep_wide + this->column_size[VGC_NAME].width;
if (protection) DrawSprite(SPR_GROUP_REPLACE_PROTECT, PAL_NONE, x, y + (this->tiny_step_height - this->column_size[VGC_PROTECT].height) / 2);
/* draw autoreplace status */
x = rtl ? x - 2 - this->column_size[VGC_AUTOREPLACE].width : x + 2 + this->column_size[VGC_PROTECT].width;
x = rtl ? x - WidgetDimensions::scaled.hsep_normal - this->column_size[VGC_AUTOREPLACE].width : x + WidgetDimensions::scaled.hsep_normal + this->column_size[VGC_PROTECT].width;
if (stats.autoreplace_defined) DrawSprite(SPR_GROUP_REPLACE_ACTIVE, stats.autoreplace_finished ? PALETTE_CRASH : PAL_NONE, x, y + (this->tiny_step_height - this->column_size[VGC_AUTOREPLACE].height) / 2);
/* draw the profit icon */
x = rtl ? x - 2 - this->column_size[VGC_PROFIT].width : x + 2 + this->column_size[VGC_AUTOREPLACE].width;
x = rtl ? x - WidgetDimensions::scaled.hsep_normal - this->column_size[VGC_PROFIT].width : x + WidgetDimensions::scaled.hsep_normal + this->column_size[VGC_AUTOREPLACE].width;
SpriteID spr;
uint num_profit_vehicle = GetGroupNumProfitVehicle(this->vli.company, g_id, this->vli.vtype);
Money profit_last_year = GetGroupProfitLastYear(this->vli.company, g_id, this->vli.vtype);
@@ -311,7 +316,7 @@ private:
DrawSprite(spr, PAL_NONE, x, y + (this->tiny_step_height - this->column_size[VGC_PROFIT].height) / 2);
/* draw the number of vehicles of the group */
x = rtl ? x - 2 - this->column_size[VGC_NUMBER].width : x + 2 + this->column_size[VGC_PROFIT].width;
x = rtl ? x - WidgetDimensions::scaled.hsep_normal - this->column_size[VGC_NUMBER].width : x + WidgetDimensions::scaled.hsep_normal + this->column_size[VGC_PROFIT].width;
int num_vehicle_with_subgroups = GetGroupNumVehicle(this->vli.company, g_id, this->vli.vtype);
int num_vehicle = GroupStatistics::Get(this->vli.company, g_id, this->vli.vtype).num_vehicle;
if (IsAllGroupID(g_id) || IsDefaultGroupID(g_id) || num_vehicle_with_subgroups == num_vehicle) {
@@ -349,7 +354,6 @@ public:
this->group_sb = this->GetScrollbar(WID_GL_LIST_GROUP_SCROLLBAR);
this->vli.index = ALL_GROUP;
this->vehicle_sel = INVALID_VEHICLE;
this->group_sel = INVALID_GROUP;
this->group_rename = INVALID_GROUP;
this->group_over = INVALID_GROUP;
@@ -409,6 +413,20 @@ public:
size->height = 4 * resize->height;
break;
case WID_GL_GROUP_BY_DROPDOWN:
size->width = GetStringListWidth(this->vehicle_group_by_names) + padding.width;
break;
case WID_GL_SORT_BY_DROPDOWN:
size->width = GetStringListWidth(this->vehicle_group_none_sorter_names);
size->width = std::max(size->width, GetStringListWidth(this->vehicle_group_shared_orders_sorter_names));
size->width += padding.width;
break;
case WID_GL_FILTER_BY_CARGO:
size->width = GetStringListWidth(this->cargo_filter_texts) + padding.width;
break;
case WID_GL_MANAGE_VEHICLES_DROPDOWN: {
Dimension d = this->GetActionDropdownSize(true, true);
d.height += padding.height;
@@ -451,6 +469,10 @@ public:
void SetStringParameters(int widget) const override
{
switch (widget) {
case WID_GL_FILTER_BY_CARGO:
SetDParam(0, this->cargo_filter_texts[this->cargo_filter_criteria]);
break;
case WID_GL_AVAILABLE_VEHICLES:
SetDParam(0, STR_VEHICLE_LIST_AVAILABLE_TRAINS + this->vli.vtype);
break;
@@ -530,6 +552,9 @@ public:
/* Set text of "sort by" dropdown widget. */
this->GetWidget<NWidgetCore>(WID_GL_SORT_BY_DROPDOWN)->widget_data = this->GetVehicleSorterNames()[this->vehgroups.SortType()];
/* Set text of filter by cargo dropdown */
this->GetWidget<NWidgetCore>(WID_GL_FILTER_BY_CARGO)->widget_data = this->cargo_filter_texts[this->cargo_filter_criteria];
this->DrawWidgets();
}
@@ -557,25 +582,23 @@ public:
occupancy += v->trip_occupancy;
}
const int left = r.left + WD_FRAMERECT_LEFT + 8;
const int right = r.right - WD_FRAMERECT_RIGHT - 8;
Rect tr = r.Shrink(WidgetDimensions::scaled.framerect);
int y = r.top + WD_FRAMERECT_TOP;
DrawString(left, right, y, STR_GROUP_PROFIT_THIS_YEAR, TC_BLACK);
DrawString(tr, STR_GROUP_PROFIT_THIS_YEAR, TC_BLACK);
SetDParam(0, this_year);
DrawString(left, right, y, STR_JUST_CURRENCY_LONG, TC_BLACK, SA_RIGHT);
DrawString(tr, STR_JUST_CURRENCY_LONG, TC_BLACK, SA_RIGHT);
y += FONT_HEIGHT_NORMAL;
DrawString(left, right, y, STR_GROUP_PROFIT_LAST_YEAR, TC_BLACK);
tr.top += FONT_HEIGHT_NORMAL;
DrawString(tr, STR_GROUP_PROFIT_LAST_YEAR, TC_BLACK);
SetDParam(0, last_year);
DrawString(left, right, y, STR_JUST_CURRENCY_LONG, TC_BLACK, SA_RIGHT);
DrawString(tr, STR_JUST_CURRENCY_LONG, TC_BLACK, SA_RIGHT);
y += FONT_HEIGHT_NORMAL;
DrawString(left, right, y, STR_GROUP_OCCUPANCY, TC_BLACK);
tr.top += FONT_HEIGHT_NORMAL;
DrawString(tr, STR_GROUP_OCCUPANCY, TC_BLACK);
const size_t vehicle_count = this->vehicles.size();
if (vehicle_count > 0) {
SetDParam(0, occupancy / vehicle_count);
DrawString(left, right, y, STR_GROUP_OCCUPANCY_VALUE, TC_BLACK, SA_RIGHT);
DrawString(tr, STR_GROUP_OCCUPANCY_VALUE, TC_BLACK, SA_RIGHT);
}
break;
@@ -589,7 +612,7 @@ public:
assert(g->owner == this->owner);
DrawGroupInfo(y1, r.left, r.right, g->index, this->indents[i] * LEVEL_WIDTH, HasBit(g->flags, GroupFlags::GF_REPLACE_PROTECTION), g->folded || (i + 1 < (int)this->groups.size() && indents[i + 1] > this->indents[i]));
DrawGroupInfo(y1, r.left, r.right, g->index, this->indents[i] * WidgetDimensions::scaled.hsep_indent, HasBit(g->flags, GroupFlags::GF_REPLACE_PROTECTION), g->folded || (i + 1 < (int)this->groups.size() && indents[i + 1] > this->indents[i]));
y1 += this->tiny_step_height;
}
@@ -606,14 +629,14 @@ public:
case WID_GL_LIST_VEHICLE:
if (this->vli.index != ALL_GROUP && this->grouping == GB_NONE) {
/* Mark vehicles which are in sub-groups (only if we are not using shared order coalescing) */
int y = r.top;
Rect mr = r.WithHeight(this->resize.step_height);
uint max = static_cast<uint>(std::min<size_t>(this->vscroll->GetPosition() + this->vscroll->GetCapacity(), this->vehgroups.size()));
for (uint i = this->vscroll->GetPosition(); i < max; ++i) {
const Vehicle *v = this->vehgroups[i].GetSingleVehicle();
if (v->group_id != this->vli.index) {
GfxFillRect(r.left + 1, y + 1, r.right - 1, y + this->resize.step_height - 2, _colour_gradient[COLOUR_GREY][3], FILLRECT_CHECKER);
GfxFillRect(mr.Shrink(WidgetDimensions::scaled.bevel), _colour_gradient[COLOUR_GREY][3], FILLRECT_CHECKER);
}
y += this->resize.step_height;
mr = mr.Translate(0, this->resize.step_height);
}
}
@@ -647,6 +670,10 @@ public:
ShowDropDownMenu(this, this->GetVehicleSorterNames(), this->vehgroups.SortType(), WID_GL_SORT_BY_DROPDOWN, 0, (this->vli.vtype == VEH_TRAIN || this->vli.vtype == VEH_ROAD) ? 0 : (1 << 10));
return;
case WID_GL_FILTER_BY_CARGO: // Select filtering criteria dropdown menu
ShowDropDownMenu(this, this->cargo_filter_texts, this->cargo_filter_criteria, WID_GL_FILTER_BY_CARGO, 0, 0);
break;
case WID_GL_ALL_VEHICLES: // All vehicles button
if (!IsAllGroupID(this->vli.index)) {
this->vli.index = ALL_GROUP;
@@ -671,8 +698,8 @@ public:
/* The group has children, check if the user clicked the fold / unfold button. */
NWidgetCore *group_display = this->GetWidget<NWidgetCore>(widget);
int x = _current_text_dir == TD_RTL ?
group_display->pos_x + group_display->current_x - WD_FRAMERECT_RIGHT - 8 - this->indents[id_g] * LEVEL_WIDTH - this->column_size[VGC_FOLD].width :
group_display->pos_x + WD_FRAMERECT_LEFT + 8 + this->indents[id_g] * LEVEL_WIDTH;
group_display->pos_x + group_display->current_x - WidgetDimensions::scaled.framerect.right - this->indents[id_g] * WidgetDimensions::scaled.hsep_indent - this->column_size[VGC_FOLD].width :
group_display->pos_x + WidgetDimensions::scaled.framerect.left + this->indents[id_g] * WidgetDimensions::scaled.hsep_indent;
if (click_count > 1 || (pt.x >= x && pt.x < (int)(x + this->column_size[VGC_FOLD].width))) {
GroupID g = this->vli.index;
@@ -878,14 +905,14 @@ public:
}
case GB_SHARED_ORDERS: {
const Vehicle *v = vehgroup.vehicles_begin[0];
/* We do not support VehicleClicked() here since the contextual action may only make sense for individual vehicles */
if (vindex == v->index) {
if (vehgroup.NumVehicles() == 1) {
ShowVehicleViewWindow(v);
} else {
ShowVehicleListWindow(v);
if (!VehicleClicked(vehgroup)) {
const Vehicle* v = vehgroup.vehicles_begin[0];
if (vindex == v->index) {
if (vehgroup.NumVehicles() == 1) {
ShowVehicleViewWindow(v);
} else {
ShowVehicleListWindow(v);
}
}
}
break;
@@ -930,6 +957,10 @@ public:
this->vehgroups.SetSortType(index);
break;
case WID_GL_FILTER_BY_CARGO: // Select a cargo filter criteria
this->SetCargoFilterIndex(index);
break;
case WID_GL_MANAGE_VEHICLES_DROPDOWN:
assert(this->vehicles.size() != 0);

View File

@@ -133,7 +133,7 @@ struct EndGameWindow : EndGameHighScoreBaseWindow {
void OnPaint() override
{
this->SetupHighScoreEndWindow();
Point pt = this->GetTopLeft(ScaleGUITrad(640), ScaleGUITrad(480));
Point pt = this->GetTopLeft(ScaleSpriteTrad(640), ScaleSpriteTrad(480));
const Company *c = Company::GetIfValid(_local_company);
if (c == nullptr) return;
@@ -144,11 +144,11 @@ struct EndGameWindow : EndGameHighScoreBaseWindow {
SetDParam(0, c->index);
SetDParam(1, c->index);
SetDParam(2, EndGameGetPerformanceTitleFromValue(c->old_economy[0].performance_history));
DrawStringMultiLine(pt.x + ScaleGUITrad(15), pt.x + ScaleGUITrad(640) - ScaleGUITrad(25), pt.y + ScaleGUITrad(90), pt.y + ScaleGUITrad(160), STR_HIGHSCORE_PRESIDENT_OF_COMPANY_ACHIEVES_STATUS, TC_FROMSTRING, SA_CENTER);
DrawStringMultiLine(pt.x + ScaleSpriteTrad(15), pt.x + ScaleSpriteTrad(640) - ScaleSpriteTrad(25), pt.y + ScaleSpriteTrad(90), pt.y + ScaleSpriteTrad(160), STR_HIGHSCORE_PRESIDENT_OF_COMPANY_ACHIEVES_STATUS, TC_FROMSTRING, SA_CENTER);
} else {
SetDParam(0, c->index);
SetDParam(1, EndGameGetPerformanceTitleFromValue(c->old_economy[0].performance_history));
DrawStringMultiLine(pt.x + ScaleGUITrad(36), pt.x + ScaleGUITrad(640), pt.y + ScaleGUITrad(140), pt.y + ScaleGUITrad(206), STR_HIGHSCORE_COMPANY_ACHIEVES_STATUS, TC_FROMSTRING, SA_CENTER);
DrawStringMultiLine(pt.x + ScaleSpriteTrad(36), pt.x + ScaleSpriteTrad(640), pt.y + ScaleSpriteTrad(140), pt.y + ScaleSpriteTrad(206), STR_HIGHSCORE_COMPANY_ACHIEVES_STATUS, TC_FROMSTRING, SA_CENTER);
}
}
};
@@ -185,24 +185,24 @@ struct HighScoreWindow : EndGameHighScoreBaseWindow {
const HighScore *hs = _highscore_table[this->window_number];
this->SetupHighScoreEndWindow();
Point pt = this->GetTopLeft(ScaleGUITrad(640), ScaleGUITrad(480));
Point pt = this->GetTopLeft(ScaleSpriteTrad(640), ScaleSpriteTrad(480));
SetDParam(0, _settings_game.game_creation.ending_year);
DrawStringMultiLine(pt.x + ScaleGUITrad(70), pt.x + ScaleGUITrad(570), pt.y, pt.y + ScaleGUITrad(140), !_networking ? STR_HIGHSCORE_TOP_COMPANIES_WHO_REACHED : STR_HIGHSCORE_TOP_COMPANIES_NETWORK_GAME, TC_FROMSTRING, SA_CENTER);
DrawStringMultiLine(pt.x + ScaleSpriteTrad(70), pt.x + ScaleSpriteTrad(570), pt.y, pt.y + ScaleSpriteTrad(140), !_networking ? STR_HIGHSCORE_TOP_COMPANIES_WHO_REACHED : STR_HIGHSCORE_TOP_COMPANIES_NETWORK_GAME, TC_FROMSTRING, SA_CENTER);
/* Draw Highscore peepz */
for (uint8 i = 0; i < lengthof(_highscore_table[0]); i++) {
SetDParam(0, i + 1);
DrawString(pt.x + ScaleGUITrad(40), pt.x + ScaleGUITrad(600), pt.y + ScaleGUITrad(140 + i * 55), STR_HIGHSCORE_POSITION);
DrawString(pt.x + ScaleSpriteTrad(40), pt.x + ScaleSpriteTrad(600), pt.y + ScaleSpriteTrad(140 + i * 55), STR_HIGHSCORE_POSITION);
if (hs[i].company[0] != '\0') {
TextColour colour = (this->rank == i) ? TC_RED : TC_BLACK; // draw new highscore in red
SetDParamStr(0, hs[i].company);
DrawString(pt.x + ScaleGUITrad(71), pt.x + ScaleGUITrad(569), pt.y + ScaleGUITrad(140 + i * 55), STR_JUST_BIG_RAW_STRING, colour);
DrawString(pt.x + ScaleSpriteTrad(71), pt.x + ScaleSpriteTrad(569), pt.y + ScaleSpriteTrad(140 + i * 55), STR_JUST_BIG_RAW_STRING, colour);
SetDParam(0, hs[i].title);
SetDParam(1, hs[i].score);
DrawString(pt.x + ScaleGUITrad(71), pt.x + ScaleGUITrad(569), pt.y + ScaleGUITrad(140) + FONT_HEIGHT_LARGE + ScaleGUITrad(i * 55), STR_HIGHSCORE_STATS, colour);
DrawString(pt.x + ScaleSpriteTrad(71), pt.x + ScaleSpriteTrad(569), pt.y + ScaleSpriteTrad(140) + FONT_HEIGHT_LARGE + ScaleSpriteTrad(i * 55), STR_HIGHSCORE_STATS, colour);
}
}
}

View File

@@ -2040,12 +2040,13 @@ CommandCost CmdBuildIndustry(DoCommandFlag flags, TileIndex tile, IndustryType i
Industry *ind = nullptr;
if (deity_prospect || (_game_mode != GM_EDITOR && _current_company != OWNER_DEITY && _settings_game.construction.raw_industry_construction == 2 && indspec->IsRawIndustry())) {
if (flags & DC_EXEC) {
/* Prospected industries are build as OWNER_TOWN to not e.g. be build on owned land of the founder */
Backup<CompanyID> cur_company(_current_company, OWNER_TOWN, FILE_LINE);
/* Prospecting has a chance to fail, however we cannot guarantee that something can
* be built on the map, so the chance gets lower when the map is fuller, but there
* is nothing we can really do about that. */
if (deity_prospect || Random() <= indspec->prospecting_chance) {
bool prospect_success = deity_prospect || Random() <= indspec->prospecting_chance;
if (prospect_success) {
/* Prospected industries are build as OWNER_TOWN to not e.g. be build on owned land of the founder */
Backup<CompanyID> cur_company(_current_company, OWNER_TOWN, FILE_LINE);
for (int i = 0; i < 5000; i++) {
/* We should not have more than one Random() in a function call
* because parameter evaluation order is not guaranteed in the c++ standard
@@ -2061,8 +2062,15 @@ CommandCost CmdBuildIndustry(DoCommandFlag flags, TileIndex tile, IndustryType i
}
if (ret.Succeeded()) break;
}
cur_company.Restore();
}
if (ret.Failed()) {
if (prospect_success) {
ShowErrorMessage(STR_ERROR_CAN_T_PROSPECT_INDUSTRY, STR_ERROR_NO_SUITABLE_PLACES_FOR_PROSPECTING, WL_INFO);
} else {
ShowErrorMessage(STR_ERROR_CAN_T_PROSPECT_INDUSTRY, STR_ERROR_PROSPECTING_WAS_UNLUCKY, WL_INFO);
}
}
cur_company.Restore();
}
} else {
size_t layout = first_layout;

View File

@@ -422,8 +422,8 @@ public:
if (this->index[i] == INVALID_INDUSTRYTYPE) continue;
d = maxdim(d, GetStringBoundingBox(GetIndustrySpec(this->index[i])->name));
}
resize->height = std::max<uint>(this->legend.height, FONT_HEIGHT_NORMAL) + WD_MATRIX_TOP + WD_MATRIX_BOTTOM;
d.width += this->legend.width + ScaleFontTrad(7) + padding.width;
resize->height = std::max<uint>(this->legend.height, FONT_HEIGHT_NORMAL) + padding.height;
d.width += this->legend.width + WidgetDimensions::scaled.hsep_wide + padding.width;
d.height = 5 * resize->height;
*size = maxdim(*size, d);
break;
@@ -471,8 +471,8 @@ public:
/* Set it to something more sane :) */
height += extra_lines_prd + extra_lines_req + extra_lines_newgrf;
size->height = height * FONT_HEIGHT_NORMAL + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
size->width = d.width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
size->height = height * FONT_HEIGHT_NORMAL + padding.height;
size->width = d.width + padding.width;
break;
}
@@ -513,52 +513,40 @@ public:
{
switch (widget) {
case WID_DPI_MATRIX_WIDGET: {
uint text_left, text_right, icon_left, icon_right;
if (_current_text_dir == TD_RTL) {
icon_right = r.right - WD_MATRIX_RIGHT;
icon_left = icon_right - this->legend.width;
text_right = icon_left - ScaleFontTrad(7);
text_left = r.left + WD_MATRIX_LEFT;
} else {
icon_left = r.left + WD_MATRIX_LEFT;
icon_right = icon_left + this->legend.width;
text_left = icon_right + ScaleFontTrad(7);
text_right = r.right - WD_MATRIX_RIGHT;
}
bool rtl = _current_text_dir == TD_RTL;
Rect text = r.WithHeight(this->resize.step_height).Shrink(WidgetDimensions::scaled.matrix);
Rect icon = text.WithWidth(this->legend.width, rtl);
text = text.Indent(this->legend.width + WidgetDimensions::scaled.hsep_wide, rtl);
/* Vertical offset for legend icon. */
int icon_top = (this->resize.step_height - this->legend.height + 1) / 2;
int icon_bottom = icon_top + this->legend.height;
icon.top = r.top + (this->resize.step_height - this->legend.height + 1) / 2;
icon.bottom = icon.top + this->legend.height - 1;
int y = r.top;
for (uint16 i = 0; i < this->vscroll->GetCapacity() && i + this->vscroll->GetPosition() < this->count; i++) {
bool selected = this->selected_index == i + this->vscroll->GetPosition();
if (this->index[i + this->vscroll->GetPosition()] == INVALID_INDUSTRYTYPE) {
DrawString(text_left, text_right, y + WD_MATRIX_TOP, STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES, selected ? TC_WHITE : TC_ORANGE);
y += this->resize.step_height;
continue;
DrawString(text, STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES, selected ? TC_WHITE : TC_ORANGE);
} else {
const IndustrySpec *indsp = GetIndustrySpec(this->index[i + this->vscroll->GetPosition()]);
/* Draw the name of the industry in white is selected, otherwise, in orange */
DrawString(text, indsp->name, selected ? TC_WHITE : TC_ORANGE);
GfxFillRect(icon, selected ? PC_WHITE : PC_BLACK);
GfxFillRect(icon.Shrink(WidgetDimensions::scaled.bevel), indsp->map_colour);
}
const IndustrySpec *indsp = GetIndustrySpec(this->index[i + this->vscroll->GetPosition()]);
/* Draw the name of the industry in white is selected, otherwise, in orange */
DrawString(text_left, text_right, y + WD_MATRIX_TOP, indsp->name, selected ? TC_WHITE : TC_ORANGE);
GfxFillRect(icon_left, y + icon_top, icon_right, y + icon_bottom, selected ? PC_WHITE : PC_BLACK);
GfxFillRect(icon_left + 1, y + icon_top + 1, icon_right - 1, y + icon_bottom - 1, indsp->map_colour);
y += this->resize.step_height;
text = text.Translate(0, this->resize.step_height);
icon = icon.Translate(0, this->resize.step_height);
}
break;
}
case WID_DPI_INFOPANEL: {
int y = r.top + WD_FRAMERECT_TOP;
int bottom = r.bottom - WD_FRAMERECT_BOTTOM;
int left = r.left + WD_FRAMERECT_LEFT;
int right = r.right - WD_FRAMERECT_RIGHT;
Rect ir = r.Shrink(WidgetDimensions::scaled.framerect);
if (this->selected_type == INVALID_INDUSTRYTYPE) {
DrawStringMultiLine(left, right, y, bottom, STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES_TOOLTIP);
DrawStringMultiLine(ir, STR_FUND_INDUSTRY_MANY_RANDOM_INDUSTRIES_TOOLTIP);
break;
}
@@ -566,8 +554,8 @@ public:
if (_game_mode != GM_EDITOR) {
SetDParam(0, indsp->GetConstructionCost());
DrawString(left, right, y, STR_FUND_INDUSTRY_INDUSTRY_BUILD_COST);
y += FONT_HEIGHT_NORMAL;
DrawString(ir, STR_FUND_INDUSTRY_INDUSTRY_BUILD_COST);
ir.top += FONT_HEIGHT_NORMAL;
}
CargoSuffix cargo_suffix[lengthof(indsp->accepts_cargo)];
@@ -575,12 +563,12 @@ public:
/* Draw the accepted cargoes, if any. Otherwise, will print "Nothing". */
GetAllCargoSuffixes(CARGOSUFFIX_IN, CST_FUND, nullptr, this->selected_type, indsp, indsp->accepts_cargo, cargo_suffix);
std::string cargostring = this->MakeCargoListString(indsp->accepts_cargo, cargo_suffix, lengthof(indsp->accepts_cargo), STR_INDUSTRY_VIEW_REQUIRES_N_CARGO);
y = DrawStringMultiLine(left, right, y, bottom, cargostring);
ir.top = DrawStringMultiLine(ir, cargostring);
/* Draw the produced cargoes, if any. Otherwise, will print "Nothing". */
GetAllCargoSuffixes(CARGOSUFFIX_OUT, CST_FUND, nullptr, this->selected_type, indsp, indsp->produced_cargo, cargo_suffix);
cargostring = this->MakeCargoListString(indsp->produced_cargo, cargo_suffix, lengthof(indsp->produced_cargo), STR_INDUSTRY_VIEW_PRODUCES_N_CARGO);
y = DrawStringMultiLine(left, right, y, bottom, cargostring);
ir.top = DrawStringMultiLine(ir, cargostring);
/* Get the additional purchase info text, if it has not already been queried. */
if (HasBit(indsp->callback_mask, CBM_IND_FUND_MORE_TEXT)) {
@@ -592,7 +580,7 @@ public:
StringID str = GetGRFStringID(indsp->grf_prop.grffile->grfid, 0xD000 + callback_res); // No. here's the new string
if (str != STR_UNDEFINED) {
StartTextRefStackUsage(indsp->grf_prop.grffile, 6);
DrawStringMultiLine(left, right, y, bottom, str, TC_YELLOW);
DrawStringMultiLine(ir, str, TC_YELLOW);
StopTextRefStackUsage();
}
}
@@ -825,6 +813,7 @@ class IndustryViewWindow : public Window
byte clicked_button; ///< The button that has been clicked (to raise)
int production_offset_y; ///< The offset of the production texts/buttons
int info_height; ///< Height needed for the #WID_IV_INFO panel
int cheat_line_height; ///< Height of each line for the #WID_IV_INFO panel
public:
IndustryViewWindow(WindowDesc *desc, WindowNumber window_number) : Window(desc)
@@ -833,7 +822,7 @@ public:
this->editbox_line = IL_NONE;
this->clicked_line = IL_NONE;
this->clicked_button = 0;
this->info_height = WD_FRAMERECT_TOP + 2 * FONT_HEIGHT_NORMAL + WD_FRAMERECT_BOTTOM + 1; // Info panel has at least two lines text.
this->info_height = WidgetDimensions::scaled.framerect.Vertical() + 2 * FONT_HEIGHT_NORMAL; // Info panel has at least two lines text.
this->InitNested(window_number);
NWidgetViewport *nvp = this->GetWidget<NWidgetViewport>(WID_IV_VIEWPORT);
@@ -842,16 +831,22 @@ public:
this->InvalidateData();
}
void OnInit() override
{
/* This only used when the cheat to alter industry production is enabled */
this->cheat_line_height = std::max(SETTING_BUTTON_HEIGHT + WidgetDimensions::scaled.vsep_normal, FONT_HEIGHT_NORMAL);
}
void OnPaint() override
{
this->DrawWidgets();
if (this->IsShaded()) return; // Don't draw anything when the window is shaded.
NWidgetBase *nwi = this->GetWidget<NWidgetBase>(WID_IV_INFO);
uint expected = this->DrawInfo(nwi->pos_x, nwi->pos_x + nwi->current_x - 1, nwi->pos_y) - nwi->pos_y;
if (expected > nwi->current_y - 1) {
this->info_height = expected + 1;
const Rect r = this->GetWidget<NWidgetBase>(WID_IV_INFO)->GetCurrentRect();
int expected = this->DrawInfo(r);
if (expected != r.bottom) {
this->info_height = expected - r.top + 1;
this->ReInit();
return;
}
@@ -859,35 +854,33 @@ public:
/**
* Draw the text in the #WID_IV_INFO panel.
* @param left Left edge of the panel.
* @param right Right edge of the panel.
* @param top Top edge of the panel.
* @param r Rectangle of the panel.
* @return Expected position of the bottom edge of the panel.
*/
int DrawInfo(uint left, uint right, uint top)
int DrawInfo(const Rect &r)
{
bool rtl = _current_text_dir == TD_RTL;
Industry *i = Industry::Get(this->window_number);
const IndustrySpec *ind = GetIndustrySpec(i->type);
int y = top + WD_FRAMERECT_TOP;
Rect ir = r.Shrink(WidgetDimensions::scaled.framerect);
bool first = true;
bool has_accept = false;
if (i->prod_level == PRODLEVEL_CLOSURE) {
DrawString(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, y, STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE);
y += 2 * FONT_HEIGHT_NORMAL;
DrawString(ir, STR_INDUSTRY_VIEW_INDUSTRY_ANNOUNCED_CLOSURE);
ir.top += FONT_HEIGHT_NORMAL + WidgetDimensions::scaled.vsep_wide;
}
CargoSuffix cargo_suffix[lengthof(i->accepts_cargo)];
GetAllCargoSuffixes(CARGOSUFFIX_IN, CST_VIEW, i, i->type, ind, i->accepts_cargo, cargo_suffix);
bool stockpiling = HasBit(ind->callback_mask, CBM_IND_PRODUCTION_CARGO_ARRIVAL) || HasBit(ind->callback_mask, CBM_IND_PRODUCTION_256_TICKS);
uint left_side = left + WD_FRAMERECT_LEFT * 4; // Indent accepted cargoes.
for (byte j = 0; j < lengthof(i->accepts_cargo); j++) {
if (i->accepts_cargo[j] == CT_INVALID) continue;
has_accept = true;
if (first) {
DrawString(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, y, STR_INDUSTRY_VIEW_REQUIRES);
y += FONT_HEIGHT_NORMAL;
DrawString(ir, STR_INDUSTRY_VIEW_REQUIRES);
ir.top += FONT_HEIGHT_NORMAL;
first = false;
}
SetDParam(0, CargoSpec::Get(i->accepts_cargo[j])->name);
@@ -913,19 +906,22 @@ public:
default:
NOT_REACHED();
}
DrawString(left_side, right - WD_FRAMERECT_RIGHT, y, str);
y += FONT_HEIGHT_NORMAL;
DrawString(ir.Indent(WidgetDimensions::scaled.hsep_indent, rtl), str);
ir.top += FONT_HEIGHT_NORMAL;
}
GetAllCargoSuffixes(CARGOSUFFIX_OUT, CST_VIEW, i, i->type, ind, i->produced_cargo, cargo_suffix);
int line_height = this->editable == EA_RATE ? this->cheat_line_height : FONT_HEIGHT_NORMAL;
int text_y_offset = (line_height - FONT_HEIGHT_NORMAL) / 2;
int button_y_offset = (line_height - SETTING_BUTTON_HEIGHT) / 2;
first = true;
for (byte j = 0; j < lengthof(i->produced_cargo); j++) {
if (i->produced_cargo[j] == CT_INVALID) continue;
if (first) {
if (has_accept) y += WD_PAR_VSEP_WIDE;
DrawString(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, y, STR_INDUSTRY_VIEW_PRODUCTION_LAST_MONTH_TITLE);
y += FONT_HEIGHT_NORMAL;
if (this->editable == EA_RATE) this->production_offset_y = y;
if (has_accept) ir.top += WidgetDimensions::scaled.vsep_wide;
DrawString(ir, STR_INDUSTRY_VIEW_PRODUCTION_LAST_MONTH_TITLE);
ir.top += FONT_HEIGHT_NORMAL;
if (this->editable == EA_RATE) this->production_offset_y = ir.top;
first = false;
}
@@ -933,26 +929,27 @@ public:
SetDParam(1, i->last_month_production[j]);
SetDParamStr(2, cargo_suffix[j].text);
SetDParam(3, ToPercent8(i->last_month_pct_transported[j]));
uint x = left + WD_FRAMETEXT_LEFT + (this->editable == EA_RATE ? SETTING_BUTTON_WIDTH + 10 : 0);
DrawString(x, right - WD_FRAMERECT_RIGHT, y, STR_INDUSTRY_VIEW_TRANSPORTED);
DrawString(ir.Indent(WidgetDimensions::scaled.hsep_indent + (this->editable == EA_RATE ? SETTING_BUTTON_WIDTH + WidgetDimensions::scaled.hsep_normal : 0), rtl).Translate(0, text_y_offset), STR_INDUSTRY_VIEW_TRANSPORTED);
/* Let's put out those buttons.. */
if (this->editable == EA_RATE) {
DrawArrowButtons(left + WD_FRAMETEXT_LEFT, y, COLOUR_YELLOW, (this->clicked_line == IL_RATE1 + j) ? this->clicked_button : 0,
DrawArrowButtons(ir.Indent(WidgetDimensions::scaled.hsep_indent, rtl).WithWidth(SETTING_BUTTON_WIDTH, rtl).left, ir.top + button_y_offset, COLOUR_YELLOW, (this->clicked_line == IL_RATE1 + j) ? this->clicked_button : 0,
i->production_rate[j] > 0, i->production_rate[j] < 255);
}
y += FONT_HEIGHT_NORMAL;
ir.top += line_height;
}
/* Display production multiplier if editable */
if (this->editable == EA_MULTIPLIER) {
y += WD_PAR_VSEP_WIDE;
this->production_offset_y = y;
line_height = this->cheat_line_height;
text_y_offset = (line_height - FONT_HEIGHT_NORMAL) / 2;
button_y_offset = (line_height - SETTING_BUTTON_HEIGHT) / 2;
ir.top += WidgetDimensions::scaled.vsep_wide;
this->production_offset_y = ir.top;
SetDParam(0, RoundDivSU(i->prod_level * 100, PRODLEVEL_DEFAULT));
uint x = left + WD_FRAMETEXT_LEFT + SETTING_BUTTON_WIDTH + 10;
DrawString(x, right - WD_FRAMERECT_RIGHT, y, STR_INDUSTRY_VIEW_PRODUCTION_LEVEL);
DrawArrowButtons(left + WD_FRAMETEXT_LEFT, y, COLOUR_YELLOW, (this->clicked_line == IL_MULTIPLIER) ? this->clicked_button : 0,
DrawString(ir.Indent(WidgetDimensions::scaled.hsep_indent + SETTING_BUTTON_WIDTH + WidgetDimensions::scaled.hsep_normal, rtl).Translate(0, text_y_offset), STR_INDUSTRY_VIEW_PRODUCTION_LEVEL);
DrawArrowButtons(ir.Indent(WidgetDimensions::scaled.hsep_indent, rtl).WithWidth(SETTING_BUTTON_WIDTH, rtl).left, ir.top + button_y_offset, COLOUR_YELLOW, (this->clicked_line == IL_MULTIPLIER) ? this->clicked_button : 0,
i->prod_level > PRODLEVEL_MINIMUM, i->prod_level < PRODLEVEL_MAXIMUM);
y += FONT_HEIGHT_NORMAL;
ir.top += line_height;
}
/* Get the extra message for the GUI */
@@ -964,13 +961,13 @@ public:
} else {
StringID message = GetGRFStringID(ind->grf_prop.grffile->grfid, 0xD000 + callback_res);
if (message != STR_NULL && message != STR_UNDEFINED) {
y += WD_PAR_VSEP_WIDE;
ir.top += WidgetDimensions::scaled.vsep_wide;
StartTextRefStackUsage(ind->grf_prop.grffile, 6);
/* Use all the available space left from where we stand up to the
* end of the window. We ALSO enlarge the window if needed, so we
* can 'go' wild with the bottom of the window. */
y = DrawStringMultiLine(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, y, UINT16_MAX, message, TC_BLACK);
ir.top = DrawStringMultiLine(ir.left, ir.right, ir.top, UINT16_MAX, message, TC_BLACK);
StopTextRefStackUsage();
}
}
@@ -979,11 +976,12 @@ public:
if (!i->text.empty()) {
SetDParamStr(0, i->text);
y += WD_PAR_VSEP_WIDE;
y = DrawStringMultiLine(left + WD_FRAMERECT_LEFT, right - WD_FRAMERECT_RIGHT, y, UINT16_MAX, STR_JUST_RAW_STRING, TC_BLACK);
ir.top += WidgetDimensions::scaled.vsep_wide;
ir.top = DrawStringMultiLine(ir.left, ir.right, ir.top, UINT16_MAX, STR_JUST_RAW_STRING, TC_BLACK);
}
return y + WD_FRAMERECT_BOTTOM;
/* Return required bottom position, the last pixel row plus some padding. */
return ir.top - 1 + WidgetDimensions::scaled.framerect.bottom;
}
void SetStringParameters(int widget) const override
@@ -1007,12 +1005,12 @@ public:
case EA_NONE: break;
case EA_MULTIPLIER:
if (IsInsideBS(pt.y, this->production_offset_y, FONT_HEIGHT_NORMAL)) line = IL_MULTIPLIER;
if (IsInsideBS(pt.y, this->production_offset_y, this->cheat_line_height)) line = IL_MULTIPLIER;
break;
case EA_RATE:
if (pt.y >= this->production_offset_y) {
int row = (pt.y - this->production_offset_y) / FONT_HEIGHT_NORMAL;
int row = (pt.y - this->production_offset_y) / this->cheat_line_height;
for (uint j = 0; j < lengthof(i->produced_cargo); j++) {
if (i->produced_cargo[j] == CT_INVALID) continue;
row--;
@@ -1026,15 +1024,15 @@ public:
}
if (line == IL_NONE) return;
NWidgetBase *nwi = this->GetWidget<NWidgetBase>(widget);
int left = nwi->pos_x + WD_FRAMETEXT_LEFT;
int right = nwi->pos_x + nwi->current_x - 1 - WD_FRAMERECT_RIGHT;
if (IsInsideMM(pt.x, left, left + SETTING_BUTTON_WIDTH)) {
bool rtl = _current_text_dir == TD_RTL;
Rect r = this->GetWidget<NWidgetBase>(widget)->GetCurrentRect().Shrink(WidgetDimensions::scaled.framerect).Indent(WidgetDimensions::scaled.hsep_indent, rtl);
if (r.WithWidth(SETTING_BUTTON_WIDTH, rtl).Contains(pt)) {
/* Clicked buttons, decrease or increase production */
byte button = (pt.x < left + SETTING_BUTTON_WIDTH / 2) ? 1 : 2;
bool decrease = r.WithWidth(SETTING_BUTTON_WIDTH / 2, rtl).Contains(pt);
switch (this->editable) {
case EA_MULTIPLIER:
if (button == 1) {
if (decrease) {
if (i->prod_level <= PRODLEVEL_MINIMUM) return;
i->prod_level = std::max<uint>(i->prod_level / 2, PRODLEVEL_MINIMUM);
} else {
@@ -1044,7 +1042,7 @@ public:
break;
case EA_RATE:
if (button == 1) {
if (decrease) {
if (i->production_rate[line - IL_RATE1] <= 0) return;
i->production_rate[line - IL_RATE1] = std::max(i->production_rate[line - IL_RATE1] / 2, 0);
} else {
@@ -1062,8 +1060,8 @@ public:
this->SetDirty();
this->SetTimeout();
this->clicked_line = line;
this->clicked_button = button;
} else if (IsInsideMM(pt.x, left + SETTING_BUTTON_WIDTH + 10, right)) {
this->clicked_button = (decrease ^ rtl) ? 1 : 2;
} else if (r.Indent(SETTING_BUTTON_WIDTH + WidgetDimensions::scaled.hsep_normal, rtl).Contains(pt)) {
/* clicked the text */
this->editbox_line = line;
switch (this->editable) {
@@ -1195,7 +1193,7 @@ static const NWidgetPart _nested_industry_view_widgets[] = {
NWidget(NWID_VIEWPORT, INVALID_COLOUR, WID_IV_VIEWPORT), SetMinimalSize(254, 86), SetFill(1, 0), SetResize(1, 1),
EndContainer(),
EndContainer(),
NWidget(WWT_PANEL, COLOUR_CREAM, WID_IV_INFO), SetMinimalSize(260, 2), SetResize(1, 0),
NWidget(WWT_PANEL, COLOUR_CREAM, WID_IV_INFO), SetMinimalSize(260, 0), SetMinimalTextLines(2, WidgetDimensions::unscaled.framerect.Vertical()), SetResize(1, 0),
EndContainer(),
NWidget(NWID_HORIZONTAL),
NWidget(WWT_PUSHTXTBTN, COLOUR_CREAM, WID_IV_DISPLAY), SetFill(1, 0), SetResize(1, 0), SetDataTip(STR_INDUSTRY_DISPLAY_CHAIN, STR_INDUSTRY_DISPLAY_CHAIN_TOOLTIP),
@@ -1661,9 +1659,9 @@ public:
case WID_ID_INDUSTRY_LIST: {
int n = 0;
int y = r.top + WD_FRAMERECT_TOP;
Rect ir = r.Shrink(WidgetDimensions::scaled.framerect);
if (this->industries.size() == 0) {
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, STR_INDUSTRY_DIRECTORY_NONE);
DrawString(ir, STR_INDUSTRY_DIRECTORY_NONE);
break;
}
TextColour tc;
@@ -1676,9 +1674,9 @@ public:
tc = TC_GREY | TC_FORCED;
}
}
DrawString(r.left + WD_FRAMERECT_LEFT, r.right - WD_FRAMERECT_RIGHT, y, this->GetIndustryString(this->industries[i]), tc);
DrawString(ir, this->GetIndustryString(this->industries[i]), tc);
y += this->resize.step_height;
ir.top += this->resize.step_height;
if (++n == this->vscroll->GetCapacity()) break; // max number of industries in 1 window
}
break;
@@ -1715,8 +1713,8 @@ public:
}
resize->height = d.height;
d.height *= 5;
d.width += padding.width + WD_FRAMERECT_LEFT + WD_FRAMERECT_RIGHT;
d.height += padding.height + WD_FRAMERECT_TOP + WD_FRAMERECT_BOTTOM;
d.width += padding.width;
d.height += padding.height;
*size = maxdim(*size, d);
break;
}
@@ -1745,7 +1743,7 @@ public:
break;
case WID_ID_INDUSTRY_LIST: {
uint p = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_ID_INDUSTRY_LIST, WD_FRAMERECT_TOP);
uint p = this->vscroll->GetScrolledRowFromWidget(pt.y, this, WID_ID_INDUSTRY_LIST, WidgetDimensions::scaled.framerect.top);
if (p < this->industries.size()) {
if (_ctrl_pressed) {
ShowExtraViewportWindow(this->industries[p]->location.tile);
@@ -1906,8 +1904,8 @@ static const uint MAX_CARGOES = 16; ///< Maximum number of cargoes carried in a
/** Data about a single field in the #IndustryCargoesWindow panel. */
struct CargoesField {
static const int VERT_INTER_INDUSTRY_SPACE;
static const int BLOB_DISTANCE;
static int vert_inter_industry_space;
static int blob_distance;
static Dimension legend;
static Dimension cargo_border;
@@ -2097,8 +2095,8 @@ struct CargoesField {
break;
case CFT_INDUSTRY: {
int ypos1 = ypos + VERT_INTER_INDUSTRY_SPACE / 2;
int ypos2 = ypos + normal_height - 1 - VERT_INTER_INDUSTRY_SPACE / 2;
int ypos1 = ypos + vert_inter_industry_space / 2;
int ypos2 = ypos + normal_height - 1 - vert_inter_industry_space / 2;
int xpos2 = xpos + industry_width - 1;
GfxDrawLine(xpos, ypos1, xpos2, ypos1, INDUSTRY_LINE_COLOUR);
GfxDrawLine(xpos, ypos1, xpos, ypos2, INDUSTRY_LINE_COLOUR);
@@ -2112,14 +2110,14 @@ struct CargoesField {
/* Draw the industry legend. */
int blob_left, blob_right;
if (_current_text_dir == TD_RTL) {
blob_right = xpos2 - BLOB_DISTANCE;
blob_right = xpos2 - blob_distance;
blob_left = blob_right - CargoesField::legend.width;
} else {
blob_left = xpos + BLOB_DISTANCE;
blob_left = xpos + blob_distance;
blob_right = blob_left + CargoesField::legend.width;
}
GfxFillRect(blob_left, ypos2 - BLOB_DISTANCE - CargoesField::legend.height, blob_right, ypos2 - BLOB_DISTANCE, PC_BLACK); // Border
GfxFillRect(blob_left + 1, ypos2 - BLOB_DISTANCE - CargoesField::legend.height + 1, blob_right - 1, ypos2 - BLOB_DISTANCE - 1, indsp->map_colour);
GfxFillRect(blob_left, ypos2 - blob_distance - CargoesField::legend.height, blob_right, ypos2 - blob_distance, PC_BLACK); // Border
GfxFillRect(blob_left + 1, ypos2 - blob_distance - CargoesField::legend.height + 1, blob_right - 1, ypos2 - blob_distance - 1, indsp->map_colour);
} else {
DrawString(xpos, xpos2, ypos, STR_INDUSTRY_CARGOES_HOUSES, TC_FROMSTRING, SA_HOR_CENTER);
}
@@ -2154,8 +2152,8 @@ struct CargoesField {
case CFT_CARGO: {
int cargo_base = this->GetCargoBase(xpos);
int top = ypos + (this->u.cargo.top_end ? VERT_INTER_INDUSTRY_SPACE / 2 + 1 : 0);
int bot = ypos - (this->u.cargo.bottom_end ? VERT_INTER_INDUSTRY_SPACE / 2 + 1 : 0) + normal_height - 1;
int top = ypos + (this->u.cargo.top_end ? vert_inter_industry_space / 2 + 1 : 0);
int bot = ypos - (this->u.cargo.bottom_end ? vert_inter_industry_space / 2 + 1 : 0) + normal_height - 1;
int colpos = cargo_base;
for (int i = 0; i < this->u.cargo.num_cargoes; i++) {
if (this->u.cargo.top_end) GfxDrawLine(colpos, top - 1, colpos + CargoesField::cargo_line.width - 1, top - 1, CARGO_LINE_COLOUR);
@@ -2177,7 +2175,7 @@ struct CargoesField {
hor_left = this->u.cargo.supp_cargoes;
hor_right = this->u.cargo.cust_cargoes;
}
ypos += CargoesField::cargo_border.height + VERT_INTER_INDUSTRY_SPACE / 2 + (FONT_HEIGHT_NORMAL - CargoesField::cargo_line.height) / 2;
ypos += CargoesField::cargo_border.height + vert_inter_industry_space / 2 + (FONT_HEIGHT_NORMAL - CargoesField::cargo_line.height) / 2;
for (uint i = 0; i < MAX_CARGOES; i++) {
if (hor_left[i] != INVALID_CARGO) {
int col = hor_left[i];
@@ -2207,11 +2205,11 @@ struct CargoesField {
}
case CFT_CARGO_LABEL:
ypos += CargoesField::cargo_border.height + VERT_INTER_INDUSTRY_SPACE / 2;
ypos += CargoesField::cargo_border.height + vert_inter_industry_space / 2;
for (uint i = 0; i < MAX_CARGOES; i++) {
if (this->u.cargo_label.cargoes[i] != INVALID_CARGO) {
const CargoSpec *csp = CargoSpec::Get(this->u.cargo_label.cargoes[i]);
DrawString(xpos + WD_FRAMERECT_LEFT, xpos + industry_width - 1 - WD_FRAMERECT_RIGHT, ypos, csp->name, TC_WHITE,
DrawString(xpos + WidgetDimensions::scaled.framerect.left, xpos + industry_width - 1 - WidgetDimensions::scaled.framerect.right, ypos, csp->name, TC_WHITE,
(this->u.cargo_label.left_align) ? SA_LEFT : SA_RIGHT);
}
ypos += FONT_HEIGHT_NORMAL + CargoesField::cargo_space.height;
@@ -2244,7 +2242,7 @@ struct CargoesField {
}
/* col = 0 -> left of first col, 1 -> left of 2nd col, ... this->u.cargo.num_cargoes right of last-col. */
int vpos = VERT_INTER_INDUSTRY_SPACE / 2 + CargoesField::cargo_border.width;
int vpos = vert_inter_industry_space / 2 + CargoesField::cargo_border.width;
uint row;
for (row = 0; row < MAX_CARGOES; row++) {
if (pt.y < vpos) return INVALID_CARGO;
@@ -2291,7 +2289,7 @@ struct CargoesField {
{
assert(this->type == CFT_CARGO_LABEL);
int vpos = VERT_INTER_INDUSTRY_SPACE / 2 + CargoesField::cargo_border.height;
int vpos = vert_inter_industry_space / 2 + CargoesField::cargo_border.height;
uint row;
for (row = 0; row < MAX_CARGOES; row++) {
if (pt.y < vpos) return INVALID_CARGO;
@@ -2332,9 +2330,9 @@ int CargoesField::normal_height; ///< Height of the non-header rows.
int CargoesField::industry_width; ///< Width of an industry field.
int CargoesField::cargo_field_width; ///< Width of a cargo field.
uint CargoesField::max_cargoes; ///< Largest number of cargoes actually on any industry.
const int CargoesField::VERT_INTER_INDUSTRY_SPACE = 6; ///< Amount of space between two industries in a column.
int CargoesField::vert_inter_industry_space; ///< Amount of space between two industries in a column.
const int CargoesField::BLOB_DISTANCE = 5; ///< Distance of the industry legend colour from the edge of the industry box.
int CargoesField::blob_distance; ///< Distance of the industry legend colour from the edge of the industry box.
const int CargoesField::INDUSTRY_LINE_COLOUR = PC_YELLOW; ///< Line colour of the industry type box.
const int CargoesField::CARGO_LINE_COLOUR = PC_YELLOW; ///< Line colour around the cargo.
@@ -2477,8 +2475,6 @@ next_cargo: ;
* customer industries). The remaining two columns are set to #CFT_EMPTY with a width equal to the average of a cargo and an industry column.
*/
struct IndustryCargoesWindow : public Window {
static const int HOR_TEXT_PADDING, VERT_TEXT_PADDING;
typedef std::vector<CargoesRow> Fields;
Fields fields; ///< Fields to display in the #WID_IC_PANEL.
@@ -2501,8 +2497,8 @@ struct IndustryCargoesWindow : public Window {
/* Initialize static CargoesField size variables. */
Dimension d = GetStringBoundingBox(STR_INDUSTRY_CARGOES_PRODUCERS);
d = maxdim(d, GetStringBoundingBox(STR_INDUSTRY_CARGOES_CUSTOMERS));
d.width += WD_FRAMETEXT_LEFT + WD_FRAMETEXT_RIGHT;
d.height += WD_FRAMETEXT_TOP + WD_FRAMETEXT_BOTTOM;
d.width += WidgetDimensions::scaled.frametext.Horizontal();
d.height += WidgetDimensions::scaled.frametext.Vertical();
CargoesField::small_height = d.height;
/* Size of the legend blob -- slightly larger than the smallmap legend blob. */
@@ -2510,7 +2506,7 @@ struct IndustryCargoesWindow : public Window {
CargoesField::legend.width = CargoesField::legend.height * 8 / 5;
/* Size of cargo lines. */
CargoesField::cargo_line.width = FONT_HEIGHT_NORMAL;
CargoesField::cargo_line.width = ScaleGUITrad(6);
CargoesField::cargo_line.height = CargoesField::cargo_line.width;
/* Size of border between cargo lines and industry boxes. */
@@ -2525,6 +2521,9 @@ struct IndustryCargoesWindow : public Window {
CargoesField::cargo_stub.width = CargoesField::cargo_line.width / 2;
CargoesField::cargo_stub.height = CargoesField::cargo_line.height; /* Unused */
CargoesField::vert_inter_industry_space = WidgetDimensions::scaled.vsep_wide;
CargoesField::blob_distance = WidgetDimensions::scaled.hsep_normal;
/* Decide about the size of the box holding the text of an industry type. */
this->ind_textsize.width = 0;
this->ind_textsize.height = 0;
@@ -2551,13 +2550,13 @@ struct IndustryCargoesWindow : public Window {
d = maxdim(d, this->cargo_textsize); // Box must also be wide enough to hold any cargo label.
this->cargo_textsize = maxdim(this->cargo_textsize, GetStringBoundingBox(STR_INDUSTRY_CARGOES_SELECT_CARGO));
d.width += 2 * HOR_TEXT_PADDING;
d.width += WidgetDimensions::scaled.frametext.Horizontal();
/* Ensure the height is enough for the industry type text, for the horizontal connections, and for the cargo labels. */
uint min_ind_height = CargoesField::cargo_border.height * 2 + CargoesField::max_cargoes * FONT_HEIGHT_NORMAL + (CargoesField::max_cargoes - 1) * CargoesField::cargo_space.height;
d.height = std::max(d.height + 2 * VERT_TEXT_PADDING, min_ind_height);
d.height = std::max(d.height + WidgetDimensions::scaled.frametext.Vertical(), min_ind_height);
CargoesField::industry_width = d.width;
CargoesField::normal_height = d.height + CargoesField::VERT_INTER_INDUSTRY_SPACE;
CargoesField::normal_height = d.height + CargoesField::vert_inter_industry_space;
/* Width of a #CFT_CARGO field. */
CargoesField::cargo_field_width = CargoesField::cargo_border.width * 2 + CargoesField::cargo_line.width * CargoesField::max_cargoes + CargoesField::cargo_space.width * (CargoesField::max_cargoes - 1);
@@ -2568,8 +2567,8 @@ struct IndustryCargoesWindow : public Window {
switch (widget) {
case WID_IC_PANEL:
resize->height = CargoesField::normal_height;
size->width = WD_FRAMETEXT_LEFT + CargoesField::industry_width * 3 + CargoesField::cargo_field_width * 2 + WD_FRAMETEXT_RIGHT;
size->height = WD_FRAMETEXT_TOP + CargoesField::small_height + 2 * resize->height + WD_FRAMETEXT_BOTTOM;
size->width = CargoesField::industry_width * 3 + CargoesField::cargo_field_width * 2 + WidgetDimensions::scaled.frametext.Horizontal();
size->height = CargoesField::small_height + 2 * resize->height + WidgetDimensions::scaled.frametext.Vertical();
break;
case WID_IC_IND_DROPDOWN:
@@ -2920,14 +2919,13 @@ struct IndustryCargoesWindow : public Window {
{
if (widget != WID_IC_PANEL) return;
Rect ir = r.Shrink(WidgetDimensions::scaled.framerect);
DrawPixelInfo tmp_dpi, *old_dpi;
int width = r.right - r.left + 1;
int height = r.bottom - r.top + 1 - WD_FRAMERECT_TOP - WD_FRAMERECT_BOTTOM;
if (!FillDrawPixelInfo(&tmp_dpi, r.left + WD_FRAMERECT_LEFT, r.top + WD_FRAMERECT_TOP, width, height)) return;
if (!FillDrawPixelInfo(&tmp_dpi, ir.left, ir.top, ir.Width(), ir.Height())) return;
old_dpi = _cur_dpi;
_cur_dpi = &tmp_dpi;
int left_pos = WD_FRAMERECT_LEFT;
int left_pos = ir.left;
if (this->ind_cargo >= NUM_INDUSTRYTYPES) left_pos += (CargoesField::industry_width + CargoesField::cargo_field_width) / 2;
int last_column = (this->ind_cargo < NUM_INDUSTRYTYPES) ? 4 : 2;
@@ -2971,7 +2969,7 @@ struct IndustryCargoesWindow : public Window {
pt.x -= nw->pos_x;
pt.y -= nw->pos_y;
int vpos = WD_FRAMERECT_TOP + CargoesField::small_height - this->vscroll->GetPosition() * nw->resize_y;
int vpos = WidgetDimensions::scaled.framerect.top + CargoesField::small_height - this->vscroll->GetPosition() * nw->resize_y;
if (pt.y < vpos) return false;
int row = (pt.y - vpos) / CargoesField::normal_height; // row is relative to row 1.
@@ -2979,7 +2977,7 @@ struct IndustryCargoesWindow : public Window {
vpos = pt.y - vpos - row * CargoesField::normal_height; // Position in the row + 1 field
row++; // rebase row to match index of this->fields.
int xpos = 2 * WD_FRAMERECT_LEFT + ((this->ind_cargo < NUM_INDUSTRYTYPES) ? 0 : (CargoesField::industry_width + CargoesField::cargo_field_width) / 2);
int xpos = 2 * WidgetDimensions::scaled.framerect.left + ((this->ind_cargo < NUM_INDUSTRYTYPES) ? 0 : (CargoesField::industry_width + CargoesField::cargo_field_width) / 2);
if (pt.x < xpos) return false;
int column;
for (column = 0; column <= 5; column++) {
@@ -3135,13 +3133,10 @@ struct IndustryCargoesWindow : public Window {
void OnResize() override
{
this->vscroll->SetCapacityFromWidget(this, WID_IC_PANEL, WD_FRAMERECT_TOP + CargoesField::small_height);
this->vscroll->SetCapacityFromWidget(this, WID_IC_PANEL, WidgetDimensions::scaled.framerect.top + CargoesField::small_height);
}
};
const int IndustryCargoesWindow::HOR_TEXT_PADDING = 5; ///< Horizontal padding around the industry type text.
const int IndustryCargoesWindow::VERT_TEXT_PADDING = 5; ///< Vertical padding around the industry type text.
/**
* Open the industry and cargoes window.
* @param id Industry type to display, \c NUM_INDUSTRYTYPES selects a default industry type.

View File

@@ -22,6 +22,7 @@
#include "strings_func.h"
#include "fios.h"
#include "ai/ai_gui.hpp"
#include "game/game_gui.hpp"
#include "gfx_func.h"
#include "core/geometry_func.hpp"
#include "language.h"
@@ -368,6 +369,7 @@ struct SelectGameWindow : public Window {
}
break;
case WID_SGI_AI_SETTINGS: ShowAIConfigWindow(); break;
case WID_SGI_GS_SETTINGS: ShowGSConfigWindow(); break;
case WID_SGI_EXIT: HandleExitGameRequest(); break;
}
}
@@ -378,7 +380,7 @@ static const NWidgetPart _nested_select_game_widgets[] = {
NWidget(WWT_PANEL, COLOUR_BROWN),
NWidget(NWID_SPACER), SetMinimalSize(0, 8),
/* 'generate game' and 'load game' buttons */
/* 'New Game' and 'Load Game' buttons */
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_GENERATE_GAME), SetMinimalSize(158, 12),
SetDataTip(STR_INTRO_NEW_GAME, STR_INTRO_TOOLTIP_NEW_GAME), SetPadding(0, 0, 0, 10), SetFill(1, 0),
@@ -388,7 +390,7 @@ static const NWidgetPart _nested_select_game_widgets[] = {
NWidget(NWID_SPACER), SetMinimalSize(0, 6),
/* 'play scenario' and 'play heightmap' buttons */
/* 'Play Scenario' and 'Play Heightmap' buttons */
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_PLAY_SCENARIO), SetMinimalSize(158, 12),
SetDataTip(STR_INTRO_PLAY_SCENARIO, STR_INTRO_TOOLTIP_PLAY_SCENARIO), SetPadding(0, 0, 0, 10), SetFill(1, 0),
@@ -398,7 +400,7 @@ static const NWidgetPart _nested_select_game_widgets[] = {
NWidget(NWID_SPACER), SetMinimalSize(0, 6),
/* 'edit scenario' and 'play multiplayer' buttons */
/* 'Scenario Editor' and 'Multiplayer' buttons */
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_EDIT_SCENARIO), SetMinimalSize(158, 12),
SetDataTip(STR_INTRO_SCENARIO_EDITOR, STR_INTRO_TOOLTIP_SCENARIO_EDITOR), SetPadding(0, 0, 0, 10), SetFill(1, 0),
@@ -408,7 +410,7 @@ static const NWidgetPart _nested_select_game_widgets[] = {
NWidget(NWID_SPACER), SetMinimalSize(0, 7),
/* climate selection buttons */
/* Climate selection buttons */
NWidget(NWID_HORIZONTAL),
NWidget(NWID_SPACER), SetMinimalSize(10, 0), SetFill(1, 0),
NWidget(WWT_IMGBTN_2, COLOUR_ORANGE, WID_SGI_TEMPERATE_LANDSCAPE), SetMinimalSize(77, 55),
@@ -437,7 +439,7 @@ static const NWidgetPart _nested_select_game_widgets[] = {
EndContainer(),
EndContainer(),
/* 'game options' and 'advanced settings' buttons */
/* 'Game Options' and 'Settings' buttons */
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_OPTIONS), SetMinimalSize(158, 12),
SetDataTip(STR_INTRO_GAME_OPTIONS, STR_INTRO_TOOLTIP_GAME_OPTIONS), SetPadding(0, 0, 0, 10), SetFill(1, 0),
@@ -447,27 +449,35 @@ static const NWidgetPart _nested_select_game_widgets[] = {
NWidget(NWID_SPACER), SetMinimalSize(0, 6),
/* 'script settings' and 'newgrf settings' buttons */
/* 'AI Settings' and 'Game Script Settings' buttons */
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_AI_SETTINGS), SetMinimalSize(158, 12),
SetDataTip(STR_INTRO_SCRIPT_SETTINGS, STR_INTRO_TOOLTIP_SCRIPT_SETTINGS), SetPadding(0, 0, 0, 10), SetFill(1, 0),
SetDataTip(STR_INTRO_AI_SETTINGS, STR_INTRO_TOOLTIP_AI_SETTINGS), SetPadding(0, 0, 0, 10), SetFill(1, 0),
NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_GS_SETTINGS), SetMinimalSize(158, 12),
SetDataTip(STR_INTRO_GAMESCRIPT_SETTINGS, STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS), SetPadding(0, 10, 0, 0), SetFill(1, 0),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 6),
/* 'Check Online Content' and 'NewGRF Settings' buttons */
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_CONTENT_DOWNLOAD), SetMinimalSize(158, 12),
SetDataTip(STR_INTRO_ONLINE_CONTENT, STR_INTRO_TOOLTIP_ONLINE_CONTENT), SetPadding(0, 0, 0, 10), SetFill(1, 0),
NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_GRF_SETTINGS), SetMinimalSize(158, 12),
SetDataTip(STR_INTRO_NEWGRF_SETTINGS, STR_INTRO_TOOLTIP_NEWGRF_SETTINGS), SetPadding(0, 10, 0, 0), SetFill(1, 0),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 6),
/* 'online content' and 'highscore' buttons */
NWidget(NWID_HORIZONTAL, NC_EQUALSIZE),
NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_CONTENT_DOWNLOAD), SetMinimalSize(158, 12),
SetDataTip(STR_INTRO_ONLINE_CONTENT, STR_INTRO_TOOLTIP_ONLINE_CONTENT), SetPadding(0, 0, 0, 10), SetFill(1, 0),
NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_HIGHSCORE), SetMinimalSize(158, 12),
SetDataTip(STR_INTRO_HIGHSCORE, STR_INTRO_TOOLTIP_HIGHSCORE), SetPadding(0, 10, 0, 0), SetFill(1, 0),
/* 'Highscore Table' button */
NWidget(NWID_HORIZONTAL),
NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_HIGHSCORE), SetMinimalSize(316, 12),
SetDataTip(STR_INTRO_HIGHSCORE, STR_INTRO_TOOLTIP_HIGHSCORE), SetPadding(0, 10, 0, 10), SetFill(1, 0),
EndContainer(),
NWidget(NWID_SPACER), SetMinimalSize(0, 6),
/* 'exit program' button */
/* 'Exit' button */
NWidget(NWID_HORIZONTAL),
NWidget(NWID_SPACER), SetFill(1, 0),
NWidget(WWT_PUSHTXTBTN, COLOUR_ORANGE, WID_SGI_EXIT), SetMinimalSize(128, 12),

View File

@@ -500,7 +500,7 @@ void DrawFoundation(TileInfo *ti, Foundation f)
if (!IsNonContinuousFoundation(f)) {
/* Lower part of foundation */
AddSortableSpriteToDraw(
leveled_base + (ti->tileh & ~SLOPE_STEEP), PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z
leveled_base + (ti->tileh & ~SLOPE_STEEP), PAL_NONE, ti->x, ti->y, TILE_SIZE, TILE_SIZE, TILE_HEIGHT - 1, ti->z
);
}
@@ -512,38 +512,44 @@ void DrawFoundation(TileInfo *ti, Foundation f)
byte inclined = highest_corner * 2 + (f == FOUNDATION_INCLINED_Y ? 1 : 0);
AddSortableSpriteToDraw(inclined_base + inclined, PAL_NONE, ti->x, ti->y,
f == FOUNDATION_INCLINED_X ? 16 : 1,
f == FOUNDATION_INCLINED_Y ? 16 : 1,
f == FOUNDATION_INCLINED_X ? TILE_SIZE : 1,
f == FOUNDATION_INCLINED_Y ? TILE_SIZE : 1,
TILE_HEIGHT, ti->z
);
OffsetGroundSprite(31, 9);
OffsetGroundSprite(0, 0);
} else if (IsLeveledFoundation(f)) {
AddSortableSpriteToDraw(leveled_base + SlopeWithOneCornerRaised(highest_corner), PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z - TILE_HEIGHT);
OffsetGroundSprite(31, 1);
AddSortableSpriteToDraw(leveled_base + SlopeWithOneCornerRaised(highest_corner), PAL_NONE, ti->x, ti->y, TILE_SIZE, TILE_SIZE, TILE_HEIGHT - 1, ti->z - TILE_HEIGHT);
OffsetGroundSprite(0, -(int)TILE_HEIGHT);
} else if (f == FOUNDATION_STEEP_LOWER) {
/* one corner raised */
OffsetGroundSprite(31, 1);
OffsetGroundSprite(0, -(int)TILE_HEIGHT);
} else {
/* halftile foundation */
int x_bb = (((highest_corner == CORNER_W) || (highest_corner == CORNER_S)) ? 8 : 0);
int y_bb = (((highest_corner == CORNER_S) || (highest_corner == CORNER_E)) ? 8 : 0);
int x_bb = (((highest_corner == CORNER_W) || (highest_corner == CORNER_S)) ? TILE_SIZE / 2 : 0);
int y_bb = (((highest_corner == CORNER_S) || (highest_corner == CORNER_E)) ? TILE_SIZE / 2 : 0);
AddSortableSpriteToDraw(halftile_base + highest_corner, PAL_NONE, ti->x + x_bb, ti->y + y_bb, 8, 8, 7, ti->z + TILE_HEIGHT);
OffsetGroundSprite(31, 9);
AddSortableSpriteToDraw(halftile_base + highest_corner, PAL_NONE, ti->x + x_bb, ti->y + y_bb, TILE_SIZE / 2, TILE_SIZE / 2, TILE_HEIGHT - 1, ti->z + TILE_HEIGHT);
/* Reposition ground sprite back to original position after bounding box change above. This is similar to
* RemapCoords() but without zoom scaling. */
Point pt = {(y_bb - x_bb) * 2, y_bb + x_bb};
OffsetGroundSprite(-pt.x, -pt.y);
}
} else {
if (IsLeveledFoundation(f)) {
/* leveled foundation */
AddSortableSpriteToDraw(leveled_base + ti->tileh, PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z);
OffsetGroundSprite(31, 1);
AddSortableSpriteToDraw(leveled_base + ti->tileh, PAL_NONE, ti->x, ti->y, TILE_SIZE, TILE_SIZE, TILE_HEIGHT - 1, ti->z);
OffsetGroundSprite(0, -(int)TILE_HEIGHT);
} else if (IsNonContinuousFoundation(f)) {
/* halftile foundation */
Corner halftile_corner = GetHalftileFoundationCorner(f);
int x_bb = (((halftile_corner == CORNER_W) || (halftile_corner == CORNER_S)) ? 8 : 0);
int y_bb = (((halftile_corner == CORNER_S) || (halftile_corner == CORNER_E)) ? 8 : 0);
int x_bb = (((halftile_corner == CORNER_W) || (halftile_corner == CORNER_S)) ? TILE_SIZE / 2 : 0);
int y_bb = (((halftile_corner == CORNER_S) || (halftile_corner == CORNER_E)) ? TILE_SIZE / 2 : 0);
AddSortableSpriteToDraw(halftile_base + halftile_corner, PAL_NONE, ti->x + x_bb, ti->y + y_bb, 8, 8, 7, ti->z);
OffsetGroundSprite(31, 9);
AddSortableSpriteToDraw(halftile_base + halftile_corner, PAL_NONE, ti->x + x_bb, ti->y + y_bb, TILE_SIZE / 2, TILE_SIZE / 2, TILE_HEIGHT - 1, ti->z);
/* Reposition ground sprite back to original position after bounding box change above. This is similar to
* RemapCoords() but without zoom scaling. */
Point pt = {(y_bb - x_bb) * 2, y_bb + x_bb};
OffsetGroundSprite(-pt.x, -pt.y);
} else if (IsSpecialRailFoundation(f)) {
/* anti-zig-zag foundation */
SpriteID spr;
@@ -554,18 +560,18 @@ void DrawFoundation(TileInfo *ti, Foundation f)
/* tile-slope = sloped along X/Y, foundation-slope = three corners raised */
spr = inclined_base + 2 * GetRailFoundationCorner(f) + ((ti->tileh == SLOPE_SW || ti->tileh == SLOPE_NE) ? 1 : 0);
}
AddSortableSpriteToDraw(spr, PAL_NONE, ti->x, ti->y, 16, 16, 7, ti->z);
OffsetGroundSprite(31, 9);
AddSortableSpriteToDraw(spr, PAL_NONE, ti->x, ti->y, TILE_SIZE, TILE_SIZE, TILE_HEIGHT - 1, ti->z);
OffsetGroundSprite(0, 0);
} else {
/* inclined foundation */
byte inclined = GetHighestSlopeCorner(ti->tileh) * 2 + (f == FOUNDATION_INCLINED_Y ? 1 : 0);
AddSortableSpriteToDraw(inclined_base + inclined, PAL_NONE, ti->x, ti->y,
f == FOUNDATION_INCLINED_X ? 16 : 1,
f == FOUNDATION_INCLINED_Y ? 16 : 1,
f == FOUNDATION_INCLINED_X ? TILE_SIZE : 1,
f == FOUNDATION_INCLINED_Y ? TILE_SIZE : 1,
TILE_HEIGHT, ti->z
);
OffsetGroundSprite(31, 9);
OffsetGroundSprite(0, 0);
}
ti->z += ApplyPixelFoundationToSlope(f, &ti->tileh);
}
@@ -1176,9 +1182,39 @@ static bool RiverMakeWider(TileIndex tile, void *data)
Command<CMD_TERRAFORM_LAND>::Do(DC_EXEC | DC_AUTO, tile, to_change, true);
}
}
/* Update cur_slope after possibly terraforming. */
cur_slope = GetTileSlope(tile);
}
/* Sloped rivers need water both upstream and downstream. */
if (IsInclinedSlope(cur_slope)) {
DiagDirection slope_direction = GetInclinedSlopeDirection(cur_slope);
TileIndex upstream_tile = TileAddByDiagDir(tile, slope_direction);
TileIndex downstream_tile = TileAddByDiagDir(tile, ReverseDiagDir(slope_direction));
/* Don't look outside the map. */
if (!IsValidTile(upstream_tile) || !IsValidTile(downstream_tile)) return false;
/* Downstream might be new ocean created by our terraforming, and it hasn't flooded yet. */
bool downstream_is_ocean = GetTileZ(downstream_tile) == 0 && (GetTileSlope(downstream_tile) == SLOPE_FLAT || IsSlopeWithOneCornerRaised(GetTileSlope(downstream_tile)));
/* If downstream is dry, flat, and not ocean, try making it a river tile. */
if (!IsWaterTile(downstream_tile) && !downstream_is_ocean) {
/* If the tile upstream isn't flat, don't bother. */
if (GetTileSlope(downstream_tile) != SLOPE_FLAT) return false;
MakeRiver(downstream_tile, Random());
}
/* If upstream is dry and flat, try making it a river tile. */
if (!IsWaterTile(upstream_tile)) {
/* If the tile upstream isn't flat, don't bother. */
if (GetTileSlope(upstream_tile) != SLOPE_FLAT) return false;
MakeRiver(upstream_tile, Random());
}
}
/* Update cur_slope after possibly terraforming. */
cur_slope = GetTileSlope(tile);
/* If the tile slope matches the desired slope, add a river tile. */
if (cur_slope == desired_slope) {
@@ -1289,7 +1325,7 @@ static void River_FoundEndNode(AyStar *aystar, OpenListNode *current)
current_river_length = DistanceManhattan(data->spring, tile);
radius = std::min(3u, (current_river_length / (long_river_length / 3u)) + 1u);
if (radius > 1) CircularTileSearch(&tile, radius + RandomRange(1), RiverMakeWider, (void *)&path->node.tile);
if (radius > 1) CircularTileSearch(&tile, radius, RiverMakeWider, (void *)&path->node.tile);
}
}
}

View File

@@ -200,6 +200,7 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}pk
STR_UNITS_POWER_METRIC :{COMMA}{NBSP}pk
STR_UNITS_POWER_SI :{COMMA}{NBSP}kW
STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}t
STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}t
STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}kg
@@ -382,10 +383,9 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR :
STR_SCENEDIT_FILE_MENU_QUIT :Verlaat
# Settings menu
###length 14
###length 15
STR_SETTINGS_MENU_GAME_OPTIONS :Spel opsies
STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Stellings
STR_SETTINGS_MENU_SCRIPT_SETTINGS :AI/Spel skript instellings
STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRF stellings
STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Deursigtigheid opsies
STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Dorp name vertoon
@@ -945,36 +945,6 @@ STR_GAME_OPTIONS_CURRENCY_NTD :Nuwe Taiwan dol
STR_GAME_OPTIONS_CURRENCY_CNY :Chinese Renminbi (CNY)
STR_GAME_OPTIONS_CURRENCY_HKD :Hong Kong Dollar (HKD)
###length 2
STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Bestuur aan linkerkant
STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Bestuur aan regterkant
STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Dorp name
STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Kies dorp naam styl
###length 21
STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Engels (Oorspronkilik)
STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Frans
STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Duits
STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Engels (Addisioneel)
STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Latyns-Amerikaans
STR_GAME_OPTIONS_TOWN_NAME_SILLY :Snaaks
STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Sweeds
STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Hollands
STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Finnish
STR_GAME_OPTIONS_TOWN_NAME_POLISH :Polish
STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Slovak
STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norwegian
STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Hungarian
STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Austrian
STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Romanian
STR_GAME_OPTIONS_TOWN_NAME_CZECH :Czech
STR_GAME_OPTIONS_TOWN_NAME_SWISS :Swiss
STR_GAME_OPTIONS_TOWN_NAME_DANISH :Deens
STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Turks
STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Italiaans
STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Catalan
STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Outostoor
STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Kies interval tussen outomatiese store
@@ -999,18 +969,8 @@ STR_GAME_OPTIONS_RESOLUTION_OTHER :ander
STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK} Koppelvlak groote
STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK} Kies die koppelvlak element groote om te gebruik
STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normaal
STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Dubbel groote
STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Quad grootte
STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Skrifgrootte
STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Normaal
STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Dubbele grootte
STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Quad grootte
@@ -1057,8 +1017,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Voorsko
STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 Pond (£) in jou koers
STR_CURRENCY_CHANGE_PARAMETER :{BLACK}verander gebruiklike koers parameter
STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Maksimum no. mededingers: {ORANGE}{COMMA}
STR_NONE :Geen
STR_FUNDING_ONLY :Befondsing alleen
STR_MINIMAL :Minimale
@@ -1108,6 +1066,12 @@ STR_SUBSIDY_X2 :x2
STR_SUBSIDY_X3 :x3
STR_SUBSIDY_X4 :x4
###length 4
STR_CLIMATE_TEMPERATE_LANDSCAPE :Matige klimaat
STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Sub-artiese landskap
STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Sub-tropiese landskap
STR_CLIMATE_TOYLAND_LANDSCAPE :Speelgoedland landskap
###length 7
STR_TERRAIN_TYPE_VERY_FLAT :Baie Plat
STR_TERRAIN_TYPE_FLAT :Plat
@@ -1447,6 +1411,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Verbeter
STR_CONFIG_SETTING_ROAD_SIDE :Padvoertuie: {STRING}
STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Kies die bestuurskant
###length 2
STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Bestuur aan linkerkant
STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Bestuur aan regterkant
STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Reliëfkaart orientasie: {STRING}
###length 2
STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Anti-kloksgewys
@@ -1935,7 +1903,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Outomatiese rig
STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Laat treine toe om agteruit te gaan by signale, as hulle daar lank gewag het
###length 2
STR_CONFIG_SETTING_PATHFINDER_NPF :NPF
STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Aanbevole)
STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Aanbevole)
STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Verander stel waarde
@@ -1976,7 +1944,6 @@ STR_INTRO_HIGHSCORE :{BLACK}Hoogste
STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Stellings
STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF Stellings
STR_INTRO_ONLINE_CONTENT :{BLACK}Soek aanlyn
STR_INTRO_SCRIPT_SETTINGS :{BLACK}AI/Spel Skript Instellings
STR_INTRO_QUIT :{BLACK}Verlaat
STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Begin nuwe spel. Ctrl+klik ignoreer kaart konfigurasie
@@ -1996,7 +1963,6 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Vertoon
STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Vertoon instellings
STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Wys NewGRF stellings
STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Kyk vir nuwe of bygewerkde inhoud om af te laai
STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Vertoon AI/Spel skript konfigurasie
STR_INTRO_TOOLTIP_QUIT :{BLACK}Verlaat 'OpenTTD'
STR_INTRO_TRANSLATION :{BLACK}Die vertaling kort {NUM} string{P "" s}. Help aseblief om OpenTTD beter te maak, deur aan te sluit as 'n vertaaler. Sien die readme.txt vir meer inligting.
@@ -2025,12 +1991,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Verande
STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Verander huidige jaar
STR_CHEAT_SETUP_PROD :{LTBLUE}Aktiveer modifisering van produksie waardes: {ORANGE}{STRING}
###length 4
STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Matige klimaat
STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Sub-artiese landskap
STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Sub-tropiese landskap
STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Speelgoedland landskap
# Livery window
STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Kleur Skema
@@ -2921,16 +2881,41 @@ STR_MAPGEN_MAPSIZE :{BLACK}Kaart gr
STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Kies kaartgrootte teëls. Die aantal werklike beskikbare teëls sal ietwat minder wees.
STR_MAPGEN_BY :{BLACK}*
STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Hoev. dorpe:
STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Dorp name
STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Kies dorp naam styl
STR_MAPGEN_DATE :{BLACK}Datum:
STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Hoev. nywerhede:
STR_MAPGEN_LAND_GENERATOR :{BLACK}Land genereerder:
STR_MAPGEN_TERRAIN_TYPE :{BLACK}Terrein tipe:
STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Seevlak:
STR_MAPGEN_SEA_LEVEL :{BLACK}Seevlak:
STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Riviere:
STR_MAPGEN_SMOOTHNESS :{BLACK}Gladheid:
STR_MAPGEN_VARIETY :{BLACK}Verskeidenheid verspreiding:
STR_MAPGEN_GENERATE :{WHITE}Genereer
###length 21
STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Engels (Oorspronkilik)
STR_MAPGEN_TOWN_NAME_FRENCH :Frans
STR_MAPGEN_TOWN_NAME_GERMAN :Duits
STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Engels (Addisioneel)
STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Latyns-Amerikaans
STR_MAPGEN_TOWN_NAME_SILLY :Snaaks
STR_MAPGEN_TOWN_NAME_SWEDISH :Sweeds
STR_MAPGEN_TOWN_NAME_DUTCH :Hollands
STR_MAPGEN_TOWN_NAME_FINNISH :Finnish
STR_MAPGEN_TOWN_NAME_POLISH :Polish
STR_MAPGEN_TOWN_NAME_SLOVAK :Slovak
STR_MAPGEN_TOWN_NAME_NORWEGIAN :Norwegian
STR_MAPGEN_TOWN_NAME_HUNGARIAN :Hungarian
STR_MAPGEN_TOWN_NAME_AUSTRIAN :Austrian
STR_MAPGEN_TOWN_NAME_ROMANIAN :Romanian
STR_MAPGEN_TOWN_NAME_CZECH :Czech
STR_MAPGEN_TOWN_NAME_SWISS :Swiss
STR_MAPGEN_TOWN_NAME_DANISH :Deens
STR_MAPGEN_TOWN_NAME_TURKISH :Turks
STR_MAPGEN_TOWN_NAME_ITALIAN :Italiaans
STR_MAPGEN_TOWN_NAME_CATALAN :Catalan
# Strings for map borders at game generation
STR_MAPGEN_BORDER_TYPE :{BLACK}Kaart kante:
STR_MAPGEN_NORTHWEST :{BLACK}Noordwes
@@ -3069,6 +3054,10 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Vorige s
STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Gaan na vorige normale sprite, en ignoreer enige pseudo/her-kleur/font sprite en spring terug na die einde
STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Voorstelling van geselekteerde sprite. Die belyning word geignoreer waneer sprite geteken word
STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Beweeg die sprite rond, verander die X en Y afwyking. Ctrl-klik om die sprite agt lengtes rond te beweeg op 'n slag
###length 2
STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Relatiewe herstel
STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Herstel die huidige relatiewe verplasing
STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}X verplasing: {NUM}, Y verplasing: {NUM} (Werklik)
@@ -3610,6 +3599,8 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Maks. Tr
STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Afstand: {GOLD}{COMMA} teëls
STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Vliegtuig tipe: {GOLD}{STRING}
###length 3
###length VEHICLE_TYPES
STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Trein kieslys - klik op voertuig vir inligting. CTRL+kliek vir wegsteek van die voertuig tipe
STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Pad voertuig kieslys - klik op voertuig vir inligting. CTRL+kliek vir wegsteek van die voertuig tipe
@@ -4253,12 +4244,12 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Een van
STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}Rekenaar Speler/Spel Skrip Ontfout venster is slegs beskikbaar aan die verskaffer
# AI configuration window
STR_AI_CONFIG_CAPTION :{WHITE}AI/Spel Konfigurasie
STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Spel Skrip wat in die volgende spel gelaai sal word
STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}Die AIs wat om die volgende spel gelaai sal word
STR_AI_CONFIG_HUMAN_PLAYER :Mens Speler
STR_AI_CONFIG_RANDOM_AI :Lukraak AI
STR_AI_CONFIG_NONE :(geen)
STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Maksimum no. mededingers: {ORANGE}{COMMA}
STR_AI_CONFIG_MOVE_UP :{BLACK}Beweeg op
STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Beweeg gekose AI op in die lys
@@ -4268,8 +4259,6 @@ STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Beweeg g
STR_AI_CONFIG_GAMESCRIPT :{SILVER}Spel Skrip
STR_AI_CONFIG_AI :{SILVER}AIs
STR_AI_CONFIG_CHANGE :{BLACK}Selekteer {STRING}
STR_AI_CONFIG_CHANGE_NONE :
STR_AI_CONFIG_CHANGE_AI :AI
STR_AI_CONFIG_CHANGE_GAMESCRIPT :Spel Skrip
STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Laai nog 'n script
@@ -4300,9 +4289,7 @@ STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Hoogteka
STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Minimap-skermkiekie
# AI Parameters
STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parameters
STR_AI_SETTINGS_CAPTION_AI :AI
STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Speletjie Skrif
STR_AI_SETTINGS_CLOSE :{BLACK}Maak toe
STR_AI_SETTINGS_RESET :{BLACK}Herstel
STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING}
@@ -4714,6 +4701,7 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Kan nie
STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... voertuig is vernietig
STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Geen voertuie gaan beskikbaar wees nie
STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Verander jou NewGRF stellings
STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Geen voertuie is op die oomblik beskikbaar nie

View File

@@ -199,6 +199,7 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}ح
STR_UNITS_POWER_METRIC :{COMMA}{NBSP}حصان
STR_UNITS_POWER_SI :{COMMA}{NBSP}ك واط
STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP} طن
STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}طن
STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}كجم
@@ -380,10 +381,9 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR :
STR_SCENEDIT_FILE_MENU_QUIT :انهاء
# Settings menu
###length 14
###length 15
STR_SETTINGS_MENU_GAME_OPTIONS :إعدادات اللعبه
STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :الإعدادات
STR_SETTINGS_MENU_SCRIPT_SETTINGS :الذكاء الصناعي/ اعدادات اللعبة
STR_SETTINGS_MENU_NEWGRF_SETTINGS :إعدادات اﻹضافات
STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :خيارات الشفافية
STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :عرض اسماء المدن
@@ -933,36 +933,6 @@ STR_GAME_OPTIONS_CURRENCY_CNY :(CNY) الرن
STR_GAME_OPTIONS_CURRENCY_HKD :(HKD) دولار هونج كونج
STR_GAME_OPTIONS_CURRENCY_INR :الروبية الهندية (INR)
###length 2
STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :القيادة على اليسار
STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :القيادة على اليمين
STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}اسماء المدن:
STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}اختيار طريقة عرض اسماء المدن
###length 21
STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :English (Original)
STR_GAME_OPTIONS_TOWN_NAME_FRENCH :فرنسي
STR_GAME_OPTIONS_TOWN_NAME_GERMAN :الماني
STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :انجليزي اضافي
STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :امريكي لاتيني
STR_GAME_OPTIONS_TOWN_NAME_SILLY :مضحك
STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :سويدي
STR_GAME_OPTIONS_TOWN_NAME_DUTCH :هولندي
STR_GAME_OPTIONS_TOWN_NAME_FINNISH :فنلندي
STR_GAME_OPTIONS_TOWN_NAME_POLISH :بلغاري
STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :سلوفاكي
STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :نرويجي
STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :هنغاري
STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :نمساوي
STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :روماني
STR_GAME_OPTIONS_TOWN_NAME_CZECH :تشيكي
STR_GAME_OPTIONS_TOWN_NAME_SWISS :سويدي
STR_GAME_OPTIONS_TOWN_NAME_DANISH :دنماكي
STR_GAME_OPTIONS_TOWN_NAME_TURKISH :تركي
STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :ايطالي
STR_GAME_OPTIONS_TOWN_NAME_CATALAN :كتالونية
STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}حفظ آلي
STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}اختار مدة الحفظ الآلي
@@ -991,20 +961,8 @@ STR_GAME_OPTIONS_VIDEO_ACCELERATION_RESTART :{WHITE}لن ي
STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}حجم اللوحة
STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}حدد العنصر المطلوب
STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :تقريب عادي
STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :تقريب ×2
STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :تقريب ×4
STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}حجم الخط
STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}حدد حجم خط الواجهة المراد استخدامه
STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(كشف أوتوماتيكي)
STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :عادي
STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :حجم مزدوج
STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :حجم رباعي
STR_GAME_OPTIONS_GRAPHICS :{BLACK}الرسومات
@@ -1056,8 +1014,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}عرض:
STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK} 10000 جنية استرليني في عملتك
STR_CURRENCY_CHANGE_PARAMETER :{BLACK}غير الخيارات الاختيارة
STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}العدد الاقصى للمتنافسين: {ORANGE}{COMMA}
STR_NONE :بدون
STR_FUNDING_ONLY :التمويل فقط
STR_MINIMAL :الادنى
@@ -1107,6 +1063,12 @@ STR_SUBSIDY_X2 :*2
STR_SUBSIDY_X3 :*3
STR_SUBSIDY_X4 :*4
###length 4
STR_CLIMATE_TEMPERATE_LANDSCAPE :مناطق معتدلة
STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :مناطق ثلجية
STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :مناطق مدارية
STR_CLIMATE_TOYLAND_LANDSCAPE :ألعاب
###length 7
STR_TERRAIN_TYPE_VERY_FLAT :مسطح تماما
STR_TERRAIN_TYPE_FLAT :مسطح
@@ -1358,6 +1320,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :المحسن
STR_CONFIG_SETTING_ROAD_SIDE :السيارات: {STRING}
STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :إختر جهة القيادة
###length 2
STR_CONFIG_SETTING_ROAD_SIDE_LEFT :القيادة على اليسار
STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :القيادة على اليمين
STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :اتجاة خريطة المرتفعات: {STRING}
###length 2
STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :عكس عقارب الساعة
@@ -1711,7 +1677,7 @@ STR_CONFIG_SETTING_PATHFINDER_FOR_SHIPS :موجد طري
STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :العكس عند الإشارات: {STRING}
###length 2
STR_CONFIG_SETTING_PATHFINDER_NPF :NPF
STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(مفضل)
STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(مفضل)
STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}عدل قيمة التغيير
@@ -1748,7 +1714,6 @@ STR_INTRO_HIGHSCORE :{BLACK}قائم
STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}الاعدادات
STR_INTRO_NEWGRF_SETTINGS :{BLACK} اعدادات NewGRF
STR_INTRO_ONLINE_CONTENT :{BLACK} إبحث عن المحتوى عبر الشبكه العنكبوتيه
STR_INTRO_SCRIPT_SETTINGS :{BLACK}إعدادات الذكاء الصناعى
STR_INTRO_QUIT :{BLACK}خروج
STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}بدأ لعبة جديدة
@@ -1795,12 +1760,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}عدل
STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}غير السنة الحالية
STR_CHEAT_SETUP_PROD :{LTBLUE}تفعيل تغيير قيمة الانتاج: {ORANGE}{STRING}
###length 4
STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :مناطق معتدلة
STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :مناطق ثلجية
STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :مناطق مدارية
STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :ألعاب
# Livery window
STR_LIVERY_GENERAL_TOOLTIP :{BLACK}اظهر اللون العام
@@ -2672,6 +2631,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}حجم
STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK} حدد حجم الخريطة بالمربعات. سيكون عدد المربعات المتاحة أصغر قليلاً
STR_MAPGEN_BY :{BLACK}*
STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}عدد المدن:
STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}اسماء المدن:
STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}اختيار طريقة عرض اسماء المدن
STR_MAPGEN_DATE :{BLACK}التاريخ:
STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}عدد المصانع:
STR_MAPGEN_HEIGHTMAP_HEIGHT_UP :{BLACK}قم بزيادة أقصى ارتفاع لأعلى قمة على الخريطة بواحد
@@ -2681,12 +2642,35 @@ STR_MAPGEN_DESERT_COVERAGE :{BLACK}مدى
STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}%
STR_MAPGEN_LAND_GENERATOR :{BLACK}مولد الخريطة:
STR_MAPGEN_TERRAIN_TYPE :{BLACK} نوع التضاريس
STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}مستوى البحر
STR_MAPGEN_SEA_LEVEL :{BLACK}مستوى البحر
STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}انهار:
STR_MAPGEN_SMOOTHNESS :{BLACK} النعومة:
STR_MAPGEN_VARIETY :{BLACK}توزيع التنوع:
STR_MAPGEN_GENERATE :{WHITE}ولد
###length 21
STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :English (Original)
STR_MAPGEN_TOWN_NAME_FRENCH :فرنسي
STR_MAPGEN_TOWN_NAME_GERMAN :الماني
STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :انجليزي اضافي
STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :امريكي لاتيني
STR_MAPGEN_TOWN_NAME_SILLY :مضحك
STR_MAPGEN_TOWN_NAME_SWEDISH :سويدي
STR_MAPGEN_TOWN_NAME_DUTCH :هولندي
STR_MAPGEN_TOWN_NAME_FINNISH :فنلندي
STR_MAPGEN_TOWN_NAME_POLISH :بلغاري
STR_MAPGEN_TOWN_NAME_SLOVAK :سلوفاكي
STR_MAPGEN_TOWN_NAME_NORWEGIAN :نرويجي
STR_MAPGEN_TOWN_NAME_HUNGARIAN :هنغاري
STR_MAPGEN_TOWN_NAME_AUSTRIAN :نمساوي
STR_MAPGEN_TOWN_NAME_ROMANIAN :روماني
STR_MAPGEN_TOWN_NAME_CZECH :تشيكي
STR_MAPGEN_TOWN_NAME_SWISS :سويدي
STR_MAPGEN_TOWN_NAME_DANISH :دنماكي
STR_MAPGEN_TOWN_NAME_TURKISH :تركي
STR_MAPGEN_TOWN_NAME_ITALIAN :ايطالي
STR_MAPGEN_TOWN_NAME_CATALAN :كتالونية
# Strings for map borders at game generation
STR_MAPGEN_BORDER_TYPE :{BLACK} حدود الخريطة:
STR_MAPGEN_NORTHWEST :{BLACK} الشمال الغربي
@@ -2821,6 +2805,10 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}العف
STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}نابع للعفريتة الطبيعية التالية، تجاوز اي عفريتة موقوفة/ مصبوغة/مخطوطة و انهي في البداية.
STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}عرض العفريتة المختارة حاليا. يتم تجاهل الموائمة عند رسم هذا العفريت.
STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}حرك العفريتة في الجوار، غير الاحداثيات س ، ص.
###length 2
STR_SPRITE_ALIGNER_PICKER_BUTTON :{BLACK}اختر عفريتة
STR_SPRITE_ALIGNER_PICKER_TOOLTIP :{BLACK}اختر عفريتة من اي مكان في الشاشة.
@@ -3301,6 +3289,8 @@ STR_PURCHASE_INFO_ALL_BUT :الكل الا
STR_PURCHASE_INFO_MAX_TE :{BLACK}تأثير الجذب القصى: {GOLD}{FORCE}
STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}نوع الطائرة:{GOLD}{STRING}
###length 3
###length VEHICLE_TYPES
STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}قائمة اختيار القطارات - اضغط على العربة لعرض معلوماتها
STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}قائمة اختيار العربات - اضغط على العربة لاظهار معلوماتها
@@ -3914,11 +3904,11 @@ 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_HUMAN_PLAYER :لاعب انساني
STR_AI_CONFIG_RANDOM_AI :ذكاء صناعي عشوائي
STR_AI_CONFIG_NONE :(لا شيء)
STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}العدد الاقصى للمتنافسين: {ORANGE}{COMMA}
STR_AI_CONFIG_MOVE_UP :{BLACK}انقل للاعلى
STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}انقل الذكاء الاصطناعي المختار للاعلى
@@ -3927,8 +3917,6 @@ STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}انقل
STR_AI_CONFIG_AI :{SILVER} الذكاء الاصطناعي
STR_AI_CONFIG_CHANGE :{BLACK}اختر {STRING}
STR_AI_CONFIG_CHANGE_NONE :
STR_AI_CONFIG_CHANGE_AI :الذكاء الاصطناعي
STR_AI_CONFIG_CHANGE_GAMESCRIPT :مخطوط اللعبة
STR_AI_CONFIG_CONFIGURE :{BLACK} اعداد
@@ -4346,6 +4334,7 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}لا ي
STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... العربة تحطمت
STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}لن تتوافر اى وسائل نقل على اﻹطلاق
STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}لا تتوافر اى آليه نقل بعد

View File

@@ -198,6 +198,7 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}hp
STR_UNITS_POWER_METRIC :{COMMA}{NBSP}hp
STR_UNITS_POWER_SI :{COMMA}{NBSP}kW
STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}t
STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}t
STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}kg
@@ -371,10 +372,9 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR :
STR_SCENEDIT_FILE_MENU_QUIT :Irten
# Settings menu
###length 14
###length 15
STR_SETTINGS_MENU_GAME_OPTIONS :Jokoaren aukerak
STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Ezarpenak
STR_SETTINGS_MENU_SCRIPT_SETTINGS :IA/Jokoaren scriptaren ezaugarriak
STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRF ezarpenak
STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Transparentzia ezarpenak
STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Herri izenak erakutsita
@@ -916,36 +916,6 @@ STR_GAME_OPTIONS_CURRENCY_CUSTOM :Pertsonalizatua
STR_GAME_OPTIONS_CURRENCY_GEL :Lari Georgiarra (GEL)
STR_GAME_OPTIONS_CURRENCY_IRR :Rial Iraniarra (IRR)
###length 2
STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Ezkerretik gidatu
STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Eskuinetik gidatu
STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Herrien izenak
STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Herrien izenen estiloak aukeratu
###length 21
STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Ingelesa (Jatorrizkoa)
STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Frantsesak
STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Alemaniarrak
STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Ingelesa (Adizionala)
STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Latino-Amerikarra
STR_GAME_OPTIONS_TOWN_NAME_SILLY :Inozoak
STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Suediarrak
STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Herbeheretakoak
STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Finlandiarrak
STR_GAME_OPTIONS_TOWN_NAME_POLISH :Poloniarrak
STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Eslovakiarrak
STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norvegiarrak
STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Hungariarrak
STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Austriarrak
STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Errumaniarrak
STR_GAME_OPTIONS_TOWN_NAME_CZECH :Txekoak
STR_GAME_OPTIONS_TOWN_NAME_SWISS :Suitzarrak
STR_GAME_OPTIONS_TOWN_NAME_DANISH :Danierarrak
STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Turkiarrak
STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Italiarrak
STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Katalanak
STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Auto-gordea
STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Aukeratu jokoa automatikoki gordetzeko denbora
@@ -970,11 +940,6 @@ STR_GAME_OPTIONS_RESOLUTION_OTHER :besteak
STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Interfaze tamaina
STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normala
STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Tamaina doblea
STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Tamaina laukoitza
@@ -1022,8 +987,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Aurreik
STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 libra (£) zure dibisan
STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Dibisa pertsonalaren ezaugarriak aldatu
STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Gehienezko arerio kopurua: {ORANGE}{COMMA}
STR_NONE :Ezer ez
STR_FUNDING_ONLY :Finantzazioa bakarrik
STR_MINIMAL :Gutxienekoa
@@ -1073,6 +1036,12 @@ STR_SUBSIDY_X2 :x2
STR_SUBSIDY_X3 :x3
STR_SUBSIDY_X4 :x4
###length 4
STR_CLIMATE_TEMPERATE_LANDSCAPE :Klima epeleko paisaia
STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Klima artikoko paisaia
STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Klima tropikaleko paisaia
STR_CLIMATE_TOYLAND_LANDSCAPE :Jostailu munduko paisaia
###length 7
STR_TERRAIN_TYPE_VERY_FLAT :Oso laua
STR_TERRAIN_TYPE_FLAT :Laua
@@ -1387,6 +1356,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Hobetua
STR_CONFIG_SETTING_ROAD_SIDE :Errepideko garraioak: {STRING}
STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Gidatzeko aldea aukeratu
###length 2
STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Ezkerretik gidatu
STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Eskuinetik gidatu
STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Garaiera maparen norabidea: {STRING}
###length 2
STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Erlojuko orratzen kontrara
@@ -1814,7 +1787,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Seinaletan auto
STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Trenak seinaleetan buelta ematea baimendu, denbora luzez itxaroten ari badira
###length 2
STR_CONFIG_SETTING_PATHFINDER_NPF :NPF
STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Gomendatua)
STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Gomendatua)
STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Ezarpenaren balioa aldatu
@@ -1854,7 +1827,6 @@ STR_INTRO_HIGHSCORE :{BLACK}Puntuazi
STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Ezarpenak
STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF-ren Ezarpenak
STR_INTRO_ONLINE_CONTENT :{BLACK}Edukiak Online Kontsultatu
STR_INTRO_SCRIPT_SETTINGS :{BLACK}IA/Joko Scripten Ezarpenak
STR_INTRO_QUIT :{BLACK}Irten
STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Joko berria hasi. Krtl+klik mapa konfigurazioa desgaitzen du
@@ -1874,7 +1846,6 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Puntuazi
STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Ezarpenak erakutsi
STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}NewGRF ezarpenak erakutsi
STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Bilatu eduki berria eta eguneratua deskargatzeko
STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}IA/Joko Scripten Ezarpenak
STR_INTRO_TOOLTIP_QUIT :{BLACK}'OpenTTD'-tik Irten
STR_INTRO_TRANSLATION :{BLACK}Itzultze honi {NUM} string falta zaio/zaizkio. Mesedez OpenTTD hobeago egiten lagundu itzultzaile bezala aritzen. Ikusi readme.txt xehetasunentzako.
@@ -1901,12 +1872,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Data al
STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Aurtengo urtea aldatu
STR_CHEAT_SETUP_PROD :{LTBLUE}Ekoizpen balioak aldatzea baimendu: {ORANGE}{STRING}
###length 4
STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Klima epeleko paisaia
STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Klima artikoko paisaia
STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Klima tropikaleko paisaia
STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Jostailu munduko paisaia
# Livery window
STR_LIVERY_GENERAL_TOOLTIP :{BLACK}Erakutsi kolore eskema orokorrak
@@ -2749,16 +2714,41 @@ STR_MAPGEN_WORLD_GENERATION_CAPTION :{WHITE}Mundua s
STR_MAPGEN_MAPSIZE :{BLACK}Maparen tamaina:
STR_MAPGEN_BY :{BLACK}*
STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Herri kopurua:
STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Herrien izenak
STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Herrien izenen estiloak aukeratu
STR_MAPGEN_DATE :{BLACK}Data:
STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Industria kopurua:
STR_MAPGEN_LAND_GENERATOR :{BLACK}Paisaia sortzailea:
STR_MAPGEN_TERRAIN_TYPE :{BLACK}Lur mota:
STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Itsaso kopurua:
STR_MAPGEN_SEA_LEVEL :{BLACK}Itsaso kopurua:
STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Errekak:
STR_MAPGEN_SMOOTHNESS :{BLACK}Leuntasuna:
STR_MAPGEN_VARIETY :{BLACK}Barietateen distribuzioa:
STR_MAPGEN_GENERATE :{WHITE}Sortu
###length 21
STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Ingelesa (Jatorrizkoa)
STR_MAPGEN_TOWN_NAME_FRENCH :Frantsesak
STR_MAPGEN_TOWN_NAME_GERMAN :Alemaniarrak
STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Ingelesa (Adizionala)
STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Latino-Amerikarra
STR_MAPGEN_TOWN_NAME_SILLY :Inozoak
STR_MAPGEN_TOWN_NAME_SWEDISH :Suediarrak
STR_MAPGEN_TOWN_NAME_DUTCH :Herbeheretakoak
STR_MAPGEN_TOWN_NAME_FINNISH :Finlandiarrak
STR_MAPGEN_TOWN_NAME_POLISH :Poloniarrak
STR_MAPGEN_TOWN_NAME_SLOVAK :Eslovakiarrak
STR_MAPGEN_TOWN_NAME_NORWEGIAN :Norvegiarrak
STR_MAPGEN_TOWN_NAME_HUNGARIAN :Hungariarrak
STR_MAPGEN_TOWN_NAME_AUSTRIAN :Austriarrak
STR_MAPGEN_TOWN_NAME_ROMANIAN :Errumaniarrak
STR_MAPGEN_TOWN_NAME_CZECH :Txekoak
STR_MAPGEN_TOWN_NAME_SWISS :Suitzarrak
STR_MAPGEN_TOWN_NAME_DANISH :Danierarrak
STR_MAPGEN_TOWN_NAME_TURKISH :Turkiarrak
STR_MAPGEN_TOWN_NAME_ITALIAN :Italiarrak
STR_MAPGEN_TOWN_NAME_CATALAN :Katalanak
# Strings for map borders at game generation
STR_MAPGEN_BORDER_TYPE :{BLACK}Maparen ertzak:
STR_MAPGEN_NORTHWEST :{BLACK}Ipar mendebaldea
@@ -2886,6 +2876,10 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Aldez au
STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Aurreko grafiko arruntera joan, pseudo/birkoloretu/grafiko tipoak desgaituz
STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Orain aukeratutako grafikoaren aurkezpena. Alineazioa ez da kontua hartzen grafiko hau egiterakoan
STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Sprite-a mugitu ingurunean, X eta Y-ren desplazamenduak aldatuz. Ctrl+Klik sprite-a zortzi unitatero mugitzeko
###length 2
STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Erlatiboa berezarri
STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Momentuan dauden desplazamendu erlatiboak erreseteatu
STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}X desplazamendua: {NUM}, Y desplazamendua: {NUM} (Absolutua)
@@ -3389,6 +3383,8 @@ STR_PURCHASE_INFO_ALL_BUT :Guztia {CARGO_L
STR_PURCHASE_INFO_MAX_TE :{BLACK}Gehienezko trakzio indarra: {GOLD}{FORCE}
STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Irismena: {GOLD}{COMMA} lauki
###length 3
###length VEHICLE_TYPES
STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Trenak aukeratzeko zerrenda - Klik xehetasunak ikusteko. Ctrl+Klik ibilgailu motaren ezkutapenaren artean aukeratzeko
STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Errepide ibilbideak aukeratzeko zerrenda - Klik xehetasunak ikusteko
@@ -4000,12 +3996,12 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Abiarazi
STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}IA/Joko Script Garbitzailearen lehioa bakarrik zerbitzariarentzako erabilgarria da
# AI configuration window
STR_AI_CONFIG_CAPTION :{WHITE}IA/Joko Script-aren Ezarpenak
STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Hurrengo jokoan kargatuko den Joko Script-a
STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}Hurrengo jokoan kargatuko diren IA-k
STR_AI_CONFIG_HUMAN_PLAYER :Jokalaria
STR_AI_CONFIG_RANDOM_AI :Ausazko IA
STR_AI_CONFIG_NONE :(ezer ez)
STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Gehienezko arerio kopurua: {ORANGE}{COMMA}
STR_AI_CONFIG_MOVE_UP :{BLACK}Gora Mugitu
STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Auratutako IA zerrendan gora igo
@@ -4015,8 +4011,6 @@ STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Aukeratu
STR_AI_CONFIG_GAMESCRIPT :{SILVER}Jokoaren Script-a
STR_AI_CONFIG_AI :{SILVER}IAk
STR_AI_CONFIG_CHANGE :{BLACK}Aukeratu {STRING}
STR_AI_CONFIG_CHANGE_NONE :
STR_AI_CONFIG_CHANGE_AI :IA
STR_AI_CONFIG_CHANGE_GAMESCRIPT :Script jokoa
STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Bestelako script bat kargatu
@@ -4040,9 +4034,7 @@ STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Ez aldat
# AI Parameters
STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parametroak
STR_AI_SETTINGS_CAPTION_AI :IA
STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Jokoaren Script-ak
STR_AI_SETTINGS_CLOSE :{BLACK}Itxi
STR_AI_SETTINGS_RESET :{BLACK}Berrabiarazi
STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING}
@@ -4443,6 +4435,7 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Ezin da
STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... garraioa suntsituta
STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Ez da ibilgailu erabilgarririk egongo
STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Aldatu zure NewGRF konfigurazioa
STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Ez dago ibilgailu erabilgarririk oraindik

View File

@@ -511,6 +511,7 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}к
STR_UNITS_POWER_METRIC :{COMMA}{NBSP}к.с.
STR_UNITS_POWER_SI :{COMMA}{NBSP}кВт
STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}т
STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}т
STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}кг
@@ -691,10 +692,9 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR :
STR_SCENEDIT_FILE_MENU_QUIT :Выхад
# Settings menu
###length 14
###length 15
STR_SETTINGS_MENU_GAME_OPTIONS :Наладкі гульні
STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Наладкі
STR_SETTINGS_MENU_SCRIPT_SETTINGS :Наладкі ШІ / скрыпту
STR_SETTINGS_MENU_NEWGRF_SETTINGS :Наладкі NewGRF
STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Наладкі празрыстасьці
STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Паказваць назвы гарадоў
@@ -1254,36 +1254,6 @@ STR_GAME_OPTIONS_CURRENCY_CNY :Кітайск
STR_GAME_OPTIONS_CURRENCY_HKD :Ганконскі даляр (HKD)
STR_GAME_OPTIONS_CURRENCY_INR :Індыйская рупія (INR)
###length 2
STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Езьдзіць леваруч
STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Езьдзіць праваруч
STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Назвы гарадоў
STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}На якой мове будуць назвы населеных пунктаў
###length 21
STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Анґельскія (арыґінальныя)
STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Францускія
STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Нямецкія
STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Анґельскія (дадатковыя)
STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Лацінаамэрыканскія
STR_GAME_OPTIONS_TOWN_NAME_SILLY :Анґельскія (жартоўныя)
STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Швэдзкія
STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Нідэрляндзкія
STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Фінскія
STR_GAME_OPTIONS_TOWN_NAME_POLISH :Польскія
STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Славацкія
STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Нарвэскія
STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Вугорскія
STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Аўстрыйскія
STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Румынскія
STR_GAME_OPTIONS_TOWN_NAME_CZECH :Чэскія
STR_GAME_OPTIONS_TOWN_NAME_SWISS :Швайцарскія
STR_GAME_OPTIONS_TOWN_NAME_DANISH :Дацкія
STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Турэцкія
STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Італьянскія
STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Каталёнскія
STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Аўтазахаваньне
STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Інтэрвал паміж аўтаматычнымі захаваньнямі гульні
@@ -1308,18 +1278,8 @@ STR_GAME_OPTIONS_RESOLUTION_OTHER :Iншае
STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Памер элементаў інтэрфейсу
STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Выберыце памер элементаў інтэрфейсу
STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Звычайны
STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Падвоены
STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Пачацвяроны
STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Памер шрыфта
STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Абярыце памер шрыфта, выкарыстоўванага ў гульні
STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Звычайны
STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Падвоены
STR_GAME_OPTIONS_REFRESH_RATE :{BLACK}Чашчыня абнаўлення экрана
@@ -1367,8 +1327,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Узо
STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 брыт. фунтаў (£) у вашай валюце
STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Зьмяніць парамэтр уласнай валюты
STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Максымальная колькасьць канкурэнтаў: {ORANGE}{COMMA}
STR_NONE :Няма
STR_FUNDING_ONLY :Будаваць самому
STR_MINIMAL :Мінімальнае
@@ -1418,6 +1376,12 @@ STR_SUBSIDY_X2 :x2
STR_SUBSIDY_X3 :x3
STR_SUBSIDY_X4 :x4
###length 4
STR_CLIMATE_TEMPERATE_LANDSCAPE :умераны ляндшафт
STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :субарктычны ляндшафт
STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :субтрапічны ляндшафт
STR_CLIMATE_TOYLAND_LANDSCAPE :цацачны ляндшафт
###length 7
STR_TERRAIN_TYPE_VERY_FLAT :Вельмі пляскатая
STR_TERRAIN_TYPE_FLAT :Раўнінная
@@ -1759,6 +1723,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Палепша
STR_CONFIG_SETTING_ROAD_SIDE :Рух аўтатранспарту: {STRING}
STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Выберыце бок дарогі, па якому рухаецца аўтатранспарт
###length 2
STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Езьдзіць леваруч
STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Езьдзіць праваруч
STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Кручэньне мапы вышыняў: {STRING}
###length 2
STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :супраць руху гадзіньнікавай стрэлкі
@@ -2255,7 +2223,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Аўтамат
STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Дазволіць цягнікам разварочвацца перад сыґналамі, калі яны чакаюць доўгі час.
###length 2
STR_CONFIG_SETTING_PATHFINDER_NPF :NPF
STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(рэкамэндуецца)
STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(рэкамэндуецца)
STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Зьмяніць значэньне
@@ -2296,7 +2264,6 @@ STR_INTRO_HIGHSCORE :{BLACK}Табл
STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Наладкі
STR_INTRO_NEWGRF_SETTINGS :{BLACK}Наладкi NewGRF
STR_INTRO_ONLINE_CONTENT :{BLACK}Праверыць анлайн-кантэнт
STR_INTRO_SCRIPT_SETTINGS :{BLACK}Наладкі ШІ / скрыпту
STR_INTRO_QUIT :{BLACK}Выхад
STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Пачаць новую гульню. Ctrl+клік прапускае этап наладак мапы
@@ -2316,7 +2283,6 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Пака
STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Акно наладак
STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Паказаць наладкі NewGRF
STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Праверыць новы й абноўлены кантэнт, каб спампаваць
STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Зьмяніць наладкі ШІ ды гульнёвага скрыпту
STR_INTRO_TOOLTIP_QUIT :{BLACK}Выйсьці з OpenTTD
STR_INTRO_BASESET :{BLACK}У абраным наборы базавай графікі адсутнічае {NUM} спрайт{P "" а аў}. Калі ласка, абнавіце набор графікі.
@@ -2346,12 +2312,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Зьм
STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Зьмяніць бягучы год
STR_CHEAT_SETUP_PROD :{LTBLUE}Дазволіць зьмяненьне прадукцыйнасьці: {ORANGE}{STRING}
###length 4
STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :умераны ляндшафт
STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :субарктычны ляндшафт
STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :субтрапічны ляндшафт
STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :цацачны ляндшафт
# Livery window
STR_LIVERY_CAPTION :{WHITE}Колеры кампаніі «{COMPANY}»
@@ -3269,18 +3229,43 @@ STR_MAPGEN_MAPSIZE :{BLACK}Паме
STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Выберыце памер памы ў клетках. Колькасьць даступных клетак будзе трохі меншай
STR_MAPGEN_BY :{BLACK}*
STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Колькасьць гарадоў:
STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Назвы гарадоў
STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}На якой мове будуць назвы населеных пунктаў
STR_MAPGEN_DATE :{BLACK}Дата:
STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Колькасьць прадпрыемстваў:
STR_MAPGEN_SNOW_COVERAGE_TEXT :{BLACK}{NUM}%
STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Паменшыць плошчу пяшчанага пакрыцця на 10%
STR_MAPGEN_LAND_GENERATOR :{BLACK}Ґенэратар ляндшафту:
STR_MAPGEN_TERRAIN_TYPE :{BLACK}Тып ляндшафту:
STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Колькасьць азёраў/мораў:
STR_MAPGEN_SEA_LEVEL :{BLACK}Колькасьць азёраў/мораў:
STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Колькасьць рэк:
STR_MAPGEN_SMOOTHNESS :{BLACK}Гладкасьць:
STR_MAPGEN_VARIETY :{BLACK}Разнастайнасьць ляндшафту:
STR_MAPGEN_GENERATE :{WHITE}Стварыць
###length 21
STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Анґельскія (арыґінальныя)
STR_MAPGEN_TOWN_NAME_FRENCH :Францускія
STR_MAPGEN_TOWN_NAME_GERMAN :Нямецкія
STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Анґельскія (дадатковыя)
STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Лацінаамэрыканскія
STR_MAPGEN_TOWN_NAME_SILLY :Анґельскія (жартоўныя)
STR_MAPGEN_TOWN_NAME_SWEDISH :Швэдзкія
STR_MAPGEN_TOWN_NAME_DUTCH :Нідэрляндзкія
STR_MAPGEN_TOWN_NAME_FINNISH :Фінскія
STR_MAPGEN_TOWN_NAME_POLISH :Польскія
STR_MAPGEN_TOWN_NAME_SLOVAK :Славацкія
STR_MAPGEN_TOWN_NAME_NORWEGIAN :Нарвэскія
STR_MAPGEN_TOWN_NAME_HUNGARIAN :Вугорскія
STR_MAPGEN_TOWN_NAME_AUSTRIAN :Аўстрыйскія
STR_MAPGEN_TOWN_NAME_ROMANIAN :Румынскія
STR_MAPGEN_TOWN_NAME_CZECH :Чэскія
STR_MAPGEN_TOWN_NAME_SWISS :Швайцарскія
STR_MAPGEN_TOWN_NAME_DANISH :Дацкія
STR_MAPGEN_TOWN_NAME_TURKISH :Турэцкія
STR_MAPGEN_TOWN_NAME_ITALIAN :Італьянскія
STR_MAPGEN_TOWN_NAME_CATALAN :Каталёнскія
# Strings for map borders at game generation
STR_MAPGEN_BORDER_TYPE :{BLACK}Краі мапы:
STR_MAPGEN_NORTHWEST :{BLACK}Паўночны захад
@@ -3419,6 +3404,10 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Папя
STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Перайсьці да папярэдняга звычайнага спрайта, прапускаючы змяняючыя колер, шрыфтавыя, псэўдаспрайты. Пераход з пачатку сьпісу да апошняга спрайта.
STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Прадстаўленьне выбранага спрайта. Выраўноўваньне не ўлічваецца пры прарысоўцы гэтага спрайта.
STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Рухайце спрайт, зьмяняючы зрушэньне па X і па Y. Ctrl+пстрычка, каб зрушыць спрайт на восем адзінак за раз
###length 2
STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Скід зрушэння
STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Скінуць значэнні адноснага зрушэння
STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}Зрушэнне X: {NUM}; зрушэнне Y: {NUM} (абсалютнае)
@@ -3956,6 +3945,8 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Макс
STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Далёкасьць: {GOLD}{COMMA} клет{P ка кi ак}
STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Тып паветр. судна: {GOLD}{STRING}
###length 3
###length VEHICLE_TYPES
STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Сьпіс лакаматываў і вагонаў - пстрыкніце для атрыманьня інфармацыі. Ctrl+пстрычка схавае/пакажа ТС.
STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Сьпіс аўтатранспарту - пстрыкніце для атрыманьня інфармацыі. Ctrl+пстрычка схавае/пакажа выбраны аўтамабіль.
@@ -4616,12 +4607,12 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Адзі
STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}Вакно адладкі ШІ / скрыпту даступна толькі для сэрвэра
# AI configuration window
STR_AI_CONFIG_CAPTION :{WHITE}Канфігурацыя ШІ / скрыпту
STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Гульнёвы скрыпт, які будзе загружаны ў наступнай гульні
STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}Модулі ШІ, якія будуць загружаны ў наступнай гульні
STR_AI_CONFIG_HUMAN_PLAYER :Чалавек
STR_AI_CONFIG_RANDOM_AI :Выпадковы ШI
STR_AI_CONFIG_NONE :(няма)
STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Максымальная колькасьць канкурэнтаў: {ORANGE}{COMMA}
STR_AI_CONFIG_MOVE_UP :{BLACK}Уверх
STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Перамясьціць гэты модуль ШI ўверх па сьпісе
@@ -4631,8 +4622,6 @@ STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Пера
STR_AI_CONFIG_GAMESCRIPT :{SILVER}Гульнёвы скрыпт
STR_AI_CONFIG_AI :{SILVER}ШI
STR_AI_CONFIG_CHANGE :{BLACK}Выбраць {STRING}
STR_AI_CONFIG_CHANGE_NONE :
STR_AI_CONFIG_CHANGE_AI :ШI
STR_AI_CONFIG_CHANGE_GAMESCRIPT :Гульнёвы скрыпт
STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Загрузіць іншы скрыпт
@@ -4657,9 +4646,7 @@ STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Не з
STR_SCREENSHOT_ZOOMIN_SCREENSHOT :{BLACK}Бачная вобласць у максімальным набліжэнні
# AI Parameters
STR_AI_SETTINGS_CAPTION :{WHITE}Параметры {STRING}
STR_AI_SETTINGS_CAPTION_AI :ШI
STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Гульнёвы скрыпт
STR_AI_SETTINGS_CLOSE :{BLACK}Закрыць
STR_AI_SETTINGS_RESET :{BLACK}Ськід
STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING}
@@ -5067,6 +5054,7 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Не а
STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... транспартны сродак зьнішчаны
STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Усе транспартныя сродкі будуць недаступныя
STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Зьмяніце канфігурацыю модуля NewGRF
STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Няма даступных транспартных сродкаў

View File

@@ -201,6 +201,16 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}hp
STR_UNITS_POWER_METRIC :{COMMA}{NBSP}cv
STR_UNITS_POWER_SI :{COMMA}{NBSP}kW
STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t
STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t
STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg
STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}hp/t
STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}hp/t
STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}hp/Mg
STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}kW/t
STR_UNITS_POWER_SI_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}kW/t
STR_UNITS_POWER_SI_TO_WEIGHT_SI :{DECIMAL}{NBSP}W/kg
STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}T
STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}t
STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}kg
@@ -227,8 +237,8 @@ STR_UNITS_HEIGHT_SI :{COMMA}{NBSP}m
# Common window strings
STR_LIST_FILTER_TITLE :{BLACK}Filtro:
STR_LIST_FILTER_OSKTITLE :{BLACK}Digite o filtro de série
STR_LIST_FILTER_TOOLTIP :{BLACK}Digite uma palavra-chave para filtrar a lista
STR_LIST_FILTER_OSKTITLE :{BLACK}Insira uma ou mais palavras-chave para filtrar a lista
STR_LIST_FILTER_TOOLTIP :{BLACK}Insira uma ou mais palavras-chave para filtrar a lista
STR_TOOLTIP_GROUP_ORDER :{BLACK}Selecionar ordem de agrupamento
STR_TOOLTIP_SORT_ORDER :{BLACK}Selecione ordem de classificação (descendente/ascendente)
@@ -379,7 +389,7 @@ STR_SCENEDIT_TOOLBAR_ROAD_CONSTRUCTION :{BLACK}Contruç
STR_SCENEDIT_TOOLBAR_TRAM_CONSTRUCTION :{BLACK}Construção de trilho de bonde
STR_SCENEDIT_TOOLBAR_PLANT_TREES :{BLACK}Plantar árvores. Shift alterna construção/exibição de preço estimado
STR_SCENEDIT_TOOLBAR_PLACE_SIGN :{BLACK}Colocar placa
STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Colocar objeto. Shift alterna construção/preço estimado
STR_SCENEDIT_TOOLBAR_PLACE_OBJECT :{BLACK}Colocar objeto. Ctrl seleciona a área na diagonal. Shift alterna construir/mostrar estimativa de custo
# Scenario editor file menu
###length 7
@@ -392,10 +402,11 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR :
STR_SCENEDIT_FILE_MENU_QUIT :Sair
# Settings menu
###length 14
###length 15
STR_SETTINGS_MENU_GAME_OPTIONS :Opções do jogo
STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Configurações
STR_SETTINGS_MENU_SCRIPT_SETTINGS :Configurações de IA /Script do jogo
STR_SETTINGS_MENU_AI_SETTINGS :Definições de IA
STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :Definições de script do jogo
STR_SETTINGS_MENU_NEWGRF_SETTINGS :Definições do NewGRF
STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Opções de Transparência
STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Nomes de cidades exibidos
@@ -735,7 +746,7 @@ STR_SMALLMAP_TOOLTIP_SHOW_INDUSTRIES_ON_MAP :{BLACK}Exibir i
STR_SMALLMAP_TOOLTIP_SHOW_LINK_STATS_ON_MAP :{BLACK}Exibir fluxo de carga no mapa
STR_SMALLMAP_TOOLTIP_SHOW_TRANSPORT_ROUTES_ON :{BLACK}Exibir rotas de transporte no mapa
STR_SMALLMAP_TOOLTIP_SHOW_VEGETATION_ON_MAP :{BLACK}Exibir vegetação no mapa
STR_SMALLMAP_TOOLTIP_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Exibir proprietários de terreno no mapa
STR_SMALLMAP_TOOLTIP_SHOW_LAND_OWNERS_ON_MAP :{BLACK}Exibir proprietários de terrenos no mapa
STR_SMALLMAP_TOOLTIP_INDUSTRY_SELECTION :{BLACK}Clique em um tipo de indústria para alternar sua exibição. Ctrl+Clique desabilita todos os tipos exceto a selecionada. Ctrl+Clique nela novamente para habilitar todos os tipos de indústrias
STR_SMALLMAP_TOOLTIP_COMPANY_SELECTION :{BLACK}Clique em uma compania para alternar a exibição de suas propriedades. Ctrl+Clique desabilita todas as companias exceto a selecionada. Ctrl+Clique nela novamente para habilitar todas as companias
STR_SMALLMAP_TOOLTIP_CARGO_SELECTION :{BLACK}Clique numa carga para alternar a exibição de sua propriedade. Ctrl+Clique desativa todas as cargas exceto a selecionada. Ctrl+Clique novamente para exibir todas
@@ -966,36 +977,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :Rúpia Indiana
STR_GAME_OPTIONS_CURRENCY_IDR :Rupia Indonésia (IDR)
STR_GAME_OPTIONS_CURRENCY_MYR :Ringgit Malaio (MYR)
###length 2
STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Dirigem na esquerda
STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Dirigem na direita
STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Nome das cidades:
STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Selecionar o estilo dos nomes das cidades
###length 21
STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Inglês (Original)
STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Francês
STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Alemão
STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Inglês (Adicional)
STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Latino-Americano
STR_GAME_OPTIONS_TOWN_NAME_SILLY :Idiota
STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Sueco
STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Holandês
STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Finlandês
STR_GAME_OPTIONS_TOWN_NAME_POLISH :Polonês
STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Eslovaco
STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Norueguês
STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Húngaro
STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Austríaco
STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Romeno
STR_GAME_OPTIONS_TOWN_NAME_CZECH :Checo
STR_GAME_OPTIONS_TOWN_NAME_SWISS :Suiço
STR_GAME_OPTIONS_TOWN_NAME_DANISH :Dinamarquês
STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Turco
STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Italiano
STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Catalão
STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Salvar automaticamente
STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Selecionar o intervalo entre jogos salvos automaticos
@@ -1026,23 +1007,21 @@ STR_GAME_OPTIONS_VIDEO_ACCELERATION_RESTART :{WHITE}A config
STR_GAME_OPTIONS_VIDEO_VSYNC :{BLACK}VSync
STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Marque esta caixa para habilitar o v-sync na tela. Qualquer mudança nesta configuração só será aplicada após reiniciar o jogo. Só funciona com a aceleração de hardware habilitada
STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Motorista atual: {STRING}
STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Driver de vídeo atual: {STRING}
STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Tamanho da interface
STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Selecione o tamanho de elemento de interface a ser usado
STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}Tamanho da interface
STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}Arraste o controle deslizante para definir o tamanho do interface. Mantenha pressionada a tecla Ctrl para um ajuste contínuo
STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}Detectar tamanho automaticamente
STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Marque esta caixa para detectar o tamanho da interface automaticamente
STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(detecção automática)
STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normal
STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Dobro
STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Quádruplo
STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Escalar de chanfros
STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Marque esta caixa para dimensionar os chanfros por tamanho de interface
STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Tamanho da fonte
STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Selecione o tamanho da fonte da interface a ser usado
STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(detecção automática)
STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Normal
STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Tamanho duplo
STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Tamanho quádruplo
STR_GAME_OPTIONS_GUI_SCALE_1X :1x
STR_GAME_OPTIONS_GUI_SCALE_2X :2x
STR_GAME_OPTIONS_GUI_SCALE_3X :3x
STR_GAME_OPTIONS_GUI_SCALE_4X :4x
STR_GAME_OPTIONS_GUI_SCALE_5X :5x
STR_GAME_OPTIONS_GRAPHICS :{BLACK}Gráficos
@@ -1094,8 +1073,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Previs
STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 Libras (£) na sua moeda
STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Alterar o parâmetro de moeda personalizada
STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Número máximo de concorrentes: {ORANGE}{COMMA}
STR_NONE :Nenhum
STR_FUNDING_ONLY :Apenas financiamento
STR_MINIMAL :Mínimo
@@ -1145,6 +1122,12 @@ STR_SUBSIDY_X2 :x2
STR_SUBSIDY_X3 :x3
STR_SUBSIDY_X4 :x4
###length 4
STR_CLIMATE_TEMPERATE_LANDSCAPE :terreno temperado
STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :terreno subártico
STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :terreno subtropical
STR_CLIMATE_TOYLAND_LANDSCAPE :terreno 'toyland'
###length 7
STR_TERRAIN_TYPE_VERY_FLAT :Muito Plano
STR_TERRAIN_TYPE_FLAT :Plano
@@ -1450,6 +1433,8 @@ STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Espessura da li
STR_CONFIG_SETTING_SHOW_NEWGRF_NAME :Mostrar o nome do NewGRF na janela de comprar veículos: {STRING}
STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT :Adicione uma linha à janela de construção do veículo, mostrando de qual NewGRF o veículo selecionado vem.
STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS :Mostrar as cargas que os veículos podem transportar nas janelas de listagem {STRING}
STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :Quando ativado, a carga transportável do veículo aparecerá acima dela nas listas de veículos
STR_CONFIG_SETTING_LANDSCAPE :Terreno: {STRING}
STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :O terreno define a jogabilidade básica com diferentes cargas e requerimentos para o crescimento das cidades. NewGRF's e Scripts de Jogo permitem um controle mais fino
@@ -1504,6 +1489,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Melhorado
STR_CONFIG_SETTING_ROAD_SIDE :Automóveis: {STRING}
STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Escolha a mão de direção
###length 2
STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Dirigem na esquerda
STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Dirigem na direita
STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Rotação do mapa topográfico: {STRING}
###length 2
STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Sentido Anti-Horário
@@ -2038,7 +2027,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Reversão autom
STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Permite trens reverterem sentido num sinal, se estiverem aguardando por muito tempo
###length 2
STR_CONFIG_SETTING_PATHFINDER_NPF :NPF
STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Recomendado)
STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Recomendado)
STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Alterar valor
@@ -2081,7 +2070,8 @@ STR_INTRO_HIGHSCORE :{BLACK}Pontuaç
STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Configurações
STR_INTRO_NEWGRF_SETTINGS :{BLACK}Configurar NewGRF
STR_INTRO_ONLINE_CONTENT :{BLACK}Checar conteúdo on-line
STR_INTRO_SCRIPT_SETTINGS :{BLACK}Configurações de IA / Script do jogo
STR_INTRO_AI_SETTINGS :{BLACK}Definições de IA
STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}Definições de Script do Jogo
STR_INTRO_QUIT :{BLACK}Sair
STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Iniciar um novo jogo. Ctrl+Clique para pular a configuração do mapa
@@ -2101,7 +2091,8 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Exibe as
STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Config. de exibição
STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Exibir configs. dos NewGRF
STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Checar por conteúdo novo e atualizado para baixar
STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Exibe configurações de IA e script do jogo
STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}Mostrar definições de IA
STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Mostrar definições de Script do Jogo
STR_INTRO_TOOLTIP_QUIT :{BLACK}Sair do 'OpenTTD'
STR_INTRO_BASESET :{BLACK}Faltam {NUM} "sprite{P "" s}" no conjunto de gráficos base selecionado. Por favor verifique se há atualizações para ele.
@@ -2133,12 +2124,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Alterar
STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Mudar ano atual
STR_CHEAT_SETUP_PROD :{LTBLUE}Ativar modificação de valores de produção: {ORANGE}{STRING}
###length 4
STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :terreno temperado
STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :terreno subártico
STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :terreno subtropical
STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :terreno 'toyland'
# Livery window
STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Esquema de cores
@@ -2498,13 +2483,13 @@ STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH :aguardando atua
STR_NETWORK_MESSAGE_CLIENT_LEAVING :saindo
STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {STRING} entrou no jogo
STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {STRING} entrou no jogo (Client #{2:NUM})
STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} entrou na companhia #{2:NUM}
STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {0:STRING} entrou no jogo (Client #{2:NUM})
STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {0:STRING} entrou na empresa #{2:NUM}
STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} está assistindo ao jogo
STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} abriu uma nova companhia (#{2:NUM})
STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} saiu do jogo ({2:STRING})
STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {0:STRING} iniciou uma nova empresa (#{2:NUM})
STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {0:STRING} saiu do jogo ({2:STRING})
STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} mudou seu nome para {STRING}
STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} deu {2:CURRENCY_LONG} a {1:STRING}
STR_NETWORK_MESSAGE_GIVE_MONEY :*** {0:STRING} deu {2:CURRENCY_LONG} a {1:STRING}
STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}O servidor fechou a sessão
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}O servidor está reiniciando...{}Aguarde...
STR_NETWORK_MESSAGE_KICKED :*** {STRING} foi kickado. Motivo: ({STRING})
@@ -2515,7 +2500,7 @@ STR_NETWORK_ERROR_COORDINATOR_ISOLATED :{WHITE}Seu serv
STR_NETWORK_ERROR_COORDINATOR_ISOLATED_DETAIL :{WHITE}Outros jogadores não poderão se conectar ao seu servidor
# Content downloading window
STR_CONTENT_TITLE :{WHITE}Baixando conteúdo
STR_CONTENT_TITLE :{WHITE}Download de conteúdo
STR_CONTENT_TYPE_CAPTION :{BLACK}Tipo
STR_CONTENT_TYPE_CAPTION_TOOLTIP :{BLACK}Tipo do conteúdo
STR_CONTENT_NAME_CAPTION :{BLACK}Nome
@@ -2537,7 +2522,7 @@ STR_CONTENT_OPEN_URL_TOOLTIP :{BLACK}Visitar
STR_CONTENT_DOWNLOAD_CAPTION :{BLACK}Baixar
STR_CONTENT_DOWNLOAD_CAPTION_TOOLTIP :{BLACK}Baixa o conteúdo selecionado
STR_CONTENT_TOTAL_DOWNLOAD_SIZE :{SILVER}Tamanho total do download: {WHITE}{BYTES}
STR_CONTENT_DETAIL_TITLE :{SILVER}INFO DO CONT.
STR_CONTENT_DETAIL_TITLE :{SILVER}INFORMAÇÕES DO CONTEÚDO
###length 5
STR_CONTENT_DETAIL_SUBTITLE_UNSELECTED :{SILVER}Você não selecionou para ser baixado
@@ -2619,6 +2604,9 @@ STR_LINKGRAPH_LEGEND_SATURATED :{TINY_FONT}{BLA
STR_LINKGRAPH_LEGEND_OVERLOADED :{TINY_FONT}{BLACK}sobrecarregado
# Linkgraph tooltip
STR_LINKGRAPH_STATS_TOOLTIP :{BLACK}{CARGO_LONG} a ser transportado mensalmente de {STATION} para {STATION} ({COMMA}% da capacidade){STRING}
STR_LINKGRAPH_STATS_TOOLTIP_RETURN_EXTENSION :{}{CARGO_LONG} para ser transportado de volta ({COMMA}% da capacidade)
STR_LINKGRAPH_STATS_TOOLTIP_TIME_EXTENSION :{}Tempo médio de viagem: {NUM}{NBSP}dia{P "" s}
# Base for station construction window(s)
STR_STATION_BUILD_COVERAGE_AREA_TITLE :{BLACK}Destacar cobertura
@@ -2628,6 +2616,7 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}Não des
STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}Destacar área de cobertura da construção proposta
STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}Aceita: {GOLD}{CARGO_LIST}
STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Suprimentos: {GOLD}{CARGO_LIST}
STR_STATION_BUILD_INFRASTRUCTURE_COST :{BLACK}Custo de manutenção: {GOLD}{CURRENCY_SHORT}/ano
# Join station window
STR_JOIN_STATION_CAPTION :{WHITE}Unir estação
@@ -2815,11 +2804,11 @@ STR_LANDSCAPING_TOOLBAR :{WHITE}Terreno
STR_LANDSCAPING_TOOLTIP_LOWER_A_CORNER_OF_LAND :{BLACK}Baixar um canto do terreno. Arrastar abaixa o primeiro canto selecionado e nivela a área selecionada à altura do novo canto. CTRL seleciona a área diagonalmente. Shift alterna construção/preço estimado
STR_LANDSCAPING_TOOLTIP_RAISE_A_CORNER_OF_LAND :{BLACK} Elevar um canto do terreno. Arrastar eleva o primeiro canto selecionado e nivela a área selecionada à nova altura do canto. Ctrl seleciona a área diagonalmente. Shift alterna contrução/preço estimado
STR_LANDSCAPING_LEVEL_LAND_TOOLTIP :{BLACK}Nivelar uma área do terreno à altura do primeiro canto selecionado. Ctrl seleciona uma área diagonalmente. Shift alterna contrução/preço estimado
STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Comprar terreno para uso futuro. Shift altera construção/preço estimado
STR_LANDSCAPING_TOOLTIP_PURCHASE_LAND :{BLACK}Comprar terreno para uso futuro. Ctrl seleciona a área na diagonal. Shift alterna construir/mostrar estimativa de custo
# Object construction window
STR_OBJECT_BUILD_CAPTION :{WHITE}Seleção de Objeto
STR_OBJECT_BUILD_TOOLTIP :{BLACK}Selecione o objeto a ser construído. Shift alterna construção/preço estimado
STR_OBJECT_BUILD_TOOLTIP :{BLACK}Selecione o objeto para construir. Ctrl seleciona a área na diagonal. Shift alterna construir/mostrar estimativa de custo
STR_OBJECT_BUILD_CLASS_TOOLTIP :{BLACK}Selecione uma categoria de objeto para construir
STR_OBJECT_BUILD_PREVIEW_TOOLTIP :{BLACK}Pré-visualização do objeto
STR_OBJECT_BUILD_SIZE :{BLACK}Tamanho: {GOLD}{NUM} x {NUM} quadrados
@@ -2833,13 +2822,13 @@ STR_PLANT_TREE_TOOLTIP :{BLACK}Selecion
STR_TREES_RANDOM_TYPE :{BLACK}Árvores de tipo aleatório
STR_TREES_RANDOM_TYPE_TOOLTIP :{BLACK}Plantar árvores de tipo aleatório, Shift alterna entre construção/preço estimado
STR_TREES_RANDOM_TREES_BUTTON :{BLACK}Plantar Aleatoriamente
STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}Planta árvores aleatoriamente pelo terreno
STR_TREES_RANDOM_TREES_TOOLTIP :{BLACK}Plantar árvores aleatoriamente pelo terreno
STR_TREES_MODE_NORMAL_BUTTON :{BLACK}Normal
STR_TREES_MODE_NORMAL_TOOLTIP :{BLACK}Planta árvores isoladas ao arrastar pelo terreno.
STR_TREES_MODE_FOREST_SM_BUTTON :{BLACK}Bosque
STR_TREES_MODE_FOREST_SM_TOOLTIP :{BLACK}Planta pequenas florestas ao arrastar pelo terreno.
STR_TREES_MODE_FOREST_SM_TOOLTIP :{BLACK}Plantar pequenas florestas ao arrastar sobre o terreno.
STR_TREES_MODE_FOREST_LG_BUTTON :{BLACK}Floresta
STR_TREES_MODE_FOREST_LG_TOOLTIP :{BLACK}Planta florestas grandes ao arrastar pelo terreno.
STR_TREES_MODE_FOREST_LG_TOOLTIP :{BLACK}Plantar florestas grandes ao arrastar pelo terreno.
# Land generation window (SE)
STR_TERRAFORM_TOOLBAR_LAND_GENERATION_CAPTION :{WHITE}Gerar Terreno
@@ -2863,6 +2852,7 @@ STR_FOUND_TOWN_RANDOM_TOWN_BUTTON :{BLACK}Cidade A
STR_FOUND_TOWN_RANDOM_TOWN_TOOLTIP :{BLACK}Constrói cidade num local aleatório
STR_FOUND_TOWN_MANY_RANDOM_TOWNS :{BLACK}Várias cidades aleatórias
STR_FOUND_TOWN_RANDOM_TOWNS_TOOLTIP :{BLACK}Cobrir o mapa com cidades colocadas aleatoriamente
STR_FOUND_TOWN_EXPAND_ALL_TOWNS_TOOLTIP :{BLACK}Fazer com que todas as cidades cresçam ligeiramente
STR_FOUND_TOWN_NAME_TITLE :{YELLOW}Nome da cidade:
STR_FOUND_TOWN_NAME_EDITOR_TITLE :{BLACK}Coloque o nome da cidade
@@ -3141,6 +3131,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}Dimensõ
STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Seleciona o tamanho do mapa em quadrados. O número de quadrados disponíveis será um pouco menor
STR_MAPGEN_BY :{BLACK}*
STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}No. de cidades:
STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Nome das cidades:
STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Selecionar o estilo dos nomes das cidades
STR_MAPGEN_DATE :{BLACK}Data:
STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}No. de indústrias:
STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Pico mais alto:
@@ -3156,11 +3148,40 @@ STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Diminuir
STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}%
STR_MAPGEN_LAND_GENERATOR :{BLACK}Gerador de terra
STR_MAPGEN_TERRAIN_TYPE :{BLACK}Tipo de terreno
STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Nível do mar:
STR_MAPGEN_SEA_LEVEL :{BLACK}Nível do mar:
STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Rios:
STR_MAPGEN_SMOOTHNESS :{BLACK}Regularidade
STR_MAPGEN_VARIETY :{BLACK}Distribuição da variedade
STR_MAPGEN_GENERATE :{WHITE}Gerar
STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}Definições de NewGRF
STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}Mostrar definições de NewGRF
STR_MAPGEN_AI_SETTINGS :{BLACK}Definições de IA
STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}Mostrar definições de IA
STR_MAPGEN_GS_SETTINGS :{BLACK}Definições de Script do Jogo
STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Mostrar definições de script do jogo
###length 21
STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Inglês (Original)
STR_MAPGEN_TOWN_NAME_FRENCH :Francês
STR_MAPGEN_TOWN_NAME_GERMAN :Alemão
STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Inglês (Adicional)
STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Latino-Americano
STR_MAPGEN_TOWN_NAME_SILLY :Idiota
STR_MAPGEN_TOWN_NAME_SWEDISH :Sueco
STR_MAPGEN_TOWN_NAME_DUTCH :Holandês
STR_MAPGEN_TOWN_NAME_FINNISH :Finlandês
STR_MAPGEN_TOWN_NAME_POLISH :Polonês
STR_MAPGEN_TOWN_NAME_SLOVAK :Eslovaco
STR_MAPGEN_TOWN_NAME_NORWEGIAN :Norueguês
STR_MAPGEN_TOWN_NAME_HUNGARIAN :Húngaro
STR_MAPGEN_TOWN_NAME_AUSTRIAN :Austríaco
STR_MAPGEN_TOWN_NAME_ROMANIAN :Romeno
STR_MAPGEN_TOWN_NAME_CZECH :Checo
STR_MAPGEN_TOWN_NAME_SWISS :Suiço
STR_MAPGEN_TOWN_NAME_DANISH :Dinamarquês
STR_MAPGEN_TOWN_NAME_TURKISH :Turco
STR_MAPGEN_TOWN_NAME_ITALIAN :Italiano
STR_MAPGEN_TOWN_NAME_CATALAN :Catalão
# Strings for map borders at game generation
STR_MAPGEN_BORDER_TYPE :{BLACK}Bordas do mapa:
@@ -3306,6 +3327,13 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}"Sprite"
STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Retorna ao "sprite" normal anterior, pulando quaisquer "sprites" falsos, recoloridos ou de fontes, e junta tudo do primeiro ao último
STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Representação do "sprite" atualmente selecionado. O alinhamento é ignorado ao desenhar esse "sprite"
STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Move o "sprite", alterando os offsets X e Y. Ctrl+Clique para mover o sprite 8 unidades por vez
###length 2
STR_SPRITE_ALIGNER_CENTRE_OFFSET :{BLACK}Deslocamento centralizado
STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Sprite centralizado
STR_SPRITE_ALIGNER_CROSSHAIR :{BLACK}Mira
STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Resetar relativo
STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Reseta os offsets relativos atuais
STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}X offset: {NUM}, Y offset: {NUM} (Absoluto)
@@ -3324,14 +3352,14 @@ STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}Um erro
STR_NEWGRF_ERROR_POPUP :{WHITE}Um erro NewGRF ocorreu:{}{STRING}
STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} não irá funcionar com a versão do TTDPatch encontrada pelo OpenTTD
STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} funciona na versão {STRING} de TTD
STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} é projetado para ser usado com {STRING}
STR_NEWGRF_ERROR_INVALID_PARAMETER :parâmetro inválido para {1:STRING}: parâmetro {STRING} ({NUM})
STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} deve ser carregado antes de {STRING}
STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} deve ser carregado depois de {STRING}
STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} requer versão {STRING} ou maior do OpenTTD
STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} é projetado para ser usado com {2:STRING}
STR_NEWGRF_ERROR_INVALID_PARAMETER :Parâmetro inválido para {1:STRING}: parâmetro {2:STRING} ({3:NUM})
STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} deve ser carregado antes de {2:STRING}
STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} deve ser carregado depois de {2:STRING}
STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} requer versão {STRING} ou superior do OpenTTD
STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :o arquivo GRF foi designado para tradução
STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :Muitas NewGRFs estão carregadas
STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Carregar {1:STRING} como um NewGRF estático em conjunto com {STRING} pode causar desincronias
STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Carregar {1:STRING} como NewGRF estático com {2:STRING} pode causar dessincronizações
STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :"Sprite" inesperado (sprite {3:NUM})
STR_NEWGRF_ERROR_UNKNOWN_PROPERTY :Propriedade de Ação Desconhecida 0 {4:HEX} (sprite {3:NUM})
STR_NEWGRF_ERROR_INVALID_ID :Tentativa de uso de ID inválido (sprite {3:NUM})
@@ -3463,14 +3491,14 @@ STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :Comprar exclusi
STR_LOCAL_AUTHORITY_ACTION_BRIBE :Subornar a prefeitura
###length 8
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}Iniciar uma pequena campanha publicitária local, para atrair mais passageiros e cargas para seus serviços de transporte.{}Fornece um aumento temporário na avaliação da estação em um pequeno raio ao redor do centro da cidade.{}Preço: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}Iniciar uma campanha publicitária média, para atrair mais passageiros e cargas para seus serviços de transporte.{}Fornece um aumento temporário na avaliação da estação em um raio médio ao redor do centro da cidade.{}Preço: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}Iniciar uma grande campanha publicitária, para atrair mais passageiros e cargas para seus serviços de transporte.{}Fornece um aumento temporário na avaliação da estação em um grande raio ao redor do centro da cidade.{}Preço: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{YELLOW}Financiar a reconstrução da malha rodoviária urbana.{}Causa engarrafamentos consideráveis ao tráfego por até 6 meses.{}Preço: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{YELLOW}Construir uma estátua em homenagem à sua empresa.{}Fornece um aumento permanente na avaliação da estação nesta cidade.{}Preço: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{YELLOW}Financiar a construção de edifícios comerciais novos na cidade.{}Fornece um aumento temporário do crescimento da cidade nesta cidade.{}Preço: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{YELLOW}Comprar a exclusividade dos serviços durante 1 ano na cidade.{}A prefeitura da cidade não permitirá que passageiros e cargas usem as estações de seus concorrentes.{}Preço: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}Subornar a prefeitura para aumentar a sua avaliação, correndo o risco de uma penalidade severa se apanhado.{}Preço: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}Iniciar uma pequena campanha publicitária local, para atrair mais passageiros e cargas para seus serviços de transporte.{}Fornece um aumento temporário na avaliação da estação em um pequeno raio ao redor do centro da cidade.{}Custo: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}Iniciar uma campanha publicitária média, para atrair mais passageiros e cargas para seus serviços de transporte.{}Fornece um aumento temporário na avaliação da estação em um raio médio ao redor do centro da cidade.{}Custo: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{YELLOW}Iniciar uma grande campanha publicitária, para atrair mais passageiros e cargas para seus serviços de transporte.{}Fornece um aumento temporário na avaliação da estação em um grande raio ao redor do centro da cidade{}{POP_COLOUR}Custo: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{PUSH_COLOUR}{YELLOW}Financiar obras de reconstrução da malha rodoviária urbana.{}Causa engarrafamentos consideráveis ao tráfego por até 6 meses.{}{POP_COLOUR}Custo: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}Construir uma estátua em homenagem à sua empresa.{}Fornece um aumento permanente na classificação da estação nesta cidade..{}{POP_COLOUR}Custo: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{PUSH_COLOUR}{YELLOW}Financiar a construção de novos edifícios na cidade.{}Providencia um aumento temporário no crescimento desta cidade.{}{POP_COLOUR}Custo: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{PUSH_COLOUR}{YELLOW}Comprar a exclusividade dos serviços durante 1 ano na cidade.{}A prefeitura da cidade não permitirá que passageiros e cargas utilizem as estações de seus concorrentes..{}{POP_COLOUR}Custo: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{PUSH_COLOUR}{YELLOW}Subornar a autoridade local para aumentar a sua avaliação, correndo o risco de uma penalidade severa se for pego.{}{POP_COLOUR}Custo: {CURRENCY_LONG}
# Goal window
STR_GOALS_CAPTION :{WHITE}{COMPANY} Objetivos
@@ -3643,15 +3671,18 @@ STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}Navios
STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}Juros do Empréstimo
STR_FINANCES_SECTION_OTHER :{GOLD}Outros
STR_FINANCES_TOTAL_CAPTION :{WHITE}Total
STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG}
STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG}
STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG}
STR_FINANCES_NET_PROFIT :{WHITE}Lucro Líquido
STR_FINANCES_PROFIT :{WHITE}Lucro
STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Balanço Bancário
STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}Fundos Próprios
STR_FINANCES_LOAN_TITLE :{WHITE}Empréstimo
STR_FINANCES_INTEREST_RATE :{WHITE}Juro do Empréstimo: {BLACK}{NUM}%
STR_FINANCES_MAX_LOAN :{WHITE}Empréstimo Máximo: {BLACK}{CURRENCY_LONG}
STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG}
STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG}
STR_FINANCES_BORROW_BUTTON :{BLACK}Pedir {CURRENCY_LONG}
STR_FINANCES_BORROW_TOOLTIP :{BLACK}Pedir empréstimo. Ctrl+Clique pede o máximo possível
STR_FINANCES_REPAY_BUTTON :{BLACK}Pagar {CURRENCY_LONG}
@@ -3752,7 +3783,7 @@ STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Produz:
STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{STRING}
STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Necessita:
STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING}
STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{0:STRING}{BLACK}{3:STRING}
STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} aguardando{STRING}
STR_CONFIG_GAME_PRODUCTION :{WHITE}Modificar produção (múltiplo de 8, até 2040)
@@ -3782,6 +3813,8 @@ STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}Envia in
STR_VEHICLE_LIST_REPLACE_VEHICLES :Substituir veículos
STR_VEHICLE_LIST_SEND_FOR_SERVICING :Enviar para Manutenção
STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Lucro anual: {CURRENCY_LONG} (último ano: {CURRENCY_LONG})
STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}]
STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING} {STRING}
STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :Enviar para Depósito
STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :Enviar para Garagem
@@ -3873,6 +3906,11 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Tração
STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Alcance: {GOLD}{COMMA} quadrados
STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Tipo de aeronave: {GOLD}{STRING}
###length 3
STR_CARGO_TYPE_FILTER_ALL :Todos os tipos de carga
STR_CARGO_TYPE_FILTER_FREIGHT :Frete
STR_CARGO_TYPE_FILTER_NONE :Nenhum
###length VEHICLE_TYPES
STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Lista de trens - clique num trem para informações. Cltr+Clique para alterar a visibilidade do tipo de trem
STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Lista de automóveis - clique num automóvel para informações. Cltr+Clique para alterar a visibilidade do tipo de automóvel
@@ -4041,7 +4079,7 @@ STR_ENGINE_PREVIEW_AIRCRAFT :aeronave
STR_ENGINE_PREVIEW_SHIP :embarcação
STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Preço: {CURRENCY_LONG} Peso: {WEIGHT_SHORT}{}Velocidade: {VELOCITY} Potência: {POWER}{}Custo de manutenção: {CURRENCY_LONG}/ano{}Capacidade: {CARGO_LONG}
STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Preço: {CURRENCY_LONG} Peso: {WEIGHT_SHORT}{}Vel.: {VELOCITY} Potência: {POWER} Tração Máx: {6:FORCE}{}Custo de manutenção: {4:CURRENCY_LONG}/yr{}Capacidade: {5:CARGO_LONG}
STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Custo: {0:CURRENCY_LONG} Peso: {1:WEIGHT_SHORT}{}Velocidade: {2:VELOCITY} Potência: {3:POWER} Tração Máx: {6:FORCE}{}Custo de Operação: {4:CURRENCY_LONG}/ano{}Capacidade: {5:CARGO_LONG}
STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Preço: {CURRENCY_LONG} Vel. Max.: {VELOCITY}{}Capacidade: {CARGO_LONG}{}Custo de manuteção: {CURRENCY_LONG}/ano
STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_CAP_RUNCOST :{BLACK}Custo: {CURRENCY_LONG} Vel Máx.: {VELOCITY}{}Tipo de aeronave: {STRING}{}Capacidade: {CARGO_LONG}, {CARGO_LONG}{}Custo de oper.: {CURRENCY_LONG}/ano
STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}Custo: {CURRENCY_LONG} Vel Máx.: {VELOCITY}{}Tipo de aeronave: {STRING}{}Capacidade: {CARGO_LONG}{}Custo de oper.: {CURRENCY_LONG}/ano
@@ -4200,11 +4238,12 @@ STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Peso: {L
STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Peso: {LTBLUE}{WEIGHT_SHORT} {BLACK}Força: {LTBLUE}{POWER}{BLACK} Velocidade Max: {LTBLUE}{VELOCITY} {BLACK}Max. T.E.: {LTBLUE}{FORCE}
STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Lucros desse ano: {LTBLUE}{CURRENCY_LONG} (ano passado: {CURRENCY_LONG})
STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}Lucro deste ano: {LTBLUE}{CURRENCY_LONG} (último ano: {CURRENCY_LONG}) {BLACK}Performance min.: {LTBLUE}{POWER_TO_WEIGHT}
STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Confiabilidade: {LTBLUE}{COMMA}% {BLACK}Quebras desde a última manutenção: {LTBLUE}{COMMA}
STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Construído: {LTBLUE}{NUM}{BLACK} Valor: {LTBLUE}{CURRENCY_LONG}
STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}Capacidade: {LTBLUE}Nenhuma{STRING}
STR_VEHICLE_INFO_CAPACITY :{BLACK}Capacidade: {LTBLUE}{CARGO_LONG}{3:STRING}
STR_VEHICLE_INFO_CAPACITY :{BLACK}Capacidade: {LTBLUE}{0:CARGO_LONG}{3:STRING}
STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Capacidade: {LTBLUE}{CARGO_LONG}{3:STRING} (x{4:NUM})
STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}Capacidade: {LTBLUE}{CARGO_LONG}, {CARGO_LONG}{STRING}
@@ -4471,7 +4510,7 @@ STR_TIMETABLE_STATUS_NOT_STARTED :{BLACK}Este hor
STR_TIMETABLE_STATUS_START_AT :{BLACK}Este horário começará em{STRING}
STR_TIMETABLE_STARTING_DATE :{BLACK}Data de início
STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Seleciona uma data como ponto de partida para esse horário. Ctrl+Clique define o ponto de partida desse horário, e distribui todos os veículos que compartilham essa ordem igualmente, baseados na sua ordem relativa, mesmo que a ordem esteja totalmente tabelada
STR_TIMETABLE_STARTING_DATE_TOOLTIP :{BLACK}Seleciona uma data como ponto de partida para esse horário. Ctrl+Clique define o ponto de partida desse horário e distribui todos os veículos que compartilham essa ordem igualmente, baseados na sua ordem relativa, mesmo que a ordem esteja totalmente tabelada
STR_TIMETABLE_CHANGE_TIME :{BLACK}Mudar horário
STR_TIMETABLE_WAIT_TIME_TOOLTIP :{BLACK}Mudar a quantidade de tempo que a ordem destacada deverá levar
@@ -4480,7 +4519,7 @@ STR_TIMETABLE_CLEAR_TIME :{BLACK}Limpar H
STR_TIMETABLE_CLEAR_TIME_TOOLTIP :{BLACK}Limpar a quantidade de tempo para a ordem destacada
STR_TIMETABLE_CHANGE_SPEED :{BLACK}Alterar Limite de Vel.
STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Altera a velocidade máxima de viagem para a ordem selecionada
STR_TIMETABLE_CHANGE_SPEED_TOOLTIP :{BLACK}Altera a velocidade máxima de viagem para a ordem selecionada. Ctrl+Clique define a velocidade para todas as ordens
STR_TIMETABLE_CLEAR_SPEED :{BLACK}Limpa Limite de Vel.
STR_TIMETABLE_CLEAR_SPEED_TOOLTIP :{BLACK}Limpar a velocidade máxima de viagem para a ordem selecionada
@@ -4533,12 +4572,14 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Um dos s
STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}Depuração de I.A./Script do jogo só é acessível pelo servidor
# AI configuration window
STR_AI_CONFIG_CAPTION :{WHITE}Configuração da I.A./Script do jogo
STR_AI_CONFIG_CAPTION_AI :{WHITE}Configuração de IA
STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}Configuração de Script de Jogo
STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}O script do jogo que será carregado no próximo jogo
STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}IAs que serão carregadas no próximo jogo
STR_AI_CONFIG_HUMAN_PLAYER :Jogador humano
STR_AI_CONFIG_RANDOM_AI :IA aleatória
STR_AI_CONFIG_NONE :{G=m}(nenhum)
STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Número máximo de concorrentes: {ORANGE}{COMMA}
STR_AI_CONFIG_MOVE_UP :{BLACK}Subir
STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Mover a IA selecionada para cima na lista
@@ -4546,12 +4587,11 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}Descer
STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Mover a IA selecionada para baixo na lista
STR_AI_CONFIG_GAMESCRIPT :{SILVER}Script do jogo
STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}Parâmetros
STR_AI_CONFIG_AI :{G=f}{SILVER}IAs
STR_AI_CONFIG_CHANGE :{BLACK}Selecionar {STRING}
STR_AI_CONFIG_CHANGE_NONE :
STR_AI_CONFIG_CHANGE_AI :{G=f}IA
STR_AI_CONFIG_CHANGE_GAMESCRIPT :Script do jogo
STR_AI_CONFIG_CHANGE_AI :{BLACK}Selecionar IA
STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}Selecionar Script do Jogo
STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Carregar outro script
STR_AI_CONFIG_CONFIGURE :{BLACK}Configurar
STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}Configurar os parâmetros do Script
@@ -4580,9 +4620,7 @@ STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Captura
STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Captura de tela do minimapa
# AI Parameters
STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Parâmetros
STR_AI_SETTINGS_CAPTION_AI :{G=f}IA
STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Script do jogo
STR_AI_SETTINGS_CAPTION_AI :{WHITE}Parâmetros de IA
STR_AI_SETTINGS_CLOSE :{BLACK}Fechar
STR_AI_SETTINGS_RESET :{BLACK}Resetar
STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING}
@@ -4592,11 +4630,11 @@ STR_AI_SETTINGS_START_DELAY :Número de dias
# Textfile window
STR_TEXTFILE_WRAP_TEXT :{WHITE}Quebra de linha
STR_TEXTFILE_WRAP_TEXT_TOOLTIP :[BLACK}Quebra linhas automaticamente para que o texto caiba na janela
STR_TEXTFILE_VIEW_README :{BLACK}Ler o Leiame
STR_TEXTFILE_VIEW_README :{BLACK}Ver o leia-me
STR_TEXTFILE_VIEW_CHANGELOG :{BLACK}Log de mudanças
STR_TEXTFILE_VIEW_LICENCE :{BLACK}Licença
###length 3
STR_TEXTFILE_README_CAPTION :{WHITE}{STRING} Leiame de {STRING}
STR_TEXTFILE_README_CAPTION :{WHITE}{STRING} Leia-me de {STRING}
STR_TEXTFILE_CHANGELOG_CAPTION :{WHITE}{STRING} log de mudanças de {STRING}
STR_TEXTFILE_LICENCE_CAPTION :{WHITE}{STRING} licença de {STRING}
@@ -4905,7 +4943,7 @@ STR_ERROR_MUST_DEMOLISH_BRIDGE_FIRST :{WHITE}Remova a
STR_ERROR_CAN_T_START_AND_END_ON :{WHITE}Impossível iniciar e terminar no mesmo ponto
STR_ERROR_BRIDGEHEADS_NOT_SAME_HEIGHT :{WHITE}Extremidades da ponte não estão no mesmo nível
STR_ERROR_BRIDGE_TOO_LOW_FOR_TERRAIN :{WHITE}Ponte é muito baixa para o terreno
STR_ERROR_BRIDGE_TOO_HIGH_FOR_TERRAIN :{WHITE}A ponte está muito alta para esse terreno.
STR_ERROR_BRIDGE_TOO_HIGH_FOR_TERRAIN :{WHITE}A ponte está muito alta para este terreno.
STR_ERROR_START_AND_END_MUST_BE_IN :{WHITE}Inicio e fim devem estar alinhados
STR_ERROR_ENDS_OF_BRIDGE_MUST_BOTH :{WHITE}... os extremos da ponte devem estar sobre a terra
STR_ERROR_BRIDGE_TOO_LONG :{WHITE}... ponte muito longa
@@ -4927,6 +4965,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}Objeto n
STR_ERROR_COMPANY_HEADQUARTERS_IN :{WHITE}... sede de empresa no caminho
STR_ERROR_CAN_T_PURCHASE_THIS_LAND :{WHITE}Impossível comprar esta área...
STR_ERROR_YOU_ALREADY_OWN_IT :{WHITE}... já a possui!
STR_ERROR_BUILD_OBJECT_LIMIT_REACHED :{WHITE}... limite de construção de objetos atingido
# Group related errors
STR_ERROR_GROUP_CAN_T_CREATE :{WHITE}Impossível criar grupo...
@@ -4999,6 +5038,8 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Impossí
STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... veículo está destruído
STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}... nem todos os veículos são idênticos
STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Não haverá nenhum veículo disponível
STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Altere sua configuração de NewGRF
STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Não há veículos disponíveis ainda
@@ -5025,6 +5066,8 @@ STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}Impossí
STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}... o veículo não pode chegar a todas as estações
STR_ERROR_CAN_T_ADD_ORDER :{WHITE}... o veículo não chega àquela estação
STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}... um veículo com essa mesma ordem não chega àquela estação
STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST :{WHITE}... nem todos os veículos possuem as mesmas ordens
STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST :{WHITE}... nem todos os veículos estão compartilhando ordens
STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}Impossível compartilhar a lista de ordens...
STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}Impossível compartilhar lista de ordens...

View File

@@ -200,6 +200,7 @@ STR_UNITS_POWER_IMPERIAL :{COMMA} к.с.
STR_UNITS_POWER_METRIC :{COMMA} к.с.
STR_UNITS_POWER_SI :{COMMA} kW
STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}т
STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA} т.
STR_UNITS_WEIGHT_SHORT_SI :{COMMA} кг.
@@ -375,10 +376,9 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR :
STR_SCENEDIT_FILE_MENU_QUIT :Изход
# Settings menu
###length 14
###length 15
STR_SETTINGS_MENU_GAME_OPTIONS :Игрови опции
STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Настройки
STR_SETTINGS_MENU_SCRIPT_SETTINGS :Настройка на ИИ програмите
STR_SETTINGS_MENU_NEWGRF_SETTINGS :Newgrf настройки
STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Настройки на прозрачност
STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Показване имената на градовете
@@ -924,36 +924,6 @@ STR_GAME_OPTIONS_CURRENCY_IRR :Ирански
STR_GAME_OPTIONS_CURRENCY_NTD :Нов тайвански долар
STR_GAME_OPTIONS_CURRENCY_HKD :Хонгконгски долар (HKD)
###length 2
STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :ляво
STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :дясно
STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Имена на градовете
STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Избор стила на имената на градовете
###length 21
STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :английски (оригинални)
STR_GAME_OPTIONS_TOWN_NAME_FRENCH :френски
STR_GAME_OPTIONS_TOWN_NAME_GERMAN :германски
STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :английски (допълнителни)
STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :латиноамерикански
STR_GAME_OPTIONS_TOWN_NAME_SILLY :глупави
STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :шведски
STR_GAME_OPTIONS_TOWN_NAME_DUTCH :холандски
STR_GAME_OPTIONS_TOWN_NAME_FINNISH :финландски
STR_GAME_OPTIONS_TOWN_NAME_POLISH :полски
STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :словашки
STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :норвежки
STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :унгарски
STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :австрийски
STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :румънски
STR_GAME_OPTIONS_TOWN_NAME_CZECH :чешки
STR_GAME_OPTIONS_TOWN_NAME_SWISS :швейцарски
STR_GAME_OPTIONS_TOWN_NAME_DANISH :датски
STR_GAME_OPTIONS_TOWN_NAME_TURKISH :турски
STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :италиански
STR_GAME_OPTIONS_TOWN_NAME_CATALAN :каталонски
STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Автозаписване
STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Интервала между две автозаписваня
@@ -978,12 +948,6 @@ STR_GAME_OPTIONS_RESOLUTION_OTHER :друго
STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Интерфейс размер
STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Изберете размера на интерфейс елемент за използване
STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Нормално
STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Двукратно
STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Четирикратно
@@ -1032,8 +996,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Пре
STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10000 лири(£) в твоята валута
STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Промяна параметрите на парична единица
STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Максимален брой конкуренти: {ORANGE}{COMMA}
STR_NONE :николко
STR_FUNDING_ONLY :Единствено финансиране
STR_MINIMAL :Минимален
@@ -1083,6 +1045,12 @@ STR_SUBSIDY_X2 :x2
STR_SUBSIDY_X3 :x3
STR_SUBSIDY_X4 :x4
###length 4
STR_CLIMATE_TEMPERATE_LANDSCAPE :умерен климат
STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Арктичен климат
STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Тропически климат
STR_CLIMATE_TOYLAND_LANDSCAPE :Земята на играчките
###length 7
STR_TERRAIN_TYPE_VERY_FLAT :платовиден
STR_TERRAIN_TYPE_FLAT :равнинен
@@ -1411,6 +1379,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :подобре
STR_CONFIG_SETTING_ROAD_SIDE :Пътни превозни средства: {STRING}
STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Изберете страна шофиране
###length 2
STR_CONFIG_SETTING_ROAD_SIDE_LEFT :ляво
STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :дясно
STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Завъртане на картата: {STRING}
###length 2
STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Обратрно на часовниковата стрелка
@@ -1858,7 +1830,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Автомат
STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Позволява на влаковете да обръщат ако са чакали твърде дълго
###length 2
STR_CONFIG_SETTING_PATHFINDER_NPF :NPF
STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(препоръчва се)
STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(препоръчва се)
STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Промяна стойноста на настройка
@@ -1898,7 +1870,6 @@ STR_INTRO_HIGHSCORE :{BLACK}Табл
STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Настройки
STR_INTRO_NEWGRF_SETTINGS :{BLACK}NewGRF настройки
STR_INTRO_ONLINE_CONTENT :{BLACK}Провери онлайн съдържанието
STR_INTRO_SCRIPT_SETTINGS :{BLACK}ИИ/Игрови настройки
STR_INTRO_QUIT :{BLACK}Изход
STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Започни нова игра. Ctrl+Click пропуска конфигурацията на картата
@@ -1918,7 +1889,6 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Пока
STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Настройки на дисплея
STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Покажи NewGRF настройки
STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Провери за ново съдържание за сваляне
STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Показва настройките на ИИ
STR_INTRO_TOOLTIP_QUIT :{BLACK}Изход от 'OpenTTD'
STR_INTRO_TRANSLATION :{BLACK}На този превод му липсват {NUM} string{P "" s}. Помогнете на OpenTTD като се запишете за преводач. Вижте readme.txt за повече информация.
@@ -1947,12 +1917,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Про
STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Промяна настоящата година
STR_CHEAT_SETUP_PROD :{LTBLUE}Промяна на производствените стойности: {ORANGE}{STRING}
###length 4
STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :умерен климат
STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Арктичен климат
STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Тропически климат
STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Земята на играчките
# Livery window
STR_LIVERY_GENERAL_TOOLTIP :{BLACK}Показване на общи цветови схеми
@@ -2804,16 +2768,41 @@ STR_MAPGEN_MAPSIZE :{BLACK}Разм
STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Изберете големината на картата в полета. Броя на наличните полета ще е малко по-малък.
STR_MAPGEN_BY :{BLACK}*
STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Брой градове:
STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Имена на градовете
STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Избор стила на имената на градовете
STR_MAPGEN_DATE :{BLACK}Дата:
STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Брой индустрии:
STR_MAPGEN_LAND_GENERATOR :{BLACK}Земегенератор:
STR_MAPGEN_TERRAIN_TYPE :{BLACK}Тип на терен:
STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Морско ниво:
STR_MAPGEN_SEA_LEVEL :{BLACK}Морско ниво:
STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Реки:
STR_MAPGEN_SMOOTHNESS :{BLACK}Полегатост:
STR_MAPGEN_VARIETY :{BLACK}Разнообразност:
STR_MAPGEN_GENERATE :{WHITE}Генериране
###length 21
STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :английски (оригинални)
STR_MAPGEN_TOWN_NAME_FRENCH :френски
STR_MAPGEN_TOWN_NAME_GERMAN :германски
STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :английски (допълнителни)
STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :латиноамерикански
STR_MAPGEN_TOWN_NAME_SILLY :глупави
STR_MAPGEN_TOWN_NAME_SWEDISH :шведски
STR_MAPGEN_TOWN_NAME_DUTCH :холандски
STR_MAPGEN_TOWN_NAME_FINNISH :финландски
STR_MAPGEN_TOWN_NAME_POLISH :полски
STR_MAPGEN_TOWN_NAME_SLOVAK :словашки
STR_MAPGEN_TOWN_NAME_NORWEGIAN :норвежки
STR_MAPGEN_TOWN_NAME_HUNGARIAN :унгарски
STR_MAPGEN_TOWN_NAME_AUSTRIAN :австрийски
STR_MAPGEN_TOWN_NAME_ROMANIAN :румънски
STR_MAPGEN_TOWN_NAME_CZECH :чешки
STR_MAPGEN_TOWN_NAME_SWISS :швейцарски
STR_MAPGEN_TOWN_NAME_DANISH :датски
STR_MAPGEN_TOWN_NAME_TURKISH :турски
STR_MAPGEN_TOWN_NAME_ITALIAN :италиански
STR_MAPGEN_TOWN_NAME_CATALAN :каталонски
# Strings for map borders at game generation
STR_MAPGEN_BORDER_TYPE :{BLACK}Краищата на картата да са:
STR_MAPGEN_NORTHWEST :{BLACK}Северозапад
@@ -2948,6 +2937,10 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Пред
STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Продължи към предишен нормален sprite, Пропускайки всички псевдо/прерисувани/текстови sprite и ги облечи в края
STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Показване на избрания sprite. Подредбата се пренебрегва при рисуването му.
STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Преместване на sprite, променяйки X и Y координатите
###length 2
STR_SPRITE_ALIGNER_PICKER_BUTTON :{BLACK}Избери sprite
STR_SPRITE_ALIGNER_PICKER_TOOLTIP :{BLACK}Избери sprite от целия екран
@@ -3453,6 +3446,8 @@ STR_PURCHASE_INFO_ALL_BUT :Всичко о
STR_PURCHASE_INFO_MAX_TE :{BLACK}Макс. теглеща сила: {GOLD}{FORCE}
STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Обхват: {GOLD}{COMMA} полета
###length 3
###length VEHICLE_TYPES
STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Списък с влакове - натисни върху влак за информация
STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Списък с избор на МПС-та - натисни върху МПС за информация
@@ -4080,12 +4075,12 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Един
STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}ИИ Дебъг прозореца е на разположение само на сървъра
# AI configuration window
STR_AI_CONFIG_CAPTION :{WHITE}ИИ Настройки
STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Иговия скрипт ще бъде зареден в следващата игра
STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}ИИ-тата ще бъдат заредени в следващата игра
STR_AI_CONFIG_HUMAN_PLAYER :Човешки играч
STR_AI_CONFIG_RANDOM_AI :Случаен AI
STR_AI_CONFIG_NONE :(нищо)
STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Максимален брой конкуренти: {ORANGE}{COMMA}
STR_AI_CONFIG_MOVE_UP :{BLACK}Премести нагоре
STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Премести маркирания AI нагоре в списъка
@@ -4095,8 +4090,6 @@ STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Прем
STR_AI_CONFIG_GAMESCRIPT :{SILVER}Игрови скрипт
STR_AI_CONFIG_AI :{SILVER}AI-та
STR_AI_CONFIG_CHANGE :{BLACK}Избери {STRING}
STR_AI_CONFIG_CHANGE_NONE :
STR_AI_CONFIG_CHANGE_AI :AI
STR_AI_CONFIG_CHANGE_GAMESCRIPT :Програмен език на играта
STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Зареди друг скрипт
@@ -4120,9 +4113,7 @@ STR_AI_LIST_CANCEL_TOOLTIP :{BLACK}Не п
# AI Parameters
STR_AI_SETTINGS_CAPTION :{WHITE}{STRING} Параметри
STR_AI_SETTINGS_CAPTION_AI :AI
STR_AI_SETTINGS_CAPTION_GAMESCRIPT :Програмен език на играта
STR_AI_SETTINGS_CLOSE :{BLACK}Затвори
STR_AI_SETTINGS_RESET :{BLACK}Рестартиране
STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING}
@@ -4529,6 +4520,7 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}Инте
STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... машината е унищожена
STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}Никакви превозни средства няма да бъдат налични
STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Промени своята NewGRF конфигурация
STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Няма налични превозни средства все още

View File

@@ -201,6 +201,16 @@ STR_UNITS_POWER_IMPERIAL :{COMMA}{NBSP}cv
STR_UNITS_POWER_METRIC :{COMMA}{NBSP}cv
STR_UNITS_POWER_SI :{COMMA}{NBSP}kW
STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}CV/t
STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}CV/t
STR_UNITS_POWER_IMPERIAL_TO_WEIGHT_SI :{DECIMAL}{NBSP}CV/Mg
STR_UNITS_POWER_METRIC_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}CV/t
STR_UNITS_POWER_METRIC_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}CV/t
STR_UNITS_POWER_METRIC_TO_WEIGHT_SI :{DECIMAL}{NBSP}CV/Mg
STR_UNITS_POWER_SI_TO_WEIGHT_IMPERIAL :{DECIMAL}{NBSP}kW/t
STR_UNITS_POWER_SI_TO_WEIGHT_METRIC :{DECIMAL}{NBSP}kW/t
STR_UNITS_POWER_SI_TO_WEIGHT_SI :{DECIMAL}{NBSP}W/kg
STR_UNITS_WEIGHT_SHORT_IMPERIAL :{COMMA}{NBSP}t
STR_UNITS_WEIGHT_SHORT_METRIC :{COMMA}{NBSP}t
STR_UNITS_WEIGHT_SHORT_SI :{COMMA}{NBSP}kg
@@ -392,10 +402,11 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR :
STR_SCENEDIT_FILE_MENU_QUIT :Surt
# Settings menu
###length 14
###length 15
STR_SETTINGS_MENU_GAME_OPTIONS :Opcions de la partida
STR_SETTINGS_MENU_CONFIG_SETTINGS_TREE :Configuració
STR_SETTINGS_MENU_SCRIPT_SETTINGS :Paràmetres dels scripts d'IA/partida
STR_SETTINGS_MENU_AI_SETTINGS :Configuració de la IA
STR_SETTINGS_MENU_GAMESCRIPT_SETTINGS :Configuració de l'script de partida
STR_SETTINGS_MENU_NEWGRF_SETTINGS :Extensions NewGRF
STR_SETTINGS_MENU_TRANSPARENCY_OPTIONS :Opcions de transparència
STR_SETTINGS_MENU_TOWN_NAMES_DISPLAYED :Mostra els noms de les poblacions
@@ -966,36 +977,6 @@ STR_GAME_OPTIONS_CURRENCY_INR :Rúpia índia (
STR_GAME_OPTIONS_CURRENCY_IDR :Rupia indonèsia (IDR)
STR_GAME_OPTIONS_CURRENCY_MYR :Ringgit (MYR)
###length 2
STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_LEFT :Conducció per l'esquerra
STR_GAME_OPTIONS_ROAD_VEHICLES_DROPDOWN_RIGHT :Conducció per la dreta
STR_GAME_OPTIONS_TOWN_NAMES_FRAME :{BLACK}Estil dels noms de les poblacions:
STR_GAME_OPTIONS_TOWN_NAMES_DROPDOWN_TOOLTIP :{BLACK}Selecciona l'estil dels noms de poblacions
###length 21
STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Anglès
STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Francès
STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Alemany
STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Anglès (addicional)
STR_GAME_OPTIONS_TOWN_NAME_LATIN_AMERICAN :Llatinoamericà
STR_GAME_OPTIONS_TOWN_NAME_SILLY :Graciós
STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Suec
STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Holandès
STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Finès
STR_GAME_OPTIONS_TOWN_NAME_POLISH :Polonès
STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Eslovac
STR_GAME_OPTIONS_TOWN_NAME_NORWEGIAN :Noruec
STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Hongarès
STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Austríac
STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Romanès
STR_GAME_OPTIONS_TOWN_NAME_CZECH :Txec
STR_GAME_OPTIONS_TOWN_NAME_SWISS :Suís
STR_GAME_OPTIONS_TOWN_NAME_DANISH :Danès
STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Turc
STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Italià
STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Català
STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Desa automàticament
STR_GAME_OPTIONS_AUTOSAVE_DROPDOWN_TOOLTIP :{BLACK}Selecciona l'interval de desada automàtica de la partida
@@ -1028,21 +1009,19 @@ STR_GAME_OPTIONS_VIDEO_VSYNC_TOOLTIP :{BLACK}Seleccio
STR_GAME_OPTIONS_VIDEO_DRIVER_INFO :{BLACK}Controlador actual: {STRING}
STR_GAME_OPTIONS_GUI_ZOOM_FRAME :{BLACK}Mida de la interfície
STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Escull la mida dels elements de la interfície
STR_GAME_OPTIONS_GUI_SCALE_FRAME :{BLACK}Mida de la interfície
STR_GAME_OPTIONS_GUI_SCALE_TOOLTIP :{BLACK}Arrossegueu el botó lliscant per a triar la mida de la interfície. Mantingueu premut Ctrl per a un ajustament contigu.
STR_GAME_OPTIONS_GUI_SCALE_AUTO :{BLACK}Detecta la mida automàticament
STR_GAME_OPTIONS_GUI_SCALE_AUTO_TOOLTIP :{BLACK}Marqueu aquesta opció si voleu que s'ajusti la mida de la interfície automàticament.
STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_AUTO :(detecta automàticament)
STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_NORMAL :Normal
STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_2X_ZOOM :Doble
STR_GAME_OPTIONS_GUI_ZOOM_DROPDOWN_4X_ZOOM :Quàdruple
STR_GAME_OPTIONS_GUI_SCALE_BEVELS :{BLACK}Escala els bisells
STR_GAME_OPTIONS_GUI_SCALE_BEVELS_TOOLTIP :{BLACK}Marqueu aquesta opció si voleu que s'escalin els bisells segons la mida de la interfície.
STR_GAME_OPTIONS_FONT_ZOOM :{BLACK}Mida de la lletra
STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_TOOLTIP :{BLACK}Seleccioneu la mida de les fonts de la interfície.
STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_AUTO :(detecta automàticament)
STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_NORMAL :Normal
STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_2X_ZOOM :Doble
STR_GAME_OPTIONS_FONT_ZOOM_DROPDOWN_4X_ZOOM :Quàdruple
STR_GAME_OPTIONS_GUI_SCALE_1X :x1
STR_GAME_OPTIONS_GUI_SCALE_2X :x2
STR_GAME_OPTIONS_GUI_SCALE_3X :x3
STR_GAME_OPTIONS_GUI_SCALE_4X :x4
STR_GAME_OPTIONS_GUI_SCALE_5X :x5
STR_GAME_OPTIONS_GRAPHICS :{BLACK}Gràfics
@@ -1094,8 +1073,6 @@ STR_CURRENCY_PREVIEW :{LTBLUE}Vista p
STR_CURRENCY_CUSTOM_CURRENCY_PREVIEW_TOOLTIP :{BLACK}10.000 lliures (£) en aquesta moneda
STR_CURRENCY_CHANGE_PARAMETER :{BLACK}Canvia el paràmetre de la moneda personalitzada
STR_DIFFICULTY_LEVEL_SETTING_MAXIMUM_NO_COMPETITORS :{LTBLUE}Nombre màxim de competidors: {ORANGE}{COMMA}
STR_NONE :Cap
STR_FUNDING_ONLY :Cap, excepte finançades
STR_MINIMAL :Mínim
@@ -1145,6 +1122,12 @@ STR_SUBSIDY_X2 :x2
STR_SUBSIDY_X3 :x3
STR_SUBSIDY_X4 :x4
###length 4
STR_CLIMATE_TEMPERATE_LANDSCAPE :Paisatge temperat
STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Paisatge subàrtic
STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Paisatge subtropical
STR_CLIMATE_TOYLAND_LANDSCAPE :Paisatge de joguines
###length 7
STR_TERRAIN_TYPE_VERY_FLAT :Molt pla
STR_TERRAIN_TYPE_FLAT :Pla
@@ -1450,6 +1433,8 @@ STR_CONFIG_SETTING_GRAPH_LINE_THICKNESS_HELPTEXT :Gruix de la lí
STR_CONFIG_SETTING_SHOW_NEWGRF_NAME :Mostra el nom del NewGRF a la finestra de construcció de vehicles: {STRING}
STR_CONFIG_SETTING_SHOW_NEWGRF_NAME_HELPTEXT :Afegeix una línia a la finestra de construcció de vehicles que mostri de quin NewGRF és el vehicle seleccionat.
STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS :Mostra les càrregues que poden portar els vehicles a les finestres de llistes {STRING}
STR_CONFIG_SETTING_SHOW_CARGO_IN_LISTS_HELPTEXT :Si s'activa, la càrrega transportable del vehicle apareixerà al damunt de les llistes dels vehicles.
STR_CONFIG_SETTING_LANDSCAPE :Paisatge: {STRING}
STR_CONFIG_SETTING_LANDSCAPE_HELPTEXT :El tipus de paisatge defineix escenaris amb diferents tipus de càrrega i requisits per al creixement de les poblacions. Els NewGRF i l'script de partida poden modificar-ne l'aparença i el comportament.
@@ -1504,6 +1489,10 @@ STR_CONFIG_SETTING_TREE_PLACER_IMPROVED :Millorat
STR_CONFIG_SETTING_ROAD_SIDE :Automòbils: {STRING}
STR_CONFIG_SETTING_ROAD_SIDE_HELPTEXT :Escollir el costat de conducció
###length 2
STR_CONFIG_SETTING_ROAD_SIDE_LEFT :Conducció per l'esquerra
STR_CONFIG_SETTING_ROAD_SIDE_RIGHT :Conducció per la dreta
STR_CONFIG_SETTING_HEIGHTMAP_ROTATION :Rotació del mapa d'alçades: {STRING}
###length 2
STR_CONFIG_SETTING_HEIGHTMAP_ROTATION_COUNTER_CLOCKWISE :Antihorari
@@ -2038,7 +2027,7 @@ STR_CONFIG_SETTING_REVERSE_AT_SIGNALS :Canvi de sentit
STR_CONFIG_SETTING_REVERSE_AT_SIGNALS_HELPTEXT :Permetre als trens girar en un senyal, si esperaven allà durant molt temps
###length 2
STR_CONFIG_SETTING_PATHFINDER_NPF :NPF
STR_CONFIG_SETTING_PATHFINDER_YAPF_RECOMMENDED :YAPF {BLUE}(Recomanat)
STR_CONFIG_SETTING_PATHFINDER_YAPF :YAPF {BLUE}(Recomanat)
STR_CONFIG_SETTING_QUERY_CAPTION :{WHITE}Canvia el valor de l'ajustament
@@ -2081,7 +2070,8 @@ STR_INTRO_HIGHSCORE :{BLACK}Taula de
STR_INTRO_CONFIG_SETTINGS_TREE :{BLACK}Configuració
STR_INTRO_NEWGRF_SETTINGS :{BLACK}Extensions NewGRF
STR_INTRO_ONLINE_CONTENT :{BLACK}Contingut en línia
STR_INTRO_SCRIPT_SETTINGS :{BLACK}Paràmetres dels scripts d'IA/partida
STR_INTRO_AI_SETTINGS :{BLACK}Configuració de la IA
STR_INTRO_GAMESCRIPT_SETTINGS :{BLACK}Configuració de l'script de partida
STR_INTRO_QUIT :{BLACK}Surt
STR_INTRO_TOOLTIP_NEW_GAME :{BLACK}Comença una partida nova. Ctrl+Clic salta la configuració del mapa
@@ -2101,7 +2091,8 @@ STR_INTRO_TOOLTIP_HIGHSCORE :{BLACK}Mostra l
STR_INTRO_TOOLTIP_CONFIG_SETTINGS_TREE :{BLACK}Mostra la finestra de configuració
STR_INTRO_TOOLTIP_NEWGRF_SETTINGS :{BLACK}Mostra la configuració de les extensions NewGRF
STR_INTRO_TOOLTIP_ONLINE_CONTENT :{BLACK}Comprova si hi ha continguts nous i actualitzats per a descarregar
STR_INTRO_TOOLTIP_SCRIPT_SETTINGS :{BLACK}Mostra els paràmetres dels scripts d'IA/partida
STR_INTRO_TOOLTIP_AI_SETTINGS :{BLACK}Mostra les opcions d'IA
STR_INTRO_TOOLTIP_GAMESCRIPT_SETTINGS :{BLACK}Mostra la configuració de l'script de partida
STR_INTRO_TOOLTIP_QUIT :{BLACK}Surt de l'OpenTTD.
STR_INTRO_BASESET :{WHITE}Al joc de gràfics base seleccionat li falten {NUM} sprite{P "" s}.{}Si us plau, comproveu si hi ha actualitzacions disponibles.
@@ -2133,12 +2124,6 @@ STR_CHEAT_CHANGE_DATE :{LTBLUE}Canvia
STR_CHEAT_CHANGE_DATE_QUERY_CAPT :{WHITE}Canvia l'any actual
STR_CHEAT_SETUP_PROD :{LTBLUE}Activa la modificació dels valors de producció: {ORANGE}{STRING}
###length 4
STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Paisatge temperat
STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Paisatge subàrtic
STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Paisatge subtropical
STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Paisatge de joguines
# Livery window
STR_LIVERY_CAPTION :{WHITE}{COMPANY} - Esquema de colors nou
@@ -2498,13 +2483,13 @@ STR_NETWORK_SERVER_MESSAGE_GAME_REASON_LINK_GRAPH :s'espera que s'
STR_NETWORK_MESSAGE_CLIENT_LEAVING :deixant
STR_NETWORK_MESSAGE_CLIENT_JOINED :*** {STRING} s'ha unit a la partida
STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {STRING} s'ha unit a la partida (Client #{2:NUM})
STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {STRING} s'ha unit a la companyia #{2:NUM}
STR_NETWORK_MESSAGE_CLIENT_JOINED_ID :*** {0:STRING} s'ha unit a la partida (Client #{2:NUM})
STR_NETWORK_MESSAGE_CLIENT_COMPANY_JOIN :*** {0:STRING} s'ha unit a la companyia #{2:NUM}
STR_NETWORK_MESSAGE_CLIENT_COMPANY_SPECTATE :*** {STRING} s'ha unit als espectadors
STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {STRING} ha començat una nova companyia (#{2:NUM})
STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {STRING} ha deixat la partida ({2:STRING})
STR_NETWORK_MESSAGE_CLIENT_COMPANY_NEW :*** {0:STRING} ha començat una nova companyia (#{2:NUM})
STR_NETWORK_MESSAGE_CLIENT_LEFT :*** {0:STRING} ha deixat la partida ({2:STRING})
STR_NETWORK_MESSAGE_NAME_CHANGE :*** {STRING} ha canviat el seu nom a {STRING}.
STR_NETWORK_MESSAGE_GIVE_MONEY :*** {STRING} ha donat {2:CURRENCY_LONG} a {1:STRING}.
STR_NETWORK_MESSAGE_GIVE_MONEY :*** {0:STRING} ha donat {2:CURRENCY_LONG} a {1:STRING}.
STR_NETWORK_MESSAGE_SERVER_SHUTDOWN :{WHITE}El servidor ha tancat la sessió
STR_NETWORK_MESSAGE_SERVER_REBOOT :{WHITE}El servidor està reiniciant...{}Espera un moment...
STR_NETWORK_MESSAGE_KICKED :*** S'ha expulsat {STRING}. Motiu: {STRING}
@@ -2631,6 +2616,7 @@ STR_STATION_BUILD_COVERAGE_AREA_OFF_TOOLTIP :{BLACK}No marca
STR_STATION_BUILD_COVERAGE_AREA_ON_TOOLTIP :{BLACK}Marcar l'àrea de cobertura del lloc proposat
STR_STATION_BUILD_ACCEPTS_CARGO :{BLACK}Accepta: {GOLD}{CARGO_LIST}
STR_STATION_BUILD_SUPPLIES_CARGO :{BLACK}Provisions: {GOLD}{CARGO_LIST}
STR_STATION_BUILD_INFRASTRUCTURE_COST :{BLACK}Cost de manteniment: {GOLD}{CURRENCY_SHORT}/any
# Join station window
STR_JOIN_STATION_CAPTION :{WHITE}Ajuntar estació
@@ -3144,6 +3130,8 @@ STR_MAPGEN_MAPSIZE :{BLACK}Mida del
STR_MAPGEN_MAPSIZE_TOOLTIP :{BLACK}Selecciona la mida del mapa en cel·les. El nombre de cel·les disponibles serà lleugerament més petit
STR_MAPGEN_BY :{BLACK}*
STR_MAPGEN_NUMBER_OF_TOWNS :{BLACK}Nombre de poblacions:
STR_MAPGEN_TOWN_NAME_LABEL :{BLACK}Estil dels noms de les poblacions:
STR_MAPGEN_TOWN_NAME_DROPDOWN_TOOLTIP :{BLACK}Selecciona l'estil dels noms de poblacions
STR_MAPGEN_DATE :{BLACK}Data:
STR_MAPGEN_NUMBER_OF_INDUSTRIES :{BLACK}Nombre d'indústries:
STR_MAPGEN_HEIGHTMAP_HEIGHT :{BLACK}Alçada del cim més alt:
@@ -3159,11 +3147,40 @@ STR_MAPGEN_DESERT_COVERAGE_DOWN :{BLACK}Redueix
STR_MAPGEN_DESERT_COVERAGE_TEXT :{BLACK}{NUM}{NBSP}%
STR_MAPGEN_LAND_GENERATOR :{BLACK}Generació de terrenys:
STR_MAPGEN_TERRAIN_TYPE :{BLACK}Tipus de terreny:
STR_MAPGEN_QUANTITY_OF_SEA_LAKES :{BLACK}Nivell de mar:
STR_MAPGEN_SEA_LEVEL :{BLACK}Nivell de mar:
STR_MAPGEN_QUANTITY_OF_RIVERS :{BLACK}Quantitat de rius:
STR_MAPGEN_SMOOTHNESS :{BLACK}Suavitat:
STR_MAPGEN_VARIETY :{BLACK}Varietat:
STR_MAPGEN_GENERATE :{WHITE}Genera
STR_MAPGEN_NEWGRF_SETTINGS :{BLACK}Configuració del NewGRF
STR_MAPGEN_NEWGRF_SETTINGS_TOOLTIP :{BLACK}Mostra la configuració de NewGRF
STR_MAPGEN_AI_SETTINGS :{BLACK}Configuració d'IA
STR_MAPGEN_AI_SETTINGS_TOOLTIP :{BLACK}Mostra la configuració de la IA
STR_MAPGEN_GS_SETTINGS :{BLACK}Configuració de l'script de partida
STR_MAPGEN_GS_SETTINGS_TOOLTIP :{BLACK}Mostra la configuració de l'script de partida.
###length 21
STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Anglès
STR_MAPGEN_TOWN_NAME_FRENCH :Francès
STR_MAPGEN_TOWN_NAME_GERMAN :Alemany
STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Anglès (addicional)
STR_MAPGEN_TOWN_NAME_LATIN_AMERICAN :Llatinoamericà
STR_MAPGEN_TOWN_NAME_SILLY :Graciós
STR_MAPGEN_TOWN_NAME_SWEDISH :Suec
STR_MAPGEN_TOWN_NAME_DUTCH :Holandès
STR_MAPGEN_TOWN_NAME_FINNISH :Finès
STR_MAPGEN_TOWN_NAME_POLISH :Polonès
STR_MAPGEN_TOWN_NAME_SLOVAK :Eslovac
STR_MAPGEN_TOWN_NAME_NORWEGIAN :Noruec
STR_MAPGEN_TOWN_NAME_HUNGARIAN :Hongarès
STR_MAPGEN_TOWN_NAME_AUSTRIAN :Austríac
STR_MAPGEN_TOWN_NAME_ROMANIAN :Romanès
STR_MAPGEN_TOWN_NAME_CZECH :Txec
STR_MAPGEN_TOWN_NAME_SWISS :Suís
STR_MAPGEN_TOWN_NAME_DANISH :Danès
STR_MAPGEN_TOWN_NAME_TURKISH :Turc
STR_MAPGEN_TOWN_NAME_ITALIAN :Italià
STR_MAPGEN_TOWN_NAME_CATALAN :Català
# Strings for map borders at game generation
STR_MAPGEN_BORDER_TYPE :{BLACK}Vores del mapa:
@@ -3309,6 +3326,11 @@ STR_SPRITE_ALIGNER_PREVIOUS_BUTTON :{BLACK}Sprite a
STR_SPRITE_ALIGNER_PREVIOUS_TOOLTIP :{BLACK}Procedeix cap a l'sprite normal anterior, saltant qualsevol sprite pseudo/recolor/font i passant del primer sprite a l'últim
STR_SPRITE_ALIGNER_SPRITE_TOOLTIP :{BLACK}Representació de l'sprite seleccionat actualment. L'alineació s'ignora quan es dibuixa aquest sprite
STR_SPRITE_ALIGNER_MOVE_TOOLTIP :{BLACK}Desplaça l'sprite un píxel en el sentit indicat. Amb Ctrl+Clic el desplaça 8 píxels.
###length 2
STR_SPRITE_ALIGNER_CENTRE_SPRITE :{BLACK}Sprite centrat
STR_SPRITE_ALIGNER_RESET_BUTTON :{BLACK}Restableix relatius
STR_SPRITE_ALIGNER_RESET_TOOLTIP :{BLACK}Restableix els desplaçaments relatius actuals
STR_SPRITE_ALIGNER_OFFSETS_ABS :{BLACK}Desplaçament X: {NUM}, Desplaçament Y: {NUM} (Absolut)
@@ -3326,15 +3348,15 @@ STR_NEWGRF_ERROR_MSG_FATAL :{RED}Fatal: {SI
STR_NEWGRF_ERROR_FATAL_POPUP :{WHITE}S'ha produït un error fatal de NewGRF:{}{STRING}
STR_NEWGRF_ERROR_POPUP :{WHITE}S'ha produït un error relacionat amb els NewGRF:{}{STRING}
STR_NEWGRF_ERROR_VERSION_NUMBER :{1:STRING} no funcionarà amb la versió TTDPatch informada per l'OpenTTD
STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} és per la versió {STRING} de TTD
STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} està dissenyat per ser utilitzat amb {STRING}
STR_NEWGRF_ERROR_INVALID_PARAMETER :Paràmetre invàlid per {1:STRING}: paràmetre {STRING} ({NUM})
STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} ha de ser carregat abans de {STRING}
STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} ha de ser carregat després de {STRING}
STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} necessita l'OpenTTD versió {STRING} o superior
STR_NEWGRF_ERROR_DOS_OR_WINDOWS :{1:STRING} és per a la versió {2:STRING} del TTD
STR_NEWGRF_ERROR_UNSET_SWITCH :{1:STRING} està dissenyat per a fer-se servir amb {2:STRING}
STR_NEWGRF_ERROR_INVALID_PARAMETER :Paràmetre no vàlid per a {1:STRING}: paràmetre {2:STRING} ({3:NUM})
STR_NEWGRF_ERROR_LOAD_BEFORE :{1:STRING} s'ha de carregar abans de {2:STRING}
STR_NEWGRF_ERROR_LOAD_AFTER :{1:STRING} s'ha de carregar després de {2:STRING}
STR_NEWGRF_ERROR_OTTD_VERSION_NUMBER :{1:STRING} necessita la versió {2:STRING} de l'OpenTTD o posterior
STR_NEWGRF_ERROR_AFTER_TRANSLATED_FILE :l'arxiu GRF dissenyat està pendent de traduir
STR_NEWGRF_ERROR_TOO_MANY_NEWGRFS_LOADED :Hi ha massa arxius NewGRF carregats
STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Carregant {1:STRING} com a NewGRF estàtic amb {STRING} podria causar desincronitzacions
STR_NEWGRF_ERROR_STATIC_GRF_CAUSES_DESYNC :Si es carrega {1:STRING} com a NewGRF estàtic amb {2:STRING}, pot provocar desincronitzacions
STR_NEWGRF_ERROR_UNEXPECTED_SPRITE :Sprite inesperat (sprite {3:NUM})
STR_NEWGRF_ERROR_UNKNOWN_PROPERTY :Propietat d'acció 0 desconeguda {4:HEX} (sprite {3:NUM})
STR_NEWGRF_ERROR_INVALID_ID :Intent d'utilitzar una ID invàlid (sprite {3:NUM})
@@ -3466,14 +3488,14 @@ STR_LOCAL_AUTHORITY_ACTION_EXCLUSIVE_TRANSPORT :Compra els dret
STR_LOCAL_AUTHORITY_ACTION_BRIBE :Suborna les autoritats locals
###length 8
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{YELLOW}Inicia una petita campanya de publicitat, per atraure més passatgers i càrregues als teus serveis de transport.{}Proporciona una millora temporal dels ratis de les estacions dins d'un radi petit al voltant del centre de la població.{}Cost: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{YELLOW}Inicia una mitjana campanya de publicitat, per atraure més passatgers i càrregues als teus serveis de transport.{}Proporciona una millora temporal dels ratis de les estacions dins un radi mitjà al voltant del centre de la població.{}Cost: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{YELLOW}Inicia una gran campanya de publicitat, per atraure més passatgers i càrregues als teus serveis de transport.{}Proporciona una millora temporal dels ratis de les estacions dins d'un radi gran al voltant del centre de la població.{}Cost: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{YELLOW}Finança la reconstrucció de la xarxa local de carrers. Dificulta notablement el trànsit durant 6 mesos.{}Causa molèsties considerables al trànsit de vehicles de carretera durant 6 mesos.{}Cost: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{YELLOW}Construeix una estàtua en honor a la teva companyia.{}Proporciona una millora permanent dels ratis d'estació de la població.{}Cost: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{YELLOW}Finança la construcció de nous edificis comercials a la població.{}Proporciona una millora temporal del creixement d'aquesta població.{}Cost: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{YELLOW}Compra per 1 any els drets exclusius de transport en la població. L'autoritat local només permetrà utilitzar les instal·lacions de la teva companyia de transports als passatgers i les mercaderies.{}L'autoritat local no permetrà que els passatgers i càrregues locals usin les estacions dels oponents.{}Cost: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{YELLOW}Suborna les autoritats locals per incrementar el teu rati, a risc de greus penalitzacions si et pesquen.{}Cost: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_SMALL_ADVERTISING :{PUSH_COLOUR}{YELLOW}Inicia una petita campanya de publicitat, per atraure més passatgers i càrregues als teus serveis de transport.{}Proporciona una millora temporal dels ratis de les estacions dins d'un radi petit al voltant del centre de la població.{}{POP_COLOUR}Cost: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_MEDIUM_ADVERTISING :{PUSH_COLOUR}{YELLOW}Inicia una mitjana campanya de publicitat, per atraure més passatgers i càrregues als teus serveis de transport.{}Proporciona una millora temporal dels ratis de les estacions dins un radi mitjà al voltant del centre de la població.{}{PUSH_COLOUR}Cost: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_LARGE_ADVERTISING :{PUSH_COLOUR}{YELLOW}Inicia una gran campanya de publicitat, per atraure més passatgers i càrregues als teus serveis de transport.{}Proporciona una millora temporal dels ratis de les estacions dins d'un radi gran al voltant del centre de la població.{}{POP_COLOUR}Cost: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_ROAD_RECONSTRUCTION :{PUSH_COLOUR}{YELLOW}Finança la reconstrucció de la xarxa local de carrers. Dificulta notablement el trànsit durant 6 mesos.{}Causa molèsties considerables al trànsit de vehicles de carretera durant 6 mesos.{}{POP_COLOUR}Cost: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_STATUE_OF_COMPANY :{PUSH_COLOUR}{YELLOW}Construeix una estàtua en honor a la teva companyia.{}Proporciona una millora permanent dels ratis d'estació de la població.{}{POP_COLOUR}Cost: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_NEW_BUILDINGS :{PUSH_COLOUR}{YELLOW}Finança la construcció de nous edificis comercials a la població.{}Proporciona una millora temporal del creixement d'aquesta població.{}{POP_COLOUR}Cost: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_EXCLUSIVE_TRANSPORT :{PUSH_COLOUR}{YELLOW}Compra per 1 any els drets exclusius de transport en la població. L'autoritat local només permetrà utilitzar les instal·lacions de la teva companyia de transports als passatgers i les mercaderies.{}L'autoritat local no permetrà que els passatgers i càrregues locals usin les estacions dels oponents.{}{POP_COLOUR}Cost: {CURRENCY_LONG}
STR_LOCAL_AUTHORITY_ACTION_TOOLTIP_BRIBE :{PUSH_COLOUR}{YELLOW}Suborna les autoritats locals per incrementar el teu rati, a risc de greus penalitzacions si et pesquen.{}{POP_COLOUR}Cost: {CURRENCY_LONG}
# Goal window
STR_GOALS_CAPTION :{WHITE}{COMPANY} Objectius
@@ -3646,16 +3668,18 @@ STR_FINANCES_SECTION_SHIP_REVENUE :{GOLD}Vaixells
STR_FINANCES_SECTION_LOAN_INTEREST :{GOLD}Interessos del préstec
STR_FINANCES_SECTION_OTHER :{GOLD}Altres
STR_FINANCES_TOTAL_CAPTION :{WHITE}Total
STR_FINANCES_NEGATIVE_INCOME :-{CURRENCY_LONG}
STR_FINANCES_ZERO_INCOME :{CURRENCY_LONG}
STR_FINANCES_POSITIVE_INCOME :+{CURRENCY_LONG}
STR_FINANCES_NET_PROFIT :{WHITE}Benefici net
STR_FINANCES_PROFIT :{WHITE}Benefici
STR_FINANCES_BANK_BALANCE_TITLE :{WHITE}Balanç bancari
STR_FINANCES_OWN_FUNDS_TITLE :{WHITE}Fons propis
STR_FINANCES_LOAN_TITLE :{WHITE}Préstec
STR_FINANCES_INTEREST_RATE :{WHITE}Interès del préstec: {BLACK}{NUM}{NBSP}%
STR_FINANCES_MAX_LOAN :{WHITE}Préstec màxim: {BLACK}{CURRENCY_LONG}
STR_FINANCES_TOTAL_CURRENCY :{BLACK}{CURRENCY_LONG}
STR_FINANCES_BANK_BALANCE :{WHITE}{CURRENCY_LONG}
STR_FINANCES_BORROW_BUTTON :{BLACK}Demana {CURRENCY_LONG}
STR_FINANCES_BORROW_TOOLTIP :{BLACK}Augmenta l'import del préstec Ctrl+Clic per demanar tants diners com sigui possible
STR_FINANCES_REPAY_BUTTON :{BLACK}Amortitza {CURRENCY_LONG}
@@ -3756,7 +3780,7 @@ STR_INDUSTRY_VIEW_PRODUCES_N_CARGO :{BLACK}Produeix
STR_INDUSTRY_VIEW_CARGO_LIST_EXTENSION :, {STRING}{STRING}
STR_INDUSTRY_VIEW_REQUIRES :{BLACK}Necessita:
STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{STRING}{BLACK}{3:STRING}
STR_INDUSTRY_VIEW_ACCEPT_CARGO :{YELLOW}{0:STRING}{BLACK}{3:STRING}
STR_INDUSTRY_VIEW_ACCEPT_CARGO_AMOUNT :{YELLOW}{STRING}{BLACK}: {CARGO_SHORT} esperant{STRING}
STR_CONFIG_GAME_PRODUCTION :{WHITE}Canvia la producció (múltiple de 8, fins a 2040)
@@ -3786,6 +3810,8 @@ STR_VEHICLE_LIST_MANAGE_LIST_TOOLTIP :{BLACK}Envia in
STR_VEHICLE_LIST_REPLACE_VEHICLES :Substitueix vehicles
STR_VEHICLE_LIST_SEND_FOR_SERVICING :Envia a fer revisió
STR_VEHICLE_LIST_PROFIT_THIS_YEAR_LAST_YEAR :{TINY_FONT}{BLACK}Benefici enguany: {CURRENCY_LONG} (darrer any: {CURRENCY_LONG})
STR_VEHICLE_LIST_CARGO :{TINY_FONT}{BLACK}[{CARGO_LIST}]
STR_VEHICLE_LIST_NAME_AND_CARGO :{TINY_FONT}{BLACK}{STRING} {STRING}
STR_VEHICLE_LIST_SEND_TRAIN_TO_DEPOT :Envia a la cotxera
STR_VEHICLE_LIST_SEND_ROAD_VEHICLE_TO_DEPOT :Envia a la cotxera
@@ -3877,6 +3903,11 @@ STR_PURCHASE_INFO_MAX_TE :{BLACK}Esforç
STR_PURCHASE_INFO_AIRCRAFT_RANGE :{BLACK}Abast: {GOLD}{COMMA} cel·les
STR_PURCHASE_INFO_AIRCRAFT_TYPE :{BLACK}Tipus d'aeronau: {GOLD}{STRING}
###length 3
STR_CARGO_TYPE_FILTER_ALL :Tots els tipus de càrrega
STR_CARGO_TYPE_FILTER_FREIGHT :Càrrega
STR_CARGO_TYPE_FILTER_NONE :Cap
###length VEHICLE_TYPES
STR_BUY_VEHICLE_TRAIN_LIST_TOOLTIP :{BLACK}Llista de selecció de trens i vagons. Clica al vehicle per més informació. Ctrl+Click per a alternar entre mostrar/ocultar el vehicle ferroviari
STR_BUY_VEHICLE_ROAD_VEHICLE_LIST_TOOLTIP :{BLACK}Llista de models de vehicles de carretera. Clica sobre el model per més informació. Amb Ctrl+Clic, commuta entre mostrar o ocultar el model.
@@ -4045,7 +4076,7 @@ STR_ENGINE_PREVIEW_AIRCRAFT :{G=Masculin}avi
STR_ENGINE_PREVIEW_SHIP :{G=Masculin}vaixell
STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER :{BLACK}Cost: {CURRENCY_LONG} Pes: {WEIGHT_SHORT}{}Velocitat: {VELOCITY} Potència: {POWER}{}Cost de circulació: {CURRENCY_LONG}/any{}Capacitat: {CARGO_LONG}
STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Cost: {CURRENCY_LONG} Pes: {WEIGHT_SHORT}{}Velocitat: {VELOCITY} Potència: {POWER} Màx. E.T.: {6:FORCE}{}Cost d'utilització: {4:CURRENCY_LONG}/any{}Capacitat: {5:CARGO_LONG}
STR_ENGINE_PREVIEW_COST_WEIGHT_SPEED_POWER_MAX_TE :{BLACK}Cost: {0:CURRENCY_LONG} Pes: {1:WEIGHT_SHORT}{}Velocitat: {2:VELOCITY} Potència: {3:POWER} Màx. E.T.: {6:FORCE}{}Cost d'utilització: {4:CURRENCY_LONG}/any{}Capacitat: {5:CARGO_LONG}
STR_ENGINE_PREVIEW_COST_MAX_SPEED_CAP_RUNCOST :{BLACK}Cost: {CURRENCY_LONG} Vel. Màx: {VELOCITY}{}Capacitat: {CARGO_LONG}{}Cost d'utilització: {CURRENCY_LONG}/any
STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_CAP_RUNCOST :{BLACK}Cost: {CURRENCY_LONG} Velocitat màx.: {VELOCITY}{}Tipus d'aeronau: {STRING}{}Capacitat: {CARGO_LONG}, {CARGO_LONG}{}Cost de circulació: {CURRENCY_LONG} per any
STR_ENGINE_PREVIEW_COST_MAX_SPEED_TYPE_CAP_RUNCOST :{BLACK}Cost: {CURRENCY_LONG} Velocitat màx.: {VELOCITY}{}Tipus d'aeronau: {STRING}{}Capacitat: {CARGO_LONG}{}Cost de circulació: {CURRENCY_LONG} per any
@@ -4204,12 +4235,13 @@ STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED :{BLACK}Pes: {LT
STR_VEHICLE_INFO_WEIGHT_POWER_MAX_SPEED_MAX_TE :{BLACK}Pes: {LTBLUE}{WEIGHT_SHORT} {BLACK}Potència: {LTBLUE}{POWER}{BLACK} Vel. màx: {LTBLUE}{VELOCITY} {BLACK}E.T. màx.: {LTBLUE}{FORCE}
STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR :{BLACK}Benefici d'aquest any: {LTBLUE}{CURRENCY_LONG} (darrer any: {CURRENCY_LONG})
STR_VEHICLE_INFO_PROFIT_THIS_YEAR_LAST_YEAR_MIN_PERFORMANCE :{BLACK}Benefici aquest any: {LTBLUE}{CURRENCY_LONG} (l'any passat: {CURRENCY_LONG}) {BLACK}Rendiment mínim: {LTBLUE}{POWER_TO_WEIGHT}
STR_VEHICLE_INFO_RELIABILITY_BREAKDOWNS :{BLACK}Fiabilitat: {LTBLUE}{COMMA}% {BLACK}Avaries des de la darrera revisió: {LTBLUE}{COMMA}
STR_VEHICLE_INFO_BUILT_VALUE :{LTBLUE}{ENGINE} {BLACK}Fabricat: {LTBLUE}{NUM}{BLACK} Valor: {LTBLUE}{CURRENCY_LONG}
STR_VEHICLE_INFO_NO_CAPACITY :{BLACK}Capacitat: {LTBLUE}Cap{STRING}
STR_VEHICLE_INFO_CAPACITY :{BLACK}Capacitat: {LTBLUE}{CARGO_LONG}{3:STRING}
STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Capacitat: {LTBLUE}{CARGO_LONG}{3:STRING} (x{4:NUM})
STR_VEHICLE_INFO_CAPACITY :{BLACK}Capacitat: {LTBLUE}{0:CARGO_LONG}{3:STRING}
STR_VEHICLE_INFO_CAPACITY_MULT :{BLACK}Capacitat: {LTBLUE}{0:CARGO_LONG}{3:STRING} (x{4:NUM})
STR_VEHICLE_INFO_CAPACITY_CAPACITY :{BLACK}Capacitat: {LTBLUE}{CARGO_LONG}, {CARGO_LONG}{STRING}
STR_VEHICLE_INFO_FEEDER_CARGO_VALUE :{BLACK}Transferir crèdits: {LTBLUE}{CURRENCY_LONG}
@@ -4537,12 +4569,14 @@ STR_ERROR_AI_PLEASE_REPORT_CRASH :{WHITE}Un dels
STR_ERROR_AI_DEBUG_SERVER_ONLY :{YELLOW}La finestra de depuració dels scripts d'IA/partida només està disponible al servidor.
# AI configuration window
STR_AI_CONFIG_CAPTION :{WHITE}Configuració dels scripts de les IA/partida
STR_AI_CONFIG_CAPTION_AI :{WHITE}Configuració de la IA
STR_AI_CONFIG_CAPTION_GAMESCRIPT :{WHITE}Configuració de l'script de partida
STR_AI_CONFIG_GAMELIST_TOOLTIP :{BLACK}Aquest és l'script que s'usarà a la propera partida.
STR_AI_CONFIG_AILIST_TOOLTIP :{BLACK}Aquesta llista conté les IA que es carregaran a la propera partida.
STR_AI_CONFIG_HUMAN_PLAYER :Jugador humà
STR_AI_CONFIG_RANDOM_AI :IA aleatòria
STR_AI_CONFIG_NONE :(cap)
STR_AI_CONFIG_MAX_COMPETITORS :{LTBLUE}Nombre màxim de competidors: {ORANGE}{COMMA}
STR_AI_CONFIG_MOVE_UP :{BLACK}Mou amunt
STR_AI_CONFIG_MOVE_UP_TOOLTIP :{BLACK}Desplaça la IA seleccionada una posició cap amunt
@@ -4550,12 +4584,11 @@ STR_AI_CONFIG_MOVE_DOWN :{BLACK}Mou aval
STR_AI_CONFIG_MOVE_DOWN_TOOLTIP :{BLACK}Desplaça la IA seleccionada una posició cap avall.
STR_AI_CONFIG_GAMESCRIPT :{SILVER}Script de partida
STR_AI_CONFIG_GAMESCRIPT_PARAM :{SILVER}Paràmetres
STR_AI_CONFIG_AI :{SILVER}IA
STR_AI_CONFIG_CHANGE :{BLACK}Selecciona {STRING}
STR_AI_CONFIG_CHANGE_NONE :
STR_AI_CONFIG_CHANGE_AI :una IA
STR_AI_CONFIG_CHANGE_GAMESCRIPT :un script de partida
STR_AI_CONFIG_CHANGE_AI :{BLACK}Trieu una IA
STR_AI_CONFIG_CHANGE_GAMESCRIPT :{BLACK}Tria un script de partida
STR_AI_CONFIG_CHANGE_TOOLTIP :{BLACK}Carrega un altre script
STR_AI_CONFIG_CONFIGURE :{BLACK}Configura
STR_AI_CONFIG_CONFIGURE_TOOLTIP :{BLACK}Configura els paràmetres de l'script
@@ -4584,9 +4617,7 @@ STR_SCREENSHOT_HEIGHTMAP_SCREENSHOT :{BLACK}Captura
STR_SCREENSHOT_MINIMAP_SCREENSHOT :{BLACK}Captura de pantalla del minimapa
# AI Parameters
STR_AI_SETTINGS_CAPTION :{WHITE}Paràmetres {STRING}
STR_AI_SETTINGS_CAPTION_AI :de la IA
STR_AI_SETTINGS_CAPTION_GAMESCRIPT :de l'script de partida
STR_AI_SETTINGS_CAPTION_AI :{WHITE}Paràmetres de la IA
STR_AI_SETTINGS_CLOSE :{BLACK}Tanca
STR_AI_SETTINGS_RESET :{BLACK}Restableix
STR_AI_SETTINGS_SETTING :{STRING}: {ORANGE}{STRING}
@@ -5004,6 +5035,8 @@ STR_ERROR_CAN_T_CHANGE_SERVICING :{WHITE}No es po
STR_ERROR_VEHICLE_IS_DESTROYED :{WHITE}... vehicle està destruït
STR_ERROR_CAN_T_CLONE_VEHICLE_LIST :{WHITE}... no tots els vehicles són idèntics.
STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL :{WHITE}No hi haurà cap vehicle disponible
STR_ERROR_NO_VEHICLES_AVAILABLE_AT_ALL_EXPLANATION :{WHITE}Canvia la teva configuració dels NewGRF
STR_ERROR_NO_VEHICLES_AVAILABLE_YET :{WHITE}Encara no hi ha vehicles disponibles
@@ -5030,6 +5063,8 @@ STR_ERROR_CAN_T_SKIP_TO_ORDER :{WHITE}Impossib
STR_ERROR_CAN_T_COPY_SHARE_ORDER :{WHITE}... el vehicle no pot anar a totes les estacions
STR_ERROR_CAN_T_ADD_ORDER :{WHITE}... el vehicle no pot anar a aquesta estació
STR_ERROR_CAN_T_ADD_ORDER_SHARED :{WHITE}... un vehicle que comparteix aquesta ordre no pot anar a aquesta estació
STR_ERROR_CAN_T_COPY_ORDER_VEHICLE_LIST :{WHITE}... no tots els vehicles tenen les mateixes ordres.
STR_ERROR_CAN_T_SHARE_ORDER_VEHICLE_LIST :{WHITE}... no tots els vehicles comparteixen ordres.
STR_ERROR_CAN_T_SHARE_ORDER_LIST :{WHITE}No es pot compartir la llista d'ordres...
STR_ERROR_CAN_T_STOP_SHARING_ORDER_LIST :{WHITE}No es pot deixar de compartir la llista d'ordres...

View File

@@ -163,6 +163,7 @@ STR_UNITS_POWER_SI :{COMMA}кВт
# Common window strings
@@ -225,7 +226,7 @@ STR_SCENEDIT_FILE_MENU_SEPARATOR :
STR_SCENEDIT_FILE_MENU_QUIT :Вӗҫле
# Settings menu
###length 14
###length 15
STR_SETTINGS_MENU_GAME_OPTIONS :Вӑййи майлаштару
STR_SETTINGS_MENU_NEWGRF_SETTINGS :NewGRF майлаштару
@@ -484,30 +485,6 @@ STR_NEWS_MESSAGE_CAPTION :{WHITE}Пӗлт
###length 42
STR_GAME_OPTIONS_CURRENCY_RUR :Вырӑсла тенкӗ (RUR)
###length 2
###length 21
STR_GAME_OPTIONS_TOWN_NAME_ORIGINAL_ENGLISH :Акӑлчан
STR_GAME_OPTIONS_TOWN_NAME_FRENCH :Францири
STR_GAME_OPTIONS_TOWN_NAME_GERMAN :Нимӗҫ
STR_GAME_OPTIONS_TOWN_NAME_ADDITIONAL_ENGLISH :Акӑлчан (Хушма)
STR_GAME_OPTIONS_TOWN_NAME_SILLY :Акӑлчан (Кулӑшма)
STR_GAME_OPTIONS_TOWN_NAME_SWEDISH :Шведла
STR_GAME_OPTIONS_TOWN_NAME_DUTCH :Голланд
STR_GAME_OPTIONS_TOWN_NAME_FINNISH :Финла
STR_GAME_OPTIONS_TOWN_NAME_POLISH :Поляк
STR_GAME_OPTIONS_TOWN_NAME_SLOVAK :Словак
STR_GAME_OPTIONS_TOWN_NAME_HUNGARIAN :Венгрла
STR_GAME_OPTIONS_TOWN_NAME_AUSTRIAN :Австри
STR_GAME_OPTIONS_TOWN_NAME_ROMANIAN :Рим
STR_GAME_OPTIONS_TOWN_NAME_CZECH :Чехла
STR_GAME_OPTIONS_TOWN_NAME_SWISS :Швеци
STR_GAME_OPTIONS_TOWN_NAME_DANISH :Датчан
STR_GAME_OPTIONS_TOWN_NAME_TURKISH :Турккӑла
STR_GAME_OPTIONS_TOWN_NAME_ITALIAN :Итали
STR_GAME_OPTIONS_TOWN_NAME_CATALAN :Катталун
STR_GAME_OPTIONS_AUTOSAVE_FRAME :{BLACK}Хӑй управ
# Autosave dropdown
@@ -533,7 +510,6 @@ STR_GAME_OPTIONS_RESOLUTION_OTHER :расна
# Custom currency window
@@ -544,7 +520,6 @@ STR_CURRENCY_SUFFIX :{LTBLUE}Суф
STR_CURRENCY_PREVIEW :{LTBLUE}Малтанласа пӑхса тухни: {ORANGE}{CURRENCY_LONG}
STR_NONE :Ҫук
STR_NUM_CUSTOM :Харпӑр хӑй
STR_NUM_CUSTOM_NUMBER :Харпӑр хӑй ({NUM})
@@ -568,6 +543,12 @@ STR_SUBSIDY_X2 :x2
STR_SUBSIDY_X3 :x3
STR_SUBSIDY_X4 :x4
###length 4
STR_CLIMATE_TEMPERATE_LANDSCAPE :Виҫеллӗ климат
STR_CLIMATE_SUB_ARCTIC_LANDSCAPE :Сивӗ климат
STR_CLIMATE_SUB_TROPICAL_LANDSCAPE :Тропик климат
STR_CLIMATE_TOYLAND_LANDSCAPE :Вӑйӑ пахчи
###length 7
###length 4
@@ -696,6 +677,8 @@ STR_CONFIG_SETTING_TREE_PLACER_ORIGINAL :Чӑн
###length 2
###length 2
@@ -891,12 +874,6 @@ STR_ABANDON_GAME_CAPTION :{WHITE}Вӑйй
# Cheat window
STR_CHEAT_CHANGE_DATE :{LTBLUE}Тӳрлет кун: {ORANGE}{DATE_SHORT}
###length 4
STR_CHEAT_SWITCH_CLIMATE_TEMPERATE_LANDSCAPE :Виҫеллӗ климат
STR_CHEAT_SWITCH_CLIMATE_SUB_ARCTIC_LANDSCAPE :Сивӗ климат
STR_CHEAT_SWITCH_CLIMATE_SUB_TROPICAL_LANDSCAPE :Тропик климат
STR_CHEAT_SWITCH_CLIMATE_TOYLAND_LANDSCAPE :Вӑйӑ пахчи
# Livery window
@@ -1208,6 +1185,27 @@ STR_ABOUT_VERSION :{BLACK}OpenTTD
STR_MAPGEN_MAPSIZE :{BLACK}Виҫа картти:
STR_MAPGEN_BY :{BLACK}*
###length 21
STR_MAPGEN_TOWN_NAME_ORIGINAL_ENGLISH :Акӑлчан
STR_MAPGEN_TOWN_NAME_FRENCH :Францири
STR_MAPGEN_TOWN_NAME_GERMAN :Нимӗҫ
STR_MAPGEN_TOWN_NAME_ADDITIONAL_ENGLISH :Акӑлчан (Хушма)
STR_MAPGEN_TOWN_NAME_SILLY :Акӑлчан (Кулӑшма)
STR_MAPGEN_TOWN_NAME_SWEDISH :Шведла
STR_MAPGEN_TOWN_NAME_DUTCH :Голланд
STR_MAPGEN_TOWN_NAME_FINNISH :Финла
STR_MAPGEN_TOWN_NAME_POLISH :Поляк
STR_MAPGEN_TOWN_NAME_SLOVAK :Словак
STR_MAPGEN_TOWN_NAME_HUNGARIAN :Венгрла
STR_MAPGEN_TOWN_NAME_AUSTRIAN :Австри
STR_MAPGEN_TOWN_NAME_ROMANIAN :Рим
STR_MAPGEN_TOWN_NAME_CZECH :Чехла
STR_MAPGEN_TOWN_NAME_SWISS :Швеци
STR_MAPGEN_TOWN_NAME_DANISH :Датчан
STR_MAPGEN_TOWN_NAME_TURKISH :Турккӑла
STR_MAPGEN_TOWN_NAME_ITALIAN :Итали
STR_MAPGEN_TOWN_NAME_CATALAN :Катталун
# Strings for map borders at game generation
@@ -1241,6 +1239,10 @@ STR_NEWGRF_INSPECT_CAPTION_OBJECT_AT_OBJECT :Объект
# Sprite aligner window
###length 2
# NewGRF (self) generated warnings/errors
STR_NEWGRF_ERROR_MSG_INFO :{SILVER}{STRING}
@@ -1380,6 +1382,8 @@ STR_INDUSTRY_DIRECTORY_NONE :{ORANGE}- Ҫу
###length VEHICLE_TYPES
###length 3
###length VEHICLE_TYPES
###length VEHICLE_TYPES
@@ -1580,7 +1584,6 @@ STR_ORDER_GO_TO_STATION :{STRING} {STATI
STR_AI_CONFIG_CHANGE_NONE :
# Available AIs window
@@ -1696,6 +1699,7 @@ STR_ERROR_OBJECT_IN_THE_WAY :{WHITE}Ҫул
# Specific vehicle errors

Some files were not shown because too many files have changed in this diff Show More